mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
327 lines
9.0 KiB
QML
327 lines
9.0 KiB
QML
pragma Singleton
|
|
|
|
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import qs.Commons
|
|
import qs.Services.Power
|
|
import qs.Services.Theming
|
|
import qs.Services.UI
|
|
|
|
Singleton {
|
|
id: root
|
|
|
|
// Hook connections for automatic script execution
|
|
Connections {
|
|
target: Settings.data.colorSchemes
|
|
function onDarkModeChanged() {
|
|
executeDarkModeHook(Settings.data.colorSchemes.darkMode);
|
|
}
|
|
}
|
|
|
|
// Pending wallpaper hook when waiting for color generation
|
|
property var pendingWallpaperHook: null
|
|
|
|
Connections {
|
|
target: WallpaperService
|
|
function onWallpaperChanged(screenName, path) {
|
|
// Check if we need to wait for color generation
|
|
if (Settings.data.colorSchemes.useWallpaperColors) {
|
|
var effectiveMonitor = Settings.data.colorSchemes.monitorForColors;
|
|
if (effectiveMonitor === "" || effectiveMonitor === undefined) {
|
|
effectiveMonitor = Screen.name;
|
|
}
|
|
|
|
if (screenName === effectiveMonitor) {
|
|
// Store pending hook and wait for colors to be generated
|
|
root.pendingWallpaperHook = {
|
|
path: path,
|
|
screenName: screenName
|
|
};
|
|
return;
|
|
}
|
|
}
|
|
// No color generation, execute immediately
|
|
executeWallpaperHook(path, screenName);
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: TemplateProcessor
|
|
function onColorsGenerated() {
|
|
// Execute pending wallpaper hook after colors are ready
|
|
if (root.pendingWallpaperHook) {
|
|
const hook = root.pendingWallpaperHook;
|
|
root.pendingWallpaperHook = null;
|
|
executeWallpaperHook(hook.path, hook.screenName);
|
|
}
|
|
executeColorGenerationHook();
|
|
}
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
}
|
|
|
|
// Track performance mode state for hooks
|
|
property bool wasPerformanceModeEnabled: false
|
|
|
|
Connections {
|
|
target: PowerProfileService
|
|
function onNoctaliaPerformanceModeChanged() {
|
|
const isEnabled = PowerProfileService.noctaliaPerformanceMode;
|
|
|
|
// Detect enabled: was disabled, now enabled
|
|
if (!wasPerformanceModeEnabled && isEnabled) {
|
|
executePerformanceModeEnabledHook();
|
|
}
|
|
// Detect disabled: was enabled, now disabled
|
|
if (wasPerformanceModeEnabled && !isEnabled) {
|
|
executePerformanceModeDisabledHook();
|
|
}
|
|
wasPerformanceModeEnabled = isEnabled;
|
|
}
|
|
}
|
|
|
|
// Execute wallpaper change hook
|
|
function executeWallpaperHook(wallpaperPath, screenName) {
|
|
if (!Settings.data.hooks?.enabled) {
|
|
return;
|
|
}
|
|
|
|
const script = Settings.data.hooks?.wallpaperChange;
|
|
if (!script || script === "") {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const theme = Settings.data.colorSchemes.darkMode ? "dark" : "light";
|
|
let command = script.replace(/\$1/g, wallpaperPath);
|
|
command = command.replace(/\$2/g, screenName || "");
|
|
command = command.replace(/\$3/g, theme);
|
|
Quickshell.execDetached(["sh", "-lc", command]);
|
|
Logger.d("HooksService", `Executed wallpaper hook: ${command}`);
|
|
} catch (e) {
|
|
Logger.e("HooksService", `Failed to execute wallpaper hook: ${e}`);
|
|
}
|
|
}
|
|
|
|
// Execute dark mode change hook
|
|
function executeDarkModeHook(isDarkMode) {
|
|
if (!Settings.data.hooks?.enabled) {
|
|
return;
|
|
}
|
|
|
|
const script = Settings.data.hooks?.darkModeChange;
|
|
if (!script || script === "") {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const command = script.replace(/\$1/g, isDarkMode ? "true" : "false");
|
|
Quickshell.execDetached(["sh", "-lc", command]);
|
|
Logger.d("HooksService", `Executed dark mode hook: ${command}`);
|
|
} catch (e) {
|
|
Logger.e("HooksService", `Failed to execute dark mode hook: ${e}`);
|
|
}
|
|
}
|
|
|
|
// Execute screen lock hook
|
|
function executeLockHook() {
|
|
if (!Settings.data.hooks?.enabled) {
|
|
return;
|
|
}
|
|
|
|
const script = Settings.data.hooks?.screenLock;
|
|
if (!script || script === "") {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Pass "lock" as $1 via shell arguments so the script receives it
|
|
Quickshell.execDetached(["sh", "-lc", script, "lock-hook", "lock"]);
|
|
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 {
|
|
// Pass "unlock" as $1 via shell arguments so the script receives it
|
|
Quickshell.execDetached(["sh", "-lc", script, "unlock-hook", "unlock"]);
|
|
Logger.d("HooksService", `Executed screen unlock hook: ${script}`);
|
|
} catch (e) {
|
|
Logger.e("HooksService", `Failed to execute screen unlock hook: ${e}`);
|
|
}
|
|
}
|
|
|
|
// Execute performance mode enabled hook
|
|
function executePerformanceModeEnabledHook() {
|
|
if (!Settings.data.hooks?.enabled) {
|
|
return;
|
|
}
|
|
|
|
const script = Settings.data.hooks?.performanceModeEnabled;
|
|
if (!script || script === "") {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
Quickshell.execDetached(["sh", "-lc", script]);
|
|
} catch (e) {
|
|
Logger.e("HooksService", `Failed to execute performance mode enabled hook: ${e}`);
|
|
}
|
|
}
|
|
|
|
// Execute performance mode disabled hook
|
|
function executePerformanceModeDisabledHook() {
|
|
if (!Settings.data.hooks?.enabled) {
|
|
return;
|
|
}
|
|
|
|
const script = Settings.data.hooks?.performanceModeDisabled;
|
|
if (!script || script === "") {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
Quickshell.execDetached(["sh", "-lc", script]);
|
|
} catch (e) {
|
|
Logger.e("HooksService", `Failed to execute performance mode disabled hook: ${e}`);
|
|
}
|
|
}
|
|
|
|
// Execute color generation hook
|
|
function executeColorGenerationHook() {
|
|
if (!Settings.data.hooks?.enabled) {
|
|
return;
|
|
}
|
|
|
|
const script = Settings.data.hooks?.colorGeneration;
|
|
if (!script || script === "") {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const theme = Settings.data.colorSchemes.darkMode ? "dark" : "light";
|
|
const command = script.replace(/\$1/g, theme);
|
|
Quickshell.execDetached(["sh", "-lc", command]);
|
|
Logger.d("HooksService", `Executed color generation hook: ${command}`);
|
|
} catch (e) {
|
|
Logger.e("HooksService", `Failed to execute color generation hook: ${e}`);
|
|
}
|
|
}
|
|
|
|
// Blocking power hook infrastructure
|
|
property var pendingPowerCallback: null
|
|
|
|
Process {
|
|
id: powerHookProcess
|
|
onExited: (exitCode, exitStatus) => {
|
|
if (exitCode !== 0) {
|
|
Logger.w("HooksService", `Power hook failed with exit code ${exitCode}`);
|
|
}
|
|
|
|
if (pendingPowerCallback !== null) {
|
|
const callback = pendingPowerCallback;
|
|
pendingPowerCallback = null;
|
|
callback();
|
|
}
|
|
}
|
|
}
|
|
|
|
function runPowerHook(script, callback) {
|
|
pendingPowerCallback = callback;
|
|
powerHookProcess.command = ["sh", "-lc", script];
|
|
powerHookProcess.running = true;
|
|
}
|
|
|
|
function executeSessionHook(action, callback) {
|
|
if (!Settings.data.hooks?.enabled) {
|
|
callback();
|
|
|
|
return;
|
|
}
|
|
|
|
const script = Settings.data.hooks?.session;
|
|
if (!script) {
|
|
callback();
|
|
|
|
return;
|
|
}
|
|
|
|
Logger.i("HooksService", `Executing session hook for ${action}`);
|
|
runPowerHook(`${script} ${action}`, callback);
|
|
}
|
|
|
|
// Execute startup hook
|
|
function executeStartupHook() {
|
|
if (!Settings.data.hooks?.enabled) {
|
|
return;
|
|
}
|
|
|
|
const script = Settings.data.hooks?.startup;
|
|
if (!script || script === "") {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
Quickshell.execDetached(["sh", "-lc", script]);
|
|
Logger.d("HooksService", `Executed startup hook: ${script}`);
|
|
} catch (e) {
|
|
Logger.e("HooksService", `Failed to execute startup 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;
|
|
}
|
|
// Initialize performance mode state tracking
|
|
wasPerformanceModeEnabled = PowerProfileService.noctaliaPerformanceMode;
|
|
// Execute startup hook
|
|
executeStartupHook();
|
|
});
|
|
}
|
|
}
|