Move logind-zbus to a dedicated 'logind' feature that is independent
of the 'systemd' feature. This allows non-systemd users (e.g., OpenRC
with elogind) to access lid switch inhibition and lid status detection
without requiring the full systemd stack.
The 'systemd' feature now depends on 'logind' to maintain backward
compatibility, so existing users are unaffected.
Feature configuration:
- default: ["systemd"]
- logind: ["logind-zbus"]
- systemd: ["libsystemd", "logind", "tracing-journald"]
Resolves#2473
Coding-Agent: OpenCode
Model: claude-sonnet-4-5
A fix for the issue reported in
https://github.com/pop-os/cosmic-comp/pull/2450.
Using `block_on` in some places for zbus calls is fine (that's what
zbus's blocking API does; it has its own executor for background tasks),
but this is problematic with `async_once_cell`. If we also use that in
the calloop async executor.
I think ideally we should avoid blocking the main thread on any async
tasks, but for now we can just block in initialization here.
We should avoid creating more than one session connection or more than
one system connection. We should also ideally avoid blocking the main
thread.
For now this still uses blocking in a couple places, but wrapping async
code (which is how `zbus::blocking` is implemented anyway).
This moves the `NameOwners` creation out of `A11yKeyboardMonitorState`,
so it can be shared with other things. We will likely want that for
https://github.com/pop-os/cosmic-comp/pull/465 to define a secured
protocol to pass an fd to the portal, and potentially any other
sensitive DBus protocols implemented by the compositor.
This protocol is now the upstream solution in at-spi2-core/orca for
registering keyboard grabs and watching key events. It should also be a
bit better than the current verious of our custom Wayland protocol for
this purpose.
Like Mutter and Kwin, we currently restrict this to only be called by
the client that holds the name `org.gnome.Orca.KeyboardMonitor` on the
session bus. We also send the `KeyEvent` signal only to registered
watchers, rather than broadcasting, as DBus does by default.
This monitors `NameOwnerChanged` events to keep track of what unique
names own what well-known names on the bus. This allows dbus protocol
implementations to check that callers own a certain name.
To initially populate the list of dbus name owners, `ListNames` is used
at start. Then `GetNameOwner` is lazily invoked to populate owners that
exist at start. To avoid calling that for every single name on the bus.
This also keeps track of unique bus names, which don't require any
additional methods or signals to monitor. This allows us to also detect
if a client has disappeared from the bus.
The `COSMIC_ENFORCE_DBUS_OWNERS` allows disabling checking of owned
names.
Previously we ignored when we had no output configuration
**and** failed to apply the automatically created one.
This leads to two problems:
- If this happens on startup, we end up with no outputs being added to the shell and we quit.
- If this happens later, we might end up in an inconsistent state, where the shell thinks we have an output, when it didn't light up for similar reasons.
Thus `read_outputs` is failable and handling that very much depends on
the where is was called from, because `read_outputs` doesn't know what
configuration was active before.
Thus make it failable and provide useful mitigations everywhere
possible:
- Try to enable just one output in case we fail on startup.
- Don't enable any additional outputs, when we fail on hotplug.
- Log the error like previously in any other case (and come up with more
mitigations, once we understand these cases better).