1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-11 07:52:50 -05:00
Files
DankMaterialShell/Services/WallpaperCyclingService.qml
2025-09-05 16:08:32 -04:00

240 lines
8.1 KiB
QML

pragma Singleton
pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import Quickshell.Io
import qs.Common
Singleton {
id: root
property bool cyclingActive: false
property string cachedCyclingTime: SessionData.wallpaperCyclingTime
property int cachedCyclingInterval: SessionData.wallpaperCyclingInterval
property string lastTimeCheck: ""
Component.onCompleted: {
updateCyclingState()
}
Connections {
target: SessionData
function onWallpaperCyclingEnabledChanged() {
updateCyclingState()
}
function onWallpaperCyclingModeChanged() {
updateCyclingState()
}
function onWallpaperCyclingIntervalChanged() {
cachedCyclingInterval = SessionData.wallpaperCyclingInterval
if (SessionData.wallpaperCyclingMode === "interval") {
updateCyclingState()
}
}
function onWallpaperCyclingTimeChanged() {
cachedCyclingTime = SessionData.wallpaperCyclingTime
if (SessionData.wallpaperCyclingMode === "time") {
updateCyclingState()
}
}
function onPerMonitorWallpaperChanged() {
updateCyclingState()
}
}
function updateCyclingState() {
if (SessionData.wallpaperCyclingEnabled && SessionData.wallpaperPath && !SessionData.perMonitorWallpaper) {
startCycling()
} else {
stopCycling()
}
}
function startCycling() {
if (SessionData.wallpaperCyclingMode === "interval") {
intervalTimer.interval = cachedCyclingInterval * 1000
intervalTimer.start()
cyclingActive = true
} else if (SessionData.wallpaperCyclingMode === "time") {
cyclingActive = true
checkTimeBasedCycling()
}
}
function stopCycling() {
intervalTimer.stop()
cyclingActive = false
}
function cycleToNextWallpaper(screenName, wallpaperPath) {
const currentWallpaper = wallpaperPath || SessionData.wallpaperPath
if (!currentWallpaper) return
const wallpaperDir = currentWallpaper.substring(0, currentWallpaper.lastIndexOf('/'))
cyclingProcess.command = ["sh", "-c", `ls -1 "${wallpaperDir}"/*.jpg "${wallpaperDir}"/*.jpeg "${wallpaperDir}"/*.png "${wallpaperDir}"/*.bmp "${wallpaperDir}"/*.gif "${wallpaperDir}"/*.webp 2>/dev/null | sort`]
cyclingProcess.targetScreenName = screenName || ""
cyclingProcess.currentWallpaper = currentWallpaper
cyclingProcess.running = true
}
function cycleToPrevWallpaper(screenName, wallpaperPath) {
const currentWallpaper = wallpaperPath || SessionData.wallpaperPath
if (!currentWallpaper) return
const wallpaperDir = currentWallpaper.substring(0, currentWallpaper.lastIndexOf('/'))
prevCyclingProcess.command = ["sh", "-c", `ls -1 "${wallpaperDir}"/*.jpg "${wallpaperDir}"/*.jpeg "${wallpaperDir}"/*.png "${wallpaperDir}"/*.bmp "${wallpaperDir}"/*.gif "${wallpaperDir}"/*.webp 2>/dev/null | sort`]
prevCyclingProcess.targetScreenName = screenName || ""
prevCyclingProcess.currentWallpaper = currentWallpaper
prevCyclingProcess.running = true
}
function cycleNextManually() {
if (SessionData.wallpaperPath) {
cycleToNextWallpaper()
// Restart timers if cycling is active
if (cyclingActive && SessionData.wallpaperCyclingEnabled) {
if (SessionData.wallpaperCyclingMode === "interval") {
intervalTimer.interval = cachedCyclingInterval * 1000
intervalTimer.restart()
}
}
}
}
function cyclePrevManually() {
if (SessionData.wallpaperPath) {
cycleToPrevWallpaper()
// Restart timers if cycling is active
if (cyclingActive && SessionData.wallpaperCyclingEnabled) {
if (SessionData.wallpaperCyclingMode === "interval") {
intervalTimer.interval = cachedCyclingInterval * 1000
intervalTimer.restart()
}
}
}
}
function cycleNextForMonitor(screenName) {
if (!screenName) return
var currentWallpaper = SessionData.getMonitorWallpaper(screenName)
if (currentWallpaper) {
cycleToNextWallpaper(screenName, currentWallpaper)
}
}
function cyclePrevForMonitor(screenName) {
if (!screenName) return
var currentWallpaper = SessionData.getMonitorWallpaper(screenName)
if (currentWallpaper) {
cycleToPrevWallpaper(screenName, currentWallpaper)
}
}
function checkTimeBasedCycling() {
const currentTime = Qt.formatTime(systemClock.date, "hh:mm")
if (currentTime === cachedCyclingTime
&& currentTime !== lastTimeCheck) {
lastTimeCheck = currentTime
cycleToNextWallpaper()
} else if (currentTime !== cachedCyclingTime) {
lastTimeCheck = ""
}
}
Timer {
id: intervalTimer
interval: cachedCyclingInterval * 1000
running: false
repeat: true
onTriggered: cycleToNextWallpaper()
}
SystemClock {
id: systemClock
precision: SystemClock.Minutes
onDateChanged: {
if (SessionData.wallpaperCyclingMode === "time" && cyclingActive) {
checkTimeBasedCycling()
}
}
}
Process {
id: cyclingProcess
property string targetScreenName: ""
property string currentWallpaper: ""
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text && text.trim()) {
const files = text.trim().split('\n').filter(file => file.length > 0)
if (files.length <= 1) return
const wallpaperList = files.sort()
const currentPath = cyclingProcess.currentWallpaper
let currentIndex = wallpaperList.findIndex(path => path === currentPath)
if (currentIndex === -1) currentIndex = 0
const nextIndex = (currentIndex + 1) % wallpaperList.length
const nextWallpaper = wallpaperList[nextIndex]
if (nextWallpaper && nextWallpaper !== currentPath) {
if (cyclingProcess.targetScreenName) {
SessionData.setMonitorWallpaper(cyclingProcess.targetScreenName, nextWallpaper)
} else {
SessionData.setWallpaper(nextWallpaper)
}
}
}
}
}
}
Process {
id: prevCyclingProcess
property string targetScreenName: ""
property string currentWallpaper: ""
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text && text.trim()) {
const files = text.trim().split('\n').filter(file => file.length > 0)
if (files.length <= 1) return
const wallpaperList = files.sort()
const currentPath = prevCyclingProcess.currentWallpaper
let currentIndex = wallpaperList.findIndex(path => path === currentPath)
if (currentIndex === -1) currentIndex = 0
const prevIndex = currentIndex === 0 ? wallpaperList.length - 1 : currentIndex - 1
const prevWallpaper = wallpaperList[prevIndex]
if (prevWallpaper && prevWallpaper !== currentPath) {
if (prevCyclingProcess.targetScreenName) {
SessionData.setMonitorWallpaper(prevCyclingProcess.targetScreenName, prevWallpaper)
} else {
SessionData.setWallpaper(prevWallpaper)
}
}
}
}
}
}
}