mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-06 05:25:41 -05:00
190 lines
7.5 KiB
QML
190 lines
7.5 KiB
QML
pragma Singleton
|
|
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import Qt.labs.platform // ← gives us StandardPaths
|
|
|
|
Singleton {
|
|
id: root
|
|
|
|
/* ──────────────── basic state ──────────────── */
|
|
signal colorsUpdated()
|
|
|
|
readonly property string _homeUrl: StandardPaths.writableLocation(StandardPaths.HomeLocation)
|
|
readonly property string homeDir: _homeUrl.startsWith("file://")
|
|
? _homeUrl.substring(7)
|
|
: _homeUrl
|
|
readonly property string wallpaperPath: homeDir + "/quickshell/current_wallpaper"
|
|
readonly property string notifyPath: homeDir + "/quickshell/wallpaper_changed"
|
|
|
|
property bool matugenAvailable: false
|
|
property string matugenJson: ""
|
|
property var matugenColors: ({})
|
|
property bool extractionRequested: false
|
|
|
|
Component.onCompleted: {
|
|
console.log("Colors.qml → home =", homeDir)
|
|
// 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 ──────────────── */
|
|
Process {
|
|
id: matugenCheck
|
|
command: ["which", "matugen"]
|
|
onExited: (code) => {
|
|
matugenAvailable = (code === 0)
|
|
console.log("Matugen in PATH:", matugenAvailable)
|
|
|
|
if (!matugenAvailable) {
|
|
console.warn("Matugen missing → dynamic theme disabled")
|
|
Theme.rootObj.wallpaperErrorStatus = "matugen_missing"
|
|
return
|
|
}
|
|
|
|
// If extraction was requested, continue the process
|
|
if (extractionRequested) {
|
|
console.log("Continuing with color extraction")
|
|
fileChecker.running = true
|
|
}
|
|
}
|
|
}
|
|
|
|
Process {
|
|
id: fileChecker // exists & readable?
|
|
command: ["test", "-r", wallpaperPath]
|
|
onExited: (code) => {
|
|
if (code === 0) {
|
|
matugenProcess.running = true
|
|
} else {
|
|
console.error("code", code)
|
|
console.error("Wallpaper not found:", wallpaperPath)
|
|
Theme.rootObj.showWallpaperError()
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ──────────────── matugen invocation ──────────────── */
|
|
Process {
|
|
id: matugenProcess
|
|
command: ["matugen", "-v", "image", wallpaperPath, "--json", "hex"]
|
|
|
|
/* ── grab stdout as a stream ── */
|
|
stdout: StdioCollector {
|
|
id: matugenCollector
|
|
onStreamFinished: {
|
|
const out = matugenCollector.text
|
|
if (!out.length) {
|
|
console.error("matugen produced zero bytes\nstderr:", matugenProcess.stderr)
|
|
Theme.rootObj.showWallpaperError()
|
|
return
|
|
}
|
|
try {
|
|
root.matugenJson = out
|
|
root.matugenColors = JSON.parse(out)
|
|
root.colorsUpdated()
|
|
Theme.rootObj.wallpaperErrorStatus = ""
|
|
} catch (e) {
|
|
console.error("JSON parse failed:", e)
|
|
Theme.rootObj.showWallpaperError()
|
|
}
|
|
}
|
|
}
|
|
|
|
/* grab stderr too, so we can print it above */
|
|
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 ──────────────── */
|
|
function extractColors() {
|
|
console.log("Colors.extractColors() called, matugenAvailable:", matugenAvailable)
|
|
extractionRequested = true
|
|
if (matugenAvailable)
|
|
fileChecker.running = true
|
|
else
|
|
matugenCheck.running = true
|
|
}
|
|
|
|
function getMatugenColor(path, fallback) {
|
|
let cur = matugenColors?.colors?.dark
|
|
for (const part of path.split(".")) {
|
|
if (!cur || typeof cur !== "object" || !(part in cur))
|
|
return fallback
|
|
cur = cur[part]
|
|
}
|
|
return cur || fallback
|
|
}
|
|
|
|
/* ──────────────── color properties (MD3) ──────────────── */
|
|
property color primary: getMatugenColor("primary", "#42a5f5")
|
|
property color secondary: getMatugenColor("secondary", "#8ab4f8")
|
|
property color tertiary: getMatugenColor("tertiary", "#bb86fc")
|
|
property color tertiaryContainer: getMatugenColor("tertiary_container", "#3700b3")
|
|
property color error: getMatugenColor("error", "#cf6679")
|
|
property color inversePrimary: getMatugenColor("inverse_primary", "#6200ea")
|
|
|
|
/* backgrounds */
|
|
property color bg: getMatugenColor("background", "#1a1c1e")
|
|
property color surface: getMatugenColor("surface", "#1a1c1e")
|
|
property color surfaceContainer: getMatugenColor("surface_container", "#1e2023")
|
|
property color surfaceContainerHigh: getMatugenColor("surface_container_high", "#292b2f")
|
|
property color surfaceVariant: getMatugenColor("surface_variant", "#44464f")
|
|
|
|
/* text */
|
|
property color surfaceText: getMatugenColor("on_background", "#e3e8ef")
|
|
property color primaryText: getMatugenColor("on_primary", "#ffffff")
|
|
property color surfaceVariantText: getMatugenColor("on_surface_variant", "#c4c7c5")
|
|
|
|
/* containers & misc */
|
|
property color primaryContainer: getMatugenColor("primary_container", "#1976d2")
|
|
property color surfaceTint: getMatugenColor("surface_tint", "#8ab4f8")
|
|
property color outline: getMatugenColor("outline", "#8e918f")
|
|
|
|
/* legacy aliases */
|
|
property color accentHi: primary
|
|
property color accentLo: secondary
|
|
|
|
function isColorDark(c) {
|
|
return (0.299 * c.r + 0.587 * c.g + 0.114 * c.b) < 0.5
|
|
}
|
|
}
|