diff --git a/quickshell/Modals/PolkitAuthContent.qml b/quickshell/Modals/PolkitAuthContent.qml index a2e2495f1..0d4941d40 100644 --- a/quickshell/Modals/PolkitAuthContent.qml +++ b/quickshell/Modals/PolkitAuthContent.qml @@ -293,7 +293,7 @@ FocusScope { font.pixelSize: Theme.fontSizeSmall color: Theme.error width: parent.width - visible: root.currentFlow?.failed ?? false + visible: PolkitService.authFailed } Item { diff --git a/quickshell/Services/PolkitService.qml b/quickshell/Services/PolkitService.qml index de59bac97..d7b366d22 100644 --- a/quickshell/Services/PolkitService.qml +++ b/quickshell/Services/PolkitService.qml @@ -3,6 +3,7 @@ pragma ComponentBehavior: Bound import QtQuick import Quickshell +import qs.Services Singleton { id: root @@ -13,6 +14,60 @@ Singleton { readonly property bool polkitAvailable: !disablePolkitIntegration readonly property var agent: polkitAgentLoader.item + property bool authFailed: false + property bool _switchingIdentity: false + + function currentUserIdentity(flow) { + const identities = flow?.identities; + if (!identities || identities.length < 2) + return null; + const uid = UserInfoService.uid; + const username = Quickshell.env("USER"); + for (let i = 0; i < identities.length; i++) { + const identity = identities[i]; + if (identity.isGroup) + continue; + if (uid >= 0 && identity.id === uid) + return identity; + if (username && identity.string === username) + return identity; + } + return null; + } + + function selectCurrentUserIdentity() { + const flow = agent?.flow; + const identity = currentUserIdentity(flow); + if (!identity || identity === flow.selectedIdentity) + return; + log.info(`Selecting identity ${identity.string} over default ${flow.selectedIdentity?.string}`); + // selectedIdentity assignment cancels the running session, which polkit + // reports as a synchronous auth failure; swallow it via _switchingIdentity + _switchingIdentity = true; + flow.selectedIdentity = identity; + _switchingIdentity = false; + } + + Connections { + target: root.agent + enabled: root.agent !== null + + function onAuthenticationRequestStarted() { + root.authFailed = false; + root.selectCurrentUserIdentity(); + } + } + + Connections { + target: root.agent?.flow ?? null + + function onAuthenticationFailed() { + if (root._switchingIdentity) + return; + root.authFailed = true; + } + } + Loader { id: polkitAgentLoader active: root.polkitAvailable diff --git a/quickshell/Services/UserInfoService.qml b/quickshell/Services/UserInfoService.qml index 8378e01a2..9eb53ecf8 100644 --- a/quickshell/Services/UserInfoService.qml +++ b/quickshell/Services/UserInfoService.qml @@ -12,10 +12,11 @@ Singleton { property string fullName: "" property string profilePicture: "" property string hostname: "" + property int uid: -1 property bool profileAvailable: false function getUserInfo() { - Proc.runCommand("userInfo", ["sh", "-c", "echo \"$USER|$(getent passwd $USER | cut -d: -f5 | cut -d, -f1)|$(hostname)\""], (output, exitCode) => { + Proc.runCommand("userInfo", ["sh", "-c", "echo \"$USER|$(getent passwd $USER | cut -d: -f5 | cut -d, -f1)|$(hostname)|$(id -u)\""], (output, exitCode) => { if (exitCode !== 0) { root.username = "User"; root.fullName = "User"; @@ -28,6 +29,10 @@ Singleton { root.fullName = parts[1] || parts[0] || ""; root.hostname = parts[2] || ""; } + if (parts.length >= 4) { + const parsedUid = parseInt(parts[3], 10); + root.uid = isNaN(parsedUid) ? -1 : parsedUid; + } }, 0); }