aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-20 11:56:11 +0200
committerDanilo M. <danix@danix.xyz>2026-09-20 11:56:11 +0200
commite4f2082fa742611fb787f73d5ef5f046c77eab5d (patch)
treee76fed77548b70670b682a8b9a98a4b0a3186676
parentdd8a4ee43c045230fa982c7ee49166f7c8c6529b (diff)
downloadquickshell-e4f2082fa742611fb787f73d5ef5f046c77eab5d.tar.gz
quickshell-e4f2082fa742611fb787f73d5ef5f046c77eab5d.zip
feat(status): auto-present while DuckStation runs
Game detection probed only gamescope and Steam, so a standalone DuckStation session never turned presentation on. Add a third probe for the duckstation-qt process. pgrep -x rather than the bracketed pgrep -f the Steam path needs: this is an exact match on the process name, so it cannot match the sh running the check, and the binary name is under the 15 character comm limit so it is not truncated.
-rw-r--r--desktop/modules/status/README.md10
-rw-r--r--shared/Status.qml9
2 files changed, 11 insertions, 8 deletions
diff --git a/desktop/modules/status/README.md b/desktop/modules/status/README.md
index e043dcd..438ead8 100644
--- a/desktop/modules/status/README.md
+++ b/desktop/modules/status/README.md
@@ -102,14 +102,16 @@ edited from here; `breaktimer.sh config` prints what is in effect.
Presentation is set automatically while a game runs, so a fullscreen game does
not get locked or interrupted by the idle timer, DND or breaktimer. The shell
-polls every five seconds for a `gamescope` process or a running Steam binary,
-and either one is enough:
+polls every five seconds for a `gamescope` process, a running Steam binary, or
+DuckStation, and any one is enough:
- pgrep -x gamescope || pgrep -f 'steamapps/commo[n]'
+ pgrep -x gamescope || pgrep -f 'steamapps/commo[n]' || pgrep -x duckstation-qt
The steam pattern is bracketed so it cannot match the check's own command
line: `pgrep -f` reads the whole argv, and a literal `steamapps/common` would
-match the `sh` running the check and report a game forever.
+match the `sh` running the check and report a game forever. `gamescope` and
+`duckstation-qt` use `pgrep -x`, an exact match on the process name, which
+cannot self-match.
The result is written to `status.gaming`, a file separate from
`status.presentation`, and presentation is the OR of the two. That separation
diff --git a/shared/Status.qml b/shared/Status.qml
index 36853af..3460dca 100644
--- a/shared/Status.qml
+++ b/shared/Status.qml
@@ -177,18 +177,19 @@ Singleton {
// A game is a fullscreen app that already holds the screen, and the idle
// lock, DND and breaktimer are all unwanted while it runs, so presentation
// is set automatically. This machine's games come from Steam and launch
- // either under gamescope or directly, so both are tested and either one is
- // enough.
+ // either under gamescope or directly, and DuckStation runs standalone, so
+ // all three are tested and any one is enough.
//
// The steam pattern is bracketed so it cannot match this very command
// line: pgrep -f reads the whole argv, and the literal "steamapps/common"
// here would otherwise match the sh running the check and report a game
// forever. The character class makes the needle miss itself while still
- // matching a real game path.
+ // matching a real game path. gamescope and duckstation-qt use pgrep -x, an
+ // exact match on the process name, which cannot self-match.
Process {
id: gameProc
command: ["sh", "-c",
- "pgrep -x gamescope >/dev/null 2>&1 || pgrep -f 'steamapps/commo[n]' >/dev/null 2>&1"]
+ "pgrep -x gamescope >/dev/null 2>&1 || pgrep -f 'steamapps/commo[n]' >/dev/null 2>&1 || pgrep -x duckstation-qt >/dev/null 2>&1"]
onExited: code => root.setGaming(code === 0)
}