mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-08-02 19:48:27 -04:00
7b1c542585
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.
334 lines
9.2 KiB
QML
334 lines
9.2 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import Quickshell.Wayland
|
|
import qs.Common
|
|
import qs.Services
|
|
|
|
Scope {
|
|
id: root
|
|
|
|
property string sharedPasswordBuffer: ""
|
|
property bool shouldLock: false
|
|
|
|
onShouldLockChanged: {
|
|
IdleService.isShellLocked = shouldLock;
|
|
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
|
|
property bool customLockerSpawned: false
|
|
|
|
Component.onCompleted: {
|
|
IdleService.lockComponent = this;
|
|
if (SettingsData.lockAtStartup)
|
|
lock();
|
|
}
|
|
|
|
function notifyLockedHint(locked: bool) {
|
|
if (!SettingsData.loginctlLockIntegration || !DMSService.isConnected)
|
|
return;
|
|
DMSService.setLockedHint(locked, () => {});
|
|
}
|
|
|
|
function notifyLoginctl(lockAction: bool) {
|
|
if (!SettingsData.loginctlLockIntegration || !DMSService.isConnected)
|
|
return;
|
|
if (lockAction)
|
|
DMSService.lockSession(() => {});
|
|
else
|
|
DMSService.unlockSession(() => {});
|
|
}
|
|
|
|
function spawnCustomLocker() {
|
|
Quickshell.execDetached(["sh", "-c", SettingsData.customPowerActionLock]);
|
|
// The custom locker manages its own surface; DMS never engages
|
|
// WlSessionLock here, so isShellLocked stays false and the fade
|
|
// overlay would never be dismissed. Hand off by dismissing it now.
|
|
IdleService.dismissFadeToLock();
|
|
customLockerSpawned = true;
|
|
}
|
|
|
|
function handleLoginctlCustomLock(): bool {
|
|
if (!(SettingsData.customPowerActionLock?.length > 0))
|
|
return false;
|
|
if (!customLockerSpawned)
|
|
spawnCustomLocker();
|
|
return true;
|
|
}
|
|
|
|
function lock() {
|
|
if (SettingsData.customPowerActionLock?.length > 0) {
|
|
spawnCustomLocker();
|
|
return;
|
|
}
|
|
if (shouldLock || pendingLock)
|
|
return;
|
|
|
|
lockInitiatedLocally = true;
|
|
lockPowerOffArmed = SettingsData.lockScreenPowerOffMonitorsOnLock;
|
|
|
|
if (!SessionService.active && SessionService.loginctlAvailable && SettingsData.loginctlLockIntegration) {
|
|
pendingLock = true;
|
|
notifyLoginctl(true);
|
|
return;
|
|
}
|
|
|
|
shouldLock = true;
|
|
notifyLoginctl(true);
|
|
}
|
|
|
|
function unlock() {
|
|
if (!shouldLock)
|
|
return;
|
|
lockInitiatedLocally = false;
|
|
notifyLoginctl(false);
|
|
shouldLock = false;
|
|
}
|
|
|
|
function forceReset() {
|
|
lockInitiatedLocally = false;
|
|
pendingLock = false;
|
|
shouldLock = false;
|
|
customLockerSpawned = false;
|
|
}
|
|
|
|
function activate() {
|
|
lock();
|
|
}
|
|
|
|
Connections {
|
|
target: SessionService
|
|
|
|
function onSessionLocked() {
|
|
if (shouldLock || pendingLock)
|
|
return;
|
|
if (handleLoginctlCustomLock())
|
|
return;
|
|
if (!SessionService.active && SessionService.loginctlAvailable && SettingsData.loginctlLockIntegration) {
|
|
pendingLock = true;
|
|
lockInitiatedLocally = false;
|
|
return;
|
|
}
|
|
lockInitiatedLocally = false;
|
|
lockPowerOffArmed = SettingsData.lockScreenPowerOffMonitorsOnLock;
|
|
shouldLock = true;
|
|
}
|
|
|
|
function onSessionUnlocked() {
|
|
customLockerSpawned = false;
|
|
if (pendingLock) {
|
|
pendingLock = false;
|
|
lockInitiatedLocally = false;
|
|
return;
|
|
}
|
|
if (!shouldLock || lockInitiatedLocally)
|
|
return;
|
|
shouldLock = false;
|
|
}
|
|
|
|
function onLoginctlStateChanged() {
|
|
if (SessionService.active && pendingLock) {
|
|
pendingLock = false;
|
|
lockInitiatedLocally = true;
|
|
lockPowerOffArmed = SettingsData.lockScreenPowerOffMonitorsOnLock;
|
|
shouldLock = true;
|
|
return;
|
|
}
|
|
if (SessionService.locked && !shouldLock && !pendingLock) {
|
|
if (handleLoginctlCustomLock())
|
|
return;
|
|
lockInitiatedLocally = false;
|
|
lockPowerOffArmed = SettingsData.lockScreenPowerOffMonitorsOnLock;
|
|
shouldLock = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: IdleService
|
|
|
|
function onLockRequested() {
|
|
lock();
|
|
}
|
|
}
|
|
|
|
Pam {
|
|
id: sharedPam
|
|
lockSecured: root.shouldLock
|
|
buffer: root.sharedPasswordBuffer
|
|
onUnlockRequested: root.unlock()
|
|
}
|
|
|
|
WlSessionLock {
|
|
id: sessionLock
|
|
|
|
locked: shouldLock
|
|
|
|
WlSessionLockSurface {
|
|
id: lockSurface
|
|
|
|
property string currentScreenName: screen?.name ?? ""
|
|
property bool isActiveScreen: {
|
|
if (Quickshell.screens.length <= 1)
|
|
return true;
|
|
return SettingsData.getFilteredScreens("lockScreen").includes(screen);
|
|
}
|
|
|
|
color: isActiveScreen ? "transparent" : SettingsData.lockScreenInactiveColor
|
|
|
|
LockSurface {
|
|
anchors.fill: parent
|
|
visible: lockSurface.isActiveScreen
|
|
lock: sessionLock
|
|
pam: sharedPam
|
|
sharedPasswordBuffer: root.sharedPasswordBuffer
|
|
screenName: lockSurface.currentScreenName
|
|
isLocked: shouldLock
|
|
onUnlockRequested: root.unlock()
|
|
onPasswordChanged: newPassword => {
|
|
root.sharedPasswordBuffer = newPassword;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: sessionLock
|
|
|
|
function onLockedChanged() {
|
|
notifyLockedHint(sessionLock.locked);
|
|
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
|
|
}
|
|
|
|
IpcHandler {
|
|
target: "lock"
|
|
|
|
function lock() {
|
|
root.lock();
|
|
}
|
|
|
|
function unlock() {
|
|
root.unlock();
|
|
}
|
|
|
|
function forceReset() {
|
|
root.forceReset();
|
|
}
|
|
|
|
function demo() {
|
|
demoWindow.showDemo();
|
|
}
|
|
|
|
function isLocked(): bool {
|
|
return sessionLock.locked;
|
|
}
|
|
|
|
function status(): string {
|
|
return JSON.stringify({
|
|
shouldLock: root.shouldLock,
|
|
sessionLockLocked: sessionLock.locked,
|
|
lockInitiatedLocally: root.lockInitiatedLocally,
|
|
pendingLock: root.pendingLock,
|
|
loginctlLocked: SessionService.locked,
|
|
loginctlActive: SessionService.active
|
|
});
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: dpmsReapplyTimer
|
|
interval: 100
|
|
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();
|
|
}
|
|
}
|
|
}
|