diff options
Diffstat (limited to 'desktop/modules/status')
| -rw-r--r-- | desktop/modules/status/BreakRow.qml | 84 | ||||
| -rw-r--r-- | desktop/modules/status/README.md | 46 | ||||
| -rw-r--r-- | desktop/modules/status/StatusPage.qml | 12 | ||||
| -rw-r--r-- | desktop/modules/status/StatusTile.qml | 9 |
4 files changed, 4 insertions, 147 deletions
diff --git a/desktop/modules/status/BreakRow.qml b/desktop/modules/status/BreakRow.qml deleted file mode 100644 index 8b732b1..0000000 --- a/desktop/modules/status/BreakRow.qml +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (C) 2026 Danilo M. <danix@danix.xyz> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as -// published by the Free Software Foundation. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -import QtQuick -import "../.." - -// Breaktimer: the daemon's phase and countdown, a pause switch and a -// start/stop button. Every control is a verb; nothing here writes the -// daemon's files. -Item { - id: row - - implicitHeight: Math.max(texts.implicitHeight, controls.implicitHeight) + 16 - - readonly property string phaseLabel: { - if (!Status.btRunning) return "Stopped"; - if (Status.btPaused) return "Paused"; - if (Status.btPhase === "breaking") return "Micro-pause"; - if (Status.btPhase === "longbreak") return "Long pause"; - return "Working"; - } - - // A paused countdown is frozen, and a frozen number reads as a bug, so - // the paused state says what it is instead of showing one. - readonly property string detail: { - if (!Status.btRunning) return "Break reminders are not running."; - if (Status.btPaused) return "Countdown frozen until resumed."; - if (Status.btPhase === "breaking" || Status.btPhase === "longbreak") - return "Back to work in " + Status.btCountdown() + "."; - return "Next break in " + Status.btCountdown() + "."; - } - - Column { - id: texts - anchors { - left: parent.left - right: controls.left - rightMargin: 12 - verticalCenter: parent.verticalCenter - } - spacing: 2 - - Text { - text: "Breaktimer · " + row.phaseLabel - font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2; bold: true } - color: Theme.text - } - - Text { - width: parent.width - wrapMode: Text.WordWrap - text: row.detail - font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 } - color: Theme.subtext - } - } - - Row { - id: controls - anchors { right: parent.right; verticalCenter: parent.verticalCenter } - spacing: 8 - - Button { - text: Status.btRunning ? "Stop" : "Start" - danger: Status.btRunning - onClicked: Status.runBreaktimer(Status.btRunning ? "stop" : "start") - } - - Switch { - id: sw - enabled: Status.btRunning - checked: Status.btRunning && !Status.btPaused - onToggled: Status.runBreaktimer(Status.btPaused ? "resume" : "pause") - } - } -} diff --git a/desktop/modules/status/README.md b/desktop/modules/status/README.md index d3d0cce..ea069d6 100644 --- a/desktop/modules/status/README.md +++ b/desktop/modules/status/README.md @@ -45,7 +45,7 @@ and reasserted when it returns. `dnd` has none of its own. It is state the notification daemon reads. `presentation` sets `dnd`, `nolock` and `quiet`, asserts a Wayland idle -inhibitor, and pauses breaktimer. Turning it off restores the three to the +inhibitor. Turning it off restores the three to the values they had before rather than clearing them, so hand-set DND or a hand-set disable survives a presentation. @@ -71,52 +71,10 @@ The opencode notifier runs its command for every event, `session_started` and are off in `opencode-notifier.json`, and it rereads that file on every event, so neither change needs an opencode restart. -breaktimer is paused and resumed by verb, never by writing its state file. See -Breaktimer below, which is also the read direction. - -## Breaktimer - -The traffic runs both ways, and only one way writes. - -**Reading.** The daemon publishes three files the singleton watches: - - $XDG_RUNTIME_DIR/breaktimer.state running | paused | stopped - $XDG_RUNTIME_DIR/breaktimer.phase working | breaking | longbreak | stopped - $XDG_RUNTIME_DIR/breaktimer.remain seconds left in the phase - -exposed as `Status.btState`, `btPhase` and `btRemain`, with `btRunning` and -`btPaused` derived from the first. The old bar script read the same three -files; the two consumers never knew about each other. - -**Writing: never.** The daemon owns those files and rewrites state and phase on -every transition, so a second writer would race its loop. Every control calls a -verb through `runBreaktimer()`, which is why presentation mode has always -called `pause` rather than writing `breaktimer.state`. - -**A stopped daemon** is read from the state file, not probed. Both paths that -end the daemon write `stopped` there: `stop_daemon`, and the `cleanup` trap on -`TERM`. A daemon lost to `KILL` leaves a stale `running` and the drawer shows a -frozen countdown, a visible wrong answer the Start button resolves, which is -cheaper than a liveness probe on every repaint. QML cannot send a signal, so -the `kill -0` check the old bar module used is not available here anyway. - -**The countdown counts in five second steps**, because that is the daemon's -tick and the shell does not interpolate between its writes. A local one second -timer would be a second clock drifting against the first, correcting itself -with a visible jump every five seconds, and it would keep counting while the -daemon is frozen outside the work window or paused. - -**The tile** shows breaktimer below every mode, so an active mode still owns -the line and breaktimer replaces only the idle `All clear`. It does not count -toward `activeCount`: a running daemon is not a mode the user switched on. - -The daemon's own configuration lives in `~/.config/breaktimer.conf` and is not -edited from here; `breaktimer.sh config` prints what is in effect. - ## Game detection 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 +not get locked or interrupted by the idle timer or DND. The shell polls every five seconds for a `gamescope` process, a running Steam binary, or the DuckStation or PCSX2 emulators, and any one is enough: diff --git a/desktop/modules/status/StatusPage.qml b/desktop/modules/status/StatusPage.qml index 8a21ad5..4741bcc 100644 --- a/desktop/modules/status/StatusPage.qml +++ b/desktop/modules/status/StatusPage.qml @@ -37,7 +37,7 @@ Column { width: page.width mode: "presentation" label: "Presentation" - description: "Do not disturb, quiet, no screen lock, breaktimer paused." + description: "Do not disturb, quiet, no screen lock." value: Status.presentation } @@ -74,14 +74,4 @@ Column { SnoozeRow { width: page.width } - - Rectangle { - width: page.width - height: 1 - color: Qt.alpha(Theme.text, 0.08) - } - - BreakRow { - width: page.width - } } diff --git a/desktop/modules/status/StatusTile.qml b/desktop/modules/status/StatusTile.qml index cec18b6..ab3a7af 100644 --- a/desktop/modules/status/StatusTile.qml +++ b/desktop/modules/status/StatusTile.qml @@ -17,15 +17,8 @@ Text { elide: Text.ElideRight font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 } color: Status.activeCount > 0 ? Theme.text : Theme.subtext - // Breaktimer sits below every mode, so an active mode still owns the line - // and breaktimer replaces only the idle "All clear". A stopped daemon - // falls through to it, which is true: nothing is being tracked. text: Status.presentation ? "Presenting" : Status.dnd ? "Do not disturb" : Status.nolock ? "No lock" - : !Status.btRunning ? "All clear" - : Status.btPaused ? "Paused" - : (Status.btPhase === "breaking" || Status.btPhase === "longbreak") - ? "Back in " + Status.btCountdown() - : "Break in " + Status.btCountdown() + : "All clear" } |
