From fbdfcd4e2d54dbc3f8767ba3ef97667802a7949b Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Mon, 19 Oct 2026 09:53:45 +0200 Subject: desktop: notification sounds on the settings page A sound per urgency chosen with the widget file dialog, previewed with pw-play, and the sound theme for apps' sound-name hints. Save writes the theme to gsettings as well, and the page reads gsettings back on every open so a change made elsewhere is shown, with a button to adopt it, rather than overwritten. Co-Authored-By: Claude Opus 5.5 --- .../modules/notifications/NotificationsPage.qml | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) (limited to 'desktop/modules/notifications/NotificationsPage.qml') diff --git a/desktop/modules/notifications/NotificationsPage.qml b/desktop/modules/notifications/NotificationsPage.qml index 28bdcf4..ce09a9d 100644 --- a/desktop/modules/notifications/NotificationsPage.qml +++ b/desktop/modules/notifications/NotificationsPage.qml @@ -9,7 +9,9 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. import Quickshell +import Quickshell.Io import QtQuick +import Qt.labs.platform as P import "../.." import "../appearance" import "../qtmaildir" @@ -71,6 +73,92 @@ Column { } } + Heading { text: "Sounds" } + Text { + width: pg.width; wrapMode: Text.Wrap + text: "Played when a balloon pops, never for one muted, held by Do Not Disturb or snoozed. An app's own sound, or its request for silence, wins." + color: Theme.overlay + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 } + } + Repeater { + model: [["low", "Low"], ["normal", "Normal"], ["critical", "Critical"]] + Row { + required property var modelData + spacing: 10 + readonly property string file: pg.d.sounds[modelData[0]] + Text { + width: 90; anchors.verticalCenter: parent.verticalCenter + text: modelData[1]; color: Theme.text + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 3 } + } + Text { + width: 180; anchors.verticalCenter: parent.verticalCenter + elide: Text.ElideMiddle + text: parent.file ? parent.file.split("/").pop() : "none" + color: parent.file ? Theme.text : Theme.overlay + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 3 } + } + Button { + text: "Choose\u2026" + onClicked: { picker.key = modelData[0]; picker.open(); } + } + Button { + icon: "\uf04b" + enabled: parent.file !== "" + onClicked: { preview.command = ["pw-play", parent.file]; preview.running = false; preview.running = true; } + } + Button { + icon: "\uf00d" + enabled: parent.file !== "" + onClicked: pg.mod.edit({ sounds: Object.assign({}, pg.d.sounds, { [modelData[0]]: "" }) }) + } + } + } + Text { + topPadding: 6 + text: "Theme for sounds apps ask for by name, also set as the system sound theme" + color: Theme.subtext + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4; bold: true } + } + Flow { + width: pg.width; spacing: 6 + Repeater { + model: pg.mod.themes + Button { + required property string modelData + text: modelData + border.color: pg.d.soundTheme === modelData ? Theme.accent : Qt.alpha(Theme.text, 0.2) + onClicked: pg.mod.edit({ soundTheme: modelData }) + } + } + } + Row { + spacing: 10 + visible: pg.mod.systemTheme !== "" && pg.mod.systemTheme !== pg.d.soundTheme + Text { + anchors.verticalCenter: parent.verticalCenter + text: "System sound theme is " + pg.mod.systemTheme + ", changed outside this page" + color: Theme.yellow + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 } + } + Button { + text: "Use " + pg.mod.systemTheme + onClicked: pg.mod.edit({ soundTheme: pg.mod.systemTheme }) + } + } + + Process { id: preview } + // Qt.labs.platform, not QtQuick.Dialogs: the Quick dialog opens light on + // this desktop (AGENTS.md); this one takes the widget style. + P.FileDialog { + id: picker + property string key: "" + folder: "file://" + Quickshell.env("HOME") + "/.local/share/sounds" + nameFilters: ["Sounds (*.oga *.ogg *.wav)"] + onAccepted: pg.mod.edit({ sounds: Object.assign({}, pg.d.sounds, + { [picker.key]: decodeURIComponent(file.toString().replace(/^file:\/\//, "")) }) }) + } + Heading { text: "Limits" } Text { width: pg.width; wrapMode: Text.Wrap -- cgit v1.2.3