diff options
Diffstat (limited to 'shared/Status.qml')
| -rw-r--r-- | shared/Status.qml | 63 |
1 files changed, 56 insertions, 7 deletions
diff --git a/shared/Status.qml b/shared/Status.qml index 03194e7..5df1847 100644 --- a/shared/Status.qml +++ b/shared/Status.qml @@ -13,6 +13,7 @@ pragma Singleton import Quickshell import Quickshell.Io +import Quickshell.Wayland import QtQuick // Desktop modes as state. One file per mode under $XDG_RUNTIME_DIR, holding @@ -21,27 +22,74 @@ import QtQuick // // The files are the interface, not this singleton: statusctl reads and writes // them directly so it works while the shell is down, and the FileView watch -// means an external write repaints the drawer with no polling. +// means an external write repaints the drawer with no polling. It also means +// a mode set from outside still fires its effects, because the watch reaches +// the same handler a tile click would. Singleton { id: root readonly property string dir: Quickshell.env("XDG_RUNTIME_DIR") || "/tmp" readonly property bool dnd: dndFile.value + readonly property bool presentation: presFile.value - // Number of modes currently on. The tile shows this. - readonly property int activeCount: (root.dnd ? 1 : 0) + readonly property int activeCount: (root.dnd ? 1 : 0) + (root.presentation ? 1 : 0) + + // Set once by shell.qml. IdleInhibitor does nothing with a null window, + // and the singleton has no window of its own to offer. + property var inhibitWindow: null + + // What dnd was before presentation mode turned it on, so turning + // presentation mode off restores it rather than clearing it. Held here + // rather than in a file: it is meaningful only while presentation mode is + // on, and presentation mode does not survive a reboot. + property bool dndBeforePresentation: false function setMode(name, on) { - if (name === "dnd") dndFile.write(on); + if (name === "dnd") { + dndFile.write(on); + } else if (name === "presentation") { + presFile.write(on); + } } function toggleMode(name) { - if (name === "dnd") dndFile.write(!root.dnd); + if (name === "dnd") root.setMode("dnd", !root.dnd); + else if (name === "presentation") root.setMode("presentation", !root.presentation); + } + + // Effects follow the mode rather than the setter, so a mode set by + // statusctl while the drawer is closed asserts them too. + onPresentationChanged: { + if (root.presentation) { + root.dndBeforePresentation = root.dnd; + root.setMode("dnd", true); + root.runBreaktimer("pause"); + } else { + root.setMode("dnd", root.dndBeforePresentation); + root.runBreaktimer("resume"); + } + } + + function runBreaktimer(verb) { + breakProc.command = ["breaktimer.sh", verb]; + breakProc.running = false; + breakProc.running = true; + } + + // breaktimer owns its own state file; this only calls its verbs. Two + // writers on that file would race with its daemon loop, which rewrites it + // on every phase change. + Process { id: breakProc } + + // Wayland idle inhibit. The compositor advertises + // zwp_idle_inhibit_manager_v1 and hypridle honours it, so no D-Bus path + // is needed even though elogind runs here. + IdleInhibitor { + window: root.inhibitWindow + enabled: root.presentation && root.inhibitWindow !== null } - // One mode file. Reads "1" as true and anything else, including a missing - // file, as false. component ModeFile: FileView { id: mf @@ -77,4 +125,5 @@ Singleton { } ModeFile { id: dndFile; path: root.dir + "/status.dnd" } + ModeFile { id: presFile; path: root.dir + "/status.presentation" } } |
