diff --git a/quickshell/Common/SettingsData.qml b/quickshell/Common/SettingsData.qml index ad20e1fe..80279ac7 100644 --- a/quickshell/Common/SettingsData.qml +++ b/quickshell/Common/SettingsData.qml @@ -295,6 +295,8 @@ Singleton { property bool enableFprint: false property int maxFprintTries: 3 property bool fprintdAvailable: false + property string lockScreenActiveMonitor: "all" + property string lockScreenInactiveColor: "#000000" property bool hideBrightnessSlider: false property int notificationTimeoutLow: 5000 diff --git a/quickshell/Common/settings/SettingsSpec.js b/quickshell/Common/settings/SettingsSpec.js index 8bef8302..5e559b30 100644 --- a/quickshell/Common/settings/SettingsSpec.js +++ b/quickshell/Common/settings/SettingsSpec.js @@ -194,6 +194,8 @@ var SPEC = { enableFprint: { def: false }, maxFprintTries: { def: 3 }, fprintdAvailable: { def: false, persist: false }, + lockScreenActiveMonitor: { def: "all" }, + lockScreenInactiveColor: { def: "#000000" }, hideBrightnessSlider: { def: false }, notificationTimeoutLow: { def: 5000 }, diff --git a/quickshell/Modals/Settings/PowerSettings.qml b/quickshell/Modals/Settings/PowerSettings.qml index 4bd806a2..72b356d3 100644 --- a/quickshell/Modals/Settings/PowerSettings.qml +++ b/quickshell/Modals/Settings/PowerSettings.qml @@ -1,4 +1,5 @@ import QtQuick +import Quickshell import qs.Common import qs.Services import qs.Widgets @@ -103,6 +104,147 @@ Item { } } + StyledRect { + width: parent.width + height: lockDisplaySection.implicitHeight + Theme.spacingL * 2 + radius: Theme.cornerRadius + color: Theme.surfaceContainerHigh + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) + border.width: 0 + visible: Quickshell.screens.length > 1 + + Column { + id: lockDisplaySection + anchors.fill: parent + anchors.margins: Theme.spacingL + spacing: Theme.spacingM + + Row { + width: parent.width + spacing: Theme.spacingM + + DankIcon { + name: "monitor" + size: Theme.iconSize + color: Theme.primary + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Lock Screen Display") + font.pixelSize: Theme.fontSizeLarge + font.weight: Font.Medium + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + } + + StyledText { + text: I18n.tr("Choose which monitor shows the lock screen interface. Other monitors will display a solid color for OLED burn-in protection.") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + width: parent.width + wrapMode: Text.Wrap + } + + DankDropdown { + id: lockScreenMonitorDropdown + width: parent.width + addHorizontalPadding: true + text: I18n.tr("Active Lock Screen Monitor") + options: { + var opts = [I18n.tr("All Monitors")]; + var screens = Quickshell.screens; + for (var i = 0; i < screens.length; i++) { + opts.push(SettingsData.getScreenDisplayName(screens[i])); + } + return opts; + } + + Component.onCompleted: { + if (SettingsData.lockScreenActiveMonitor === "all") { + currentValue = I18n.tr("All Monitors"); + return; + } + var screens = Quickshell.screens; + for (var i = 0; i < screens.length; i++) { + if (screens[i].name === SettingsData.lockScreenActiveMonitor) { + currentValue = SettingsData.getScreenDisplayName(screens[i]); + return; + } + } + currentValue = I18n.tr("All Monitors"); + } + + onValueChanged: value => { + if (value === I18n.tr("All Monitors")) { + SettingsData.set("lockScreenActiveMonitor", "all"); + return; + } + var screens = Quickshell.screens; + for (var i = 0; i < screens.length; i++) { + if (SettingsData.getScreenDisplayName(screens[i]) === value) { + SettingsData.set("lockScreenActiveMonitor", screens[i].name); + return; + } + } + } + } + + Row { + width: parent.width + spacing: Theme.spacingM + visible: SettingsData.lockScreenActiveMonitor !== "all" + + Column { + width: parent.width - inactiveColorPreview.width - Theme.spacingM + spacing: Theme.spacingXS + anchors.verticalCenter: parent.verticalCenter + + StyledText { + text: I18n.tr("Inactive Monitor Color") + font.pixelSize: Theme.fontSizeMedium + color: Theme.surfaceText + } + + StyledText { + text: I18n.tr("Color displayed on monitors without the lock screen") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + width: parent.width + wrapMode: Text.Wrap + } + } + + Rectangle { + id: inactiveColorPreview + width: 48 + height: 48 + radius: Theme.cornerRadius + color: SettingsData.lockScreenInactiveColor + border.color: Theme.outline + border.width: 1 + anchors.verticalCenter: parent.verticalCenter + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: { + if (!PopoutService.colorPickerModal) + return; + PopoutService.colorPickerModal.selectedColor = SettingsData.lockScreenInactiveColor; + PopoutService.colorPickerModal.pickerTitle = I18n.tr("Inactive Monitor Color"); + PopoutService.colorPickerModal.onColorSelectedCallback = function (selectedColor) { + SettingsData.set("lockScreenInactiveColor", selectedColor); + }; + PopoutService.colorPickerModal.show(); + } + } + } + } + } + } + StyledRect { width: parent.width height: timeoutSection.implicitHeight + Theme.spacingL * 2 diff --git a/quickshell/Modules/Lock/Lock.qml b/quickshell/Modules/Lock/Lock.qml index 40b0575a..25ab3201 100644 --- a/quickshell/Modules/Lock/Lock.qml +++ b/quickshell/Modules/Lock/Lock.qml @@ -84,13 +84,23 @@ Scope { WlSessionLockSurface { id: lockSurface - color: "transparent" + property string currentScreenName: screen?.name ?? "" + property bool isActiveScreen: { + if (Quickshell.screens.length <= 1) + return true; + if (SettingsData.lockScreenActiveMonitor === "all") + return true; + return currentScreenName === SettingsData.lockScreenActiveMonitor; + } + + color: isActiveScreen ? "transparent" : SettingsData.lockScreenInactiveColor LockSurface { anchors.fill: parent + visible: lockSurface.isActiveScreen lock: sessionLock sharedPasswordBuffer: root.sharedPasswordBuffer - screenName: lockSurface.screen?.name ?? "" + screenName: lockSurface.currentScreenName isLocked: shouldLock onUnlockRequested: { root.unlock();