Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion modules/background/Background.qml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ Loader {
id: win

required property ShellScreen modelData

screen: modelData
name: "background"
WlrLayershell.exclusionMode: ExclusionMode.Ignore
Expand Down
65 changes: 65 additions & 0 deletions modules/background/ImageWallpaper.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
pragma ComponentBehavior: Bound

import qs.components
import qs.components.images
import qs.components.filedialog
import qs.services
import qs.config
import qs.utils
import QtQuick

Item {
id: root
anchors.fill: parent

property bool isCurrent: false

signal ready

function update(explicitSource) {
explicitSource = explicitSource.toString();
const target = explicitSource;

if (img.path === target && img.status === Image.Ready) {
console.log("Same path, emitting ready manually for:", target);
Qt.callLater(() => root.ready());
return;
}

img.path = target;

img.onStatusChanged.connect(function handler() {
if (img.status === Image.Ready) {
Qt.callLater(() => root.ready());
console.log("Called ready for: ", target);

img.onStatusChanged.disconnect(handler);
}
});
}

CachingImage {
id: img
anchors.fill: parent
asynchronous: true
fillMode: Image.PreserveAspectCrop
opacity: root.isCurrent ? 1 : 0
scale: Wallpapers.showPreview ? 1 : 0.8
states: State {
name: "visible"
when: root.isCurrent
PropertyChanges {
target: img
opacity: 1
scale: 1
}
}

transitions: Transition {
Anim {
target: img
properties: "opacity,scale"
}
}
}
}
104 changes: 104 additions & 0 deletions modules/background/VideoWallpaper.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
pragma ComponentBehavior: Bound

import qs.components
import qs.components.images
import qs.components.filedialog
import qs.services
import qs.config
import qs.utils
import QtQuick
import QtMultimedia

Item {
id: root
anchors.fill: parent

property string source: ""
property bool isCurrent: false

signal ready
signal failed

property string activePath: ""

function update(path) {
path = path.toString();
if (!path || path.trim() === "")
return;

root.source = path;
player.source = path;

console.log("update ⚠️ Switching video to:", path);

player.onMediaStatusChanged.connect(function handler() {
if (player.mediaStatus === MediaPlayer.BufferedMedia || player.mediaStatus === MediaPlayer.LoadedMedia) {
if (root.source === path) {
console.log("Media loaded LoadedMedia, emitting ready:", path);
Qt.callLater(() => root.ready());
player.onMediaStatusChanged.disconnect(handler);
}
}
});

player.play();
}

MediaPlayer {
id: player

autoPlay: false
loops: MediaPlayer.Infinite

videoOutput: video
audioOutput: AudioOutput {}

onErrorOccurred: root.failed()

function tryPlayVideo() {
if (root.isCurrent) {
if (source && mediaStatus !== MediaPlayer.PlayingState) {
console.log("Starting video:", source);
play();
}
} else {
if (mediaStatus !== MediaPlayer.NoMedia) {
console.log("Stopping video:", source);
stop();
// source = "";
}
}
}
}

VideoOutput {
id: video
anchors.fill: parent
opacity: root.isCurrent ? 1 : 0
scale: Wallpapers.showPreview ? 1 : 0.8
}

states: State {
name: "visible"
when: root.isCurrent
PropertyChanges {
target: video
opacity: 1
scale: 1
}
}

transitions: Transition {
Anim {
target: video
properties: "opacity,scale"
}
}

Connections {
target: root
function onIsCurrentChanged() {
player.tryPlayVideo();
}
}
}
Loading