From dfbbe3fccae849e471cf9e1f3ed6c7ef3d9d4acf Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Thu, 30 Oct 2025 11:07:57 +0100 Subject: [PATCH] lock: make window hiding anim work with floating windows --- .../quickshell/ii/modules/lock/Lock.qml | 180 ++++++++++-------- 1 file changed, 99 insertions(+), 81 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/lock/Lock.qml b/dots/.config/quickshell/ii/modules/lock/Lock.qml index 458f7c63c..1a273cb0b 100644 --- a/dots/.config/quickshell/ii/modules/lock/Lock.qml +++ b/dots/.config/quickshell/ii/modules/lock/Lock.qml @@ -1,4 +1,6 @@ +pragma ComponentBehavior: Bound import qs +import qs.services import qs.modules.common import qs.modules.common.functions import qs.modules.lock @@ -9,9 +11,9 @@ import Quickshell.Wayland import Quickshell.Hyprland Scope { - id: root + id: root - function unlockKeyring() { + function unlockKeyring() { Quickshell.execDetached({ environment: ({ UNLOCK_PASSWORD: root.currentText @@ -20,120 +22,136 @@ Scope { }) } - // This stores all the information shared between the lock surfaces on each screen. - // https://github.com/quickshell-mirror/quickshell-examples/tree/master/lockscreen - LockContext { - id: lockContext + property var windowData: [] + function saveWindowPositionAndTile() { + root.windowData = HyprlandData.windowList.filter(w => w.floating) + root.windowData.forEach(w => { + Hyprland.dispatch(`settiled address:${w.address}`) + }) + } + function restoreWindowPositionAndTile() { + root.windowData.forEach(w => { + Hyprland.dispatch(`setfloating address:${w.address}`) + Hyprland.dispatch(`movewindowpixel exact ${w.at[0]} ${w.at[1]}, address:${w.address}`) + }) + } - Connections { - target: GlobalStates - function onScreenLockedChanged() { - if (GlobalStates.screenLocked) { - lockContext.reset(); - lockContext.tryFingerUnlock(); - } - } - } + // This stores all the information shared between the lock surfaces on each screen. + // https://github.com/quickshell-mirror/quickshell-examples/tree/master/lockscreen + LockContext { + id: lockContext - onUnlocked: (targetAction) => { - // Perform the target action if it's not just unlocking - if (targetAction == LockContext.ActionEnum.Poweroff) { - Session.poweroff(); - return; - } else if (targetAction == LockContext.ActionEnum.Reboot) { - Session.reboot(); - return; - } + Connections { + target: GlobalStates + function onScreenLockedChanged() { + if (GlobalStates.screenLocked) { + lockContext.reset(); + lockContext.tryFingerUnlock(); + } + } + } - // Unlock the keyring if configured to do so - if (Config.options.lock.security.unlockKeyring) root.unlockKeyring(); + onUnlocked: (targetAction) => { + // Perform the target action if it's not just unlocking + if (targetAction == LockContext.ActionEnum.Poweroff) { + Session.poweroff(); + return; + } else if (targetAction == LockContext.ActionEnum.Reboot) { + Session.reboot(); + return; + } - // Unlock the screen before exiting, or the compositor will display a - // fallback lock you can't interact with. - GlobalStates.screenLocked = false; - - // Refocus last focused window on unlock (hack) - Quickshell.execDetached(["bash", "-c", `sleep 0.2; hyprctl --batch "dispatch togglespecialworkspace; dispatch togglespecialworkspace"`]) + // Unlock the keyring if configured to do so + if (Config.options.lock.security.unlockKeyring) root.unlockKeyring(); + + // Unlock the screen before exiting, or the compositor will display a + // fallback lock you can't interact with. + GlobalStates.screenLocked = false; + + // Refocus last focused window on unlock (hack) + Quickshell.execDetached(["bash", "-c", `sleep 0.2; hyprctl --batch "dispatch togglespecialworkspace; dispatch togglespecialworkspace"`]) // Reset lockContext.reset(); - } - } + } + } - WlSessionLock { - id: lock - locked: GlobalStates.screenLocked + WlSessionLock { + id: lock + locked: GlobalStates.screenLocked - WlSessionLockSurface { - color: "transparent" - Loader { - active: GlobalStates.screenLocked - anchors.fill: parent - opacity: active ? 1 : 0 - Behavior on opacity { - animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) - } - sourceComponent: LockSurface { - context: lockContext - } - } - } - } + WlSessionLockSurface { + color: "transparent" + Loader { + active: GlobalStates.screenLocked + anchors.fill: parent + opacity: active ? 1 : 0 + Behavior on opacity { + animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) + } + sourceComponent: LockSurface { + context: lockContext + } + } + } + } - // Blur layer hack - Variants { + // Blur layer hack + Variants { model: Quickshell.screens - delegate: Scope { - required property ShellScreen modelData - property bool shouldPush: GlobalStates.screenLocked - property string targetMonitorName: modelData.name - property int verticalMovementDistance: modelData.height - property int horizontalSqueeze: modelData.width * 0.2 - onShouldPushChanged: { - if (shouldPush) { - Quickshell.execDetached(["bash", "-c", `hyprctl keyword monitor ${targetMonitorName}, addreserved, ${verticalMovementDistance}, ${-verticalMovementDistance}, ${horizontalSqueeze}, ${horizontalSqueeze}`]) - } else { - Quickshell.execDetached(["bash", "-c", `hyprctl keyword monitor ${targetMonitorName}, addreserved, 0, 0, 0, 0`]) - } - } - } - } + delegate: Scope { + required property ShellScreen modelData + property bool shouldPush: GlobalStates.screenLocked + property string targetMonitorName: modelData.name + property int verticalMovementDistance: modelData.height + property int horizontalSqueeze: modelData.width * 0.2 + onShouldPushChanged: { + if (shouldPush) { + root.saveWindowPositionAndTile(); + Quickshell.execDetached(["bash", "-c", `hyprctl keyword monitor ${targetMonitorName}, addreserved, ${verticalMovementDistance}, ${-verticalMovementDistance}, ${horizontalSqueeze}, ${horizontalSqueeze}`]) + } else { + Quickshell.execDetached(["bash", "-c", `hyprctl keyword monitor ${targetMonitorName}, addreserved, 0, 0, 0, 0`]) + root.restoreWindowPositionAndTile(); + } + } + } + } - IpcHandler { + IpcHandler { target: "lock" function activate(): void { GlobalStates.screenLocked = true; } - function focus(): void { - lockContext.shouldReFocus(); - } + function focus(): void { + lockContext.shouldReFocus(); + } } - GlobalShortcut { + GlobalShortcut { name: "lock" description: "Locks the screen" onPressed: { - if (Config.options.lock.useHyprlock) { - Quickshell.execDetached(["bash", "-c", "pidof hyprlock || hyprlock"]); - return; - } + if (Config.options.lock.useHyprlock) { + Quickshell.execDetached(["bash", "-c", "pidof hyprlock || hyprlock"]); + return; + } GlobalStates.screenLocked = true; } } - GlobalShortcut { + GlobalShortcut { name: "lockFocus" description: "Re-focuses the lock screen. This is because Hyprland after waking up for whatever reason" - + "decides to keyboard-unfocus the lock screen" + + "decides to keyboard-unfocus the lock screen" onPressed: { lockContext.shouldReFocus(); } } - Connections { + Connections { target: Config function onReadyChanged() { if (Config.options.lock.launchOnStartup && Config.ready && Persistent.ready && Persistent.isNewHyprlandInstance) {