quickshell: run a single shared gamemode monitor

GamemodePill is instantiated per screen Variant, so it spawned one
long-lived gdbus monitor per monitor (3 on desktop). Move the watcher into
a shared Gamemode singleton so only one runs regardless of screen count.
This commit is contained in:
2026-06-01 14:15:07 +02:00
parent 5c585697ae
commit 7c798c005c
2 changed files with 40 additions and 33 deletions
+3 -33
View File
@@ -1,20 +1,17 @@
import Quickshell
import Quickshell.Io
import QtQuick
import QtQuick.Layouts
import "../shared" as Shared
// Gamemode indicator — visible only when gamemode is active.
// Event-driven: re-checks status when GameMode emits a D-Bus register/unregister
// signal (via `gdbus monitor`), instead of polling on a timer.
// State comes from the shared Gamemode singleton (one gdbus monitor for all
// screens), not a per-pill process.
BarPill {
id: root
groupName: "" // no popout
accentColor: Shared.Theme.green
visible: isActive
property bool isActive: false
visible: Shared.Gamemode.active
content: [
Text {
@@ -25,31 +22,4 @@ BarPill {
font.family: Shared.Theme.iconFont
}
]
Process {
id: gameProc
command: ["gamemoded", "--status"]
stdout: StdioCollector {
onStreamFinished: {
root.isActive = this.text.indexOf("is active") >= 0
}
}
}
function poll() { gameProc.running = false; gameProc.running = true; }
// Long-lived monitor on GameMode's session-bus object. Each GameRegistered /
// GameUnregistered signal prints a line; re-check status only then.
Process {
id: monitor
running: true
command: ["gdbus", "monitor", "-e",
"-d", "com.feralinteractive.GameMode",
"-o", "/com/feralinteractive/GameMode"]
stdout: SplitParser {
onRead: line => { if (line.indexOf("Registered") >= 0) root.poll() }
}
}
Component.onCompleted: root.poll()
}
+37
View File
@@ -0,0 +1,37 @@
pragma Singleton
import Quickshell
import Quickshell.Io
import QtQuick
// Single GameMode watcher shared by every bar instance, so only one long-lived
// `gdbus monitor` runs regardless of how many screens exist. Event-driven:
// re-checks status only when GameMode emits a register/unregister signal.
Singleton {
id: root
property bool active: false
Process {
id: gameProc
command: ["gamemoded", "--status"]
stdout: StdioCollector {
onStreamFinished: root.active = this.text.indexOf("is active") >= 0
}
}
function poll() { gameProc.running = false; gameProc.running = true; }
Process {
id: monitor
running: true
command: ["gdbus", "monitor", "-e",
"-d", "com.feralinteractive.GameMode",
"-o", "/com/feralinteractive/GameMode"]
stdout: SplitParser {
onRead: line => { if (line.indexOf("Registered") >= 0) root.poll() }
}
}
Component.onCompleted: poll()
}