diff options
| author | Nippy <nippy@rp1.hu> | 2026-05-08 19:50:49 +0200 |
|---|---|---|
| committer | Nippy <nippy@rp1.hu> | 2026-05-08 19:50:49 +0200 |
| commit | 3462bcc46ecf74f576ea4397f16492c16bd75b10 (patch) | |
| tree | c5ab7aef4498647e057bda8d49c11e5f9dda74c9 /raveos-hyprland-theme/theme-data/dms/Modules/Lock/VideoScreensaver.qml | |
| parent | 56616f693b4f263cbf0d47da43b67424efa6022d (diff) | |
| download | RaveOS-PKGBUILD-3462bcc46ecf74f576ea4397f16492c16bd75b10.tar.gz RaveOS-PKGBUILD-3462bcc46ecf74f576ea4397f16492c16bd75b10.zip | |
raveos update
Diffstat (limited to 'raveos-hyprland-theme/theme-data/dms/Modules/Lock/VideoScreensaver.qml')
| -rw-r--r-- | raveos-hyprland-theme/theme-data/dms/Modules/Lock/VideoScreensaver.qml | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/raveos-hyprland-theme/theme-data/dms/Modules/Lock/VideoScreensaver.qml b/raveos-hyprland-theme/theme-data/dms/Modules/Lock/VideoScreensaver.qml new file mode 100644 index 0000000..129f507 --- /dev/null +++ b/raveos-hyprland-theme/theme-data/dms/Modules/Lock/VideoScreensaver.qml @@ -0,0 +1,200 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import Quickshell.Io +import qs.Common +import qs.Services + +Item { + id: root + + required property string screenName + property bool active: false + property string videoSource: "" + property bool inputEnabled: false + property point lastMousePos: Qt.point(-1, -1) + property bool mouseInitialized: false + property var videoPlayer: null + + signal dismissed + + visible: active + z: 1000 + + Rectangle { + id: background + anchors.fill: parent + color: "black" + visible: root.active + } + + Timer { + id: inputEnableTimer + interval: 500 + onTriggered: root.inputEnabled = true + } + + Process { + id: videoPicker + property string result: "" + property string folder: "" + + command: ["sh", "-c", "find '" + folder + "' -maxdepth 1 -type f \\( " + "-iname '*.mp4' -o -iname '*.mkv' -o -iname '*.webm' -o " + "-iname '*.mov' -o -iname '*.avi' -o -iname '*.m4v' " + "\\) 2>/dev/null | shuf -n1"] + + stdout: SplitParser { + onRead: data => { + const path = data.trim(); + if (path) { + videoPicker.result = path; + root.videoSource = "file://" + path; + } + } + } + + onExited: exitCode => { + if (exitCode !== 0 || !videoPicker.result) { + console.warn("VideoScreensaver: no video found in folder"); + ToastService.showError(I18n.tr("Video Screensaver"), I18n.tr("No video found in folder")); + root.dismiss(); + } + } + } + + Process { + id: fileChecker + command: ["test", "-d", SettingsData.lockScreenVideoPath] + + onExited: exitCode => { + const isDir = exitCode === 0; + const videoPath = SettingsData.lockScreenVideoPath; + + if (isDir) { + videoPicker.folder = videoPath; + videoPicker.running = true; + } else if (SettingsData.lockScreenVideoCycling) { + const parentFolder = videoPath.substring(0, videoPath.lastIndexOf('/')); + videoPicker.folder = parentFolder; + videoPicker.running = true; + } else { + root.videoSource = "file://" + videoPath; + } + } + } + + function createVideoPlayer() { + if (videoPlayer) + return true; + + try { + videoPlayer = Qt.createQmlObject(` + import QtQuick + import QtMultimedia + Video { + anchors.fill: parent + fillMode: VideoOutput.PreserveAspectCrop + loops: MediaPlayer.Infinite + volume: 0 + } + `, background, "VideoScreensaver.VideoPlayer"); + + videoPlayer.errorOccurred.connect((error, errorString) => { + console.warn("VideoScreensaver: playback error:", errorString); + ToastService.showError(I18n.tr("Video Screensaver"), I18n.tr("Playback error: ") + errorString); + root.dismiss(); + }); + + return true; + } catch (e) { + console.warn("VideoScreensaver: Failed to create video player:", e); + return false; + } + } + + function destroyVideoPlayer() { + if (videoPlayer) { + videoPlayer.stop(); + videoPlayer.destroy(); + videoPlayer = null; + } + } + + function start() { + if (!SettingsData.lockScreenVideoEnabled || !SettingsData.lockScreenVideoPath) + return; + + if (!MultimediaService.available) { + ToastService.showError(I18n.tr("Video Screensaver"), I18n.tr("QtMultimedia is not available")); + return; + } + + if (!createVideoPlayer()) + return; + + videoPicker.result = ""; + videoPicker.folder = ""; + inputEnabled = false; + mouseInitialized = false; + lastMousePos = Qt.point(-1, -1); + active = true; + inputEnableTimer.start(); + fileChecker.running = true; + } + + function dismiss() { + if (!active) + return; + destroyVideoPlayer(); + inputEnabled = false; + active = false; + videoSource = ""; + dismissed(); + } + + onVideoSourceChanged: { + if (videoSource && active && videoPlayer) { + videoPlayer.source = videoSource; + videoPlayer.play(); + } + } + + MouseArea { + id: mouseArea + anchors.fill: parent + enabled: root.active && root.inputEnabled + hoverEnabled: true + propagateComposedEvents: false + + onPositionChanged: mouse => { + if (!root.mouseInitialized) { + root.lastMousePos = Qt.point(mouse.x, mouse.y); + root.mouseInitialized = true; + return; + } + var dx = Math.abs(mouse.x - root.lastMousePos.x); + var dy = Math.abs(mouse.y - root.lastMousePos.y); + if (dx > 5 || dy > 5) { + root.dismiss(); + } + } + onClicked: root.dismiss() + onPressed: root.dismiss() + onWheel: root.dismiss() + } + + Connections { + target: IdleService + + function onLockRequested() { + if (SettingsData.lockScreenVideoEnabled && !root.active) { + root.start(); + } + } + + function onFadeToLockRequested() { + if (SettingsData.lockScreenVideoEnabled && !root.active) { + IdleService.cancelFadeToLock(); + root.start(); + } + } + } +} |