From 79428bb209c9a20a12606dbd47edcc384be3161d Mon Sep 17 00:00:00 2001 From: Zacharias-Brohn Date: Thu, 19 Feb 2026 14:41:42 +0100 Subject: [PATCH] auto light/dark scheme --- Config/Config.qml | 4 ++ Config/General.qml | 2 + Helpers/ModeScheduler.qml | 81 +++++++++++++++++++++++++++++++++++++++ Modules/Shortcuts.qml | 1 + Modules/Wallust.qml | 5 ++- 5 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 Helpers/ModeScheduler.qml diff --git a/Config/Config.qml b/Config/Config.qml index 791e3db..859217b 100644 --- a/Config/Config.qml +++ b/Config/Config.qml @@ -5,6 +5,7 @@ import Quickshell.Io import ZShell import QtQuick import qs.Modules as Modules +import qs.Helpers import qs.Paths Singleton { @@ -126,6 +127,8 @@ Singleton { wallust: general.color.wallust, mode: general.color.mode, schemeGeneration: general.color.schemeGeneration, + scheduleDarkStart: general.color.scheduleDarkStart, + scheduleDarkEnd: general.color.scheduleDarkEnd }, apps: { terminal: general.apps.terminal, @@ -332,6 +335,7 @@ Singleton { } onLoaded: { + ModeScheduler.checkStartup(); try { JSON.parse(text()); const elapsed = timer.elapsedMs(); diff --git a/Config/General.qml b/Config/General.qml index 0e57cf0..78531e4 100644 --- a/Config/General.qml +++ b/Config/General.qml @@ -12,6 +12,8 @@ JsonObject { property bool wallust: false property bool schemeGeneration: true property string mode: "dark" + property int scheduleDarkStart: 0 + property int scheduleDarkEnd: 0 } component Apps: JsonObject { diff --git a/Helpers/ModeScheduler.qml b/Helpers/ModeScheduler.qml new file mode 100644 index 0000000..36041e5 --- /dev/null +++ b/Helpers/ModeScheduler.qml @@ -0,0 +1,81 @@ +pragma Singleton + +import Quickshell +import QtQuick +import qs.Modules +import qs.Helpers +import qs.Config +import qs.Paths + +Singleton { + id: root + + readonly property int darkStart: Config.general.color.scheduleDarkStart + readonly property int darkEnd: Config.general.color.scheduleDarkEnd + + Timer { + id: darkModeTimer + + interval: 5000 + + running: true + repeat: true + onTriggered: { + if ( darkStart === darkEnd ) + return; + var now = new Date(); + if ( now.getHours() >= darkStart || now.getHours() < darkEnd ) { + if ( DynamicColors.light ) + applyDarkMode(); + } else { + if ( !DynamicColors.light ) + applyLightMode(); + } + } + } + + function applyDarkMode() { + if ( Config.general.color.schemeGeneration ) { + Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--image-path", `${WallpaperPath.currentWallpaperPath}`, "--thumbnail-path", `${Paths.cache}/imagecache/thumbnail.jpg`, "--output", `${Paths.state}/scheme.json`, "--scheme", `${Config.colors.schemeType}`, "--mode", "dark"]); + } else { + Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${DynamicColors.scheme}:${DynamicColors.flavour}`, "--output", `${Paths.state}/scheme.json`, "--mode", "dark"]); + } + + Config.general.color.mode = "dark"; + + Quickshell.execDetached(["gsettings", "set", "org.gnome.desktop.interface", "color-scheme", "'prefer-dark'"]) + + Quickshell.execDetached(["sh", "-c", `sed -i 's/color_scheme_path=\\(.*\\)Light.colors/color_scheme_path=\\1Dark.colors/' ${Paths.home}/.config/qt6ct/qt6ct.conf`]) + + if( Config.general.color.wallust ) + Wallust.generateColors(WallpaperPath.currentWallpaperPath); + } + + function applyLightMode() { + if ( Config.general.color.schemeGeneration ) { + Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--image-path", `${WallpaperPath.currentWallpaperPath}`, "--thumbnail-path", `${Paths.cache}/imagecache/thumbnail.jpg`, "--output", `${Paths.state}/scheme.json`, "--scheme", `${Config.colors.schemeType}`, "--mode", "light"]); + } else { + Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${DynamicColors.scheme}:${DynamicColors.flavour}`, "--output", `${Paths.state}/scheme.json`, "--mode", "light"]); + } + + Config.general.color.mode = "light"; + + Quickshell.execDetached(["gsettings", "set", "org.gnome.desktop.interface", "color-scheme", "'prefer-light'"]) + + Quickshell.execDetached(["sh", "-c", `sed -i 's/color_scheme_path=\\(.*\\)Dark.colors/color_scheme_path=\\1Light.colors/' ${Paths.home}/.config/qt6ct/qt6ct.conf`]) + + if( Config.general.color.wallust ) + Wallust.generateColors(WallpaperPath.currentWallpaperPath); + } + + function checkStartup() { + if ( darkStart === darkEnd ) + return; + var now = new Date(); + if ( now.getHours() >= darkStart || now.getHours() < darkEnd ) { + applyDarkMode(); + } else { + applyLightMode(); + } + } +} diff --git a/Modules/Shortcuts.qml b/Modules/Shortcuts.qml index 6111b42..c4ff3dc 100644 --- a/Modules/Shortcuts.qml +++ b/Modules/Shortcuts.qml @@ -10,6 +10,7 @@ Scope { property bool launcherInterrupted readonly property bool hasFullscreen: Hypr.focusedWorkspace?.toplevels.values.some(t => t.lastIpcObject.fullscreen === 2) ?? false + CustomShortcut { name: "toggle-launcher" description: "Toggle launcher" diff --git a/Modules/Wallust.qml b/Modules/Wallust.qml index 6a5373a..dad85dd 100644 --- a/Modules/Wallust.qml +++ b/Modules/Wallust.qml @@ -3,11 +3,14 @@ pragma Singleton import Quickshell import Quickshell.Io import QtQuick +import qs.Config Singleton { id: root property var args + readonly property string mode: Config.general.color.mode + readonly property string threshold: mode === "dark" ? "--threshold=9" : "--dynamic-threshold" function generateColors(wallpaperPath) { root.args = wallpaperPath; @@ -16,7 +19,7 @@ Singleton { Process { id: wallustProc - command: ["wallust", "run", root.args, "--palette=dark", "--ignore-sequence=cursor", "--threshold=9" ] + command: ["wallust", "run", root.args, `--palette=${root.mode}`, "--ignore-sequence=cursor", `${root.threshold}` ] running: false } }