Add IdleInhibitor
This commit is contained in:
parent
bfc2adfca4
commit
e7577ed488
6 changed files with 231 additions and 1 deletions
|
|
@ -229,6 +229,9 @@ Singleton {
|
|||
|
||||
// Legacy compatibility
|
||||
property string fontFamily: fontDefault // Keep for backward compatibility
|
||||
|
||||
// Idle inhibitor state
|
||||
property bool idleInhibitorEnabled: false
|
||||
}
|
||||
|
||||
// Scaling (not stored inside JsonObject, or it crashes)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ Item {
|
|||
IpcHandler {
|
||||
target: "idleInhibitor"
|
||||
|
||||
function toggle() {// TODO
|
||||
function toggle() {
|
||||
return IdleInhibitorService.manualToggle()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,17 @@ NBox {
|
|||
}
|
||||
}
|
||||
|
||||
// Idle Inhibitor
|
||||
NIconButton {
|
||||
icon: IdleInhibitorService.isInhibited ? "coffee" : "bedtime"
|
||||
tooltipText: IdleInhibitorService.isInhibited ? "Disable Keep Awake" : "Enable Keep Awake"
|
||||
colorBg: IdleInhibitorService.isInhibited ? Color.mPrimary : Color.mSurfaceVariant
|
||||
colorFg: IdleInhibitorService.isInhibited ? Color.mOnPrimary : Color.mPrimary
|
||||
onClicked: {
|
||||
IdleInhibitorService.manualToggle()
|
||||
}
|
||||
}
|
||||
|
||||
// Wallpaper
|
||||
NIconButton {
|
||||
icon: "image"
|
||||
|
|
|
|||
209
Services/IdleInhibitorService.qml
Normal file
209
Services/IdleInhibitorService.qml
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
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")
|
||||
}
|
||||
}
|
||||
|
||||
// Convenience functions for common use cases
|
||||
function inhibitForMedia(active = true) {
|
||||
if (active) {
|
||||
addInhibitor("media", "Media playback active")
|
||||
} else {
|
||||
removeInhibitor("media")
|
||||
}
|
||||
}
|
||||
|
||||
function inhibitForPresentation(active = true) {
|
||||
if (active) {
|
||||
addInhibitor("presentation", "Presentation mode")
|
||||
} else {
|
||||
removeInhibitor("presentation")
|
||||
}
|
||||
}
|
||||
|
||||
function inhibitForFullscreen(active = true) {
|
||||
if (active) {
|
||||
addInhibitor("fullscreen", "Fullscreen application")
|
||||
} else {
|
||||
removeInhibitor("fullscreen")
|
||||
}
|
||||
}
|
||||
|
||||
// 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()
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,11 @@ Singleton {
|
|||
property real currentPosition: 0
|
||||
property int selectedPlayerIndex: 0
|
||||
property bool isPlaying: currentPlayer ? currentPlayer.isPlaying : false
|
||||
|
||||
// Auto-inhibit idle when media is playing
|
||||
onIsPlayingChanged: {
|
||||
IdleInhibitorService.inhibitForMedia(isPlaying)
|
||||
}
|
||||
property string trackTitle: currentPlayer ? (currentPlayer.trackTitle || "") : ""
|
||||
property string trackArtist: currentPlayer ? (currentPlayer.trackArtist || "") : ""
|
||||
property string trackAlbum: currentPlayer ? (currentPlayer.trackAlbum || "") : ""
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import qs.Modules.Notification
|
|||
import qs.Modules.SettingsPanel
|
||||
import qs.Modules.SidePanel
|
||||
import qs.Modules.Toast
|
||||
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue