Add event-driven wallpaper rotation
This commit is contained in:
@@ -20,6 +20,13 @@ Singleton {
|
||||
property bool scanning: false
|
||||
property var transaction: null
|
||||
property bool startupRestoreEnabled: true
|
||||
property var outputOverride: null
|
||||
property var candidateOverride: null
|
||||
property string slideshowPath: ""
|
||||
property int slideshowIndex: -1
|
||||
property var shuffleBag: []
|
||||
property int slideshowIntervalOverrideMs: 0
|
||||
property bool pendingHotplugReapply: false
|
||||
|
||||
readonly property string configured: DesktopPreferences.get("wallpaperPath")
|
||||
readonly property string shippedPath: `${Quickshell.env("HOME")}/Pictures/Wallpapers/faroe_islands.jpg`
|
||||
@@ -32,8 +39,14 @@ Singleton {
|
||||
}
|
||||
readonly property bool busy: root.transaction !== null
|
||||
|| applyProcess.running || verifyProcess.running
|
||||
readonly property var slideshowCollection: WallpaperPolicy.validCollection(
|
||||
DesktopPreferences.get("wallpaperSlideshowPaths") ?? [], root.candidates([]))
|
||||
readonly property bool slideshowTimerRunning: slideshowTimer.running
|
||||
readonly property string outputSignature: root.outputNames().slice().sort().join("|")
|
||||
|
||||
property var outputNames: function() {
|
||||
if (Array.isArray(root.outputOverride))
|
||||
return root.outputOverride.slice();
|
||||
return Quickshell.screens.map(screen => screen.name).filter(name => !!name);
|
||||
}
|
||||
|
||||
@@ -79,6 +92,7 @@ Singleton {
|
||||
if (exitCode !== 0) {
|
||||
root.lastError = "Hyprpaper did not apply that background.";
|
||||
root.transaction = null;
|
||||
root.schedulePendingHotplug();
|
||||
return;
|
||||
}
|
||||
root.drainTransaction();
|
||||
@@ -110,6 +124,34 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: slideshowTimer
|
||||
interval: root.slideshowIntervalOverrideMs > 0
|
||||
? root.slideshowIntervalOverrideMs
|
||||
: DesktopPreferences.get("wallpaperIntervalMinutes") * 60000
|
||||
repeat: true
|
||||
running: DesktopPreferences.get("wallpaperMode") === "slideshow"
|
||||
&& root.slideshowCollection.length >= 2 && !root.busy
|
||||
onTriggered: root.advanceSlideshow()
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: outputSettle
|
||||
interval: 350
|
||||
onTriggered: {
|
||||
if (root.busy) {
|
||||
root.pendingHotplugReapply = true;
|
||||
return;
|
||||
}
|
||||
root.applyCurrentPolicy(false);
|
||||
}
|
||||
}
|
||||
|
||||
onOutputSignatureChanged: {
|
||||
if (Object.keys(root.activeByOutput).length > 0)
|
||||
outputSettle.restart();
|
||||
}
|
||||
|
||||
function rescan(): void {
|
||||
if (scan.running)
|
||||
return;
|
||||
@@ -124,7 +166,9 @@ Singleton {
|
||||
|
||||
function candidates(extra: var): var {
|
||||
const result = [];
|
||||
for (const path of root.available.concat([root.shippedPath, root.configured]).concat(extra || [])) {
|
||||
const discovered = Array.isArray(root.candidateOverride)
|
||||
? root.candidateOverride : root.available;
|
||||
for (const path of discovered.concat([root.shippedPath, root.configured]).concat(extra || [])) {
|
||||
if (typeof path === "string" && /^\/[^,\n]+$/.test(path) && !result.includes(path))
|
||||
result.push(path);
|
||||
}
|
||||
@@ -139,7 +183,7 @@ Singleton {
|
||||
intervalMinutes: DesktopPreferences.get("wallpaperIntervalMinutes") ?? 30,
|
||||
shuffle: DesktopPreferences.get("wallpaperShuffle") !== false,
|
||||
assignments: DesktopPreferences.get("wallpaperPerMonitor") ?? ({}),
|
||||
slideshowPath: root.active
|
||||
slideshowPath: root.slideshowPath !== "" ? root.slideshowPath : root.active
|
||||
};
|
||||
}
|
||||
|
||||
@@ -165,6 +209,10 @@ Singleton {
|
||||
assignments: WallpaperPolicy.validAssignments(policy.assignments || {}, candidatePaths),
|
||||
slideshowPath: WallpaperPolicy.validPath(policy.slideshowPath, candidatePaths)
|
||||
? policy.slideshowPath : rawGlobal,
|
||||
nextShuffleBag: Array.isArray(policy.nextShuffleBag)
|
||||
? policy.nextShuffleBag.slice() : root.shuffleBag.slice(),
|
||||
nextSlideshowIndex: Number.isInteger(policy.nextSlideshowIndex)
|
||||
? policy.nextSlideshowIndex : root.slideshowIndex,
|
||||
candidates: candidatePaths
|
||||
};
|
||||
}
|
||||
@@ -240,6 +288,7 @@ Singleton {
|
||||
if (!matches) {
|
||||
root.lastError = "Hyprpaper did not confirm that background.";
|
||||
root.transaction = null;
|
||||
root.schedulePendingHotplug();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -247,8 +296,14 @@ Singleton {
|
||||
root.activeByOutput = observed;
|
||||
root.transaction = null;
|
||||
root.lastError = "";
|
||||
if (completed.automatic) {
|
||||
root.slideshowPath = completed.policy.slideshowPath;
|
||||
root.shuffleBag = completed.policy.nextShuffleBag;
|
||||
root.slideshowIndex = completed.policy.nextSlideshowIndex;
|
||||
}
|
||||
if (completed.persist)
|
||||
root.persistPolicy(completed.policy);
|
||||
root.schedulePendingHotplug();
|
||||
}
|
||||
|
||||
function persistPolicy(policy: var): void {
|
||||
@@ -264,6 +319,41 @@ Singleton {
|
||||
return root.applyPolicy(root.currentPolicy(), persist === true, false);
|
||||
}
|
||||
|
||||
function schedulePendingHotplug(): void {
|
||||
if (!root.pendingHotplugReapply)
|
||||
return;
|
||||
root.pendingHotplugReapply = false;
|
||||
outputSettle.restart();
|
||||
}
|
||||
|
||||
function advanceSlideshow(): bool {
|
||||
if (root.busy)
|
||||
return false;
|
||||
const collection = root.slideshowCollection;
|
||||
if (collection.length < 2)
|
||||
return false;
|
||||
|
||||
const current = root.slideshowPath !== ""
|
||||
? root.slideshowPath
|
||||
: (root.active !== "" ? root.active : collection[0]);
|
||||
const policy = root.currentPolicy();
|
||||
policy.mode = "slideshow";
|
||||
policy.collection = collection;
|
||||
|
||||
if (DesktopPreferences.get("wallpaperShuffle") !== false) {
|
||||
const next = WallpaperPolicy.shuffledNext(
|
||||
collection, root.shuffleBag, current, Math.random);
|
||||
policy.slideshowPath = next.path;
|
||||
policy.nextShuffleBag = next.bag;
|
||||
policy.nextSlideshowIndex = collection.indexOf(next.path);
|
||||
} else {
|
||||
policy.slideshowPath = WallpaperPolicy.orderedNext(collection, current);
|
||||
policy.nextShuffleBag = [];
|
||||
policy.nextSlideshowIndex = collection.indexOf(policy.slideshowPath);
|
||||
}
|
||||
return root.applyPolicy(policy, false, true);
|
||||
}
|
||||
|
||||
function setSingle(path: string): bool {
|
||||
const effectivePath = path === "" ? root.shippedPath : path;
|
||||
const allowed = root.candidates([]);
|
||||
|
||||
@@ -7,8 +7,10 @@ import qs.services
|
||||
|
||||
ShellRoot {
|
||||
Component.onCompleted: {
|
||||
Wallpaper.outputNames = function() { return ["DP-2", "HDMI-A-1"]; };
|
||||
Wallpaper.outputOverride = ["DP-2", "HDMI-A-1"];
|
||||
Wallpaper.candidateOverride = ["/images/a.jpg", "/images/b.jpg", "/images/c.jpg"];
|
||||
Wallpaper.startupRestoreEnabled = false;
|
||||
Wallpaper.slideshowIntervalOverrideMs = 60000;
|
||||
Wallpaper.available = ["/images/a.jpg", "/images/b.jpg", "/images/c.jpg"];
|
||||
}
|
||||
|
||||
@@ -31,6 +33,25 @@ ShellRoot {
|
||||
return Wallpaper.set(path);
|
||||
}
|
||||
|
||||
function seedSlideshow(paths: string, shuffle: bool): void {
|
||||
DesktopPreferences.set("wallpaperMode", "slideshow");
|
||||
DesktopPreferences.set("wallpaperPath", "/images/a.jpg");
|
||||
DesktopPreferences.set("wallpaperSlideshowPaths", JSON.parse(paths));
|
||||
DesktopPreferences.set("wallpaperShuffle", shuffle);
|
||||
Wallpaper.slideshowPath = "/images/a.jpg";
|
||||
Wallpaper.shuffleBag = [];
|
||||
}
|
||||
|
||||
function advanceSlideshow(): bool {
|
||||
return Wallpaper.advanceSlideshow();
|
||||
}
|
||||
|
||||
function rapidOutputs(): void {
|
||||
Wallpaper.outputOverride = ["DP-2"];
|
||||
Wallpaper.outputOverride = ["HDMI-A-1"];
|
||||
Wallpaper.outputOverride = ["DP-2", "HDMI-A-1"];
|
||||
}
|
||||
|
||||
function status(): string {
|
||||
return JSON.stringify({
|
||||
busy: Wallpaper.busy,
|
||||
@@ -39,7 +60,10 @@ ShellRoot {
|
||||
active: Wallpaper.active,
|
||||
mode: DesktopPreferences.get("wallpaperMode"),
|
||||
path: DesktopPreferences.get("wallpaperPath"),
|
||||
assignments: DesktopPreferences.get("wallpaperPerMonitor")
|
||||
assignments: DesktopPreferences.get("wallpaperPerMonitor"),
|
||||
slideshowPath: Wallpaper.slideshowPath,
|
||||
shuffleBag: Wallpaper.shuffleBag,
|
||||
slideshowTimerRunning: Wallpaper.slideshowTimerRunning
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user