diff --git a/Services/IdleService.qml b/Services/IdleService.qml index 2b4b703c..16db7809 100644 --- a/Services/IdleService.qml +++ b/Services/IdleService.qml @@ -28,118 +28,32 @@ Singleton { readonly property int suspendTimeout: isOnBattery ? SessionData.batterySuspendTimeout : SessionData.acSuspendTimeout readonly property int hibernateTimeout: isOnBattery ? SessionData.batteryHibernateTimeout : SessionData.acHibernateTimeout - readonly property int firstTimeout: { - const timeouts = [] - if (monitorTimeout > 0) timeouts.push(monitorTimeout) - if (lockTimeout > 0) timeouts.push(lockTimeout) - if (suspendTimeout > 0) timeouts.push(suspendTimeout) - if (hibernateTimeout > 0) timeouts.push(hibernateTimeout) - return timeouts.length > 0 ? Math.min(...timeouts) : 0 - } + onMonitorTimeoutChanged: _rearmIdleMonitors() + onLockTimeoutChanged: _rearmIdleMonitors() + onSuspendTimeoutChanged: _rearmIdleMonitors() + onHibernateTimeoutChanged: _rearmIdleMonitors() - property int currentStepIndex: -1 - property var steps: [] + function _rearmIdleMonitors() { + _enableGate = false + Qt.callLater(() => { _enableGate = true }) + } signal lockRequested() signal requestMonitorOff() signal requestMonitorOn() signal requestSuspend() signal requestHibernate() - signal stageFired(string name) - onFirstTimeoutChanged: { - if (idleMonitor) _rearmIdleMonitor() - } - - function _rearmIdleMonitor() { - cancel() - - _enableGate = false - Qt.callLater(() => { _enableGate = true }) - } - - function makeSteps() { - const steps = [] - if (lockTimeout > 0) { - steps.push({name: "lock", delaySec: lockTimeout}) - } - if (monitorTimeout > 0) { - steps.push({name: "monitor-off", delaySec: monitorTimeout}) - } - if (suspendTimeout > 0) { - steps.push({name: "suspend", delaySec: suspendTimeout}) - } - if (hibernateTimeout > 0) { - steps.push({name: "hibernate", delaySec: hibernateTimeout}) - } - return steps.sort((a, b) => a.delaySec - b.delaySec) - } - - function start() { - if (!enabled || !idleMonitorAvailable) return - if (currentStepIndex !== -1) return - - steps = makeSteps() - currentStepIndex = -1 - next() - } - - function next() { - if (++currentStepIndex >= steps.length) return - - const currentStep = steps[currentStepIndex] - - const firstStepDelay = steps[0].delaySec - const relativeDelay = currentStep.delaySec - firstStepDelay - const ms = (relativeDelay * 1000) | 0 - - if (ms > 0) { - stepTimer.interval = ms - stepTimer.restart() - } else { - Qt.callLater(run) - } - } - - function run() { - const currentStep = steps[currentStepIndex] - if (!currentStep) return - - console.log("IdleService: Executing step:", currentStep.name) - - if (currentStep.name === "lock") { - lockRequested() - } else if (currentStep.name === "monitor-off") { - requestMonitorOff() - } else if (currentStep.name === "suspend") { - requestSuspend() - } else if (currentStep.name === "hibernate") { - requestHibernate() - } - - stageFired(currentStep.name) - next() - } - - function cancel() { - stepTimer.stop() - currentStepIndex = -1 - } + property var monitorOffMonitor: null + property var lockMonitor: null + property var suspendMonitor: null + property var hibernateMonitor: null function wake() { - cancel() requestMonitorOn() } - Timer { - id: stepTimer - repeat: false - onTriggered: root.run() - } - - property var idleMonitor: null - - function createIdleMonitor() { + function createIdleMonitors() { if (!idleMonitorAvailable) { console.log("IdleService: IdleMonitor not available, skipping creation") return @@ -157,27 +71,57 @@ Singleton { } ` - idleMonitor = Qt.createQmlObject(qmlString, root, "IdleService.IdleMonitor") - - if (idleMonitor) { - idleMonitor.enabled = Qt.binding( - () => root._enableGate && root.enabled && root.idleMonitorAvailable && root.firstTimeout > 0 - ) - idleMonitor.respectInhibitors = Qt.binding(() => root.respectInhibitors) - idleMonitor.timeout = Qt.binding(() => root.firstTimeout) - - idleMonitor.isIdleChanged.connect(function() { - if (idleMonitor.isIdle) { - console.log("IdleService: User is idle, starting power management") - Qt.callLater(root.start) + if (monitorTimeout > 0) { + monitorOffMonitor = Qt.createQmlObject(qmlString, root, "IdleService.MonitorOffMonitor") + monitorOffMonitor.enabled = Qt.binding(() => root._enableGate && root.enabled && root.idleMonitorAvailable && root.monitorTimeout > 0) + monitorOffMonitor.respectInhibitors = Qt.binding(() => root.respectInhibitors) + monitorOffMonitor.timeout = Qt.binding(() => root.monitorTimeout) + monitorOffMonitor.isIdleChanged.connect(function() { + if (monitorOffMonitor.isIdle) { + root.requestMonitorOff() } else { - console.log("IdleService: User is active, canceling power management") - Qt.callLater(root.cancel) + root.requestMonitorOn() + } + }) + } + + if (lockTimeout > 0) { + lockMonitor = Qt.createQmlObject(qmlString, root, "IdleService.LockMonitor") + lockMonitor.enabled = Qt.binding(() => root._enableGate && root.enabled && root.idleMonitorAvailable && root.lockTimeout > 0) + lockMonitor.respectInhibitors = Qt.binding(() => root.respectInhibitors) + lockMonitor.timeout = Qt.binding(() => root.lockTimeout) + lockMonitor.isIdleChanged.connect(function() { + if (lockMonitor.isIdle) { + root.lockRequested() + } + }) + } + + if (suspendTimeout > 0) { + suspendMonitor = Qt.createQmlObject(qmlString, root, "IdleService.SuspendMonitor") + suspendMonitor.enabled = Qt.binding(() => root._enableGate && root.enabled && root.idleMonitorAvailable && root.suspendTimeout > 0) + suspendMonitor.respectInhibitors = Qt.binding(() => root.respectInhibitors) + suspendMonitor.timeout = Qt.binding(() => root.suspendTimeout) + suspendMonitor.isIdleChanged.connect(function() { + if (suspendMonitor.isIdle) { + root.requestSuspend() + } + }) + } + + if (hibernateTimeout > 0) { + hibernateMonitor = Qt.createQmlObject(qmlString, root, "IdleService.HibernateMonitor") + hibernateMonitor.enabled = Qt.binding(() => root._enableGate && root.enabled && root.idleMonitorAvailable && root.hibernateTimeout > 0) + hibernateMonitor.respectInhibitors = Qt.binding(() => root.respectInhibitors) + hibernateMonitor.timeout = Qt.binding(() => root.hibernateTimeout) + hibernateMonitor.isIdleChanged.connect(function() { + if (hibernateMonitor.isIdle) { + root.requestHibernate() } }) } } catch (e) { - console.warn("IdleService: Error creating IdleMonitor:", e) + console.warn("IdleService: Error creating IdleMonitors:", e) } } @@ -205,7 +149,7 @@ Singleton { console.warn("IdleService: IdleMonitor not available - power management disabled. This requires a newer version of Quickshell.") } else { console.log("IdleService: Initialized with idle monitoring support") - createIdleMonitor() + createIdleMonitors() } } } \ No newline at end of file