Hooks: add screen lock/unlock hook (#1030)

This commit is contained in:
Ly-sec
2025-12-16 17:51:46 +01:00
parent 3ea17b8f29
commit 07050928bd
16 changed files with 236 additions and 2 deletions
+10
View File
@@ -1642,6 +1642,16 @@
"description": "Befehl, der ausgeführt wird, wenn sich das Hintergrundbild ändert.",
"label": "Hintergrundbild geändert",
"placeholder": "z.B. notify-send \"Hintergrundbild\" \"Geändert\""
},
"screen-lock": {
"description": "Befehl, der ausgeführt wird, wenn der Bildschirm gesperrt wird.",
"label": "Bildschirm gesperrt",
"placeholder": "z.B. notify-send \"Bildschirm\" \"Gesperrt\""
},
"screen-unlock": {
"description": "Befehl, der ausgeführt wird, wenn der Bildschirm entsperrt wird.",
"label": "Bildschirm entsperrt",
"placeholder": "z.B. notify-send \"Bildschirm\" \"Entsperrt\""
}
},
"launcher": {
+11 -1
View File
@@ -1618,7 +1618,7 @@
"label": "Hook command information"
},
"parameters": {
"description": "• Wallpaper hook: $1 = wallpaper path, $2 = screen name<br>• Theme toggle hook: $1 = true/false (Dark Mode state)",
"description": "• Wallpaper hook: $1 = wallpaper path, $2 = screen name<br>• Theme toggle hook: $1 = true/false (Dark Mode state)<br>• Screen lock/unlock hooks: No parameters",
"label": "Available parameters"
}
},
@@ -1642,6 +1642,16 @@
"description": "Command to be executed when wallpaper changes.",
"label": "Wallpaper changed",
"placeholder": "e.g., notify-send \"Wallpaper\" \"Changed\""
},
"screen-lock": {
"description": "Command to be executed when the screen is locked.",
"label": "Screen locked",
"placeholder": "e.g., notify-send \"Screen\" \"Locked\""
},
"screen-unlock": {
"description": "Command to be executed when the lock screen is unlocked.",
"label": "Screen unlocked",
"placeholder": "e.g., notify-send \"Screen\" \"Unlocked\""
}
},
"launcher": {
+10
View File
@@ -1642,6 +1642,16 @@
"description": "Comando a ejecutar cuando cambia el fondo de pantalla.",
"label": "Fondo de pantalla cambiado",
"placeholder": "ej., notify-send \"Fondo de pantalla\" \"Cambiado\""
},
"screen-lock": {
"description": "Comando a ejecutar cuando se bloquea la pantalla.",
"label": "Pantalla bloqueada",
"placeholder": "ej., notify-send \"Pantalla\" \"Bloqueada\""
},
"screen-unlock": {
"description": "Comando a ejecutar cuando se desbloquea la pantalla.",
"label": "Pantalla desbloqueada",
"placeholder": "ej., notify-send \"Pantalla\" \"Desbloqueada\""
}
},
"launcher": {
+10
View File
@@ -1642,6 +1642,16 @@
"description": "Commande à exécuter lorsque le fond d'écran change.",
"label": "Fond d'écran changé",
"placeholder": "ex: notify-send \"Fond d'écran\" \"Changé\""
},
"screen-lock": {
"description": "Commande à exécuter lorsque l'écran est verrouillé.",
"label": "Écran verrouillé",
"placeholder": "ex: notify-send \"Écran\" \"Verrouillé\""
},
"screen-unlock": {
"description": "Commande à exécuter lorsque l'écran est déverrouillé.",
"label": "Écran déverrouillé",
"placeholder": "ex: notify-send \"Écran\" \"Déverrouillé\""
}
},
"launcher": {
+10
View File
@@ -1642,6 +1642,16 @@
"description": "壁紙が変更された際に実行されるコマンド。",
"label": "壁紙変更時",
"placeholder": "例: notify-send \"Wallpaper\" \"Changed\""
},
"screen-lock": {
"description": "画面がロックされた際に実行されるコマンド。",
"label": "画面ロック時",
"placeholder": "例: notify-send \"Screen\" \"Locked\""
},
"screen-unlock": {
"description": "ロック画面が解除された際に実行されるコマンド。",
"label": "画面ロック解除時",
"placeholder": "例: notify-send \"Screen\" \"Unlocked\""
}
},
"launcher": {
+10
View File
@@ -1642,6 +1642,16 @@
"description": "Commando dat wordt uitgevoerd wanneer de achtergrond verandert.",
"label": "Achtergrond gewijzigd",
"placeholder": "bijv. notify-send \"Achtergrond\" \"Gewijzigd\""
},
"screen-lock": {
"description": "Commando dat wordt uitgevoerd wanneer het scherm wordt vergrendeld.",
"label": "Scherm vergrendeld",
"placeholder": "bijv. notify-send \"Scherm\" \"Vergrendeld\""
},
"screen-unlock": {
"description": "Commando dat wordt uitgevoerd wanneer het scherm wordt ontgrendeld.",
"label": "Scherm ontgrendeld",
"placeholder": "bijv. notify-send \"Scherm\" \"Ontgrendeld\""
}
},
"launcher": {
+10
View File
@@ -1642,6 +1642,16 @@
"description": "Comando a ser executado quando o papel de parede muda.",
"label": "Papel de parede alterado",
"placeholder": "ex., notify-send \"Papel de parede\" \"Alterado\""
},
"screen-lock": {
"description": "Comando a ser executado quando a tela é bloqueada.",
"label": "Tela bloqueada",
"placeholder": "ex., notify-send \"Tela\" \"Bloqueada\""
},
"screen-unlock": {
"description": "Comando a ser executado quando a tela é desbloqueada.",
"label": "Tela desbloqueada",
"placeholder": "ex., notify-send \"Tela\" \"Desbloqueada\""
}
},
"launcher": {
+10
View File
@@ -1642,6 +1642,16 @@
"description": "Команда для выполнения при смене обоев.",
"label": "Обои изменены",
"placeholder": "например, notify-send \"Wallpaper\" \"Changed\""
},
"screen-lock": {
"description": "Команда для выполнения при блокировке экрана.",
"label": "Экран заблокирован",
"placeholder": "например, notify-send \"Экран\" \"Заблокирован\""
},
"screen-unlock": {
"description": "Команда для выполнения при разблокировке экрана.",
"label": "Экран разблокирован",
"placeholder": "например, notify-send \"Экран\" \"Разблокирован\""
}
},
"launcher": {
+10
View File
@@ -1642,6 +1642,16 @@
"description": "Duvar kâğıdı değiştiğinde çalıştırılacak komut.",
"label": "Duvar kâğıdı değişti",
"placeholder": "örn., notify-send \"Duvar Kâğıdı\" \"Değişti\""
},
"screen-lock": {
"description": "Ekran kilitlendiğinde çalıştırılacak komut.",
"label": "Ekran kilitlendi",
"placeholder": "örn., notify-send \"Ekran\" \"Kilitlendi\""
},
"screen-unlock": {
"description": "Ekran kilidi açıldığında çalıştırılacak komut.",
"label": "Ekran kilidi açıldı",
"placeholder": "örn., notify-send \"Ekran\" \"Açıldı\""
}
},
"launcher": {
+10
View File
@@ -1642,6 +1642,16 @@
"description": "Команда для виконання при зміні шпалер.",
"label": "Шпалери змінено",
"placeholder": "напр., notify-send \"Шпалери\" \"Змінено\""
},
"screen-lock": {
"description": "Команда для виконання при блокуванні екрана.",
"label": "Екран заблоковано",
"placeholder": "напр., notify-send \"Екран\" \"Заблоковано\""
},
"screen-unlock": {
"description": "Команда для виконання при розблокуванні екрана.",
"label": "Екран розблоковано",
"placeholder": "напр., notify-send \"Екран\" \"Розблоковано\""
}
},
"launcher": {
+10
View File
@@ -1642,6 +1642,16 @@
"description": "壁纸更改时执行的命令。",
"label": "壁纸已更改",
"placeholder": "例如:notify-send \"壁纸\" \"已更改\""
},
"screen-lock": {
"description": "屏幕锁定时执行的命令。",
"label": "屏幕已锁定",
"placeholder": "例如:notify-send \"屏幕\" \"已锁定\""
},
"screen-unlock": {
"description": "屏幕解锁时执行的命令。",
"label": "屏幕已解锁",
"placeholder": "例如:notify-send \"屏幕\" \"已解锁\""
}
},
"launcher": {
+3 -1
View File
@@ -400,7 +400,9 @@
"hooks": {
"enabled": false,
"wallpaperChange": "",
"darkModeChange": ""
"darkModeChange": "",
"screenLock": "",
"screenUnlock": ""
},
"desktopWidgets": {
"enabled": false,
+2
View File
@@ -611,6 +611,8 @@ Singleton {
property bool enabled: false
property string wallpaperChange: ""
property string darkModeChange: ""
property string screenLock: ""
property string screenUnlock: ""
}
// desktop widgets
+3
View File
@@ -24,6 +24,9 @@ Loader {
id: root
active: false
// Expose lockContext for hooks
readonly property var lockContext: item ? item.lockContext : null
Component.onCompleted: {
// Register with panel service
PanelService.lockScreen = this;
+44
View File
@@ -77,6 +77,50 @@ ColumnLayout {
Layout.fillWidth: true
}
// Screen Lock Hook Section
NInputAction {
id: screenLockHookInput
label: I18n.tr("settings.hooks.screen-lock.label")
description: I18n.tr("settings.hooks.screen-lock.description")
placeholderText: I18n.tr("settings.hooks.screen-lock.placeholder")
text: Settings.data.hooks.screenLock
onEditingFinished: {
Settings.data.hooks.screenLock = screenLockHookInput.text;
}
onActionClicked: {
if (screenLockHookInput.text) {
HooksService.executeLockHook();
}
}
Layout.fillWidth: true
}
NDivider {
Layout.fillWidth: true
}
// Screen Unlock Hook Section
NInputAction {
id: screenUnlockHookInput
label: I18n.tr("settings.hooks.screen-unlock.label")
description: I18n.tr("settings.hooks.screen-unlock.description")
placeholderText: I18n.tr("settings.hooks.screen-unlock.placeholder")
text: Settings.data.hooks.screenUnlock
onEditingFinished: {
Settings.data.hooks.screenUnlock = screenUnlockHookInput.text;
}
onActionClicked: {
if (screenUnlockHookInput.text) {
HooksService.executeUnlockHook();
}
}
Layout.fillWidth: true
}
NDivider {
Layout.fillWidth: true
}
// Info section
ColumnLayout {
spacing: Style.marginM
+73
View File
@@ -23,6 +23,34 @@ Singleton {
}
}
// Track lock screen state for unlock hook
property bool wasLocked: false
Connections {
target: PanelService
function onLockScreenChanged() {
if (PanelService.lockScreen) {
lockScreenActiveConnection.target = PanelService.lockScreen;
}
}
}
Connections {
id: lockScreenActiveConnection
target: PanelService.lockScreen
function onActiveChanged() {
// Detect lock: was unlocked, now locked
if (!wasLocked && PanelService.lockScreen.active) {
executeLockHook();
}
// Detect unlock: was locked, now not locked
if (wasLocked && !PanelService.lockScreen.active) {
executeUnlockHook();
}
wasLocked = PanelService.lockScreen.active;
}
}
// Execute wallpaper change hook
function executeWallpaperHook(wallpaperPath, screenName) {
if (!Settings.data.hooks?.enabled) {
@@ -64,8 +92,53 @@ Singleton {
}
}
// Execute screen lock hook
function executeLockHook() {
if (!Settings.data.hooks?.enabled) {
return;
}
const script = Settings.data.hooks?.screenLock;
if (!script || script === "") {
return;
}
try {
Quickshell.execDetached(["sh", "-c", script]);
Logger.d("HooksService", `Executed screen lock hook: ${script}`);
} catch (e) {
Logger.e("HooksService", `Failed to execute screen lock hook: ${e}`);
}
}
// Execute screen unlock hook
function executeUnlockHook() {
if (!Settings.data.hooks?.enabled) {
return;
}
const script = Settings.data.hooks?.screenUnlock;
if (!script || script === "") {
return;
}
try {
Quickshell.execDetached(["sh", "-c", script]);
Logger.d("HooksService", `Executed screen unlock hook: ${script}`);
} catch (e) {
Logger.e("HooksService", `Failed to execute screen unlock hook: ${e}`);
}
}
// Initialize the service
function init() {
Logger.i("HooksService", "Service started");
// Initialize lock screen state tracking
Qt.callLater(() => {
if (PanelService.lockScreen) {
wasLocked = PanelService.lockScreen.active;
lockScreenActiveConnection.target = PanelService.lockScreen;
}
});
}
}