Settings sheet clips Good / Warning ΔE threshold fields past the modal edge #165
Closed
opened 2026-09-13 22:37:10 +01:00 by gronod
·
1 comment
No Branch/Tag Specified
main
docs/27-roadmap-candidates
develop
milestone/m13-print-ticket
feat/218-paper-source
feat/217-panel-ticket-restore
bugfix/211-print-output-flip
milestone/m12-native-spool
feat/202-airprint-detection
feat/201-native-print-operation
feat/201-raster-canvas
feat/201-ticket-capture
feat/201-pm-ticket-bridge
chore/m11-sync-develop
milestone/m11-print-settings
chore/m11-docs-hygiene
feat/186-panel-binding
feat/181-canon-media-locale
feat/180-epson-qual-options
feat/183-stage2-print-settings
chore/m11-tracking
docs/ui-interactive-map
v2.0.4-prerelease-docs27
v2.0.4
v2.0.3
v2.0.3-prerelease
v2.0.2
v2.0.1
v2.0.0
Labels
Clear labels
Bug/Architecture
Bug/Backend
Bug/DevOps
Bug/UI
Compat/Breaking
Feature/Architecture
Feature/Backend
Feature/DevOps
Feature/UI
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Project/ICCery-v2
Core / wizard / process infra defect
Argyll orchestration, file/data defect
Build, packaging, CI defect
Views, controls, dialogs defect
Breaking change that won't be backward compatible
Core / wizard / process infra
Argyll orchestration, file/data engines
Build, packaging, CI
Views, controls, dialogs
Something is not working
Documentation changes
Improve existing functionality
New functionality
This is security issue
Issue or pull request related to testing
Priority
Critical
1
The priority is critical
Priority
High
2
The priority is high
Priority
Low
4
The priority is low
Priority
Medium
3
The priority is medium
ICCery v2 Mac rewrite
Reviewed
Confirmed
1
Issue has been confirmed
Reviewed
Duplicate
2
This issue or pull request already exists
Reviewed
Invalid
3
Invalid issue
Reviewed
Won't Fix
3
This issue won't be fixed
Status
Abandoned
3
Somebody has started to work on this but abandoned work
Status
Blocked
1
Something is blocking this issue or pull request
Status
Need More Info
2
Feedback is required to reproduce issue or to continue work
Milestone
No items
Projects
Clear projects
No projects
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: gronod/iccery-v2-mac#165
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
On the Settings sheet, the Verification thresholds (Good ΔE / Warning ΔE — the green and amber bands used as the traffic-light cutoffs) draw past the right edge of the modal. The Warning field is the one that leaves the sheet; depending on macOS 12 Form metrics the Good field can clip as well.
This is a layout bug in
SettingsView, not a settings-store or validation bug. Values still persist if you can reach Save.Where
Sources/ICCery/SettingsView.swiftRootView.sheet { SettingsView() }(no inner frame on the presenter)milestone/m10-studioReproduction
Good ΔE ≤ [ 2.0 ] Warning ΔE ≤ [ 5.0 ].Form.Expected: both fields fully visible, with ≥12 pt inset from the sheet edge, matching the Calibration row (
Stale after [ 30 ] days).Root cause
Three layout facts stack.
1. One non-wrapping HStack holds four controls
HStackdoes not wrap. The texts have nolineLimit,minimumScaleFactor,layoutPriority, orminWidth: 0. The fields are a fixed 60 pt each. Intrinsic width of the row is:width("Good ΔE ≤") + 60 + width("Warning ΔE ≤") + 60 + HStack spacingThe Δ and ≤ glyphs are wider than ASCII. On the app's default body font that row wants ~360–400 pt before Form chrome.
2. macOS Form steals horizontal space the HStack does not know about
The sheet is hard-sized:
A macOS grouped
Formthen applies:Textin a row as the trailing-label column and puts the rest of theHStackin the remaining control columnAvailable width for the remaining three children is therefore far less than 560. Four-across content is laid out at its ideal size and drawn past the clip of the
NSHostingView/ sheet.The Calibration section only has three children (
Stale after+ 60 pt field +days) and still fits. Verification does not.3. Fixed sheet height + M10 copy makes the Form tighter
M10 added a long caption under Default instrument (
Seeds Spot Read and Stage 3…). That grows the Argyll section. TheFormsits in aVStackwith a non-flexible footer (Divider+ 12 pt padded button row). If the Form fails to become a scroll view inside that fixed 620 pt height (a known SwiftUI-on-12 pattern when Form is not givenframe(maxHeight: .infinity)explicitly), the Verification block is also the first section pushed toward the bottom-right clip.Horizontal overflow is the primary defect; vertical clip is a related risk on 12.
This is not caused by:
SettingsViewModel/AppSettings.validate()(good < warning still works)RootView(no competing frame)Suggested fix
Do not keep two labelled numeric fields on one
HStackinside a Form row.Preferred (Form-native, ViewBuilder-safe):
Also:
Form.frame(maxHeight: .infinity)so it scrolls inside the 620 pt sheet after M10 captions.deltaEid.Acceptance
warning <= good), and a successful Save still work.SettingsView.bodystays ≤10 per stack (split if the Form grows).Test notes
No existing UI test targets these two fields (Settings is opened from the gear; current UI tests do not assert the Verification row). Add a focused layout assertion if a Settings UI test is introduced; until then, manual check on the Monterey runner-class machine is enough to close.
Second defect found on the same sheet (fixed on this branch)
All three numeric fields — Good ΔE, Warning ΔE, and the Calibration row — passed their default value as the
TextField's first argument. On macOS that argument is a label rendered inline, not a placeholder, so the rows drew the value twice:Stale after 30 [30] daysGood ΔE ≤ 2.0 [2.0]Warning ΔE ≤ 5.0 [5.0]The earlier
Text("Stale after")in eachHStackwas being lifted into the Form's right-aligned label column, and theTextField's own label ("30") rendered inline inside the control column next to the real box.Fix
The three fields are now direct
Formchildren carrying their descriptive label —TextField("Good ΔE ≤", …),TextField("Warning ΔE ≤", …),TextField("Stale after (days)", …)— so macOS renders the label once in the label column (ending x≈513.7, same as the Pickers) and the editable box fills the control column (x=522), matchingDefault instrument,Install location, andLog level.The
.frame(width: 60)boxes were dropped: the modifier wraps the composite label+box and would truncate the label. Fields now flex to the control-column edge (~3.5 pt inside the sheet, same as the PopUpButtons).settingsCalStaleDayswas added as the stale-days field identifier (roster → 358).Test changes
testNumericFieldsCarryLabelsNotDuplicatedValues: asserts each field's value, that the descriptive label renders exactly once as a label-columnstaticText, and that nostaticTextechoes the old label literal ("2.0"/"5.0"/"30").testVerificationRowsStayInsideSheetupdated for the label-column layout: right-edge assertion is now "inside the sheet" (the control column ends ~3.5 pt in — the 12 pt inset only applied to the old 60 pt boxes); alignment and left-inset checks unchanged.