ed063ab1fe
Capture desktop-specific system, session, Noctalia, and Pi integration alongside shared laptop support. Retire obsolete X11 configuration and make package ownership explicit for repeatable Decman deployments.
86 lines
2.5 KiB
Lua
86 lines
2.5 KiB
Lua
-- Click-through details for both logind idle inhibitors and session
|
|
-- ScreenSaver requests such as browser video wake locks.
|
|
local command = (noctalia.getenv("HOME") or "") .. "/.local/bin/idle-inhibitor-monitor --list"
|
|
|
|
local inhibitors = {}
|
|
local status = "Loading idle inhibitors…"
|
|
local request_in_flight = false
|
|
|
|
local function renderPanel()
|
|
local children = {
|
|
ui.column({ gap = 2 }, {
|
|
ui.label({ text = "Idle inhibitors", fontSize = 18, fontWeight = "bold" }),
|
|
ui.label({ text = status, color = "on_surface_variant" }),
|
|
}),
|
|
ui.button({ text = "Refresh", onClick = "onRefresh" }),
|
|
}
|
|
|
|
if #inhibitors == 0 then
|
|
table.insert(children, ui.label({ text = "No process currently blocks automatic idle." }))
|
|
else
|
|
for _, inhibitor in ipairs(inhibitors) do
|
|
local title = inhibitor.comm ~= "" and inhibitor.comm or inhibitor.who
|
|
table.insert(children, ui.column({ gap = 2 }, {
|
|
ui.label({ text = string.format("%s · %s", inhibitor.source, title), fontWeight = "bold" }),
|
|
ui.label({ text = inhibitor.why ~= "" and inhibitor.why or "No reason supplied", maxLines = 2 }),
|
|
ui.label({
|
|
text = string.format("%s · %s · PID %s", inhibitor.mode, inhibitor.user, inhibitor.pid),
|
|
color = "on_surface_variant",
|
|
fontSize = 11,
|
|
}),
|
|
}))
|
|
end
|
|
end
|
|
|
|
panel.render(ui.scroll({ padding = 20, gap = 12 }, children))
|
|
end
|
|
|
|
local function refreshInhibitors()
|
|
if request_in_flight then return end
|
|
request_in_flight = true
|
|
status = "Loading idle inhibitors…"
|
|
renderPanel()
|
|
|
|
noctalia.runAsync(command, function(result)
|
|
request_in_flight = false
|
|
inhibitors = {}
|
|
|
|
if result.exitCode ~= 0 then
|
|
status = "Unable to inspect logind inhibitors."
|
|
renderPanel()
|
|
return
|
|
end
|
|
|
|
for line in string.gmatch(result.stdout, "[^\r\n]+") do
|
|
local source, who, user, pid, comm, mode, why = string.match(
|
|
line,
|
|
"^([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t(.*)$"
|
|
)
|
|
if source ~= nil then
|
|
table.insert(inhibitors, {
|
|
source = source,
|
|
who = who,
|
|
user = user,
|
|
pid = pid,
|
|
comm = comm,
|
|
mode = mode,
|
|
why = why,
|
|
})
|
|
end
|
|
end
|
|
|
|
status = #inhibitors == 0
|
|
and "Automatic idle is eligible."
|
|
or string.format("%d active idle inhibitor%s.", #inhibitors, #inhibitors == 1 and "" or "s")
|
|
renderPanel()
|
|
end)
|
|
end
|
|
|
|
function onOpen()
|
|
refreshInhibitors()
|
|
end
|
|
|
|
function onRefresh()
|
|
refreshInhibitors()
|
|
end
|