diff --git a/quickshell/Common/SettingsData.qml b/quickshell/Common/SettingsData.qml index 45e56927..e1dc3377 100644 --- a/quickshell/Common/SettingsData.qml +++ b/quickshell/Common/SettingsData.qml @@ -394,6 +394,7 @@ Singleton { property bool lockScreenShowDate: true property bool lockScreenShowProfileImage: true property bool lockScreenShowPasswordField: true + property bool lockScreenPowerOffMonitorsOnLock: false property bool enableFprint: false property int maxFprintTries: 15 diff --git a/quickshell/Common/settings/SettingsSpec.js b/quickshell/Common/settings/SettingsSpec.js index ecab83d5..664e1227 100644 --- a/quickshell/Common/settings/SettingsSpec.js +++ b/quickshell/Common/settings/SettingsSpec.js @@ -259,6 +259,7 @@ var SPEC = { lockScreenShowDate: { def: true }, lockScreenShowProfileImage: { def: true }, lockScreenShowPasswordField: { def: true }, + lockScreenPowerOffMonitorsOnLock: { def: false }, enableFprint: { def: false }, maxFprintTries: { def: 15 }, fprintdAvailable: { def: false, persist: false }, diff --git a/quickshell/Modules/Lock/Lock.qml b/quickshell/Modules/Lock/Lock.qml index c5991452..9fb6b56e 100644 --- a/quickshell/Modules/Lock/Lock.qml +++ b/quickshell/Modules/Lock/Lock.qml @@ -12,8 +12,34 @@ Scope { property string sharedPasswordBuffer: "" property bool shouldLock: false + + onShouldLockChanged: { + if (shouldLock && lockPowerOffArmed) { + lockStateCheck.restart(); + } + } + + Timer { + id: lockStateCheck + interval: 100 + repeat: false + onTriggered: { + if (sessionLock.locked && lockPowerOffArmed) { + pendingLock = false; + IdleService.monitorsOff = true; + CompositorService.powerOffMonitors(); + lockWakeAllowed = false; + lockWakeDebounce.restart(); + lockPowerOffArmed = false; + dpmsReapplyTimer.start(); + } + } + } + property bool lockInitiatedLocally: false property bool pendingLock: false + property bool lockPowerOffArmed: false + property bool lockWakeAllowed: false Component.onCompleted: { IdleService.lockComponent = this; @@ -37,6 +63,7 @@ Scope { return; lockInitiatedLocally = true; + lockPowerOffArmed = SettingsData.lockScreenPowerOffMonitorsOnLock; if (!SessionService.active && SessionService.loginctlAvailable) { pendingLock = true; @@ -78,6 +105,7 @@ Scope { return; } lockInitiatedLocally = false; + lockPowerOffArmed = SettingsData.lockScreenPowerOffMonitorsOnLock; shouldLock = true; } @@ -96,11 +124,13 @@ Scope { if (SessionService.active && pendingLock) { pendingLock = false; lockInitiatedLocally = true; + lockPowerOffArmed = SettingsData.lockScreenPowerOffMonitorsOnLock; shouldLock = true; return; } if (SessionService.locked && !shouldLock && !pendingLock) { lockInitiatedLocally = false; + lockPowerOffArmed = SettingsData.lockScreenPowerOffMonitorsOnLock; shouldLock = true; } } @@ -119,13 +149,6 @@ Scope { locked: shouldLock - onLockedChanged: { - if (locked) { - pendingLock = false; - dpmsReapplyTimer.start(); - } - } - WlSessionLockSurface { id: lockSurface @@ -155,7 +178,33 @@ Scope { } } + Connections { + target: sessionLock + + function onLockedChanged() { + if (sessionLock.locked) { + pendingLock = false; + if (lockPowerOffArmed && SettingsData.lockScreenPowerOffMonitorsOnLock) { + IdleService.monitorsOff = true; + CompositorService.powerOffMonitors(); + lockWakeAllowed = false; + lockWakeDebounce.restart(); + } + lockPowerOffArmed = false; + dpmsReapplyTimer.start(); + return; + } + + lockWakeAllowed = false; + if (IdleService.monitorsOff && SettingsData.lockScreenPowerOffMonitorsOnLock) { + IdleService.monitorsOff = false; + CompositorService.powerOnMonitors(); + } + } + } + LockScreenDemo { + id: demoWindow } @@ -200,4 +249,46 @@ Scope { repeat: false onTriggered: IdleService.reapplyDpmsIfNeeded() } + + Timer { + id: lockWakeDebounce + interval: 200 + repeat: false + onTriggered: { + if (!sessionLock.locked) + return; + if (!SettingsData.lockScreenPowerOffMonitorsOnLock) + return; + if (!IdleService.monitorsOff) { + lockWakeAllowed = true; + return; + } + if (lockWakeAllowed) { + IdleService.monitorsOff = false; + CompositorService.powerOnMonitors(); + } else { + lockWakeAllowed = true; + } + } + } + + MouseArea { + anchors.fill: parent + enabled: sessionLock.locked + hoverEnabled: enabled + onPressed: lockWakeDebounce.restart() + onPositionChanged: lockWakeDebounce.restart() + onWheel: lockWakeDebounce.restart() + } + + FocusScope { + anchors.fill: parent + focus: sessionLock.locked + + Keys.onPressed: event => { + if (!sessionLock.locked) + return; + lockWakeDebounce.restart(); + } + } } diff --git a/quickshell/Modules/Settings/LockScreenTab.qml b/quickshell/Modules/Settings/LockScreenTab.qml index 3b670319..bb796f27 100644 --- a/quickshell/Modules/Settings/LockScreenTab.qml +++ b/quickshell/Modules/Settings/LockScreenTab.qml @@ -131,6 +131,15 @@ Item { onToggled: checked => SettingsData.set("lockBeforeSuspend", checked) } + SettingsToggleRow { + settingKey: "lockScreenPowerOffMonitorsOnLock" + tags: ["lock", "screen", "monitor", "display", "dpms", "power"] + text: I18n.tr("Power off monitors on lock") + description: I18n.tr("Turn off all displays immediately when the lock screen activates") + checked: SettingsData.lockScreenPowerOffMonitorsOnLock + onToggled: checked => SettingsData.set("lockScreenPowerOffMonitorsOnLock", checked) + } + SettingsToggleRow { settingKey: "enableFprint" tags: ["lock", "screen", "fingerprint", "authentication", "biometric", "fprint"]