Files
omarchy/shell/Ui/BackgroundMedia.qml
T
Bjarne Oeverli dbebc458db Replace the desktop video path with OWE
The desktop background no longer plays videos. OWE owns video
backgrounds, and the shell layer stays empty behind one. The shell keeps
stills, which OWE hands back to it.

Remove the desktop video pause plumbing that only existed to stop an
unseen player: the lock, idle, and battery service lookups, the
per-output fullscreen check, the first-screen audio opt-in, and the audio
output in BackgroundVideo. The lock screen keeps its own silent playback.

Update the background tests, the manual, and the package note.
2026-09-18 18:46:17 +02:00

83 lines
2.8 KiB
QML

import QtQuick
import qs.Commons
Item {
id: root
property string path: ""
property int version: 0
property bool playbackEnabled: true
// The desktop turns this off because OWE owns video backgrounds. The lock
// screen leaves it on and keeps its own playback.
property bool videoEnabled: true
// Bumped when the file behind an unchanged path may have been replaced.
// Images cache-bust through version; a video is rebuilt, since FFmpeg
// would read a query as part of the filename.
property int reloads: 0
property bool reloading: false
readonly property var current: video ? videoLoader.item : imageLoader.item
readonly property bool ready: current ? current.ready : false
readonly property bool video: Util.isVideoPath(path)
// Cache-bust images selected in a running lock session. FFmpeg treats the
// query as part of a local filename, so videos must keep their plain URL.
// Each URL is empty for the other kind, so a switch never hands the still
// loader a video, or the player a still, in the moment before it unloads.
// Both test the path directly: going through `video` lets a URL evaluate
// against the stale flag and leak the wrong file for one pass.
readonly property url imageUrl: path && !Util.isVideoPath(path) ? Util.fileUrl(path) + (version ? "?v=" + version : "") : ""
readonly property url videoUrl: path && Util.isVideoPath(path) && videoEnabled ? Util.fileUrl(path) : ""
Loader {
id: imageLoader
anchors.fill: parent
active: root.path !== "" && !root.video
sourceComponent: imageComponent
}
// Loaded by URL rather than from a Component here, so QtMultimedia and its
// audio dependency closure never map into a session that only shows images.
Loader {
id: videoLoader
anchors.fill: parent
active: root.path !== "" && root.video && !root.reloading && root.videoEnabled
source: "BackgroundVideo.qml"
}
onReloadsChanged: {
if (!video) return
reloading = true
Qt.callLater(function() { root.reloading = false })
}
// A player on its way out keeps its source: pushing an empty one starts a
// load of nothing that its destructor then cancels, which FFmpeg logs.
Binding {
target: videoLoader.item
property: "mediaSource"
value: root.videoUrl
when: videoLoader.item !== null && Util.isVideoPath(root.path)
restoreMode: Binding.RestoreNone
}
Binding {
target: videoLoader.item
property: "playbackEnabled"
value: root.playbackEnabled
when: videoLoader.item !== null
}
Component {
id: imageComponent
Image {
readonly property bool ready: status === Image.Ready
source: root.imageUrl
fillMode: Image.PreserveAspectCrop
asynchronous: true
cache: root.version === 0
sourceSize.width: root.version > 0 ? width : 0
sourceSize.height: root.version > 0 ? height : 0
}
}
}