aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AGENTS.md2
-rw-r--r--desktop/NotificationRow.qml7
-rw-r--r--notifications/NotificationBalloon.qml2
l---------notifications/Status.qml1
-rw-r--r--shared/Notify.qml18
5 files changed, 26 insertions, 4 deletions
diff --git a/AGENTS.md b/AGENTS.md
index ccd2fa3..300d4ce 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -240,7 +240,7 @@ changing that component. The ones that generalise:
is not an interruption.
- **A notification appears as a balloon or in the drawer's reserved space,
never both.** The drawer writes `notifyd/drawer` and the balloon shell reads
- it; `Drawer.qml`'s reserved `Item` is the space.
+ it; `desktop/NotificationList.qml` is the space.
- **The dead `waybar/modules/custom/notification.jsonc` and
`waybar/scripts/notifications.py` still shell out to `dunstctl`.** They are
not in the live waybar config; do not resurrect them.
diff --git a/desktop/NotificationRow.qml b/desktop/NotificationRow.qml
index f95f3b4..7aff362 100644
--- a/desktop/NotificationRow.qml
+++ b/desktop/NotificationRow.qml
@@ -26,8 +26,13 @@ Item {
MouseArea {
anchors.fill: parent
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
cursorShape: Qt.PointingHandCursor
- onClicked: {
+ onClicked: mouse => {
+ if (mouse.button === Qt.RightButton) {
+ Notify.closeAll();
+ return;
+ }
if (!row.live) return;
const acts = row.notification.actions || [];
if (acts.length > 0 && !row.inert) Notify.actions(row.notification.id, acts);
diff --git a/notifications/NotificationBalloon.qml b/notifications/NotificationBalloon.qml
index e3763da..b8ce0f7 100644
--- a/notifications/NotificationBalloon.qml
+++ b/notifications/NotificationBalloon.qml
@@ -31,7 +31,7 @@ Rectangle {
visible: {
if (Notify.drawerOpen) return false;
if (Notify.snoozeUntil > b.now) return false;
- if (Status.dnd && b.notification.urgency !== "critical") return false;
+ if (Notify.dnd && b.notification.urgency !== "critical") return false;
if (b.notification.expires !== 0 && b.now >= b.notification.expires) return false;
return true;
}
diff --git a/notifications/Status.qml b/notifications/Status.qml
deleted file mode 120000
index e7188a3..0000000
--- a/notifications/Status.qml
+++ /dev/null
@@ -1 +0,0 @@
-../shared/Status.qml \ No newline at end of file
diff --git a/shared/Notify.qml b/shared/Notify.qml
index ff07575..897e50b 100644
--- a/shared/Notify.qml
+++ b/shared/Notify.qml
@@ -39,6 +39,14 @@ Singleton {
// Epoch milliseconds; 0 means not snoozing.
property double snoozeUntil: 0
+ // Read from the status registry's own file rather than from the Status
+ // singleton. The renderers only read DND; referencing Status here would
+ // instantiate it, and its onPresentationChanged writes status.dnd and
+ // shells out to breaktimer.sh, side effects a read-only consumer must not
+ // trigger. The file is the interface, so reading it directly is the same
+ // value with none of the write side.
+ property bool dnd: false
+
function parseQueue() {
try { root.queue = JSON.parse(queueFile.text() || "[]"); }
catch (e) { root.queue = []; }
@@ -109,6 +117,16 @@ Singleton {
}
FileView {
+ id: dndFile
+ path: (Quickshell.env("XDG_RUNTIME_DIR") || "/tmp") + "/status.dnd"
+ watchChanges: true
+ printErrors: false
+ onFileChanged: reload()
+ onLoaded: root.dnd = dndFile.text().trim() === "1"
+ onLoadFailed: root.dnd = false
+ }
+
+ FileView {
id: snoozeFile
path: root.dir + "/snooze"
watchChanges: true