mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-05 21:15:38 -05:00
Auto-detect wallpaper changes, prefs in ~/.config/DankMaterialShell
This commit is contained in:
@@ -15,14 +15,20 @@ Singleton {
|
|||||||
? _homeUrl.substring(7)
|
? _homeUrl.substring(7)
|
||||||
: _homeUrl
|
: _homeUrl
|
||||||
readonly property string wallpaperPath: homeDir + "/quickshell/current_wallpaper"
|
readonly property string wallpaperPath: homeDir + "/quickshell/current_wallpaper"
|
||||||
|
readonly property string notifyPath: homeDir + "/quickshell/wallpaper_changed"
|
||||||
|
|
||||||
property bool matugenAvailable: false
|
property bool matugenAvailable: false
|
||||||
property string matugenJson: ""
|
property string matugenJson: ""
|
||||||
property var matugenColors: ({})
|
property var matugenColors: ({})
|
||||||
|
property bool extractionRequested: false
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
console.log("Colors.qml → home =", homeDir)
|
console.log("Colors.qml → home =", homeDir)
|
||||||
matugenCheck.running = true // kick off the chain
|
// Don't automatically run color extraction - only when requested
|
||||||
|
matugenCheck.running = true // Just check if matugen is available
|
||||||
|
|
||||||
|
// Start monitoring for wallpaper changes
|
||||||
|
wallpaperMonitorTimer.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ──────────────── availability checks ──────────────── */
|
/* ──────────────── availability checks ──────────────── */
|
||||||
@@ -38,7 +44,12 @@ Singleton {
|
|||||||
Theme.rootObj.wallpaperErrorStatus = "matugen_missing"
|
Theme.rootObj.wallpaperErrorStatus = "matugen_missing"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fileChecker.running = true
|
|
||||||
|
// If extraction was requested, continue the process
|
||||||
|
if (extractionRequested) {
|
||||||
|
console.log("Continuing with color extraction")
|
||||||
|
fileChecker.running = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,8 +98,46 @@ Singleton {
|
|||||||
stderr: StdioCollector { id: matugenErr }
|
stderr: StdioCollector { id: matugenErr }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ──────────────── wallpaper change monitor ──────────────── */
|
||||||
|
property string lastWallpaperTimestamp: ""
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: wallpaperMonitorTimer
|
||||||
|
interval: 1000 // Check every second
|
||||||
|
repeat: true
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
wallpaperNotifyMonitor.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileView {
|
||||||
|
id: wallpaperNotifyMonitor
|
||||||
|
path: "file://" + notifyPath
|
||||||
|
|
||||||
|
onLoaded: {
|
||||||
|
var timestamp = wallpaperNotifyMonitor.text()
|
||||||
|
if (timestamp && timestamp !== lastWallpaperTimestamp) {
|
||||||
|
console.log("Wallpaper change detected - updating dynamic theme")
|
||||||
|
lastWallpaperTimestamp = timestamp
|
||||||
|
|
||||||
|
// Only update if we're currently using dynamic theme
|
||||||
|
if (typeof Theme !== "undefined" && Theme.isDynamicTheme) {
|
||||||
|
console.log("Triggering color extraction due to wallpaper change")
|
||||||
|
extractColors()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoadFailed: {
|
||||||
|
// File doesn't exist yet, this is normal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ──────────────── public helper ──────────────── */
|
/* ──────────────── public helper ──────────────── */
|
||||||
function extractColors() {
|
function extractColors() {
|
||||||
|
console.log("Colors.extractColors() called, matugenAvailable:", matugenAvailable)
|
||||||
|
extractionRequested = true
|
||||||
if (matugenAvailable)
|
if (matugenAvailable)
|
||||||
fileChecker.running = true
|
fileChecker.running = true
|
||||||
else
|
else
|
||||||
|
|||||||
106
Common/Prefs.qml
106
Common/Prefs.qml
@@ -1,40 +1,102 @@
|
|||||||
pragma Singleton
|
pragma Singleton
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Qt.labs.settings
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property alias themeIndex: settings.themeIndex
|
property int themeIndex: 0
|
||||||
property alias themeIsDynamic: settings.themeIsDynamic
|
property bool themeIsDynamic: false
|
||||||
|
|
||||||
Settings {
|
readonly property string configDir: Qt.resolvedUrl("file://" + Quickshell.env("HOME") + "/.config/DankMaterialDark")
|
||||||
id: settings
|
readonly property string configFile: configDir + "/settings.json"
|
||||||
category: "theme"
|
|
||||||
|
|
||||||
// 0-9 = built-in static themes, 10 = Auto (dynamic)
|
|
||||||
property int themeIndex: 0
|
|
||||||
property bool themeIsDynamic: false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply theme when component is ready
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
console.log("Prefs Component.onCompleted - themeIndex:", settings.themeIndex, "isDynamic:", settings.themeIsDynamic)
|
loadSettings()
|
||||||
Qt.callLater(applyStoredTheme)
|
Qt.callLater(applyStoredTheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyStoredTheme() {
|
Process {
|
||||||
console.log("Applying stored theme:", settings.themeIndex, settings.themeIsDynamic)
|
id: mkdirProcess
|
||||||
|
running: false
|
||||||
|
|
||||||
|
onExited: (exitCode) => {
|
||||||
|
if (exitCode === 0) {
|
||||||
|
console.log("Config directory created successfully")
|
||||||
|
}
|
||||||
|
// Reload settings file after directory creation completes
|
||||||
|
settingsFileView.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: writeProcess
|
||||||
|
running: false
|
||||||
|
|
||||||
|
onExited: (exitCode) => {
|
||||||
|
if (exitCode === 0) {
|
||||||
|
console.log("Settings saved successfully")
|
||||||
|
} else {
|
||||||
|
console.error("Failed to save settings, exit code:", exitCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileView {
|
||||||
|
id: settingsFileView
|
||||||
|
path: "file://" + Quickshell.env("HOME") + "/.config/DankMaterialDark/settings.json"
|
||||||
|
|
||||||
|
onLoaded: {
|
||||||
|
console.log("Settings file loaded successfully")
|
||||||
|
try {
|
||||||
|
var content = settingsFileView.text()
|
||||||
|
console.log("Settings file content:", content)
|
||||||
|
if (content && content.trim()) {
|
||||||
|
var settings = JSON.parse(content)
|
||||||
|
themeIndex = settings.themeIndex !== undefined ? settings.themeIndex : 0
|
||||||
|
themeIsDynamic = settings.themeIsDynamic !== undefined ? settings.themeIsDynamic : false
|
||||||
|
console.log("Loaded settings - themeIndex:", themeIndex, "isDynamic:", themeIsDynamic)
|
||||||
|
} else {
|
||||||
|
console.log("Settings file is empty")
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Could not parse settings, using defaults:", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoadFailed: (error) => {
|
||||||
|
console.log("Settings file not found, using defaults. Error:", error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadSettings() {
|
||||||
|
mkdirProcess.command = ["mkdir", "-p", Quickshell.env("HOME") + "/.config/DankMaterialDark"]
|
||||||
|
mkdirProcess.running = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveSettings() {
|
||||||
|
var settings = {
|
||||||
|
themeIndex: themeIndex,
|
||||||
|
themeIsDynamic: themeIsDynamic
|
||||||
|
}
|
||||||
|
|
||||||
|
var content = JSON.stringify(settings, null, 2)
|
||||||
|
|
||||||
|
writeProcess.command = ["sh", "-c", "echo '" + content + "' > '" + Quickshell.env("HOME") + "/.config/DankMaterialDark/settings.json'"]
|
||||||
|
writeProcess.running = true
|
||||||
|
console.log("Saving settings - themeIndex:", themeIndex, "isDynamic:", themeIsDynamic)
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyStoredTheme() {
|
||||||
|
console.log("Applying stored theme:", themeIndex, themeIsDynamic)
|
||||||
|
|
||||||
// Make sure Theme is available
|
|
||||||
if (typeof Theme !== "undefined") {
|
if (typeof Theme !== "undefined") {
|
||||||
Theme.switchTheme(settings.themeIndex, settings.themeIsDynamic, false) // Don't save during startup
|
Theme.switchTheme(themeIndex, themeIsDynamic, false)
|
||||||
} else {
|
} else {
|
||||||
// Try again in a moment
|
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
if (typeof Theme !== "undefined") {
|
if (typeof Theme !== "undefined") {
|
||||||
Theme.switchTheme(settings.themeIndex, settings.themeIsDynamic, false) // Don't save during startup
|
Theme.switchTheme(themeIndex, themeIsDynamic, false)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -42,8 +104,8 @@ Singleton {
|
|||||||
|
|
||||||
function setTheme(index, isDynamic) {
|
function setTheme(index, isDynamic) {
|
||||||
console.log("Prefs setTheme called - themeIndex:", index, "isDynamic:", isDynamic)
|
console.log("Prefs setTheme called - themeIndex:", index, "isDynamic:", isDynamic)
|
||||||
settings.themeIndex = index
|
themeIndex = index
|
||||||
settings.themeIsDynamic = isDynamic
|
themeIsDynamic = isDynamic
|
||||||
console.log("Prefs saved - themeIndex:", settings.themeIndex, "isDynamic:", settings.themeIsDynamic)
|
saveSettings()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,13 +30,19 @@ QtObject {
|
|||||||
// Handle successful color extraction
|
// Handle successful color extraction
|
||||||
function onColorsUpdated() {
|
function onColorsUpdated() {
|
||||||
console.log("Colors updated successfully - switching to dynamic theme")
|
console.log("Colors updated successfully - switching to dynamic theme")
|
||||||
currentThemeIndex = 10
|
|
||||||
isDynamicTheme = true
|
|
||||||
console.log("Dynamic theme activated. Theme.primary should now be:", primary)
|
|
||||||
|
|
||||||
// Save preference after successful switch
|
// Only switch to dynamic theme if we're already in dynamic mode
|
||||||
if (typeof Prefs !== "undefined") {
|
if (isDynamicTheme) {
|
||||||
Prefs.setTheme(currentThemeIndex, isDynamicTheme)
|
currentThemeIndex = 10
|
||||||
|
isDynamicTheme = true
|
||||||
|
console.log("Dynamic theme activated. Theme.primary should now be:", primary)
|
||||||
|
|
||||||
|
// Save preference after successful switch
|
||||||
|
if (typeof Prefs !== "undefined") {
|
||||||
|
Prefs.setTheme(currentThemeIndex, isDynamicTheme)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("Color extraction completed, but staying with static theme")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,7 +231,10 @@ QtObject {
|
|||||||
if (isDynamic && themeIndex === 10) {
|
if (isDynamic && themeIndex === 10) {
|
||||||
console.log("Attempting to switch to dynamic theme - checking colors first")
|
console.log("Attempting to switch to dynamic theme - checking colors first")
|
||||||
|
|
||||||
// Don't change theme yet - wait for color extraction to succeed
|
// Set dynamic theme flag immediately so onColorsUpdated works
|
||||||
|
isDynamicTheme = true
|
||||||
|
|
||||||
|
// Don't change theme index yet - wait for color extraction to succeed
|
||||||
if (typeof Colors !== "undefined") {
|
if (typeof Colors !== "undefined") {
|
||||||
console.log("Calling Colors.extractColors()")
|
console.log("Calling Colors.extractColors()")
|
||||||
Colors.extractColors()
|
Colors.extractColors()
|
||||||
|
|||||||
@@ -934,13 +934,19 @@ PanelWindow {
|
|||||||
function start(exec) {
|
function start(exec) {
|
||||||
// Clean up exec command (remove field codes)
|
// Clean up exec command (remove field codes)
|
||||||
var cleanExec = exec.replace(/%[fFuU]/g, "").trim()
|
var cleanExec = exec.replace(/%[fFuU]/g, "").trim()
|
||||||
command = ["sh", "-c", cleanExec]
|
console.log("Launching app - Original:", exec, "Cleaned:", cleanExec)
|
||||||
|
|
||||||
|
// Use setsid to fully detach from shell session
|
||||||
|
command = ["setsid", "sh", "-c", cleanExec]
|
||||||
running = true
|
running = true
|
||||||
}
|
}
|
||||||
|
|
||||||
onExited: {
|
onExited: (exitCode) => {
|
||||||
if (exitCode !== 0) {
|
if (exitCode !== 0) {
|
||||||
console.log("Failed to launch application, exit code:", exitCode)
|
console.log("Failed to launch application, exit code:", exitCode)
|
||||||
|
console.log("Command was:", command)
|
||||||
|
} else {
|
||||||
|
console.log("App launch command completed successfully")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,4 +77,9 @@ EOF
|
|||||||
echo "→ Ghostty theme: $QS_DIR/generated_ghostty_colors.conf"
|
echo "→ Ghostty theme: $QS_DIR/generated_ghostty_colors.conf"
|
||||||
echo " (use in ghostty: theme = $QS_DIR/generated_ghostty_colors.conf )"
|
echo " (use in ghostty: theme = $QS_DIR/generated_ghostty_colors.conf )"
|
||||||
|
|
||||||
niri msg action do-screen-transition --delay-ms 100
|
niri msg action do-screen-transition --delay-ms 100
|
||||||
|
|
||||||
|
# Notify running shell about wallpaper change (for dynamic theme updates)
|
||||||
|
NOTIFY_FILE="$QS_DIR/wallpaper_changed"
|
||||||
|
echo "$(date '+%s')" > "$NOTIFY_FILE"
|
||||||
|
echo "→ Shell notified: $NOTIFY_FILE"
|
||||||
Reference in New Issue
Block a user