aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-19 09:34:02 +0200
committerDanilo M. <danix@danix.xyz>2026-10-19 09:34:02 +0200
commitc0c407306426fcb12a51a0cdd0b3bdde92014af3 (patch)
tree081f8e28467e31e77298954de6ee877fbbeccd28 /desktop/modules
parent909b9c98da02913b603a0339cf733aa03e69897e (diff)
downloadquickshell-c0c407306426fcb12a51a0cdd0b3bdde92014af3.tar.gz
quickshell-c0c407306426fcb12a51a0cdd0b3bdde92014af3.zip
desktop: notification page follows the file, saves once, keeps nested keys
From the final review. An edit broke the draft's binding to Notify.config and Discard assigned a plain value, so a later change to the file read as unsaved edits; discard and refresh now restore the binding. Save stays disabled while the write runs, since a second click killed the first mid-write. Unknown keys inside timeouts and balloons are merged rather than replaced, as the spec asks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'desktop/modules')
-rw-r--r--desktop/modules/notifications/NotificationsModule.qml27
1 files changed, 19 insertions, 8 deletions
diff --git a/desktop/modules/notifications/NotificationsModule.qml b/desktop/modules/notifications/NotificationsModule.qml
index 6dea790..01eea18 100644
--- a/desktop/modules/notifications/NotificationsModule.qml
+++ b/desktop/modules/notifications/NotificationsModule.qml
@@ -30,19 +30,30 @@ Module {
dirty: JSON.stringify(nm.draft) !== JSON.stringify(Notify.config)
readonly property bool valid: [nm.draft.liveCap, nm.draft.historyCap].every(v => v >= 1 && v <= 100)
- // Not over unsaved edits.
- function refresh() { if (!nm.dirty) nm.draft = Notify.config; }
- function discard() { nm.draft = Notify.config; nm.notice = ""; }
+ // An edit replaces the draft's binding with a value; these put the
+ // binding back, so a change to the file shows up while nothing is
+ // edited. The window calls refresh() on every open, which covers the
+ // value a save leaves behind. Not over unsaved edits.
+ function follow() { nm.draft = Qt.binding(() => Notify.config); }
+ function refresh() { if (!nm.dirty) nm.follow(); }
+ function discard() { nm.follow(); nm.notice = ""; }
function edit(patch) { nm.draft = Object.assign({}, nm.draft, patch); }
- // Unknown keys in the file survive. The text goes on stdin to cat (the
- // notes pattern: the exit code is the outcome); 1 is the write, 2 the
- // reload, so a stopped daemon reads as saved-but-not-applied.
+ // Unknown keys in the file survive, including inside timeouts and
+ // balloons, which are merged one level down. The text goes on stdin to
+ // cat (the notes pattern: the exit code is the outcome); 1 is the write,
+ // 2 the reload, so a stopped daemon reads as saved-but-not-applied.
// Written in onStarted, then stdinEnabled cleared to give cat its EOF:
// the sequence notes' bodyWriter uses (NotesModule.qml).
function save() {
nm.notice = "";
- nm.saver.data = JSON.stringify(Object.assign({}, Notify.rawConfig, nm.draft), null, 2) + "\n";
+ const raw = Notify.rawConfig;
+ const obj = v => v && typeof v === "object" && !Array.isArray(v) ? v : {};
+ const out = Object.assign({}, raw, nm.draft, {
+ timeouts: Object.assign({}, obj(raw.timeouts), nm.draft.timeouts),
+ balloons: Object.assign({}, obj(raw.balloons), nm.draft.balloons),
+ });
+ nm.saver.data = JSON.stringify(out, null, 2) + "\n";
nm.saver.stdinEnabled = true;
nm.saver.running = false;
nm.saver.running = true;
@@ -64,7 +75,7 @@ Module {
Page {
title: "Notifications"
actions: Component {
- SaveBar { dirty: nm.dirty; valid: nm.valid; note: "caps are 1 to 100"
+ SaveBar { dirty: nm.dirty; valid: nm.valid; note: "caps are 1 to 100"; busy: nm.saver.running
onSave: nm.save(); onDiscard: nm.discard() }
}
NotificationsPage { width: parent.width; mod: nm }