forked from Shinonome/dots-hyprland
refractor lock screen
This commit is contained in:
@@ -0,0 +1,157 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import qs
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.functions
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
|
||||||
|
Scope {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property Component lockSurface
|
||||||
|
property alias context: lockContext
|
||||||
|
property Component sessionLockSurface: WlSessionLockSurface {
|
||||||
|
id: sessionLockSurface
|
||||||
|
color: "transparent"
|
||||||
|
Loader {
|
||||||
|
active: GlobalStates.screenLocked
|
||||||
|
anchors.fill: parent
|
||||||
|
opacity: active ? 1 : 0
|
||||||
|
Behavior on opacity {
|
||||||
|
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
sourceComponent: root.lockSurface
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: unlockKeyringProc
|
||||||
|
onExited: (exitCode, exitStatus) => {
|
||||||
|
KeyringStorage.fetchKeyringData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function unlockKeyring() {
|
||||||
|
unlockKeyringProc.exec({
|
||||||
|
environment: ({
|
||||||
|
"UNLOCK_PASSWORD": lockContext.currentText
|
||||||
|
}),
|
||||||
|
command: ["bash", "-c", Quickshell.shellPath("scripts/keyring/unlock.sh")]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: GlobalStates
|
||||||
|
function onScreenLockedChanged() {
|
||||||
|
if (GlobalStates.screenLocked) {
|
||||||
|
lockContext.reset();
|
||||||
|
lockContext.tryFingerUnlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 keyring if configured to do so
|
||||||
|
if (Config.options.lock.security.unlockKeyring) root.unlockKeyring(); // Async
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
// Post-unlock actions
|
||||||
|
if (lockContext.alsoInhibitIdle) {
|
||||||
|
lockContext.alsoInhibitIdle = false;
|
||||||
|
Idle.toggleInhibit(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WlSessionLock {
|
||||||
|
id: lock
|
||||||
|
locked: GlobalStates.screenLocked
|
||||||
|
|
||||||
|
surface: root.sessionLockSurface
|
||||||
|
}
|
||||||
|
|
||||||
|
function lock() {
|
||||||
|
if (Config.options.lock.useHyprlock) {
|
||||||
|
Quickshell.execDetached(["bash", "-c", "pidof hyprlock || hyprlock"]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GlobalStates.screenLocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
IpcHandler {
|
||||||
|
target: "lock"
|
||||||
|
|
||||||
|
function activate(): void {
|
||||||
|
root.lock();
|
||||||
|
}
|
||||||
|
function focus(): void {
|
||||||
|
lockContext.shouldReFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalShortcut {
|
||||||
|
name: "lock"
|
||||||
|
description: "Locks the screen"
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
root.lock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
lockContext.shouldReFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function initIfReady() {
|
||||||
|
if (!Config.ready || !Persistent.ready) return;
|
||||||
|
if (Config.options.lock.launchOnStartup && Persistent.isNewHyprlandInstance) {
|
||||||
|
root.lock();
|
||||||
|
} else {
|
||||||
|
KeyringStorage.fetchKeyringData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: Config
|
||||||
|
function onReadyChanged() {
|
||||||
|
root.initIfReady();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: Persistent
|
||||||
|
function onReadyChanged() {
|
||||||
|
root.initIfReady();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,116 +3,39 @@ import qs
|
|||||||
import qs.services
|
import qs.services
|
||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
import qs.modules.common.functions
|
import qs.modules.common.functions
|
||||||
|
import qs.modules.common.panels.lock
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
|
|
||||||
Scope {
|
LockScreen {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
Process {
|
lockSurface: LockSurface {
|
||||||
id: unlockKeyringProc
|
context: root.context
|
||||||
onExited: (exitCode, exitStatus) => {
|
|
||||||
KeyringStorage.fetchKeyringData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function unlockKeyring() {
|
|
||||||
unlockKeyringProc.exec({
|
|
||||||
environment: ({
|
|
||||||
"UNLOCK_PASSWORD": lockContext.currentText
|
|
||||||
}),
|
|
||||||
command: ["bash", "-c", Quickshell.shellPath("scripts/keyring/unlock.sh")]
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Push everything down
|
||||||
property var windowData: []
|
property var windowData: []
|
||||||
function saveWindowPositionAndTile() {
|
function saveWindowPositionAndTile() {
|
||||||
Quickshell.execDetached(["hyprctl", "keyword", "dwindle:pseudotile", "true"])
|
Quickshell.execDetached(["hyprctl", "keyword", "dwindle:pseudotile", "true"]);
|
||||||
root.windowData = HyprlandData.windowList.filter(w => (w.floating && w.workspace.id === HyprlandData.activeWorkspace.id))
|
root.windowData = HyprlandData.windowList.filter(w => (w.floating && w.workspace.id === HyprlandData.activeWorkspace.id));
|
||||||
root.windowData.forEach(w => {
|
root.windowData.forEach(w => {
|
||||||
Hyprland.dispatch(`pseudo address:${w.address}`)
|
Hyprland.dispatch(`pseudo address:${w.address}`);
|
||||||
Hyprland.dispatch(`settiled address:${w.address}`)
|
Hyprland.dispatch(`settiled address:${w.address}`);
|
||||||
Hyprland.dispatch(`movetoworkspacesilent ${w.workspace.id},address:${w.address}`)
|
Hyprland.dispatch(`movetoworkspacesilent ${w.workspace.id},address:${w.address}`);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
function restoreWindowPositionAndTile() {
|
function restoreWindowPositionAndTile() {
|
||||||
root.windowData.forEach(w => {
|
root.windowData.forEach(w => {
|
||||||
Hyprland.dispatch(`setfloating address:${w.address}`)
|
Hyprland.dispatch(`setfloating address:${w.address}`);
|
||||||
Hyprland.dispatch(`movewindowpixel exact ${w.at[0]} ${w.at[1]}, address:${w.address}`)
|
Hyprland.dispatch(`movewindowpixel exact ${w.at[0]} ${w.at[1]}, address:${w.address}`);
|
||||||
Hyprland.dispatch(`pseudo address:${w.address}`)
|
Hyprland.dispatch(`pseudo address:${w.address}`);
|
||||||
})
|
});
|
||||||
Quickshell.execDetached(["hyprctl", "keyword", "dwindle:pseudotile", "false"])
|
Quickshell.execDetached(["hyprctl", "keyword", "dwindle:pseudotile", "false"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: GlobalStates
|
|
||||||
function onScreenLockedChanged() {
|
|
||||||
if (GlobalStates.screenLocked) {
|
|
||||||
lockContext.reset();
|
|
||||||
lockContext.tryFingerUnlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 keyring if configured to do so
|
|
||||||
if (Config.options.lock.security.unlockKeyring) root.unlockKeyring(); // Async
|
|
||||||
|
|
||||||
// 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();
|
|
||||||
|
|
||||||
// Post-unlock actions
|
|
||||||
if (lockContext.alsoInhibitIdle) {
|
|
||||||
lockContext.alsoInhibitIdle = false;
|
|
||||||
Idle.toggleInhibit(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Blur layer hack
|
|
||||||
Variants {
|
Variants {
|
||||||
model: Quickshell.screens
|
model: Quickshell.screens
|
||||||
delegate: Scope {
|
delegate: Scope {
|
||||||
@@ -124,71 +47,12 @@ Scope {
|
|||||||
onShouldPushChanged: {
|
onShouldPushChanged: {
|
||||||
if (shouldPush) {
|
if (shouldPush) {
|
||||||
root.saveWindowPositionAndTile();
|
root.saveWindowPositionAndTile();
|
||||||
Quickshell.execDetached(["bash", "-c", `hyprctl keyword monitor ${targetMonitorName}, addreserved, ${verticalMovementDistance}, ${-verticalMovementDistance}, ${horizontalSqueeze}, ${horizontalSqueeze}`])
|
Quickshell.execDetached(["bash", "-c", `hyprctl keyword monitor ${targetMonitorName}, addreserved, ${verticalMovementDistance}, ${-verticalMovementDistance}, ${horizontalSqueeze}, ${horizontalSqueeze}`]);
|
||||||
} else {
|
} else {
|
||||||
Quickshell.execDetached(["bash", "-c", `hyprctl keyword monitor ${targetMonitorName}, addreserved, 0, 0, 0, 0`])
|
Quickshell.execDetached(["bash", "-c", `hyprctl keyword monitor ${targetMonitorName}, addreserved, 0, 0, 0, 0`]);
|
||||||
root.restoreWindowPositionAndTile();
|
root.restoreWindowPositionAndTile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function lock() {
|
|
||||||
if (Config.options.lock.useHyprlock) {
|
|
||||||
Quickshell.execDetached(["bash", "-c", "pidof hyprlock || hyprlock"]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
GlobalStates.screenLocked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
IpcHandler {
|
|
||||||
target: "lock"
|
|
||||||
|
|
||||||
function activate(): void {
|
|
||||||
root.lock();
|
|
||||||
}
|
|
||||||
function focus(): void {
|
|
||||||
lockContext.shouldReFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalShortcut {
|
|
||||||
name: "lock"
|
|
||||||
description: "Locks the screen"
|
|
||||||
|
|
||||||
onPressed: {
|
|
||||||
root.lock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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"
|
|
||||||
|
|
||||||
onPressed: {
|
|
||||||
lockContext.shouldReFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function initIfReady() {
|
|
||||||
if (!Config.ready || !Persistent.ready) return;
|
|
||||||
if (Config.options.lock.launchOnStartup && Persistent.isNewHyprlandInstance) {
|
|
||||||
root.lock();
|
|
||||||
} else {
|
|
||||||
KeyringStorage.fetchKeyringData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Connections {
|
|
||||||
target: Config
|
|
||||||
function onReadyChanged() {
|
|
||||||
root.initIfReady();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Connections {
|
|
||||||
target: Persistent
|
|
||||||
function onReadyChanged() {
|
|
||||||
root.initIfReady();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import qs.services
|
|||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
import qs.modules.common.widgets
|
import qs.modules.common.widgets
|
||||||
import qs.modules.common.functions
|
import qs.modules.common.functions
|
||||||
|
import qs.modules.common.panels.lock
|
||||||
import qs.modules.ii.bar as Bar
|
import qs.modules.ii.bar as Bar
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Services.SystemTray
|
import Quickshell.Services.SystemTray
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ ShellRoot {
|
|||||||
property list<string> families: ["ii", "waffle"]
|
property list<string> families: ["ii", "waffle"]
|
||||||
property var panelFamilies: ({
|
property var panelFamilies: ({
|
||||||
"ii": ["iiBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiVerticalBar", "iiWallpaperSelector"],
|
"ii": ["iiBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiVerticalBar", "iiWallpaperSelector"],
|
||||||
"waffle": ["wActionCenter", "wBar", "wBackground", "wNotificationCenter", "wOnScreenDisplay", "wPolkit", "wStartMenu", "iiCheatsheet", "iiLock", "iiNotificationPopup", "iiOnScreenKeyboard", "iiOverlay", "iiRegionSelector", "wSessionScreen", "iiWallpaperSelector"],
|
"waffle": ["wActionCenter", "wBar", "wBackground", "wNotificationCenter", "wOnScreenDisplay", "wPolkit", "wSessionScreen", "wStartMenu", "iiCheatsheet", "iiLock", "iiNotificationPopup", "iiOnScreenKeyboard", "iiOverlay", "iiRegionSelector", "iiWallpaperSelector"],
|
||||||
})
|
})
|
||||||
function cyclePanelFamily() {
|
function cyclePanelFamily() {
|
||||||
const currentIndex = families.indexOf(Config.options.panelFamily)
|
const currentIndex = families.indexOf(Config.options.panelFamily)
|
||||||
|
|||||||
Reference in New Issue
Block a user