aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-11-06 17:44:33 +0100
committerDanilo M. <danix@danix.xyz>2026-11-06 17:44:33 +0100
commit698e163924744a57de12519dbbceff0e68c7e1a6 (patch)
treea7e6400a1d7b0fe2e1c63cbdccee4e9a410de469
parentf6d325615cb461473e96c9a61cfd877ab8a62075 (diff)
downloadquickshell-698e163924744a57de12519dbbceff0e68c7e1a6.tar.gz
quickshell-698e163924744a57de12519dbbceff0e68c7e1a6.zip
wallpaper: a page to preview and pick the transition
A tile per transition plus Random. A click selects in the draft and plays the real shader between the two current wallpapers, and Apply or Reset in the header settle it, like every other draft page. Ticks are Random's pool. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-rw-r--r--desktop/modules/appearance/TransitionTile.qml120
-rw-r--r--desktop/modules/appearance/TransitionsModule.qml43
-rw-r--r--desktop/modules/appearance/TransitionsTab.qml57
-rw-r--r--desktop/shell.qml1
4 files changed, 221 insertions, 0 deletions
diff --git a/desktop/modules/appearance/TransitionTile.qml b/desktop/modules/appearance/TransitionTile.qml
new file mode 100644
index 0000000..9c6d9eb
--- /dev/null
+++ b/desktop/modules/appearance/TransitionTile.qml
@@ -0,0 +1,120 @@
+// Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+import QtQuick
+import "../.."
+
+// One choice on the transitions page. A click selects it in the draft and
+// plays it once between the two current wallpapers. The tick puts it in
+// Random's pool. The tile named "random" has no shader and no tick.
+Item {
+ id: tile
+ required property string name
+ required property string label
+ readonly property bool random: name === "random"
+ readonly property bool selected: Transitions.draftPick === name
+ readonly property bool shows: !random && Wallpapers.currentH !== "" && Wallpapers.currentV !== ""
+ property real progress: 0
+ property point origin: Qt.point(0.5, 0.5)
+
+ implicitHeight: thumb.height + 30
+
+ Glow {
+ anchors.fill: thumb
+ on: tile.selected
+ }
+
+ Rectangle {
+ id: thumb
+ width: tile.width
+ height: Math.round(width * 9 / 16)
+ color: Theme.surface
+ clip: true
+
+ // Same layering as the cover, WallpaperSpread.qml. ponytail: rests on
+ // the old picture again after playing, with a cut.
+ Image {
+ id: newImg
+ visible: tile.shows
+ anchors.fill: parent
+ source: tile.shows ? Wallpapers.currentV : ""
+ fillMode: Image.PreserveAspectCrop
+ sourceSize: Qt.size(thumb.width, thumb.height)
+ asynchronous: true
+ layer.enabled: tile.shows
+ }
+ Image {
+ id: oldImg
+ visible: tile.shows
+ anchors.fill: parent
+ source: tile.shows ? Wallpapers.currentH : ""
+ fillMode: Image.PreserveAspectCrop
+ sourceSize: Qt.size(thumb.width, thumb.height)
+ asynchronous: true
+ layer.enabled: tile.shows
+ layer.effect: WallShader {
+ name: tile.name
+ target: newImg
+ progress: tile.progress
+ aspect: thumb.width / Math.max(1, thumb.height)
+ origin: tile.origin
+ }
+ }
+
+ Text {
+ anchors.centerIn: parent
+ visible: tile.random
+ // nf-fa-shuffle, present in Inconsolata Nerd Font.
+ text: ""
+ color: Theme.subtext
+ font { family: Theme.iconFamily; pixelSize: Theme.fontSize * 2 }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ onClicked: {
+ Transitions.draftPick = tile.name;
+ if (!tile.shows) return;
+ tile.origin = Qt.point(Math.random(), Math.random());
+ play.restart();
+ }
+ }
+ }
+
+ NumberAnimation {
+ id: play
+ target: tile
+ property: "progress"
+ from: 0
+ to: 1
+ duration: Transitions.duration
+ onFinished: tile.progress = 0
+ }
+
+ Toggle {
+ anchors { top: thumb.bottom; topMargin: 6; left: parent.left }
+ visible: !tile.random
+ label: tile.label
+ // Toggle assigns checked itself, which would break a plain binding
+ // and leave the tick stale after Reset.
+ Binding on checked { value: Transitions.draftPool.indexOf(tile.name) >= 0 }
+ onToggled: Transitions.toggle(tile.name)
+ }
+
+ Text {
+ anchors { top: thumb.bottom; topMargin: 8; left: parent.left }
+ visible: tile.random
+ text: tile.label
+ color: Theme.subtext
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 }
+ }
+}
diff --git a/desktop/modules/appearance/TransitionsModule.qml b/desktop/modules/appearance/TransitionsModule.qml
new file mode 100644
index 0000000..3ad56fb
--- /dev/null
+++ b/desktop/modules/appearance/TransitionsModule.qml
@@ -0,0 +1,43 @@
+// Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+import QtQuick
+import "../.."
+
+// The transitions page: which effect covers a wallpaper change.
+Module {
+ name: "transitions"
+ label: "Transitions"
+ // nf-fa-magic, present in Inconsolata Nerd Font.
+ icon: ""
+ settings: true
+ dirty: Transitions.dirty
+ group: "Appearance"
+ keywords: ["wallpaper", "transition", "effect", "burn", "ink", "shatter", "ripple", "melt", "blinds", "random"]
+
+ page: Component {
+ Page {
+ title: "Transitions"
+ actions: Component {
+ SaveBar {
+ dirty: Transitions.dirty
+ valid: Transitions.valid
+ note: "tick at least one transition for Random"
+ saveText: "Apply"
+ discardText: "Reset"
+ onSave: Transitions.apply()
+ onDiscard: Transitions.reset()
+ }
+ }
+ TransitionsTab { width: parent.width }
+ }
+ }
+}
diff --git a/desktop/modules/appearance/TransitionsTab.qml b/desktop/modules/appearance/TransitionsTab.qml
new file mode 100644
index 0000000..190a117
--- /dev/null
+++ b/desktop/modules/appearance/TransitionsTab.qml
@@ -0,0 +1,57 @@
+// Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+import QtQuick
+import "../.."
+
+Item {
+ id: tab
+ implicitHeight: col.implicitHeight
+
+ readonly property int gap: 14
+ readonly property int columns: Math.max(1, Math.floor((width + gap) / 260))
+ readonly property real tileWidth: (width - (columns - 1) * gap) / columns
+
+ Column {
+ id: col
+ width: parent.width
+ spacing: 14
+
+ Text {
+ width: col.width
+ wrapMode: Text.Wrap
+ text: "Click a transition to see it between your two current wallpapers. "
+ + "Random draws from the ticked ones, and never the same one twice running."
+ color: Theme.overlay
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 }
+ }
+
+ Grid {
+ columns: tab.columns
+ spacing: tab.gap
+
+ Repeater {
+ model: Transitions.all
+ TransitionTile {
+ required property var modelData
+ width: tab.tileWidth
+ name: modelData.name
+ label: modelData.label
+ }
+ }
+ TransitionTile {
+ width: tab.tileWidth
+ name: "random"
+ label: "Random"
+ }
+ }
+ }
+}
diff --git a/desktop/shell.qml b/desktop/shell.qml
index 660c4a5..44a31ca 100644
--- a/desktop/shell.qml
+++ b/desktop/shell.qml
@@ -87,6 +87,7 @@ ShellRoot {
NotesModule {},
WallpaperModule {},
WallEngineModule {},
+ TransitionsModule {},
ThemeModule {},
UdtModule {},
IconsModule {},