diff --git a/dots/.config/hypr/hyprland/execs.conf b/dots/.config/hypr/hyprland/execs.conf index e4f42ca3f..252e3afa8 100644 --- a/dots/.config/hypr/hyprland/execs.conf +++ b/dots/.config/hypr/hyprland/execs.conf @@ -7,7 +7,6 @@ exec-once = qs -c $qsConfig & # Core components (authentication, lock screen, notification daemon) exec-once = gnome-keyring-daemon --start --components=secrets -exec-once = /usr/lib/polkit-kde-authentication-agent-1 || /usr/libexec/polkit-kde-authentication-agent-1 || /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 || /usr/libexec/polkit-gnome-authentication-agent-1 exec-once = hypridle exec-once = dbus-update-activation-environment --all exec-once = sleep 1 && dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP # Some fix idk diff --git a/dots/.config/quickshell/ii/modules/common/widgets/WindowDialog.qml b/dots/.config/quickshell/ii/modules/common/widgets/WindowDialog.qml index a0ca64e98..16a82c4ee 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/WindowDialog.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/WindowDialog.qml @@ -10,7 +10,8 @@ Rectangle { property bool show: false default property alias data: contentColumn.data - property real backgroundHeight: 600 + property real backgroundHeight: dialogBackground.implicitHeight + property real backgroundWidth: 350 property real backgroundAnimationMovementDistance: 60 signal dismiss() @@ -49,7 +50,7 @@ Rectangle { property real targetY: root.height / 2 - root.backgroundHeight / 2 y: root.show ? targetY : (targetY - root.backgroundAnimationMovementDistance) - implicitWidth: 350 + implicitWidth: root.backgroundWidth implicitHeight: contentColumn.implicitHeight + dialogBackground.radius * 2 Behavior on implicitHeight { NumberAnimation { diff --git a/dots/.config/quickshell/ii/modules/common/widgets/WindowDialogParagraph.qml b/dots/.config/quickshell/ii/modules/common/widgets/WindowDialogParagraph.qml new file mode 100644 index 000000000..83b2166d5 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/common/widgets/WindowDialogParagraph.qml @@ -0,0 +1,12 @@ +import QtQuick +import Quickshell +import qs.modules.common +import qs.modules.common.functions +import qs.modules.common.widgets + +StyledText { + text: "Some body content" + color: Appearance.colors.colOnSurfaceVariant + font.pixelSize: Appearance.font.pixelSize.small + wrapMode: Text.Wrap +} diff --git a/dots/.config/quickshell/ii/modules/common/widgets/WindowDialogSlider.qml b/dots/.config/quickshell/ii/modules/common/widgets/WindowDialogSlider.qml index 5c6db1443..1ae6da194 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/WindowDialogSlider.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/WindowDialogSlider.qml @@ -35,7 +35,7 @@ Column { left: parent.left right: parent.right leftMargin: 4 - rightMargin: leftMargin + rightMargin: 4 } configuration: StyledSlider.Configuration.S onMoved: root.moved() diff --git a/dots/.config/quickshell/ii/modules/common/widgets/WindowDialogTitle.qml b/dots/.config/quickshell/ii/modules/common/widgets/WindowDialogTitle.qml index a450030fa..98ca24f69 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/WindowDialogTitle.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/WindowDialogTitle.qml @@ -6,6 +6,8 @@ import qs.modules.common.widgets StyledText { text: "Dialog Title" + color: Appearance.colors.colOnSurface + wrapMode: Text.Wrap font { pixelSize: Appearance.font.pixelSize.title family: Appearance.font.family.title diff --git a/dots/.config/quickshell/ii/modules/polkit/Polkit.qml b/dots/.config/quickshell/ii/modules/polkit/Polkit.qml new file mode 100644 index 000000000..e1c54a42f --- /dev/null +++ b/dots/.config/quickshell/ii/modules/polkit/Polkit.qml @@ -0,0 +1,42 @@ +import qs +import qs.services +import qs.modules.common +import qs.modules.common.widgets +import qs.modules.common.functions +import QtQuick +import Quickshell +import Quickshell.Wayland +import Quickshell.Hyprland + +Scope { + id: root + + Loader { + active: PolkitService.active + sourceComponent: Variants { + model: Quickshell.screens + delegate: PanelWindow { + id: panelWindow + required property var modelData + screen: modelData + + anchors { + top: true + left: true + right: true + bottom: true + } + + color: "transparent" + WlrLayershell.namespace: "quickshell:polkit" + WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand + WlrLayershell.layer: WlrLayer.Overlay + exclusionMode: ExclusionMode.Ignore + + PolkitContent { + anchors.fill: parent + } + } + } + } +} diff --git a/dots/.config/quickshell/ii/modules/polkit/PolkitContent.qml b/dots/.config/quickshell/ii/modules/polkit/PolkitContent.qml new file mode 100644 index 000000000..1729bb3d9 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/polkit/PolkitContent.qml @@ -0,0 +1,107 @@ +import QtQuick +import QtQuick.Layouts +import Quickshell +import Quickshell.Widgets +import qs.services +import qs.modules.common +import qs.modules.common.widgets + +Item { + id: root + readonly property bool usePasswordChars: !PolkitService.flow?.responseVisible ?? true + + Keys.onPressed: event => { // Esc to close + if (event.key === Qt.Key_Escape) { + PolkitService.cancel(); + } + } + + function submit() { + PolkitService.submit(inputField.text); + } + Connections { + target: PolkitService + function onInteractionAvailableChanged() { + if (!PolkitService.interactionAvailable) return; + inputField.text = ""; + inputField.forceActiveFocus(); + } + } + + Rectangle { + id: bg + anchors.fill: parent + color: Appearance.colors.colScrim + opacity: 0 + Component.onCompleted: { + opacity = 1 + } + Behavior on opacity { + animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) + } + } + + WindowDialog { + anchors.centerIn: parent + backgroundWidth: 450 + show: false + Component.onCompleted: { + show = true + } + + MaterialSymbol { + Layout.alignment: Qt.AlignHCenter + iconSize: 26 + text: "shield_locked" + color: Appearance.colors.colSecondary + } + + WindowDialogTitle { + id: titleText + Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + text: Translation.tr("Authentication") + } + + WindowDialogParagraph { + Layout.fillWidth: true + horizontalAlignment: Text.AlignLeft + text: { + if (!PolkitService.flow) return; + return PolkitService.flow.message.endsWith(".") + ? PolkitService.flow.message.slice(0, -1) + : PolkitService.flow.message + } + } + + MaterialTextField { + id: inputField + Layout.fillWidth: true + focus: true + enabled: PolkitService.interactionAvailable + placeholderText: { + const inputPrompt = PolkitService.flow?.inputPrompt.trim() ?? ""; + const cleanedInputPrompt = inputPrompt.endsWith(":") ? inputPrompt.slice(0, -1) : inputPrompt; + return cleanedInputPrompt || (root.usePasswordChars ? Translation.tr("Password") : Translation.tr("Input")) + } + echoMode: root.usePasswordChars ? TextInput.Password : TextInput.Normal + onAccepted: root.submit(); + } + + WindowDialogButtonRow { + + Item { + Layout.fillWidth: true + } + DialogButton { + buttonText: Translation.tr("Cancel") + onClicked: PolkitService.cancel(); + } + DialogButton { + enabled: PolkitService.interactionAvailable + buttonText: Translation.tr("OK") + onClicked: root.submit(); + } + } + } +} diff --git a/dots/.config/quickshell/ii/modules/sidebarRight/bluetoothDevices/BluetoothDialog.qml b/dots/.config/quickshell/ii/modules/sidebarRight/bluetoothDevices/BluetoothDialog.qml index f51053697..69e354704 100644 --- a/dots/.config/quickshell/ii/modules/sidebarRight/bluetoothDevices/BluetoothDialog.qml +++ b/dots/.config/quickshell/ii/modules/sidebarRight/bluetoothDevices/BluetoothDialog.qml @@ -15,6 +15,7 @@ import Quickshell.Hyprland WindowDialog { id: root + backgroundHeight: 600 WindowDialogTitle { text: Translation.tr("Bluetooth devices") diff --git a/dots/.config/quickshell/ii/modules/sidebarRight/nightLight/NightLightDialog.qml b/dots/.config/quickshell/ii/modules/sidebarRight/nightLight/NightLightDialog.qml index 1b423df4e..9343c4588 100644 --- a/dots/.config/quickshell/ii/modules/sidebarRight/nightLight/NightLightDialog.qml +++ b/dots/.config/quickshell/ii/modules/sidebarRight/nightLight/NightLightDialog.qml @@ -15,6 +15,7 @@ WindowDialog { id: root property var screen: root.QsWindow.window?.screen property var brightnessMonitor: Brightness.getMonitorForScreen(screen) + backgroundHeight: 600 WindowDialogTitle { text: Translation.tr("Eye protection") diff --git a/dots/.config/quickshell/ii/modules/sidebarRight/wifiNetworks/WifiDialog.qml b/dots/.config/quickshell/ii/modules/sidebarRight/wifiNetworks/WifiDialog.qml index cb7686c44..36683c353 100644 --- a/dots/.config/quickshell/ii/modules/sidebarRight/wifiNetworks/WifiDialog.qml +++ b/dots/.config/quickshell/ii/modules/sidebarRight/wifiNetworks/WifiDialog.qml @@ -9,6 +9,7 @@ import Quickshell WindowDialog { id: root + backgroundHeight: 600 WindowDialogTitle { text: Translation.tr("Connect to Wi-Fi") diff --git a/dots/.config/quickshell/ii/services/PolkitService.qml b/dots/.config/quickshell/ii/services/PolkitService.qml new file mode 100644 index 000000000..56576f4f4 --- /dev/null +++ b/dots/.config/quickshell/ii/services/PolkitService.qml @@ -0,0 +1,37 @@ +pragma Singleton +pragma ComponentBehavior: Bound + +import QtQuick +import Quickshell +import Quickshell.Services.Polkit + +Singleton { + id: root + property alias agent: polkitAgent + property alias active: polkitAgent.isActive + property alias flow: polkitAgent.flow + property bool interactionAvailable: false + + function cancel() { + root.flow.cancelAuthenticationRequest() + } + + function submit(string) { + root.flow.submit(string) + root.interactionAvailable = false + } + + Connections { + target: root.flow + function onAuthenticationFailed() { + root.interactionAvailable = true; + } + } + + PolkitAgent { + id: polkitAgent + onAuthenticationRequestStarted: { + root.interactionAvailable = true; + } + } +} diff --git a/dots/.config/quickshell/ii/services/Translation.qml b/dots/.config/quickshell/ii/services/Translation.qml index c504ba21c..fe8f8d75c 100644 --- a/dots/.config/quickshell/ii/services/Translation.qml +++ b/dots/.config/quickshell/ii/services/Translation.qml @@ -122,7 +122,6 @@ Singleton { signal contentLoaded(var data) function reread() { // Proper reload in case the file was incorrect before - print("rereading translations for", translationReader.languageCode); translationReader.path = ""; translationReader.path = `${translationReader.translationsDir}/${translationReader.languageCode}.json`; translationReader.reload(); diff --git a/dots/.config/quickshell/ii/shell.qml b/dots/.config/quickshell/ii/shell.qml index 9cb90f102..d50f6640f 100644 --- a/dots/.config/quickshell/ii/shell.qml +++ b/dots/.config/quickshell/ii/shell.qml @@ -19,6 +19,7 @@ import qs.modules.notificationPopup import qs.modules.onScreenDisplay import qs.modules.onScreenKeyboard import qs.modules.overview +import qs.modules.polkit import qs.modules.regionSelector import qs.modules.screenCorners import qs.modules.sessionScreen @@ -43,6 +44,7 @@ ShellRoot { property bool enableLock: true property bool enableMediaControls: true property bool enableNotificationPopup: true + property bool enablePolkit: true property bool enableOnScreenDisplay: true property bool enableOnScreenKeyboard: true property bool enableOverview: true @@ -76,6 +78,7 @@ ShellRoot { LazyLoader { active: enableOnScreenDisplay; component: OnScreenDisplay {} } LazyLoader { active: enableOnScreenKeyboard; component: OnScreenKeyboard {} } LazyLoader { active: enableOverview; component: Overview {} } + LazyLoader { active: enablePolkit; component: Polkit {} } LazyLoader { active: enableRegionSelector; component: RegionSelector {} } LazyLoader { active: enableReloadPopup; component: ReloadPopup {} } LazyLoader { active: enableScreenCorners; component: ScreenCorners {} }