summaryrefslogtreecommitdiffstats
path: root/quickshell/modules/desktop
diff options
context:
space:
mode:
authorcoast <coasteen@proton.me>2026-10-13 05:03:11 +0330
committercoast <coasteen@proton.me>2026-10-13 05:03:11 +0330
commit8c5c2d270fd0f3bbc276e3b1cc28fc1dfae3fa59 (patch)
treea18e4d6016c4df3ca97e017b9f9d351398e950da /quickshell/modules/desktop
downloadcoast-newdot-8c5c2d270fd0f3bbc276e3b1cc28fc1dfae3fa59.tar.gz
coast-newdot-8c5c2d270fd0f3bbc276e3b1cc28fc1dfae3fa59.tar.bz2
coast-newdot-8c5c2d270fd0f3bbc276e3b1cc28fc1dfae3fa59.tar.xz
coast-newdot-8c5c2d270fd0f3bbc276e3b1cc28fc1dfae3fa59.tar.zst
init
Diffstat (limited to 'quickshell/modules/desktop')
-rw-r--r--quickshell/modules/desktop/Wallpaper.qml180
1 files changed, 180 insertions, 0 deletions
diff --git a/quickshell/modules/desktop/Wallpaper.qml b/quickshell/modules/desktop/Wallpaper.qml
new file mode 100644
index 0000000..c956862
--- /dev/null
+++ b/quickshell/modules/desktop/Wallpaper.qml
@@ -0,0 +1,180 @@
+import QtQuick
+import QtQuick.Effects
+import Quickshell
+import Quickshell.Io
+import Quickshell.Wayland
+import "../../config.js" as Config
+
+Variants {
+ model: Quickshell.screens
+
+ PanelWindow {
+ id: win
+
+ required property var modelData
+
+ property var wallpaper: Config.wallpapers.find(function(w) {
+ return w.outputs.indexOf(modelData.name) !== -1
+ })
+
+ property string currentPath: wallpaper ? wallpaper.path : ""
+ property string previousPath: ""
+ property real reveal: 1
+ property bool started: false
+ property bool initialized: false
+ property int direction: 0
+
+ readonly property bool horizontal: direction < 2
+ readonly property bool fromStart: direction % 2 === 0
+
+ readonly property int fillValue: wallpaper ? Image[wallpaper.fillMode] : Image.PreserveAspectCrop
+
+ readonly property bool ready: initialized && currentPath !== "" && newImage.status === Image.Ready && (previousPath === "" || oldImage.status === Image.Ready)
+
+ screen: modelData
+ visible: wallpaper !== undefined
+ color: "#000000"
+
+ anchors {
+ top: true
+ bottom: true
+ left: true
+ right: true
+ }
+
+ exclusionMode: ExclusionMode.Ignore
+
+ WlrLayershell.layer: WlrLayer.Background
+ WlrLayershell.namespace: "wallpaper"
+
+ FileView {
+ id: stateFile
+
+ path: Quickshell.env("HOME") + "/.cache/qs-wallpaper-" + win.modelData.name
+ blockLoading: true
+ printErrors: false
+ }
+
+ function pickDirection() {
+ const names = ["left", "right", "top", "bottom"]
+ const wanted = Config.wallpaperWipeDirection ?? "random"
+ const index = names.indexOf(wanted)
+
+ if (index !== -1)
+ return index
+
+ return Math.floor(Math.random() * 4)
+ }
+
+ function begin() {
+ if (started || currentPath === "")
+ return
+
+ started = true
+
+ if (reveal < 1)
+ wipe.start()
+ else
+ finish()
+ }
+
+ function finish() {
+ previousPath = currentPath
+ stateFile.setText(currentPath)
+ }
+
+ onReadyChanged: {
+ if (ready)
+ begin()
+ }
+
+ Component.onCompleted: {
+ let saved = ""
+
+ try {
+ saved = stateFile.text().trim()
+ } catch (e) {
+ saved = ""
+ }
+
+ previousPath = saved
+ direction = pickDirection()
+ reveal = (saved !== currentPath) ? 0 : 1
+ initialized = true
+
+ if (ready)
+ begin()
+ }
+
+ NumberAnimation {
+ id: wipe
+
+ target: win
+ property: "reveal"
+ from: 0
+ to: 1
+ duration: Config.wallpaperWipeDuration ?? 700
+ easing.type: Easing.InOutCubic
+
+ onFinished: win.finish()
+ }
+
+ Item {
+ id: stack
+
+ anchors.fill: parent
+ opacity: win.wallpaper ? win.wallpaper.opacity : 1.0
+
+ readonly property real clipWidth: win.horizontal ? (width * win.reveal) : width
+ readonly property real clipHeight: win.horizontal ? height : (height * win.reveal)
+ readonly property real clipX: (win.horizontal && !win.fromStart) ? (width - clipWidth) : 0
+ readonly property real clipY: (!win.horizontal && !win.fromStart) ? (height - clipHeight) : 0
+
+ Image {
+ id: oldImage
+
+ anchors.fill: parent
+ clip: true
+
+ source: win.initialized ? win.previousPath : ""
+ fillMode: win.fillValue
+ asynchronous: win.wallpaper ? win.wallpaper.asynchronous : true
+ cache: win.wallpaper ? win.wallpaper.cache : true
+ }
+
+ Item {
+ id: revealClip
+
+ x: stack.clipX
+ y: stack.clipY
+ width: stack.clipWidth
+ height: stack.clipHeight
+ clip: true
+
+ Image {
+ id: newImage
+
+ x: 0 - stack.clipX
+ y: 0 - stack.clipY
+ width: stack.width
+ height: stack.height
+ clip: true
+
+ source: win.initialized ? win.currentPath : ""
+ fillMode: win.fillValue
+ asynchronous: win.wallpaper ? win.wallpaper.asynchronous : true
+ cache: win.wallpaper ? win.wallpaper.cache : true
+ }
+ }
+ }
+
+ MultiEffect {
+ anchors.fill: stack
+
+ source: stack
+
+ blurEnabled: win.wallpaper ? win.wallpaper.blur > 0 : false
+ blur: win.wallpaper ? win.wallpaper.blur : 0
+ }
+ }
+}