Files
Panama/config/dot/quickshell/services/SoundFeedback.qml
T
Gabriel Brown d96863b687 Convert British spellings to American across the repo
colour -> color, behaviour -> behavior, centre -> center, favourite ->
favorite, and about twenty other pairs, applied consistently across
comments, docs, error/UI copy, and a handful of QML identifiers that
used the British spelling as their actual name: SystemSettings'
serialiseValue/serialiseTable/normaliseGradient, Displays'
normaliseModes, Wallpaper's normalisePolicy, SettingsBackup's
serialiseHomeState, DateTime's ntpSynchronised property, Clipboard's
_normalise helper, and ShortcutCapture's cancelled signal (with its
onCancelled handler in ShortcutsPage.qml). Every call site and the two
tests that assert on the literal source text (settings-ownership and
settings-backup-live contracts) were updated in lockstep.

Left untouched: config/dot/espanso/match/packages/misspell-en/ is a
vendored third-party autocorrect dictionary -- its entries are typo
corrections, not our prose, and rewriting them would fight the
package's own purpose (and any future re-sync from upstream).

The already-American `favorites` property (Home page pinned
accessories) was never actually misspelled -- only nearby comments and
error strings said "favourites" -- so no data migration was needed
there.

Claude-Session: https://claude.ai/code/session_01E6TJUAh41HaP25MVHWkhRZ
2026-08-19 08:07:55 -04:00

123 lines
3.9 KiB
QML

pragma Singleton
// GNOME and GTK applications already honor these desktop sound preferences.
// Panama controls the same durable keys so moving between sessions does not
// create two competing notions of whether event feedback is enabled.
import Quickshell
import Quickshell.Io
import QtQuick
Singleton {
id: root
property bool eventSounds: true
property bool inputFeedback: false
property string lastError: ""
readonly property bool busy: eventRead.running || inputRead.running
|| eventWrite.running || inputWrite.running
function parsedBoolean(text: string, fallback: bool): bool {
const value = text.trim();
if (value === "true")
return true;
if (value === "false")
return false;
return fallback;
}
function refresh(): void {
if (!eventRead.running)
eventRead.running = true;
if (!inputRead.running)
inputRead.running = true;
}
function setEventSounds(enabled: bool): void {
root.eventSounds = enabled;
root._writeEventSounds();
}
function setInputFeedback(enabled: bool): void {
root.inputFeedback = enabled;
root._writeInputFeedback();
}
// Assigning `running = true` to a Process that is already running is a
// no-op, not a queue -- so a toggle that lands mid-write would otherwise
// be dropped silently. eventWrite.onExited re-checks root.eventSounds
// against what was actually written and calls this again if they still
// disagree.
function _writeEventSounds(): void {
if (eventWrite.running)
return;
eventWrite.writtenValue = root.eventSounds;
eventWrite.command = ["gsettings", "set", "org.gnome.desktop.sound", "event-sounds", String(root.eventSounds)];
eventWrite.running = true;
}
function _writeInputFeedback(): void {
if (inputWrite.running)
return;
inputWrite.writtenValue = root.inputFeedback;
inputWrite.command = ["gsettings", "set", "org.gnome.desktop.sound", "input-feedback-sounds", String(root.inputFeedback)];
inputWrite.running = true;
}
Process {
id: eventRead
command: ["gsettings", "get", "org.gnome.desktop.sound", "event-sounds"]
stdout: StdioCollector {
onStreamFinished: root.eventSounds = root.parsedBoolean(this.text, root.eventSounds)
}
onExited: (code, status) => {
if (code !== 0)
root.lastError = "Event sound preferences could not be read.";
}
}
Process {
id: inputRead
command: ["gsettings", "get", "org.gnome.desktop.sound", "input-feedback-sounds"]
stdout: StdioCollector {
onStreamFinished: root.inputFeedback = root.parsedBoolean(this.text, root.inputFeedback)
}
onExited: (code, status) => {
if (code !== 0)
root.lastError = "Input feedback preferences could not be read.";
}
}
Process {
id: eventWrite
property bool writtenValue: true
onExited: (code, status) => {
if (code !== 0) {
root.lastError = "Event sound preferences could not be changed.";
root.refresh();
} else {
root.lastError = "";
}
if (root.eventSounds !== eventWrite.writtenValue)
root._writeEventSounds();
}
}
Process {
id: inputWrite
property bool writtenValue: false
onExited: (code, status) => {
if (code !== 0) {
root.lastError = "Input feedback preferences could not be changed.";
root.refresh();
} else {
root.lastError = "";
}
if (root.inputFeedback !== inputWrite.writtenValue)
root._writeInputFeedback();
}
}
Component.onCompleted: root.refresh()
}