Files
printserver/openspec/changes/fix-airprint-discovery/proposal.md
T
juergen 843c6866a5
ci/woodpecker/push/build Pipeline was successful
fix airprint discovery
2026-10-19 22:44:08 +02:00

69 lines
3.3 KiB
Markdown

# Proposal
## Why
macOS adds the queue with *Use:* = **Generic PostScript Printer** instead of the
driverless **AirPrint Printer**, so duplex, colour and tray 2 stay hidden — the
generic PPD gates duplex behind `APOptionalDuplexer False`. The certificate is
no longer the cause: `curl https://podp.local:631/` succeeds, CUPS serves the
expected certificate, and every IPP query the Mac makes against the queue
succeeds (7/7 `HTTP_STATUS_OK, ipp status 0`). iOS, which queries the printer
live, already offers every option.
The remaining cause is a Bonjour sub-type. Disassembling
`AddPrinter.app/Contents/Frameworks/PMBrowser.framework` (macOS 27.0.1) shows the
gate for the AirPrint driver entry:
- `-[DNSSDPrinter isShared]` returns YES as soon as any of the printer's
registration types ends in `,_cups`; the registration types are the `regType`
strings the Bonjour browse callback reports.
- `-[DNSSDPrinter airprintMatch]` returns nothing when `isShared` is YES, and
only builds the AirPrint driver when `isAirPrint` is YES — that is, when the
service was browsed under `_ipp._tcp,_universal` or `_ipps._tcp,_universal`.
- `-[DNSSDBrowser startBrowsing]` browses `_ipp._tcp,_cups` **and**
`_ipp._tcp,_universal` (and the `_ipps` equivalents), so a printer that
carries both sub-types is classified as *shared* and never gets the AirPrint
driver.
CUPS registers `DNSSDSubTypes`, whose default is `_cups,_print,_universal`
(`scheduler/conf.c`), which is exactly that combination. The queue is therefore
advertised as a shared CUPS printer and macOS falls back to its generic driver.
The sub-types are configurable with the `BrowseDNSSDSubTypes` directive.
## What Changes
- Set `BrowseDNSSDSubTypes _print,_universal` in `cupsd.conf`, so the queue is
advertised with the AirPrint (`_universal`) sub-type and without the CUPS
(`_cups`) one. `_print` is kept for clients that look for it.
- Keep CUPS' own advertising otherwise (the unconditional `_printer._tcp`
registration, the `printer-type` TXT key and the resulting `/cups` device
URI), so CUPS clients keep resolving the queue exactly as before.
- Correct the README: the "macOS adds the printer as a Generic PostScript
printer" section blames the certificate alone and recommends adding the queue
from the command line; it now documents the sub-type cause first and how to
confirm what is advertised.
Non-goals: hand-written Avahi service files, and patching CUPS' TXT record.
Neither is needed unless the sub-type alone turns out to be insufficient.
## Capabilities
### New Capabilities
<!-- None: this fixes the advertisement required by an existing capability. -->
### Modified Capabilities
- `printserver/cups`: the "Printer is shared and discoverable" requirement gains
a scenario that fixes which Bonjour sub-types are advertised, because the
advertised sub-types decide whether macOS offers the driverless AirPrint
driver.
## Impact
- `cupsd.conf`: one directive plus an explanatory comment.
- `README.md`: troubleshooting section corrected.
- `openspec/specs/printserver/cups/spec.md`: one scenario added.
- Clients: macOS should offer *AirPrint Printer* under *Use:*; the `_ipp`/`_ipps`
services, the `/cups` device URI and Linux/Windows clients are unaffected.
macOS caches the old classification per printer entry, so an existing entry
has to be removed and added again.