diff --git a/bin/omarchy-toggle-idle b/bin/omarchy-toggle-idle index 26e948ed..022a685c 100755 --- a/bin/omarchy-toggle-idle +++ b/bin/omarchy-toggle-idle @@ -33,15 +33,11 @@ apply_state() { stay-awake) mkdir -p "$STATE_DIR" touch "$STATE_FILE" - omarchy-shell -q idle disable ;; allow-idle) rm -f "$STATE_FILE" - omarchy-shell -q idle enable ;; esac - - omarchy-shell -q omarchy.indicators refresh } case "${1:-toggle}" in diff --git a/shell/plugins/bar/indicators/StayAwake.qml b/shell/plugins/bar/indicators/StayAwake.qml index 7a2eb9e3..70a7829e 100644 --- a/shell/plugins/bar/indicators/StayAwake.qml +++ b/shell/plugins/bar/indicators/StayAwake.qml @@ -1,51 +1,19 @@ import QtQuick -import Quickshell.Io import qs.Ui BarIndicator { id: root + readonly property var idleService: bar?.shell?.firstPartyServiceFor("omarchy.idle") + + active: idleService ? idleService.stayAwake : false activeText: "󰅶" inactiveText: "󰅶" activeTooltipText: "Allow Idle Lock & Screensaver" inactiveTooltipText: "Stay Awake" - function refresh() { - if (!statusProc.running) statusProc.running = true - } - function toggle() { - if (root.bar) root.bar.run("omarchy-toggle-idle") - refreshTimer.restart() - } - - Component.onCompleted: refresh() - - Connections { - target: root.indicatorHost - ignoreUnknownSignals: true - function onRefreshRequested() { root.refresh() } - } - - Process { - id: statusProc - command: ["omarchy-toggle-idle", "--status"] - stdout: StdioCollector { - waitForEnd: true - onStreamFinished: { - var data = root.extractData(text) - root.active = data && data.enabled === true - } - } - onExited: function(exitCode) { - if (exitCode !== 0) root.active = false - } - } - - Timer { - id: refreshTimer - interval: 1500 - onTriggered: root.refresh() + if (root.idleService) root.idleService.setIdleEnabled(root.active) } onPressed: function() { root.toggle() } diff --git a/test/shell.d/fixtures/indicator-contract/shell.qml b/test/shell.d/fixtures/indicator-contract/shell.qml index 842e7bb4..ad02aa13 100644 --- a/test/shell.d/fixtures/indicator-contract/shell.qml +++ b/test/shell.d/fixtures/indicator-contract/shell.qml @@ -24,10 +24,21 @@ ShellRoot { } } + QtObject { + id: idleService + property bool stayAwake: false + readonly property bool idleEnabled: !stayAwake + function setIdleEnabled(value) { + stayAwake = !value + } + } + QtObject { id: mockShell function firstPartyServiceFor(id) { - return id === "omarchy.notifications" ? notificationService : null + if (id === "omarchy.notifications") return notificationService + if (id === "omarchy.idle") return idleService + return null } } @@ -151,7 +162,7 @@ ShellRoot { stayAwake.moduleName = "StayAwake" root.injectBar(stayAwake) stayAwake.triggerPress(Qt.LeftButton) - root.assertTrue(root.commandCount("omarchy-toggle-idle") === 1, "Stay Awake left click runs idle toggle command") + root.assertTrue(idleService.stayAwake === true, "Stay Awake left click toggles the idle service") } root.writeResult() diff --git a/test/shell.d/idle-test.sh b/test/shell.d/idle-test.sh index 3d6dc64c..62a19c2c 100644 --- a/test/shell.d/idle-test.sh +++ b/test/shell.d/idle-test.sh @@ -34,3 +34,21 @@ assertDeepEqual( 'idle leaves screensaver windows unchanged without an address' ) JS + +test_tmp=$(mktemp -d) +trap 'rm -rf "$test_tmp"' EXIT + +test_home="$test_tmp/home" +mkdir -p "$test_home" + +HOME="$test_home" "$ROOT/bin/omarchy-toggle-idle" stay-awake >/dev/null +[[ -f $test_home/.local/state/omarchy/indicators/stay-awake ]] || fail "Stay Awake toggle persists enabled state" + +HOME="$test_home" "$ROOT/bin/omarchy-toggle-idle" allow-idle >/dev/null +[[ ! -f $test_home/.local/state/omarchy/indicators/stay-awake ]] || fail "Stay Awake toggle persists disabled state" + +if rg -q 'omarchy-shell' "$ROOT/bin/omarchy-toggle-idle"; then + fail "Stay Awake toggle avoids reentrant shell IPC" +fi + +pass "Stay Awake toggle persists state without reentrant shell IPC"