From 7b1c5425853a94bb97ce9694933c07c4e46585df Mon Sep 17 00:00:00 2001 From: Scott McKendry Date: Sun, 5 Jul 2026 03:04:59 +1200 Subject: [PATCH] feat: lockscreen screen filter (#2740) this makes use of the existing getFilteredScreens function to allow users to specify which displays the lockscreen should appear on. prior to this change, it was "all" or just one. --- quickshell/Common/SettingsData.qml | 12 +++- quickshell/Common/settings/SettingsSpec.js | 1 - quickshell/Modules/Lock/Lock.qml | 4 +- quickshell/Modules/Settings/LockScreenTab.qml | 57 +++++-------------- .../Widgets/SettingsDisplayPicker.qml | 2 +- .../translations/settings_search_index.json | 18 ------ 6 files changed, 26 insertions(+), 68 deletions(-) diff --git a/quickshell/Common/SettingsData.qml b/quickshell/Common/SettingsData.qml index 3f1f5bba0..f9adc1269 100644 --- a/quickshell/Common/SettingsData.qml +++ b/quickshell/Common/SettingsData.qml @@ -889,7 +889,6 @@ Singleton { readonly property bool greeterU2fReady: Processes.greeterU2fReady readonly property string greeterU2fReason: Processes.greeterU2fReason readonly property string greeterU2fSource: Processes.greeterU2fSource - property string lockScreenActiveMonitor: "all" property string lockScreenInactiveColor: "#000000" property int lockScreenNotificationMode: 0 property bool lockScreenVideoEnabled: false @@ -1745,6 +1744,17 @@ Singleton { } } + if (obj?.lockScreenActiveMonitor !== undefined) { + var oldVal = obj.lockScreenActiveMonitor; + if (oldVal && oldVal !== "all") { + if (!obj.screenPreferences) obj.screenPreferences = {}; + if (obj.screenPreferences.lockScreen === undefined) { + obj.screenPreferences.lockScreen = [oldVal]; + } + } + delete obj.lockScreenActiveMonitor; + } + Store.parse(root, obj); if (obj?.directionalAnimationMode === 3 && frameMode !== "connected") diff --git a/quickshell/Common/settings/SettingsSpec.js b/quickshell/Common/settings/SettingsSpec.js index 848b63d26..907046f6f 100644 --- a/quickshell/Common/settings/SettingsSpec.js +++ b/quickshell/Common/settings/SettingsSpec.js @@ -451,7 +451,6 @@ var SPEC = { maxFprintTries: { def: 15 }, enableU2f: { def: false, onChange: "scheduleAuthApply" }, u2fMode: { def: "or" }, - lockScreenActiveMonitor: { def: "all" }, lockScreenInactiveColor: { def: "#000000" }, lockScreenNotificationMode: { def: 0 }, lockScreenVideoEnabled: { def: false }, diff --git a/quickshell/Modules/Lock/Lock.qml b/quickshell/Modules/Lock/Lock.qml index 5dd94a0a6..de28b81b6 100644 --- a/quickshell/Modules/Lock/Lock.qml +++ b/quickshell/Modules/Lock/Lock.qml @@ -196,9 +196,7 @@ Scope { property bool isActiveScreen: { if (Quickshell.screens.length <= 1) return true; - if (SettingsData.lockScreenActiveMonitor === "all") - return true; - return currentScreenName === SettingsData.lockScreenActiveMonitor; + return SettingsData.getFilteredScreens("lockScreen").includes(screen); } color: isActiveScreen ? "transparent" : SettingsData.lockScreenInactiveColor diff --git a/quickshell/Modules/Settings/LockScreenTab.qml b/quickshell/Modules/Settings/LockScreenTab.qml index 664bfa5d1..518b70387 100644 --- a/quickshell/Modules/Settings/LockScreenTab.qml +++ b/quickshell/Modules/Settings/LockScreenTab.qml @@ -398,64 +398,33 @@ Item { iconName: "monitor" title: I18n.tr("Lock Screen Display") settingKey: "lockDisplay" - visible: Quickshell.screens.length > 1 StyledText { - text: I18n.tr("Choose which monitor shows the lock screen interface. Other monitors will display a solid color for OLED burn-in protection.") + text: I18n.tr("Choose which monitors show 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 } - SettingsDropdownRow { - id: lockScreenMonitorDropdown - settingKey: "lockScreenActiveMonitor" - tags: ["lock", "screen", "monitor", "display", "active"] - 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; - } - } + SettingsDisplayPicker { + width: parent.width + displayPreferences: SettingsData.screenPreferences?.lockScreen || ["all"] + onPreferencesChanged: prefs => { + var p = SettingsData.screenPreferences || {}; + var updated = Object.assign({}, p); + updated["lockScreen"] = prefs; + SettingsData.set("screenPreferences", updated); } } Row { width: parent.width spacing: Theme.spacingM - visible: SettingsData.lockScreenActiveMonitor !== "all" + visible: { + var prefs = SettingsData.screenPreferences?.lockScreen; + return Array.isArray(prefs) && !prefs.includes("all") && prefs.length > 0; + } Column { width: parent.width - inactiveColorPreview.width - Theme.spacingM diff --git a/quickshell/Modules/Settings/Widgets/SettingsDisplayPicker.qml b/quickshell/Modules/Settings/Widgets/SettingsDisplayPicker.qml index ab4074f8d..e45be9a61 100644 --- a/quickshell/Modules/Settings/Widgets/SettingsDisplayPicker.qml +++ b/quickshell/Modules/Settings/Widgets/SettingsDisplayPicker.qml @@ -80,7 +80,7 @@ Item { width: parent.width text: SettingsData.getScreenDisplayName(modelData) - description: modelData.width + "×" + modelData.height + description: modelData.width + "×" + modelData.height + " • " + (SettingsData.displayNameMode === "system" ? (modelData.model || I18n.tr("Unknown Model")) : modelData.name) checked: localChecked onToggled: isChecked => { var prefs = JSON.parse(JSON.stringify(root.displayPreferences)); diff --git a/quickshell/translations/settings_search_index.json b/quickshell/translations/settings_search_index.json index 4dad18558..45ce40040 100644 --- a/quickshell/translations/settings_search_index.json +++ b/quickshell/translations/settings_search_index.json @@ -4579,23 +4579,6 @@ "zenbrowser" ] }, - { - "section": "lockScreenActiveMonitor", - "label": "Active Lock Screen Monitor", - "tabIndex": 11, - "category": "Lock Screen", - "keywords": [ - "active", - "display", - "lock", - "lockscreen", - "login", - "monitor", - "password", - "screen", - "security" - ] - }, { "section": "lockScreenVideoCycling", "label": "Automatic Cycling", @@ -4747,7 +4730,6 @@ "tabIndex": 11, "category": "Lock Screen", "keywords": [ - "active", "display", "lock", "lockscreen",