Files
pdfcraft/crates
efd7c9fc24 fix(print): fall back to the lpoptions listing when the PPD is unreadable (#4699) (#4703)
* fix(print): fall back to the lpoptions listing when the PPD is unreadable

cupsd keeps /etc/cups/ppd/<queue>.ppd at 0640 root:cups on Arch and
similar setups, so an ordinary desktop user cannot open it. The option
reader treated that permission error as "no options", and Print ▸
Properties… said "This printer offers no settings of its own" for a
queue whose driver options cupsd was serving all along through
lpoptions.

When the PPD is missing, unreadable, or parses to no options, the list is
now built from `lpoptions -p <queue> -l`. The options Craft handles
itself are skipped, as the PPD parser does, and the starred choice is the
fallback default.

Fixes #4699

* fix(print): skip CUPS custom-value templates in the lpoptions fallback

`lpoptions -l` prints `Custom`, `Custom.<TYPE>` (`Custom.PASSCODE`,
`Custom.STRING`, …) or `Custom.WIDTHxHEIGHT` in place of the choices of an
option whose value the user has to type. Nothing in the dialog collects that
value, so offering the template sent its literal text to the driver. Those
entries are now dropped, and a starred template never becomes the default.

The choice cap is also tested before the duplicate scan, so a listing past
`MAX_LPOPTIONS_CHOICES` no longer walks the stored choices on every token.

Refs #4699

* fix(print): refuse a destination that starts with a dash

`lpoptions` parses its argv with getopt, so `-p -E -l` reads `-E` as an
option rather than as the destination; `--` cannot help, because it ends
option parsing before the `-p` that names the queue. Reject a leading
`-` on the queue and on the instance component beside the existing name
checks, before the PPD is opened or the command is spawned.

* fix(print): read the listing by its last colon, and stop inventing a default

`list_group()` prints the option as `"%s/%s:"` from the PPD's keyword and
translated text and each choice as a bare `" %s"`, so a colon can sit in
the text but not in a choice keyword. Splitting at the first colon turned
the rest of the text ("Supporto: Tipo") into invented choices; split at
the last one instead.

When the choice CUPS marks is a custom-value template, the parser dropped
it and stood the first retained choice in as the default. The UI then
showed a value the job does not use, because only options changed away
from the default are submitted. Leave the default empty in that case:
there is nothing the dialog could collect, and an invented choice is
worse than no selection.

---------

Co-authored-by: Jarvis (Hermes) <jarvis@localhost>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-10 00:24:22 +01:00
..
2026-11-09 18:32:42 +07:00
…