From 5d94c0a7d44a2255b81815a52a7056a94a39842d Mon Sep 17 00:00:00 2001 From: nippy Date: Sat, 18 Apr 2026 13:49:56 +0200 Subject: update Raveos themes --- .../quickshell/Modals/PolkitAuthModal.qml | 412 +++++++++++++++++++++ 1 file changed, 412 insertions(+) create mode 100644 raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/PolkitAuthModal.qml (limited to 'raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/PolkitAuthModal.qml') diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/PolkitAuthModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/PolkitAuthModal.qml new file mode 100644 index 0000000..21ddf8f --- /dev/null +++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/PolkitAuthModal.qml @@ -0,0 +1,412 @@ +import QtQuick +import Quickshell +import Quickshell.Io +import qs.Common +import qs.Services +import qs.Widgets + +FloatingWindow { + id: root + + property bool disablePopupTransparency: true + property string passwordInput: "" + property var currentFlow: PolkitService.agent?.flow + property bool isLoading: false + property bool awaitingFprintForPassword: false + readonly property int inputFieldHeight: Theme.fontSizeMedium + Theme.spacingL * 2 + + property string polkitEtcPamText: "" + property string polkitLibPamText: "" + property string systemAuthPamText: "" + property string commonAuthPamText: "" + property string passwordAuthPamText: "" + readonly property bool polkitPamHasFprint: { + const polkitText = polkitEtcPamText !== "" ? polkitEtcPamText : polkitLibPamText; + if (!polkitText) + return false; + return pamModuleEnabled(polkitText, "pam_fprintd") || (polkitText.includes("system-auth") && pamModuleEnabled(systemAuthPamText, "pam_fprintd")) || (polkitText.includes("common-auth") && pamModuleEnabled(commonAuthPamText, "pam_fprintd")) || (polkitText.includes("password-auth") && pamModuleEnabled(passwordAuthPamText, "pam_fprintd")); + } + + function stripPamComment(line) { + if (!line) + return ""; + const trimmed = line.trim(); + if (!trimmed || trimmed.startsWith("#")) + return ""; + const hashIdx = trimmed.indexOf("#"); + if (hashIdx >= 0) + return trimmed.substring(0, hashIdx).trim(); + return trimmed; + } + + function pamModuleEnabled(pamText, moduleName) { + if (!pamText || !moduleName) + return false; + const lines = pamText.split(/\r?\n/); + for (let i = 0; i < lines.length; i++) { + const line = stripPamComment(lines[i]); + if (line && line.includes(moduleName)) + return true; + } + return false; + } + + function focusPasswordField() { + passwordField.forceActiveFocus(); + } + + function show() { + passwordInput = ""; + isLoading = false; + awaitingFprintForPassword = false; + visible = true; + Qt.callLater(focusPasswordField); + } + + function hide() { + visible = false; + } + + function _commitSubmit() { + isLoading = true; + awaitingFprintForPassword = false; + currentFlow.submit(passwordInput); + passwordInput = ""; + } + + function submitAuth() { + if (!currentFlow || isLoading) + return; + if (!currentFlow.isResponseRequired) { + awaitingFprintForPassword = true; + return; + } + _commitSubmit(); + } + + function cancelAuth() { + if (isLoading) + return; + awaitingFprintForPassword = false; + if (currentFlow) { + currentFlow.cancelAuthenticationRequest(); + return; + } + hide(); + } + + objectName: "polkitAuthModal" + title: I18n.tr("Authentication") + minimumSize: Qt.size(460, 220) + maximumSize: Qt.size(460, 220) + color: Theme.surfaceContainer + visible: false + + onVisibleChanged: { + if (visible) { + Qt.callLater(focusPasswordField); + return; + } + passwordInput = ""; + isLoading = false; + awaitingFprintForPassword = false; + } + + Connections { + target: PolkitService.agent + enabled: PolkitService.polkitAvailable + + function onAuthenticationRequestStarted() { + show(); + } + + function onIsActiveChanged() { + if (!(PolkitService.agent?.isActive ?? false)) + hide(); + } + } + + Connections { + target: currentFlow + enabled: currentFlow !== null + + function onIsResponseRequiredChanged() { + if (!currentFlow.isResponseRequired) + return; + if (awaitingFprintForPassword && passwordInput !== "") { + _commitSubmit(); + return; + } + awaitingFprintForPassword = false; + isLoading = false; + passwordInput = ""; + passwordField.forceActiveFocus(); + } + + function onAuthenticationSucceeded() { + hide(); + } + + function onAuthenticationFailed() { + isLoading = false; + } + + function onAuthenticationRequestCancelled() { + hide(); + } + } + + FileView { + path: "/etc/pam.d/polkit-1" + printErrors: false + onLoaded: root.polkitEtcPamText = text() + onLoadFailed: root.polkitEtcPamText = "" + } + + FileView { + path: "/usr/lib/pam.d/polkit-1" + printErrors: false + onLoaded: root.polkitLibPamText = text() + onLoadFailed: root.polkitLibPamText = "" + } + + FileView { + path: "/etc/pam.d/system-auth" + printErrors: false + onLoaded: root.systemAuthPamText = text() + onLoadFailed: root.systemAuthPamText = "" + } + + FileView { + path: "/etc/pam.d/common-auth" + printErrors: false + onLoaded: root.commonAuthPamText = text() + onLoadFailed: root.commonAuthPamText = "" + } + + FileView { + path: "/etc/pam.d/password-auth" + printErrors: false + onLoaded: root.passwordAuthPamText = text() + onLoadFailed: root.passwordAuthPamText = "" + } + + FocusScope { + id: contentFocusScope + + anchors.fill: parent + focus: true + + Keys.onEscapePressed: event => { + cancelAuth(); + event.accepted = true; + } + + Item { + id: headerSection + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.margins: Theme.spacingM + height: Math.max(titleColumn.implicitHeight, windowButtonRow.implicitHeight) + + MouseArea { + anchors.fill: parent + onPressed: windowControls.tryStartMove() + onDoubleClicked: windowControls.tryToggleMaximize() + } + + Column { + id: titleColumn + anchors.left: parent.left + anchors.right: windowButtonRow.left + anchors.rightMargin: Theme.spacingM + spacing: Theme.spacingXS + + StyledText { + text: I18n.tr("Authentication Required") + font.pixelSize: Theme.fontSizeLarge + color: Theme.surfaceText + font.weight: Font.Medium + } + + StyledText { + text: currentFlow?.message ?? "" + font.pixelSize: Theme.fontSizeMedium + color: Theme.surfaceTextMedium + width: parent.width + wrapMode: Text.Wrap + maximumLineCount: 2 + elide: Text.ElideRight + visible: text !== "" + } + + StyledText { + text: currentFlow?.supplementaryMessage ?? "" + font.pixelSize: Theme.fontSizeSmall + color: (currentFlow?.supplementaryIsError ?? false) ? Theme.error : Theme.surfaceTextMedium + width: parent.width + wrapMode: Text.Wrap + maximumLineCount: 2 + elide: Text.ElideRight + opacity: (currentFlow?.supplementaryIsError ?? false) ? 1 : 0.8 + visible: text !== "" + } + } + + Row { + id: windowButtonRow + anchors.right: parent.right + anchors.top: parent.top + spacing: Theme.spacingXS + + DankActionButton { + visible: windowControls.supported && windowControls.canMaximize + iconName: root.maximized ? "fullscreen_exit" : "fullscreen" + iconSize: Theme.iconSize - 4 + iconColor: Theme.surfaceText + onClicked: windowControls.tryToggleMaximize() + } + + DankActionButton { + iconName: "close" + iconSize: Theme.iconSize - 4 + iconColor: Theme.surfaceText + enabled: !isLoading + opacity: enabled ? 1 : 0.5 + onClicked: cancelAuth() + } + } + } + + Column { + id: bottomSection + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.margins: Theme.spacingM + spacing: Theme.spacingS + + StyledText { + text: currentFlow?.inputPrompt ?? "" + font.pixelSize: Theme.fontSizeMedium + color: Theme.surfaceText + width: parent.width + visible: text !== "" + } + + DankTextField { + id: passwordField + + width: parent.width + height: inputFieldHeight + backgroundColor: Theme.surfaceHover + normalBorderColor: Theme.outlineStrong + focusedBorderColor: Theme.primary + borderWidth: 1 + focusedBorderWidth: 2 + leftIconName: polkitPamHasFprint ? "fingerprint" : "" + leftIconSize: 20 + leftIconColor: Theme.primary + leftIconFocusedColor: Theme.primary + opacity: isLoading ? 0.5 : 1 + font.pixelSize: Theme.fontSizeMedium + textColor: Theme.surfaceText + text: passwordInput + showPasswordToggle: !(currentFlow?.responseVisible ?? false) + echoMode: (currentFlow?.responseVisible ?? false) || passwordVisible ? TextInput.Normal : TextInput.Password + placeholderText: "" + enabled: !isLoading + onTextEdited: passwordInput = text + onAccepted: submitAuth() + } + + StyledText { + text: I18n.tr("Authentication failed, please try again") + font.pixelSize: Theme.fontSizeSmall + color: Theme.error + width: parent.width + visible: currentFlow?.failed ?? false + } + + Item { + width: parent.width + height: 36 + + Row { + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingM + + Rectangle { + width: Math.max(70, cancelText.contentWidth + Theme.spacingM * 2) + height: 36 + radius: Theme.cornerRadius + color: cancelArea.containsMouse ? Theme.surfaceTextHover : "transparent" + border.color: Theme.surfaceVariantAlpha + border.width: 1 + enabled: !isLoading + opacity: enabled ? 1 : 0.5 + + StyledText { + id: cancelText + anchors.centerIn: parent + text: I18n.tr("Cancel") + font.pixelSize: Theme.fontSizeMedium + color: Theme.surfaceText + font.weight: Font.Medium + } + + MouseArea { + id: cancelArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + enabled: parent.enabled + onClicked: cancelAuth() + } + } + + Rectangle { + width: Math.max(80, authText.contentWidth + Theme.spacingM * 2) + height: 36 + radius: Theme.cornerRadius + color: authArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary + enabled: !isLoading + opacity: enabled ? 1 : 0.5 + + StyledText { + id: authText + anchors.centerIn: parent + text: I18n.tr("Authenticate") + font.pixelSize: Theme.fontSizeMedium + color: Theme.background + font.weight: Font.Medium + } + + MouseArea { + id: authArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + enabled: parent.enabled + onClicked: submitAuth() + } + + Behavior on color { + ColorAnimation { + duration: Theme.shortDuration + easing.type: Theme.standardEasing + } + } + } + } + } + } + } + + FloatingWindowControls { + id: windowControls + targetWindow: root + } +} -- cgit v1.3