mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2026-08-15 18:43:59 +00:00
Background: on the hunt again
This commit is contained in:
+69
-69
@@ -9,76 +9,76 @@ import qs.Commons
|
||||
// - Assets/Matugen/templates/
|
||||
// - ~/.config/matugen/ (when enableUserTemplates is true)
|
||||
Singleton {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
// Build the base TOML using current settings
|
||||
function buildConfigToml() {
|
||||
var lines = [];
|
||||
lines.push("[config]");
|
||||
var mode = Settings.data.colorSchemes.darkMode ? "dark" : "light";
|
||||
// Always include noctalia colors output for the shell
|
||||
lines.push("[templates.noctalia]");
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/noctalia.json"');
|
||||
lines.push('output_path = "' + Settings.configDir + 'colors.json"');
|
||||
// Build the base TOML using current settings
|
||||
function buildConfigToml() {
|
||||
var lines = []
|
||||
lines.push("[config]")
|
||||
var mode = Settings.data.colorSchemes.darkMode ? "dark" : "light"
|
||||
// Always include noctalia colors output for the shell
|
||||
lines.push("[templates.noctalia]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/noctalia.json"')
|
||||
lines.push('output_path = "' + Settings.configDir + 'colors.json"')
|
||||
|
||||
if (Settings.data.matugen.gtk4) {
|
||||
lines.push("\n[templates.gtk4]");
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/gtk4.css"');
|
||||
lines.push('output_path = "~/.config/gtk-4.0/gtk.css"');
|
||||
lines.push("post_hook = 'gsettings set org.gnome.desktop.interface color-scheme prefer-" + mode + "'");
|
||||
}
|
||||
if (Settings.data.matugen.gtk3) {
|
||||
lines.push("\n[templates.gtk3]");
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/gtk3.css"');
|
||||
lines.push('output_path = "~/.config/gtk-3.0/gtk.css"');
|
||||
lines.push("post_hook = 'gsettings set org.gnome.desktop.interface color-scheme prefer-" + mode + "'");
|
||||
}
|
||||
if (Settings.data.matugen.qt6) {
|
||||
lines.push("\n[templates.qt6]");
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/qtct.conf"');
|
||||
lines.push('output_path = "~/.config/qt6ct/colors/noctalia.conf"');
|
||||
}
|
||||
if (Settings.data.matugen.qt5) {
|
||||
lines.push("\n[templates.qt5]");
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/qtct.conf"');
|
||||
lines.push('output_path = "~/.config/qt5ct/colors/noctalia.conf"');
|
||||
}
|
||||
if (Settings.data.matugen.kitty) {
|
||||
lines.push("\n[templates.kitty]");
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/kitty.conf"');
|
||||
lines.push('output_path = "~/.config/kitty/themes/noctalia.conf"');
|
||||
lines.push("post_hook = 'kitty +kitten themes --reload-in=all noctalia'");
|
||||
}
|
||||
if (Settings.data.matugen.ghostty) {
|
||||
lines.push("\n[templates.ghostty]");
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/ghostty.conf"');
|
||||
lines.push('output_path = "~/.config/ghostty/themes/noctalia"');
|
||||
lines.push("post_hook = \"grep -q '^theme *= *' ~/.config/ghostty/config; and sed -i 's/^theme *= *.*/theme = noctalia/' ~/.config/ghostty/config; or echo 'theme = noctalia' >> ~/.config/ghostty/config; and pkill -SIGUSR2 ghostty\"");
|
||||
}
|
||||
if (Settings.data.matugen.foot) {
|
||||
lines.push("\n[templates.foot]");
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/foot.conf"');
|
||||
lines.push('output_path = "~/.config/foot/themes/noctalia"');
|
||||
lines.push('post_hook = "sed -i /themes/d ~/.config/foot/foot.ini && echo include=~/.config/foot/themes/noctalia >> ~/.config/foot/foot.ini"');
|
||||
}
|
||||
if (Settings.data.matugen.fuzzel) {
|
||||
lines.push("\n[templates.fuzzel]");
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/fuzzel.conf"');
|
||||
lines.push('output_path = "~/.config/fuzzel/themes/noctalia"');
|
||||
lines.push('post_hook = "sed -i /themes/d ~/.config/fuzzel/fuzzel.ini && echo include=~/.config/fuzzel/themes/noctalia >> ~/.config/fuzzel/fuzzel.ini"');
|
||||
}
|
||||
if (Settings.data.matugen.vesktop) {
|
||||
lines.push("\n[templates.vesktop]");
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/vesktop.css"');
|
||||
lines.push('output_path = "~/.config/vesktop/themes/noctalia.theme.css"');
|
||||
}
|
||||
if (Settings.data.matugen.pywalfox) {
|
||||
lines.push("\n[templates.pywalfox]");
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/pywalfox.json"');
|
||||
lines.push('output_path = "~/.cache/wal/colors.json"');
|
||||
lines.push('post_hook = "pywalfox update"');
|
||||
}
|
||||
|
||||
return lines.join("\n") + "\n";
|
||||
if (Settings.data.matugen.gtk4) {
|
||||
lines.push("\n[templates.gtk4]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/gtk4.css"')
|
||||
lines.push('output_path = "~/.config/gtk-4.0/gtk.css"')
|
||||
lines.push("post_hook = 'gsettings set org.gnome.desktop.interface color-scheme prefer-" + mode + "'")
|
||||
}
|
||||
if (Settings.data.matugen.gtk3) {
|
||||
lines.push("\n[templates.gtk3]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/gtk3.css"')
|
||||
lines.push('output_path = "~/.config/gtk-3.0/gtk.css"')
|
||||
lines.push("post_hook = 'gsettings set org.gnome.desktop.interface color-scheme prefer-" + mode + "'")
|
||||
}
|
||||
if (Settings.data.matugen.qt6) {
|
||||
lines.push("\n[templates.qt6]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/qtct.conf"')
|
||||
lines.push('output_path = "~/.config/qt6ct/colors/noctalia.conf"')
|
||||
}
|
||||
if (Settings.data.matugen.qt5) {
|
||||
lines.push("\n[templates.qt5]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/qtct.conf"')
|
||||
lines.push('output_path = "~/.config/qt5ct/colors/noctalia.conf"')
|
||||
}
|
||||
if (Settings.data.matugen.kitty) {
|
||||
lines.push("\n[templates.kitty]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/kitty.conf"')
|
||||
lines.push('output_path = "~/.config/kitty/themes/noctalia.conf"')
|
||||
lines.push("post_hook = 'kitty +kitten themes --reload-in=all noctalia'")
|
||||
}
|
||||
if (Settings.data.matugen.ghostty) {
|
||||
lines.push("\n[templates.ghostty]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/ghostty.conf"')
|
||||
lines.push('output_path = "~/.config/ghostty/themes/noctalia"')
|
||||
lines.push("post_hook = \"grep -q '^theme *= *' ~/.config/ghostty/config; and sed -i 's/^theme *= *.*/theme = noctalia/' ~/.config/ghostty/config; or echo 'theme = noctalia' >> ~/.config/ghostty/config; and pkill -SIGUSR2 ghostty\"")
|
||||
}
|
||||
if (Settings.data.matugen.foot) {
|
||||
lines.push("\n[templates.foot]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/foot.conf"')
|
||||
lines.push('output_path = "~/.config/foot/themes/noctalia"')
|
||||
lines.push('post_hook = "sed -i /themes/d ~/.config/foot/foot.ini && echo include=~/.config/foot/themes/noctalia >> ~/.config/foot/foot.ini"')
|
||||
}
|
||||
if (Settings.data.matugen.fuzzel) {
|
||||
lines.push("\n[templates.fuzzel]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/fuzzel.conf"')
|
||||
lines.push('output_path = "~/.config/fuzzel/themes/noctalia"')
|
||||
lines.push('post_hook = "sed -i /themes/d ~/.config/fuzzel/fuzzel.ini && echo include=~/.config/fuzzel/themes/noctalia >> ~/.config/fuzzel/fuzzel.ini"')
|
||||
}
|
||||
if (Settings.data.matugen.vesktop) {
|
||||
lines.push("\n[templates.vesktop]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/vesktop.css"')
|
||||
lines.push('output_path = "~/.config/vesktop/themes/noctalia.theme.css"')
|
||||
}
|
||||
if (Settings.data.matugen.pywalfox) {
|
||||
lines.push("\n[templates.pywalfox]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/pywalfox.json"')
|
||||
lines.push('output_path = "~/.cache/wal/colors.json"')
|
||||
lines.push('post_hook = "pywalfox update"')
|
||||
}
|
||||
|
||||
return lines.join("\n") + "\n"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,14 @@ Variants {
|
||||
|
||||
Component.onCompleted: setWallpaperInitial()
|
||||
|
||||
Component.onDestruction: {
|
||||
transitionAnimation.stop()
|
||||
debounceTimer.stop()
|
||||
shaderLoader.active = false
|
||||
currentWallpaper.source = ""
|
||||
nextWallpaper.source = ""
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Settings.data.wallpaper
|
||||
function onFillModeChanged() {
|
||||
@@ -97,6 +105,11 @@ Variants {
|
||||
visible: false
|
||||
cache: false
|
||||
asynchronous: true
|
||||
onStatusChanged: {
|
||||
if (status === Image.Error) {
|
||||
Logger.warn("Current wallpaper failed to load:", source)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
@@ -107,108 +120,139 @@ Variants {
|
||||
visible: false
|
||||
cache: false
|
||||
asynchronous: true
|
||||
onStatusChanged: {
|
||||
if (status === Image.Error) {
|
||||
Logger.warn("Next wallpaper failed to load:", source)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fade or None transition shader
|
||||
ShaderEffect {
|
||||
id: fadeShader
|
||||
// Dynamic shader loader - only loads the active transition shader
|
||||
Loader {
|
||||
id: shaderLoader
|
||||
anchors.fill: parent
|
||||
visible: transitionType === "fade" || transitionType === "none"
|
||||
active: true
|
||||
|
||||
property variant source1: currentWallpaper
|
||||
property variant source2: nextWallpaper
|
||||
property real progress: root.transitionProgress
|
||||
|
||||
// Fill mode properties
|
||||
property real fillMode: root.fillMode
|
||||
property vector4d fillColor: root.fillColor
|
||||
property real imageWidth1: source1.sourceSize.width
|
||||
property real imageHeight1: source1.sourceSize.height
|
||||
property real imageWidth2: source2.sourceSize.width
|
||||
property real imageHeight2: source2.sourceSize.height
|
||||
property real screenWidth: width
|
||||
property real screenHeight: height
|
||||
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/wp_fade.frag.qsb")
|
||||
sourceComponent: {
|
||||
switch (transitionType) {
|
||||
case "wipe":
|
||||
return wipeShaderComponent
|
||||
case "disc":
|
||||
return discShaderComponent
|
||||
case "stripes":
|
||||
return stripesShaderComponent
|
||||
case "fade":
|
||||
case "none":
|
||||
default:
|
||||
return fadeShaderComponent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wipe transition shader
|
||||
ShaderEffect {
|
||||
id: wipeShader
|
||||
anchors.fill: parent
|
||||
visible: transitionType === "wipe"
|
||||
// Fade or None transition shader component
|
||||
Component {
|
||||
id: fadeShaderComponent
|
||||
ShaderEffect {
|
||||
anchors.fill: parent
|
||||
|
||||
property variant source1: currentWallpaper
|
||||
property variant source2: nextWallpaper
|
||||
property real progress: root.transitionProgress
|
||||
property real smoothness: root.edgeSmoothness
|
||||
property real direction: root.wipeDirection
|
||||
property variant source1: currentWallpaper
|
||||
property variant source2: nextWallpaper
|
||||
property real progress: root.transitionProgress
|
||||
|
||||
// Fill mode properties
|
||||
property real fillMode: root.fillMode
|
||||
property vector4d fillColor: root.fillColor
|
||||
property real imageWidth1: source1.sourceSize.width
|
||||
property real imageHeight1: source1.sourceSize.height
|
||||
property real imageWidth2: source2.sourceSize.width
|
||||
property real imageHeight2: source2.sourceSize.height
|
||||
property real screenWidth: width
|
||||
property real screenHeight: height
|
||||
// Fill mode properties
|
||||
property real fillMode: root.fillMode
|
||||
property vector4d fillColor: root.fillColor
|
||||
property real imageWidth1: source1.sourceSize.width
|
||||
property real imageHeight1: source1.sourceSize.height
|
||||
property real imageWidth2: source2.sourceSize.width
|
||||
property real imageHeight2: source2.sourceSize.height
|
||||
property real screenWidth: width
|
||||
property real screenHeight: height
|
||||
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/wp_wipe.frag.qsb")
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/wp_fade.frag.qsb")
|
||||
}
|
||||
}
|
||||
|
||||
// Disc reveal transition shader
|
||||
ShaderEffect {
|
||||
id: discShader
|
||||
anchors.fill: parent
|
||||
visible: transitionType === "disc"
|
||||
// Wipe transition shader component
|
||||
Component {
|
||||
id: wipeShaderComponent
|
||||
ShaderEffect {
|
||||
anchors.fill: parent
|
||||
|
||||
property variant source1: currentWallpaper
|
||||
property variant source2: nextWallpaper
|
||||
property real progress: root.transitionProgress
|
||||
property real smoothness: root.edgeSmoothness
|
||||
property real aspectRatio: root.width / root.height
|
||||
property real centerX: root.discCenterX
|
||||
property real centerY: root.discCenterY
|
||||
property variant source1: currentWallpaper
|
||||
property variant source2: nextWallpaper
|
||||
property real progress: root.transitionProgress
|
||||
property real smoothness: root.edgeSmoothness
|
||||
property real direction: root.wipeDirection
|
||||
|
||||
// Fill mode properties
|
||||
property real fillMode: root.fillMode
|
||||
property vector4d fillColor: root.fillColor
|
||||
property real imageWidth1: source1.sourceSize.width
|
||||
property real imageHeight1: source1.sourceSize.height
|
||||
property real imageWidth2: source2.sourceSize.width
|
||||
property real imageHeight2: source2.sourceSize.height
|
||||
property real screenWidth: width
|
||||
property real screenHeight: height
|
||||
// Fill mode properties
|
||||
property real fillMode: root.fillMode
|
||||
property vector4d fillColor: root.fillColor
|
||||
property real imageWidth1: source1.sourceSize.width
|
||||
property real imageHeight1: source1.sourceSize.height
|
||||
property real imageWidth2: source2.sourceSize.width
|
||||
property real imageHeight2: source2.sourceSize.height
|
||||
property real screenWidth: width
|
||||
property real screenHeight: height
|
||||
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/wp_disc.frag.qsb")
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/wp_wipe.frag.qsb")
|
||||
}
|
||||
}
|
||||
|
||||
// Diagonal stripes transition shader
|
||||
ShaderEffect {
|
||||
id: stripesShader
|
||||
anchors.fill: parent
|
||||
visible: transitionType === "stripes"
|
||||
// Disc reveal transition shader component
|
||||
Component {
|
||||
id: discShaderComponent
|
||||
ShaderEffect {
|
||||
anchors.fill: parent
|
||||
|
||||
property variant source1: currentWallpaper
|
||||
property variant source2: nextWallpaper
|
||||
property real progress: root.transitionProgress
|
||||
property real smoothness: root.edgeSmoothness
|
||||
property real aspectRatio: root.width / root.height
|
||||
property real stripeCount: root.stripesCount
|
||||
property real angle: root.stripesAngle
|
||||
property variant source1: currentWallpaper
|
||||
property variant source2: nextWallpaper
|
||||
property real progress: root.transitionProgress
|
||||
property real smoothness: root.edgeSmoothness
|
||||
property real aspectRatio: root.width / root.height
|
||||
property real centerX: root.discCenterX
|
||||
property real centerY: root.discCenterY
|
||||
|
||||
// Fill mode properties
|
||||
property real fillMode: root.fillMode
|
||||
property vector4d fillColor: root.fillColor
|
||||
property real imageWidth1: source1.sourceSize.width
|
||||
property real imageHeight1: source1.sourceSize.height
|
||||
property real imageWidth2: source2.sourceSize.width
|
||||
property real imageHeight2: source2.sourceSize.height
|
||||
property real screenWidth: width
|
||||
property real screenHeight: height
|
||||
// Fill mode properties
|
||||
property real fillMode: root.fillMode
|
||||
property vector4d fillColor: root.fillColor
|
||||
property real imageWidth1: source1.sourceSize.width
|
||||
property real imageHeight1: source1.sourceSize.height
|
||||
property real imageWidth2: source2.sourceSize.width
|
||||
property real imageHeight2: source2.sourceSize.height
|
||||
property real screenWidth: width
|
||||
property real screenHeight: height
|
||||
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/wp_stripes.frag.qsb")
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/wp_disc.frag.qsb")
|
||||
}
|
||||
}
|
||||
|
||||
// Diagonal stripes transition shader component
|
||||
Component {
|
||||
id: stripesShaderComponent
|
||||
ShaderEffect {
|
||||
anchors.fill: parent
|
||||
|
||||
property variant source1: currentWallpaper
|
||||
property variant source2: nextWallpaper
|
||||
property real progress: root.transitionProgress
|
||||
property real smoothness: root.edgeSmoothness
|
||||
property real aspectRatio: root.width / root.height
|
||||
property real stripeCount: root.stripesCount
|
||||
property real angle: root.stripesAngle
|
||||
|
||||
// Fill mode properties
|
||||
property real fillMode: root.fillMode
|
||||
property vector4d fillColor: root.fillColor
|
||||
property real imageWidth1: source1.sourceSize.width
|
||||
property real imageHeight1: source1.sourceSize.height
|
||||
property real imageWidth2: source2.sourceSize.width
|
||||
property real imageHeight2: source2.sourceSize.height
|
||||
property real screenWidth: width
|
||||
property real screenHeight: height
|
||||
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/wp_stripes.frag.qsb")
|
||||
}
|
||||
}
|
||||
|
||||
// Animation for the transition progress
|
||||
@@ -222,13 +266,19 @@ Variants {
|
||||
duration: transitionType == "stripes" ? Settings.data.wallpaper.transitionDuration * 1.6 : Settings.data.wallpaper.transitionDuration
|
||||
easing.type: Easing.InOutCubic
|
||||
onFinished: {
|
||||
// Swap images after transition completes
|
||||
currentWallpaper.source = ""
|
||||
currentWallpaper.source = nextWallpaper.source
|
||||
// Swap images while keeping shader active to prevent flickering
|
||||
const tempSource = nextWallpaper.source
|
||||
nextWallpaper.source = ""
|
||||
transitionProgress = 0.0
|
||||
currentWallpaper.source = ""
|
||||
|
||||
// Use Qt.callLater to allow GC to clean up before reassignment
|
||||
Qt.callLater(() => {
|
||||
currentWallpaper.asynchronous = true
|
||||
currentWallpaper.source = tempSource
|
||||
transitionProgress = 0.0
|
||||
|
||||
Qt.callLater(() => {
|
||||
currentWallpaper.asynchronous = true
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -246,9 +296,14 @@ Variants {
|
||||
function setWallpaperImmediate(source) {
|
||||
transitionAnimation.stop()
|
||||
transitionProgress = 0.0
|
||||
currentWallpaper.source = ""
|
||||
currentWallpaper.source = source
|
||||
|
||||
// Clear with proper delay to allow GC
|
||||
nextWallpaper.source = ""
|
||||
currentWallpaper.source = ""
|
||||
|
||||
Qt.callLater(() => {
|
||||
currentWallpaper.source = source
|
||||
})
|
||||
}
|
||||
|
||||
function setWallpaperWithTransition(source) {
|
||||
@@ -257,15 +312,28 @@ Variants {
|
||||
}
|
||||
|
||||
if (transitioning) {
|
||||
// We are interrupting a transition
|
||||
// We are interrupting a transition - handle cleanup properly
|
||||
transitionAnimation.stop()
|
||||
transitionProgress = 0
|
||||
|
||||
const newCurrentSource = nextWallpaper.source
|
||||
|
||||
// Clear both properly while keeping shader active
|
||||
currentWallpaper.source = ""
|
||||
nextWallpaper.source = ""
|
||||
|
||||
currentWallpaper.source = newCurrentSource
|
||||
// Defer the reassignment to allow cleanup
|
||||
Qt.callLater(() => {
|
||||
currentWallpaper.source = newCurrentSource
|
||||
|
||||
// Now set the next wallpaper after a brief delay
|
||||
Qt.callLater(() => {
|
||||
nextWallpaper.source = source
|
||||
currentWallpaper.asynchronous = false
|
||||
transitionAnimation.start()
|
||||
})
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
nextWallpaper.source = source
|
||||
|
||||
@@ -37,7 +37,7 @@ Variants {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Connections {
|
||||
target: WallpaperService
|
||||
function onIsInitializedChanged() {
|
||||
|
||||
Reference in New Issue
Block a user