diff options
Diffstat (limited to 'quickshell/modules/desktop')
| -rw-r--r-- | quickshell/modules/desktop/Wallpaper.qml | 180 |
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 + } + } +} |
