Skip to content

Fix seat access selection and provisioning - #4746

Open
VykosMolt wants to merge 2 commits into
archlinux:masterfrom
VykosMolt:fix/seat-access-3467
Open

Fix seat access selection and provisioning#4746
VykosMolt wants to merge 2 commits into
archlinux:masterfrom
VykosMolt:fix/seat-access-3467

Conversation

@VykosMolt

Copy link
Copy Markdown

Fixes #3467

The seat access setting currently treats seatd and polkit as equivalent choices, then reuses the selected string as both a package name and a service name.

That causes several problems:

  • polkit is not a seat manager; the actual alternative to seatd is systemd-logind.
  • Hyprland enables the selected service without ensuring its package is installed.
  • polkit.service is static, so enabling it does not provision the logind-based path.
  • saved seat-access values are strings while menu items contain enum values, so the previous choice is not restored correctly.
  • package and service handling has drifted between desktop profiles.

SeatAccess now represents the two actual choices, seatd and systemd-logind, and defines the packages and services required by each.

For the logind path, polkit is installed because it is the optional systemd dependency used for unprivileged authorization, but no static service is explicitly enabled.

The four affected desktop profiles now consume the same package/service mapping instead of treating one string as both.

Existing configurations using the old "polkit" value are migrated to the logind choice. Unknown values are warned about and ignored rather than being passed through as package or service names.

Tests cover menu contents and saved-value restoration, legacy migration, package/service provisioning across all affected profiles, and the Hyprland case where the selected seat package was previously missing.

Claude Opus was used for codebase archaeology, implementation assistance, and test review. I manually reviewed and tested the resulting changes.

Arch has two ways of giving a compositor access to the seat: seatd, or
systemd-logind. The menu offered "seatd" and "polkit", but polkit is not a
seat manager. It is part of the authorization machinery: systemd lists polkit
as an optional dependency, and logind checks with it before letting an
unprivileged user act, so polkit has to be installed for the logind route to
work as intended on Arch. That made it the thing to install, never the thing
being chosen.

The second option is now called systemd-logind, and SeatAccess carries what
each choice actually needs: which packages to install and which services to
enable. Configurations written before this still say 'polkit', and are read
back as systemd-logind, so a saved choice is not silently discarded.

Enabling polkit was doing nothing in any case. Its unit is static, so
`systemctl enable polkit` only prints "The unit files have no installation
config" and exits 0. The same is true of systemd-logind, which is started on
demand, so neither has a service to enable.

While the saved value was being read: select_seat_access() handed the stored
string to set_default_by_value(), which compares it against menu items holding
SeatAccess members. A str is never equal to one, so a previously chosen option
was never pre-selected.
The chosen option was stored as a plain string and then used twice: once as a
package to install, once as a service to enable. That only worked because the
seatd package and the seatd service happen to share a name, and it hid a real
bug. Hyprland listed the string under services but never added it to packages,
so choosing seatd there ran `systemctl enable seatd` against a target where
the package was never installed. That exits 1 with "Unit seatd.service does
not exist", and enable_service() turns a non-zero exit into a
ServiceException, which stops the installation.

Sway, Hyprland, niri and labwc now ask the chosen option what it needs instead
of reusing one string for both jobs, so all four behave the same and each
installs whatever it enables.

The test that covers this runs over every profile and asserts exactly that, so
a profile cannot drift apart from the others again the way Hyprland did.
@VykosMolt
VykosMolt requested a review from Torxed as a code owner August 31, 2026 16:29
@svartkanin

Copy link
Copy Markdown
Collaborator

#4745 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SeatAccess labels incorrect

2 participants