noctalia-shell/Services/IdleInhibitorService.qml
LemmyCook 7d2eaa46e6 qmlfmt: increase line-length to 360 to avoid hard-wrap.
+ cleaned up power menu/panel
2025-09-12 21:07:11 -04:00

182 lines
4.8 KiB
QML

pragma Singleton
import QtQuick
import Quickshell
import Quickshell.Io
import qs.Commons
import qs.Services
Singleton {
id: root
property bool isInhibited: false
property string reason: "User requested"
property var activeInhibitors: []
// Different inhibitor strategies
property string strategy: "systemd" // "systemd", "wayland", or "auto"
Component.onCompleted: {
Logger.log("IdleInhibitor", "Service started")
detectStrategy()
// Restore previous state from settings
if (Settings.data.ui.idleInhibitorEnabled) {
addInhibitor("manual", "Restored from previous session")
Logger.log("IdleInhibitor", "Restored previous manual inhibition state")
}
}
// Auto-detect the best strategy
function detectStrategy() {
if (strategy === "auto") {
// Check if systemd-inhibit is available
try {
var systemdResult = Quickshell.execDetached(["which", "systemd-inhibit"])
strategy = "systemd"
Logger.log("IdleInhibitor", "Using systemd-inhibit strategy")
return
} catch (e) {
// systemd-inhibit not found, try Wayland tools
}
try {
var waylandResult = Quickshell.execDetached(["which", "wayhibitor"])
strategy = "wayland"
Logger.log("IdleInhibitor", "Using wayhibitor strategy")
return
} catch (e) {
// wayhibitor not found
}
Logger.warn("IdleInhibitor", "No suitable inhibitor found - will try systemd as fallback")
strategy = "systemd" // Fallback to systemd even if not detected
}
}
// Add an inhibitor
function addInhibitor(id, reason = "Application request") {
if (activeInhibitors.includes(id)) {
Logger.warn("IdleInhibitor", "Inhibitor already active:", id)
return false
}
activeInhibitors.push(id)
updateInhibition(reason)
Logger.log("IdleInhibitor", "Added inhibitor:", id)
return true
}
// Remove an inhibitor
function removeInhibitor(id) {
const index = activeInhibitors.indexOf(id)
if (index === -1) {
Logger.warn("IdleInhibitor", "Inhibitor not found:", id)
return false
}
activeInhibitors.splice(index, 1)
updateInhibition()
Logger.log("IdleInhibitor", "Removed inhibitor:", id)
return true
}
// Update the actual system inhibition
function updateInhibition(newReason = reason) {
const shouldInhibit = activeInhibitors.length > 0
if (shouldInhibit === isInhibited) {
return
// No change needed
}
if (shouldInhibit) {
startInhibition(newReason)
} else {
stopInhibition()
}
}
// Start system inhibition
function startInhibition(newReason) {
reason = newReason
if (strategy === "systemd") {
startSystemdInhibition()
} else if (strategy === "wayland") {
startWaylandInhibition()
} else {
Logger.warn("IdleInhibitor", "No inhibition strategy available")
return
}
isInhibited = true
Logger.log("IdleInhibitor", "Started inhibition:", reason)
}
// Stop system inhibition
function stopInhibition() {
if (!isInhibited)
return
if (inhibitorProcess.running) {
inhibitorProcess.signal(15) // SIGTERM
}
isInhibited = false
Logger.log("IdleInhibitor", "Stopped inhibition")
}
// Systemd inhibition using systemd-inhibit
function startSystemdInhibition() {
inhibitorProcess.command = ["systemd-inhibit", "--what=idle:sleep:handle-lid-switch", "--why=" + reason, "--mode=block", "sleep", "infinity"]
inhibitorProcess.running = true
}
// Wayland inhibition using wayhibitor or similar
function startWaylandInhibition() {
inhibitorProcess.command = ["wayhibitor"]
inhibitorProcess.running = true
}
// Process for maintaining the inhibition
Process {
id: inhibitorProcess
running: false
onExited: function (exitCode, exitStatus) {
if (isInhibited) {
Logger.warn("IdleInhibitor", "Inhibitor process exited unexpectedly:", exitCode)
isInhibited = false
}
}
onStarted: function () {
Logger.log("IdleInhibitor", "Inhibitor process started successfully")
}
}
// Manual toggle for user control
function manualToggle() {
if (activeInhibitors.includes("manual")) {
removeInhibitor("manual")
Settings.data.ui.idleInhibitorEnabled = false
ToastService.showNotice("Keep Awake", "Disabled", false, 3000)
Logger.log("IdleInhibitor", "Manual inhibition disabled and saved to settings")
return false
} else {
addInhibitor("manual", "Manually activated by user")
Settings.data.ui.idleInhibitorEnabled = true
ToastService.showNotice("Keep Awake", "Enabled", false, 3000)
Logger.log("IdleInhibitor", "Manual inhibition enabled and saved to settings")
return true
}
}
// Clean up on shutdown
Component.onDestruction: {
stopInhibition()
}
}