DarkModeToggle: new bar widget

This commit is contained in:
LemmyCook 2025-09-02 10:34:05 -04:00
parent b908dc0ed2
commit 508c1407be
7 changed files with 89 additions and 36 deletions

View file

@ -63,6 +63,7 @@ Singleton {
Logger.log("Settings", "Bar monitor list is empty, will show on all available screens") Logger.log("Settings", "Bar monitor list is empty, will show on all available screens")
} }
} }
Item { Item {
Component.onCompleted: { Component.onCompleted: {
@ -100,8 +101,13 @@ Singleton {
// Emit the signal // Emit the signal
root.settingsLoaded() root.settingsLoaded()
// Kickoff ColorScheme service
ColorSchemeService.init()
// Kickoff Matugen service
MatugenService.init()
Qt.callLater(function () { Qt.callLater(function () {
// Some stuff like settings validation should just be executed once on startup and not on every reload
validateMonitorConfigurations() validateMonitorConfigurations()
}) })
} }

View file

@ -0,0 +1,23 @@
import Quickshell
import qs.Commons
import qs.Widgets
import qs.Services
NIconButton {
id: root
property ShellScreen screen
property real scaling: 1.0
icon: "contrast"
tooltipText: "Toggle light/dark mode"
sizeRatio: 0.8
colorBg: Color.mSurfaceVariant
colorFg: Color.mOnSurface
colorBorder: Color.transparent
colorBorderHover: Color.transparent
anchors.verticalCenter: parent.verticalCenter
onClicked: Settings.data.colorSchemes.darkMode = !Settings.data.colorSchemes.darkMode
}

View file

@ -63,7 +63,6 @@ ColumnLayout {
if (exitCode === 0) { if (exitCode === 0) {
// Matugen exists, enable it // Matugen exists, enable it
Settings.data.colorSchemes.useWallpaperColors = true Settings.data.colorSchemes.useWallpaperColors = true
Settings.data.colorSchemes.predefinedScheme = ""
MatugenService.generateFromWallpaper() MatugenService.generateFromWallpaper()
ToastService.showNotice("Matugen", "Enabled") ToastService.showNotice("Matugen", "Enabled")
} else { } else {
@ -122,19 +121,7 @@ ColumnLayout {
description: Settings.data.colorSchemes.useWallpaperColors ? "Generate dark theme colors when using Matugen." : "Use a dark variant if available." description: Settings.data.colorSchemes.useWallpaperColors ? "Generate dark theme colors when using Matugen." : "Use a dark variant if available."
checked: Settings.data.colorSchemes.darkMode checked: Settings.data.colorSchemes.darkMode
enabled: true enabled: true
onToggled: checked => { onToggled: checked => Settings.data.colorSchemes.darkMode = checked
Settings.data.colorSchemes.darkMode = checked
if (Settings.data.colorSchemes.useWallpaperColors) {
MatugenService.generateFromWallpaper()
} else if (Settings.data.colorSchemes.predefinedScheme) {
// Re-apply current scheme to pick the right variant
ColorSchemeService.applyScheme(Settings.data.colorSchemes.predefinedScheme)
// Force refresh of previews
var tmp = schemeColorsCache
schemeColorsCache = {}
schemeColorsCache = tmp
}
}
} }
// Use Matugen // Use Matugen
@ -149,6 +136,11 @@ ColumnLayout {
} else { } else {
Settings.data.colorSchemes.useWallpaperColors = false Settings.data.colorSchemes.useWallpaperColors = false
ToastService.showNotice("Matugen", "Disabled") ToastService.showNotice("Matugen", "Disabled")
if (Settings.data.colorSchemes.predefinedScheme) {
ColorSchemeService.applyScheme(Settings.data.colorSchemes.predefinedScheme)
}
} }
} }
} }
@ -199,7 +191,8 @@ ColumnLayout {
radius: Style.radiusM * scaling radius: Style.radiusM * scaling
color: getSchemeColor(modelData, "mSurface") color: getSchemeColor(modelData, "mSurface")
border.width: Math.max(1, Style.borderL * scaling) border.width: Math.max(1, Style.borderL * scaling)
border.color: Settings.data.colorSchemes.predefinedScheme === modelData ? Color.mPrimary : Color.mOutline border.color: (!Settings.data.colorSchemes.useWallpaperColors
&& (Settings.data.colorSchemes.predefinedScheme === modelData)) ? Color.mPrimary : Color.mOutline
scale: root.cardScaleLow scale: root.cardScaleLow
// Mouse area for selection // Mouse area for selection
@ -290,9 +283,10 @@ ColumnLayout {
} }
} }
// Selection indicator // Selection indicator (Checkmark)
Rectangle { Rectangle {
visible: Settings.data.colorSchemes.predefinedScheme === schemePath visible: !Settings.data.colorSchemes.useWallpaperColors
&& (Settings.data.colorSchemes.predefinedScheme === schemePath)
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
anchors.margins: Style.marginS * scaling anchors.margins: Style.marginS * scaling

View file

@ -58,27 +58,21 @@ ColumnLayout {
label: "Show Corners" label: "Show Corners"
description: "Display rounded corners on the edge of the screen." description: "Display rounded corners on the edge of the screen."
checked: Settings.data.general.showScreenCorners checked: Settings.data.general.showScreenCorners
onToggled: checked => onToggled: checked => Settings.data.general.showScreenCorners = checked
Settings.data.general.showScreenCorners = checked
} }
NToggle { NToggle {
label: "Dim Desktop" label: "Dim Desktop"
description: "Dim the desktop when panels or menus are open." description: "Dim the desktop when panels or menus are open."
checked: Settings.data.general.dimDesktop checked: Settings.data.general.dimDesktop
onToggled: checked => onToggled: checked => Settings.data.general.dimDesktop = checked
Settings.data.general.dimDesktop = checked
} }
NToggle { NToggle {
label: "Auto-hide Dock" label: "Auto-hide Dock"
description: "Automatically hide the dock when not in use." description: "Automatically hide the dock when not in use."
checked: Settings.data.dock.autoHide checked: Settings.data.dock.autoHide
onToggled: checked => onToggled: checked => Settings.data.dock.autoHide = checked
Settings.data.dock.autoHide = checked
} }
ColumnLayout { ColumnLayout {

View file

@ -16,6 +16,7 @@ Singleton {
"Bluetooth": bluetoothComponent, "Bluetooth": bluetoothComponent,
"Brightness": brightnessComponent, "Brightness": brightnessComponent,
"Clock": clockComponent, "Clock": clockComponent,
"DarkModeToggle": darkModeToggle,
"KeyboardLayout": keyboardLayoutComponent, "KeyboardLayout": keyboardLayoutComponent,
"MediaMini": mediaMiniComponent, "MediaMini": mediaMiniComponent,
"Microphone": microphoneComponent, "Microphone": microphoneComponent,
@ -51,6 +52,9 @@ Singleton {
property Component clockComponent: Component { property Component clockComponent: Component {
Clock {} Clock {}
} }
property Component darkModeToggle: Component {
DarkModeToggle {}
}
property Component keyboardLayoutComponent: Component { property Component keyboardLayoutComponent: Component {
KeyboardLayout {} KeyboardLayout {}
} }

View file

@ -10,16 +10,30 @@ import qs.Services
Singleton { Singleton {
id: root id: root
Component.onCompleted: {
Logger.log("ColorScheme", "Service started")
loadColorSchemes()
}
property var schemes: [] property var schemes: []
property bool scanning: false property bool scanning: false
property string schemesDirectory: Quickshell.shellDir + "/Assets/ColorScheme" property string schemesDirectory: Quickshell.shellDir + "/Assets/ColorScheme"
property string colorsJsonFilePath: Settings.configDir + "colors.json" property string colorsJsonFilePath: Settings.configDir + "colors.json"
Connections {
target: Settings.data.colorSchemes
function onDarkModeChanged() {
Logger.log("ColorScheme", "Detected dark mode change")
if (!Settings.data.colorSchemes.useWallpaperColors && Settings.data.colorSchemes.predefinedScheme) {
// Re-apply current scheme to pick the right variant
applyScheme(Settings.data.colorSchemes.predefinedScheme)
}
}
}
// --------------------------------
function init() {
// does nothing but ensure the singleton is created
// do not remove
Logger.log("ColorScheme", "Service started")
loadColorSchemes()
}
function loadColorSchemes() { function loadColorSchemes() {
Logger.log("ColorScheme", "Load ColorScheme") Logger.log("ColorScheme", "Load ColorScheme")
scanning = true scanning = true

View file

@ -10,7 +10,7 @@ import qs.Services
Singleton { Singleton {
id: root id: root
property string dynamicConfigPath: Settings.cacheDir + "matugen.dynamic.toml" property string dynamicConfigPath: Settings.isLoaded ? Settings.cacheDir + "matugen.dynamic.toml" : ""
// External state management // External state management
Connections { Connections {
@ -23,6 +23,23 @@ Singleton {
} }
} }
Connections {
target: Settings.data.colorSchemes
function onDarkModeChanged() {
Logger.log("Matugen", "Detected dark mode change")
if (Settings.data.colorSchemes.useWallpaperColors) {
MatugenService.generateFromWallpaper()
}
}
}
// --------------------------------
function init() {
// does nothing but ensure the singleton is created
// do not remove
Logger.log("Matugen", "Service started")
}
// Build TOML content based on settings // Build TOML content based on settings
function buildConfigToml() { function buildConfigToml() {
return Matugen.buildConfigToml() return Matugen.buildConfigToml()
@ -30,11 +47,12 @@ Singleton {
// Generate colors using current wallpaper and settings // Generate colors using current wallpaper and settings
function generateFromWallpaper() { function generateFromWallpaper() {
// Ensure cache dir exists
Quickshell.execDetached(["mkdir", "-p", Settings.cacheDir])
Logger.log("Matugen", "Generating from wallpaper on screen:", Screen.name) Logger.log("Matugen", "Generating from wallpaper on screen:", Screen.name)
var wp = WallpaperService.getWallpaper(Screen.name).replace(/'/g, "'\\''") var wp = WallpaperService.getWallpaper(Screen.name).replace(/'/g, "'\\''")
if (wp === "") {
Logger.error("Matugen", "No wallpaper was found")
return
}
var content = buildConfigToml() var content = buildConfigToml()
var mode = Settings.data.colorSchemes.darkMode ? "dark" : "light" var mode = Settings.data.colorSchemes.darkMode ? "dark" : "light"