From 1661d3264181f39ed2027796d7ff56c342185eb8 Mon Sep 17 00:00:00 2001 From: purian23 Date: Sun, 15 Mar 2026 02:54:23 -0400 Subject: [PATCH] (greeter): Trial fix for 30s auth delay & wireplumber state dir --- distro/nix/greeter.nix | 1 + quickshell/Modules/Greetd/GreeterContent.qml | 40 ++++++++++++++++++-- quickshell/Modules/Greetd/assets/dms-greeter | 15 ++++++++ 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/distro/nix/greeter.nix b/distro/nix/greeter.nix index 9549249e..8b0424ea 100644 --- a/distro/nix/greeter.nix +++ b/distro/nix/greeter.nix @@ -24,6 +24,7 @@ let lib.makeBinPath [ cfg.quickshell.package compositorPackage + pkgs.glib # provides gdbus, used by the fprintd hardware probe in GreeterContent.qml ] } ${ diff --git a/quickshell/Modules/Greetd/GreeterContent.qml b/quickshell/Modules/Greetd/GreeterContent.qml index 2facad08..b6b8fb47 100644 --- a/quickshell/Modules/Greetd/GreeterContent.qml +++ b/quickshell/Modules/Greetd/GreeterContent.qml @@ -56,7 +56,10 @@ Item { property string externalAuthAutoStartedForUser: "" property int passwordSessionTransitionRetryCount: 0 property int maxPasswordSessionTransitionRetries: 2 - readonly property bool greeterPamHasFprint: greeterPamStackHasModule("pam_fprintd") + property bool fprintdProbeComplete: false + property bool fprintdHasDevice: false + // Falls back to PAM-only detection until the fprintd D-Bus probe completes. + readonly property bool greeterPamHasFprint: greeterPamStackHasModule("pam_fprintd") && (!fprintdProbeComplete || fprintdHasDevice) readonly property bool greeterPamHasU2f: greeterPamStackHasModule("pam_u2f") readonly property bool greeterExternalAuthAvailable: (greeterPamHasFprint && GreetdSettings.greeterEnableFprint) || (greeterPamHasU2f && GreetdSettings.greeterEnableU2f) readonly property bool greeterPamHasExternalAuth: greeterPamHasFprint || greeterPamHasU2f @@ -430,6 +433,8 @@ Item { if (CompositorService.isHyprland) updateHyprlandLayout(); + + fprintdDeviceProbe.running = true; } function applyLastSuccessfulUser() { @@ -527,9 +532,8 @@ Item { pendingPasswordResponse = false; passwordSubmitRequested = submitPassword; awaitingExternalAuth = !submitPassword && !hasPasswordBuffer && root.greeterExternalAuthAvailable; - // Included PAM stacks (system-auth/common-auth/password-auth) may still run - // biometric/U2F modules before password even when DMS toggles are off. - const waitingOnPamExternalBeforePassword = submitPassword && root.greeterPamHasExternalAuth; + // Use greeterExternalAuthAvailable so systems with pam_fprintd but no hardware don't incur the 30 s wait. + const waitingOnPamExternalBeforePassword = submitPassword && root.greeterExternalAuthAvailable; authTimeout.interval = (awaitingExternalAuth || waitingOnPamExternalBeforePassword) ? externalAuthTimeoutMs : defaultAuthTimeoutMs; authTimeout.restart(); Greetd.createSession(GreeterState.username); @@ -599,6 +603,34 @@ Item { } } + // Probe fprintd D-Bus for physically enrolled scanners to eliminate PAM stack false-positives. + Process { + id: fprintdDeviceProbe + running: false + // sh wrapper: emits PROBE_UNAVAILABLE if gdbus is absent or fprintd unreachable, + // keeping the PAM-only fallback active in those cases. + command: ["sh", "-c", + "command -v gdbus >/dev/null 2>&1 || { echo PROBE_UNAVAILABLE; exit 0; }; " + + "gdbus call --system " + + "--dest net.reactivated.Fprint " + + "--object-path /net/reactivated/Fprint/Manager " + + "--method net.reactivated.Fprint.Manager.GetDevices 2>/dev/null " + + "|| echo PROBE_UNAVAILABLE"] + stdout: StdioCollector { + onStreamFinished: { + if (text.includes("PROBE_UNAVAILABLE")) + return; // PAM-only fallback stays active + root.fprintdHasDevice = text.includes("objectpath"); + root.fprintdProbeComplete = true; + root.maybeAutoStartExternalAuth(); + } + } + onExited: function(exitCode, exitStatus) { + if (!root.fprintdProbeComplete) + root.maybeAutoStartExternalAuth(); // PAM-only fallback stays active + } + } + Connections { target: CompositorService.isHyprland ? Hyprland : null enabled: CompositorService.isHyprland diff --git a/quickshell/Modules/Greetd/assets/dms-greeter b/quickshell/Modules/Greetd/assets/dms-greeter index 522d53f8..39285f6e 100755 --- a/quickshell/Modules/Greetd/assets/dms-greeter +++ b/quickshell/Modules/Greetd/assets/dms-greeter @@ -224,6 +224,19 @@ export XDG_STATE_HOME="$CACHE_DIR/.local/state" export XDG_DATA_HOME="$CACHE_DIR/.local/share" export XDG_CACHE_HOME="$CACHE_DIR/.cache" +# Propagate correct XDG dirs into the systemd user session so socket-activated +# services (e.g. wireplumber) don't inherit HOME=/ from /etc/passwd. +if command -v systemctl >/dev/null 2>&1; then + systemctl --user set-environment \ + HOME="$CACHE_DIR" \ + XDG_STATE_HOME="$CACHE_DIR/.local/state" \ + XDG_DATA_HOME="$CACHE_DIR/.local/share" \ + XDG_CACHE_HOME="$CACHE_DIR/.cache" 2>/dev/null || true + if systemctl --user is-active --quiet wireplumber.service 2>/dev/null; then + systemctl --user restart wireplumber.service 2>/dev/null || true + fi +fi + # Keep greeter VT clean by default; callers can override via env or --debug. if [[ -z "${RUST_LOG:-}" ]]; then export RUST_LOG=warn @@ -336,6 +349,7 @@ misc { disable_hyprland_logo = true } +exec-once = systemctl --user import-environment HOME XDG_STATE_HOME XDG_DATA_HOME XDG_CACHE_HOME 2>/dev/null || true exec-once = sh -c "$QS_CMD; hyprctl dispatch exit" HYPRLAND_EOF COMPOSITOR_CONFIG="$TEMP_CONFIG" @@ -348,6 +362,7 @@ env = HOME,$CACHE_DIR env = XDG_STATE_HOME,$CACHE_DIR/.local/state env = XDG_DATA_HOME,$CACHE_DIR/.local/share env = XDG_CACHE_HOME,$CACHE_DIR/.cache +exec-once = systemctl --user import-environment HOME XDG_STATE_HOME XDG_DATA_HOME XDG_CACHE_HOME 2>/dev/null || true exec-once = sh -c "$QS_CMD; hyprctl dispatch exit" HYPRLAND_EOF COMPOSITOR_CONFIG="$TEMP_CONFIG"