[Bug/Critical] Epson printer quality options limited to default only — only "Normal" shown, 6 other options missing #180
Notifications
Due Date
No due date set.
Blocks
Depends on
Reference: gronod/iccery-v2-mac#180
Reference in New Issue
Block a user
Summary
The Epson driver (e.g., Epson XP-55 Series) offers 7 quality options — Fast Economy (301), Economy (302), Normal (303), Draft (308), Fine (304), Quality (305), Best Quality (307) — but ICCery v2 Mac does not enumerate them:
CupsService.capabilities(from:ppd:)performs no quality extraction at all, so only the driver default ("Normal" / 303) can ever apply.Note: no quality picker exists in Stage 2 until #183 lands — the enumeration gap becomes user-visible once it does.
This same limitation isn't present in TargetPrint (ICCery-CPU) which doesn't restrict available quality settings and correctly shows all 7 options.
Root Cause Analysis
What
lpoptions -lActually ReturnsAll 7 options ARE present in the CUPS
lpoptions -loutput. The issue is not with CUPS — it's with ICCery v2 Mac's parsing code.Where the Bug Lives
CupsService.capabilities(from:ppd:)(Packages/ICCeryCore/Sources/ICCeryCore/Print/CupsService.swift:105-136) — the actual blockerInputSlot/MediaSource,PageSize/MediaSize, andCupsParsers.mediaTypeKeysNo quality-key detection roster exists in
CupsParsersCupsOptionsFilter.relevantKeys(CupsOptionsFilter.swift:16-32) is a capture-relevance roster — it decides which-ooptions survive into capturedcupsOptions, not which options get enumerated.EPIJ_Qualalready survivesisRelevantvia the permissive non-com.*rule (CupsOptionsFilter.swift:44-52), so the roster is not the blocker — a new detection roster + extraction isEPIJ_Quality(inrelevantKeys, CupsOptionsFilter.swift:28) is a phantom/alias — real Epson PPDs useEPIJ_Qual. KeepEPIJ_Quality(harmless for capture); treatEPIJ_Qualas canonical in the new quality-key rosterTest fixture mismatch (Tests/ICCeryCoreTests/CupsParserTests.swift:33)
cupsPrintQuality/cupsPrintQuality: Draft *Normal High(3 options)EPIJ_Qualwith 7 optionsComparison with ICCery-CPU (TargetPrint)
ICCery-CPU correctly handles this in
CUPSManager.discoverPPDOptions()(Sources/Printing/CUPSManager.swift:190-196):It includes
EPIJ_Qualin candidate keywords AND scans*OpenUItranslations.PPD Evidence (Epson XP-55 Series)
Proposed Fix Options
Option 1: Minimal Fix — quality extraction + detection roster
CupsService.capabilities()(or a new function) — this is the actual blockerEPIJ_Qualcanonical, ordered vendor-first / weakest-last (OutputMode/Resolutionlast — EpsonOutputModeis a colour-mode key, misdetect risk);EPIJ_Qualmay also be added toCupsOptionsFilter.relevantKeysfor explicitness (it already survivesisRelevant)lpoptions -lpath to capture all quality optionsOption 2: Full PPD Parsing (aligns with ICCery-CPU)
Option 3: Hybrid Approach (Recommended)
lpoptions -lfor basic enumerationdiscoverOptionChoicesapproachAcceptance Criteria
EPIJ_QualkeyEPIJ_QualoutputDependencies
References
Sources/Printing/CUPSManager.swift(discoverOptionChoices, optionDetails)Packages/ICCeryCore/Sources/ICCeryCore/Print/CupsOptionsFilter.swiftPackages/ICCeryCore/Sources/ICCeryCore/Print/CupsService.swiftPackages/ICCeryCore/Sources/ICCeryCore/Print/CupsParsers.swiftTests/ICCeryCoreTests/CupsParserTests.swiftPlanning errata (verified on develop@736fd08):
lpoptions -levidence:EPIJ_Qual/Print Quality: 301 302 *303 308 304 305 307).CupsOptionsFilter.relevantKeysis a capture-relevance roster, not an enumeration roster —EPIJ_Qualalready survivesisRelevantvia the permissive non-com.*rule (CupsOptionsFilter.swift:44–52). The actual blockers are:CupsService.capabilities(from:ppd:)has no quality extraction at all (CupsService.swift:105–136 handles InputSlot/MediaSource, PageSize/MediaSize, and mediaTypeKeys only), and no quality-key detection roster exists inCupsParsers.EPIJ_Quality(inrelevantKeys, CupsOptionsFilter.swift:28) is a phantom/alias — real Epson PPDs useEPIJ_Qual. KeepEPIJ_Quality(harmless for capture); treatEPIJ_Qualas canonical in the new quality-key roster.Errata above incorporated into the issue body — the ticket itself is now the corrected contract.