printers@cinnamon.org: Update the applet when the printer list is empty or unavailable, and check for system-config-printer - #13936
Conversation
The initial printer list is fetched with Util.spawn_async(), which runs the command through cinnamon-subprocess-wrapper and pushes the result back over DBus. PushSubprocessResult() only invokes the callback when the command succeeded, so when lpstat is missing (cups-client is not installed, or CUPS is not installed at all) or exits non-zero, the callback is silently dropped and _updateApplet() is never reached. The applet then keeps the visibility it had at creation time: with the default "show icon when printers exist" setting and no printers, the icon stays in the panel forever. The same happened when lpstat succeeded but printed nothing, because the callback returned early on empty output. Use Util.spawnAsyncIO() instead: it reports the exit status and stderr to the callback, and throws right away if the binary cannot be executed at all, so both failure paths can log a warning and still call _updateApplet(). Also drop the hardcoded /usr/bin path so lpstat is looked up in PATH. Assisted-by: Claude Code:claude-opus-5
|
Can you use Cinnamon.find_program_in_path() instead of GLib? It's asynchronous with a callback. ref: d62a19f |
42a4103 to
be3a39a
Compare
|
Done, the second commit now uses One thing worth knowing for other conversions: since the callback runs after Retested on 6.7.5 in the same way as before, with the applet queried over
|
|
Maybe construct the full menu like normal (before |
…issing The applet menu item shown when no printer is configured, the context menu entry and the activation of a printer row all spawn system-config-printer unconditionally. On a system installed without the printing stack that program is not there, so those actions can only produce an "Execution of 'system-config-printer' failed" error notification. Cinnamon's own settings already deal with this: the Printers entry of System Settings is a standalone module, and SAModule.process() only lists it when the executable is found in PATH. Look the binary up once at construction time with Cinnamon.find_program_in_path() and keep the result in this._hasConfigTool. The context menu entry is built as before but starts out hidden, and the callback only makes it visible again, so the menu keeps its usual order and the separator finalizeContextMenu() adds hides itself along with the entry when the program is missing. The callback also schedules a menu rebuild, so a menu built before the lookup completed picks up the result. When the program is missing the activation handler of the printer rows is not connected and the placeholder item is shown as insensitive, instead of pretending it can open something. Assisted-by: Claude Code:claude-opus-5
be3a39a to
ef8d969
Compare
|
Much nicer, thanks — done that way. The entry is built as before and just starts out hidden; the callback only shows it, so the menu keeps its usual order and One detail I ran into while testing: that runs on Retested on 6.7.5, applet queried over
|
The applet assumes that the CUPS command line tools and
system-config-printerare always there. On a system installed without the printing stack neither is true, and the applet ends up in a broken state instead of quietly staying out of the way. Two commits, each usable on its own.1. Update the applet even when lpstat fails
On a system where
lpstatis not available the printers applet never updates itself, and with the default settings its icon stays in the panel forever._bootstrapPrinters()fetches the initial printer list withUtil.spawn_async(), which runs the command throughcinnamon-subprocess-wrapperand pushes the output back over DBus.PushSubprocessResult()only invokes the callback when the command succeeded:So if
lpstatis missing, or exits non-zero, the callback is silently dropped:_updateApplet()is never reached, and neither is the_updateVisibility()it calls. Thetry/catcharound the call cannot help, since the failure happens in the wrapper process, not in Cinnamon. The result is that the applet keeps whatever visibility it had when it was created — with the defaultshow-iconvalue (printers, i.e. "when printers exist") and no printers configured, the icon is shown even though it should be hidden. The same happened whenlpstatdid run but printed nothing, because the callback returned early on empty output.This is not an exotic case: the applet is enabled by default in
panel1:right, andlpstatis packaged separately from CUPS on Debian and derivatives (cups-client), so it can easily be absent on a machine with no printing setup. It was the cause of Debian bug #993152, which used to be worse before the rework — with the old code the missing command broke the nestedspawn_asyncchain and leftupdating = true, so the menu would not open at all.Fix
Use
Util.spawnAsyncIO()instead: it passes the exit status and stderr to the callback, and it throws immediately (Gio.Subprocess.init()fails withG_SPAWN_ERROR_NOENT) when the binary cannot be executed at all. Both failure paths now log a warning and still call_updateApplet(), so the applet ends up in a consistent state — hidden, with the default setting and no printers. The hardcoded/usr/binpath is dropped as well, solpstatis looked up inPATH.Testing
Tested on Cinnamon 6.7.5,
show-iconleft at its default (printers), asking the applet itself for its state overorg.Cinnamon.Eval:lpstatnot installed{visible: true, printers: 0}— icon stuck in the panel, nothing logged{visible: false, printers: 0}+printers@cinnamon.org: could not list printers: Failed to execute child process “lpstat” (No such file or directory)lpstatinstalled, no printer configured{visible: true, printers: 0}{visible: false, printers: 0}{visible: true, printers: 1}{visible: true, printers: 1}, menu opens and lists the printer2. Don't offer system-config-printer when it is missing
Three places spawn
system-config-printerunconditionally: the context menu entry, the item shown when no printer is configured, and the activation of a printer row. Where the printing stack was never installed that program is not there either, so those actions can only end in anExecution of 'system-config-printer' failederror notification. Cinnamon's own settings already handle this properly — the Printers entry of System Settings is a standalone module, andSAModule.process()only lists it when the executable is found inPATH.The commit looks the binary up with
GLib.find_program_in_path()and, when it is missing, leaves the context menu entry out, does not connect the activation handler of the printer rows, and shows the placeholder item as insensitive instead of pretending it can open something. No new translatable strings.Same test setup, this time with the applet's menus inspected over
org.Cinnamon.Eval:system-config-printermissing, one printerPrintersentrysystem-config-printermissing, no printerPrintersplaceholder,reactive: falsePrintersentrysystem-config-printerinstalled, one printerPrintersentry, as before