[Feature/Medium] Stage 2: paper source selection — enumerate vendor tray keys and wire through ticket, panel, and spool #218
Notifications
Due Date
No due date set.
Depends on
Reference: gronod/iccery-v2-mac#218
Reference in New Issue
Block a user
Summary
Stage 2 has a "Tray" picker (
printerTraySelect,Stage2View.swift:299-307) populated fromprinterCaps.trays, but it never appears on real Epson/Canon queues and is never applied anywhere:CupsService.capabilities(from:ppd:)buildstraysonly fromInputSlot/MediaSourcelpoptions -llistings (CupsService.swift:139-144). Epson InkjetPrinter2 exposes the feed source asEPIJ_PSrc/EPIJ_FdSo; Canon BJPrinter asCNIJMediaSupply(docs/24:133). Neither is enumerated →traysis empty → the picker is hidden. (Confirmed on XP-55 and Pro9500-class queues.)selectedTraynever reachesPrintPanelInitialSelections,TargetPrintOverrides/TicketWriteResolver, ormakeRequest(PrintSessionViewModel.swift:416-433). CapturedInputSlot=in the panel result is never mapped back to the picker, andPrintOptions.paperSource(PrinterModels.swift:171) is never populated.paper_sourceas ignored (docs/10 §paper_source).Users must open the driver dialog to choose tray/cassette/manual feed — currently the only place it can be set at all.
Implementation plan
Capabilities / parsing (ICCeryCore)
CupsParsers: addtrayKeysroster +detectTrayKey(optionKeys:). Candidates in preference order:InputSlot,MediaSource,EPIJ_FdSo,EPIJ_PSrc,CNIJMediaSupply.EPIJ_FdSois preferred overEPIJ_PSrcbecause recorded XP-55 listings labelEPIJ_FdSoasPaper SourceandEPIJ_PSrcasPage Setup;EPIJ_FdSois the actual feed-source control.AP_D_InputSlotis a capture-side alias, not an enumeration key.CupsService.capabilities(from:ppd:): enumerate trays from the detected roster key (replace the hard-codedInputSlot/MediaSourcelast-wins match); record the producing key on a newPrinterCapabilities.trayKey(mirrorsqualityKey, #183). Where a queue exposes more than one roster key, enumerate the preferred one and record it.PrinterTray: add atokenfield for the machine value written to the ticket; keep the 1-based indexid;namebecomes the PPD-enriched label (like media/quality).selectedTrayfrom the listing's*defaultChoiceinstead oftrays.first(reloadSelectedCapabilities, PrintSessionViewModel.swift:131-133).MediaQualityConstraints.resolve: accept an optional tray override so Epson*EPIJUIConstraintLHS terms (EPIJ_PSrc,EPIJ_FdSo) are evaluated against the selected feed source rather than the queue's lpoptions default. Precompute one media→quality map per enumerated tray token during capability loading; no async reload on tray switch.Write path (Stage 2 → ticket → driver)
PrintSessionViewModel.selectedTrayToken: String?— id→token lookup (mirrorsselectedPaperSizeToken, :217-221).PrintPanelInitialSelectionsgainstrayKey/tray;applyInitialSelectionswritesPMPrintSettingsSetValue(trayKey, token)immediately afterPageSize.TargetPrintOverridesgainstrayKey/tray;TicketWriteResolveradds a numbered write<trayKey>=<token>placed afterPageSizeand before media; update the locked-order contract comment andtestLockedWriteOrder.makeRequestpasses the tray override.NativeTargetSpooler.mirrorneeds no change — it replays every resolved write intoNSPrintInfo.printSettings.Capture-back (driver → Stage 2)
AP_D_InputSlot. Map token →PrinterTray.id; setselectedTrayand populatePrintOptions.paperSource(Int, 1-based — docs/10 semantics). If the token is non-empty but unknown, append a syntheticPrinterTrayentry (id = current max + 1, token/name = raw token) and select it.UITestHooks.printPanelResultmirrors the new field so UI tests can drive it (AppEnvironment.swift:136-165).UI
printerTraySelecta11y id so existing UI tests don't churn.Picker("Orientation", selection: $workflow.print.printOrientation)dropdown usingprinterOrientationSelect; keepportrait/landscapevalues and downstreamorientation-requested=3|4behavior unchanged.Considerations / non-goals
trayKeywrite doesn't move the driver PDE on hardware, note it — do not guess key pairs.MediaSourceis also in some media rosters (docs/11:410); tray detection must not regress media-key detection — assert precedence in tests.Acceptance criteria
EPIJ_FdSois preferred overEPIJ_PSrcon Epson queuesICCERY_TEST_SPOOL_LOGrecords<trayKey>=<token>— and honoured by the driver*default choicePrintOptions.paperSourcepopulatedprinterOrientationSelect); old button IDs removed;portrait/landscapestring state andorientation-requested=3|4unchangedCupsParserTests,TicketWriteResolverTests,PrintSessionViewModelTests,PrintPanelTicketTests,PrintPanelStubTests,MediaQualityConstraintsTests,CupsOptionsFilterTestsDependencies
runNativePanel(ticket restore + validate) and both touchPrintPanelInitialSelections/TicketWriteResolver.References
Sources/ICCery/Stage2View.swift:299-307— hiddenprinterTraySelectpickerPackages/ICCeryCore/Sources/ICCeryCore/Print/CupsService.swift:139-144—InputSlot/MediaSource→ traysPackages/ICCeryCore/Sources/ICCeryCore/Print/PrinterModels.swift:50-60,171—PrinterTray,PrintOptions.paperSourceSources/ICCery/Print/TicketWriteResolver.swift:37-54— locked write orderSources/ICCery/Print/PrintPanelService.swift:214-244— initial-selection writesdocs/24-issues-invariants.md:133— vendor tray-key rosterdocs/10-print-system.md—paper_sourcesemanticsdocs/11-print-macos.md— native panel/spool path and resolver order