Never leave the desktop without a wallpaper after a theme intro (#15000)
A theme switch that plays an intro gave the shell the new still only when the intro failed. The shell kept the old theme's path, which the theme swap deletes, and loaded it again when OWE handed the desktop back, leaving it empty. The new still is now handed over either way. The shell also re-reads the background link whenever OWE hands the desktop back or a wallpaper fails to load, falling back to the theme's first background when the link itself is broken. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
754d2d04b3
commit
1ac31e55ae
5 files changed
+70
-8
No files matched your search
@@ -18,6 +18,8 @@ Item {
|
||||
property size decodeSize: Qt.size(0, 0)
|
||||
readonly property var current: imageLoader.item
|
||||
readonly property bool ready: current ? current.ready : false
|
||||
// The file behind path could not be loaded, as when it was deleted.
|
||||
readonly property bool failed: current ? current.failed : false
|
||||
readonly property bool video: Util.isVideoPath(path)
|
||||
// Cache-bust images selected in a running lock session, so a theme switch
|
||||
// that replaces the file behind an unchanged path shows the new pixels.
|
||||
@@ -35,6 +37,7 @@ Item {
|
||||
|
||||
Image {
|
||||
readonly property bool ready: status === Image.Ready
|
||||
readonly property bool failed: status === Image.Error
|
||||
source: !root.constrainDecode || root.decodeSize.width > 0 ? root.imageUrl : ""
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
asynchronous: true
|
||||
|
||||
@@ -16,6 +16,7 @@ Item {
|
||||
readonly property string home: Quickshell.env("HOME")
|
||||
readonly property string stateHome: home + "/.local/state"
|
||||
readonly property string currentBackgroundLink: stateHome + "/omarchy/current/background"
|
||||
readonly property string currentThemeBackgrounds: stateHome + "/omarchy/current/theme/backgrounds"
|
||||
|
||||
property string currentBackground: ""
|
||||
property string displayedBackground: ""
|
||||
@@ -66,6 +67,36 @@ Item {
|
||||
if (!readlinkProc.running) readlinkProc.running = true
|
||||
}
|
||||
|
||||
// The desktop must never be left without a wallpaper. A path that stops
|
||||
// loading, say one that ran through a theme since replaced, is resolved
|
||||
// again from the background link, which a theme switch always repoints.
|
||||
// Only a different path is taken, so a file that is there but unreadable
|
||||
// cannot loop. Resolving runs out of process, so a background chosen in the
|
||||
// meantime wins over what it finds; if that one fails too, it is resolved
|
||||
// in turn once the running lookup is done.
|
||||
property string failedBackground: ""
|
||||
property int recoverVersion: -1
|
||||
|
||||
function recoverBackground(failedPath) {
|
||||
if (!failedPath || failedPath !== displayedBackground) return
|
||||
failedBackground = failedPath
|
||||
if (recoverProc.running) return
|
||||
recoverVersion = backgroundVersion
|
||||
recoverProc.running = true
|
||||
}
|
||||
|
||||
function finishRecovery(path) {
|
||||
path = String(path || "").trim()
|
||||
var failedPath = failedBackground
|
||||
failedBackground = ""
|
||||
if (recoverVersion !== backgroundVersion) {
|
||||
recoverBackground(failedPath)
|
||||
return
|
||||
}
|
||||
if (!path || path === failedPath) return
|
||||
setBackground(path, true)
|
||||
}
|
||||
|
||||
function setBackground(path, instant) {
|
||||
if (instant) reloadVersion += 1
|
||||
transitionBackground("", path, path, instant, instant)
|
||||
@@ -85,6 +116,7 @@ Item {
|
||||
requestNativeSize(finalPath)
|
||||
currentBackground = finalPath
|
||||
backgroundVersion += 1
|
||||
failedBackground = ""
|
||||
revealStartedVersion = -1
|
||||
|
||||
revealAnimation.stop()
|
||||
@@ -220,6 +252,21 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
// The link's target when it exists, or else the theme's first background,
|
||||
// so a link left dangling still finds a wallpaper.
|
||||
Process {
|
||||
id: recoverProc
|
||||
command: [
|
||||
"bash", "-c",
|
||||
'target=$(readlink -f "$1"); if [[ -e $target ]]; then echo "$target"; else ' +
|
||||
'find "$2" -maxdepth 1 -type f \\( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.webp" \\) | sort | head -n 1; fi',
|
||||
"resolve", root.currentBackgroundLink, root.currentThemeBackgrounds
|
||||
]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: root.finishRecovery(text)
|
||||
}
|
||||
}
|
||||
|
||||
ShellIpc {
|
||||
target: "background"
|
||||
|
||||
@@ -365,6 +412,7 @@ Item {
|
||||
cached: true
|
||||
constrainDecode: true
|
||||
decodeSize: panel.decodeSize(root.displayedBackground)
|
||||
onFailedChanged: if (failed) root.recoverBackground(path)
|
||||
onReadyChanged: {
|
||||
panel.readyFrames = 0
|
||||
if (ready && root.finishingTransition) {
|
||||
|
||||
Reference in new issue
Block a user