Skip to content

Add users to seat group when seatd is selected#4578

Open
Softer wants to merge 4 commits into
archlinux:masterfrom
Softer:fix-seatd-group
Open

Add users to seat group when seatd is selected#4578
Softer wants to merge 4 commits into
archlinux:masterfrom
Softer:fix-seatd-group

Conversation

@Softer

@Softer Softer commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Fixes #4471

When seatd is chosen as seat access for sway/hyprland/niri/labwc, the compositor needs the user to be in the seat group to access input devices. Without this, the compositor fails to start after installation.

Verified on real hardware: installed sway + seatd, confirmed seat group was missing from user groups. After the fix, groups test shows seat.

What changed:

  • desktops/utils.py: added provision_seat_access() helper that runs usermod -a -G seat for each user when seatd is selected
  • sway.py, hyprland.py, niri.py, labwc.py: added provision() override calling the helper

Softer added 2 commits June 3, 2026 16:19
When a desktop profile uses seatd for seat access, the user must be
in the seat group for the compositor to access input devices. Without
this, sway/hyprland/niri/labwc fail to start after installation.
@Softer Softer requested a review from Torxed as a code owner June 6, 2026 13:18
from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType

if TYPE_CHECKING:
from archinstall.lib.installer import Installer

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are they in the TYPE_CHECKING scope?

def provision_seat_access(
install_session: Installer,
users: list[User],
seat_access: str | None,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function itself is pointless if the seat_access is passed as None, the consumers of the function should perform this validation and only call it if it is not None

return []

@override
def provision(self, install_session: Installer, users: list[User]) -> None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all these profiles essentially implement the same provision logic, instead we can move this into

	@override
	def provision(self, install_session: Installer, users: list[User]) -> None:
		for profile in self.current_selection:
			profile.provision(install_session, users)

			if seat_access := profile.custom_settings.get(CustomSetting.SeatAccess):
				provision_seat_access(install_session, users, seat_access)

The four Wayland profiles (Hyprland, Sway, niri, labwc) each duplicated a
provision() override calling provision_seat_access(). Move that into the
base DesktopProfile.provision() loop, which already iterates the selected
profiles, and read CustomSetting.SeatAccess from each. The None check now
lives at the call site (walrus), so provision_seat_access() takes a plain
str. This removes the per-profile overrides and their TYPE_CHECKING imports.
@Softer

Softer commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @svartkanin! I reworked it so all three are covered at once. The seat-access setup now lives in the base DesktopProfile.provision() instead of being copy-pasted into each Wayland profile, so Hyprland/Sway/niri/labwc lost their duplicated overrides (and with them the TYPE_CHECKING imports). The None check moved to the caller, so the helper just takes a str now.

from archinstall.tui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.result import ResultType

if TYPE_CHECKING:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the TYPE_CHECKING here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, missed that one - leftover from the refactor. Fixed.

The Installer and User imports were under a TYPE_CHECKING guard, but
they cause no circular import (bspwm.py already imports both at top
level). Move them to module scope per review feedback.
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.

Sway + seatd greeter lock

2 participants