Audited bar, dock, quick settings, date menu and Settings for three things: a setting reachable in one UI but not another, a setting that exists but is unreachable anywhere, and UI that states something false. Night Light was fully exposed in Quick Settings and had no control anywhere in Settings. It now has a card on Displays, where GNOME also puts it, with on/off, schedule, times and temperature. Adding those controls would have shipped the exact defect this audit exists to find. NightLight declared enabled, temperature and automatic as bindings on the store, but toggle() assigns to them, and an assignment destroys a QML binding permanently -- so the service wrote to the store and never read from it again. The Settings controls would have written values the service ignored, while Quick Settings kept working. It now follows the store. Every other service was swept for the same pattern; this was the only one. The night light schedule was two hardcoded literals, so the hours could not be changed. They are schema keys now, with a row that renders 17.5 as "5:30 PM" and honours the 24-hour preference rather than showing a decimal nobody reads as a time. keyboardLayout was in the schema and read by input.lua but had no control anywhere: configurable in principle, unreachable in practice. It is surfaced on Input & Shortcuts as read-only, with the reason, because it needs a compositor reload and a control implying instant apply would be a smaller lie but still a lie. Caffeine was a Quick Settings toggle mentioned only in a subtitle in Settings. It has a real control now. Claude-Session: https://claude.ai/code/session_01BRvzt4H8XXLPVH5MyYdk9L
178 lines
5.8 KiB
QML
178 lines
5.8 KiB
QML
import QtQuick
|
|
import qs.config
|
|
import qs.services
|
|
|
|
SettingsPage {
|
|
title: "Notifications & Focus"
|
|
lede: "Control interruptions without losing useful history."
|
|
|
|
SettingsCard {
|
|
title: "Notifications"
|
|
|
|
SettingRow {
|
|
label: "Do Not Disturb"
|
|
detail: "Keep notifications in the center but suppress banners"
|
|
controlWidth: 48
|
|
|
|
SettingsToggle {
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
checked: Notifs.doNotDisturb
|
|
onToggled: value => Notifs.doNotDisturb = value
|
|
}
|
|
}
|
|
|
|
TextRow {
|
|
label: "Notification history"
|
|
detail: "Live notifications retained by Panama"
|
|
value: `${Notifs.history.length} items`
|
|
}
|
|
|
|
ActionRow {
|
|
label: "Clear notification history"
|
|
detail: "Dismiss every item currently in the notification center"
|
|
divider: false
|
|
action: "Clear all"
|
|
enabled: Notifs.history.length > 0
|
|
onTriggered: Notifs.dismissAll()
|
|
}
|
|
}
|
|
|
|
SettingsCard {
|
|
title: "Banner behavior"
|
|
|
|
SliderRow { setting: "notificationTimeoutMs" }
|
|
SliderRow {
|
|
setting: "notificationTimeoutCriticalMs"
|
|
zeroLabel: "Never"
|
|
}
|
|
SliderRow { setting: "notificationHistoryLimit" }
|
|
SliderRow { setting: "maxVisibleToasts"; divider: false }
|
|
}
|
|
|
|
SettingsCard {
|
|
title: "Application rules"
|
|
subtitle: "Apps appear here after they send a notification."
|
|
|
|
TextRow {
|
|
visible: Notifs.applications.length === 0
|
|
label: "No applications remembered yet"
|
|
detail: "Application controls will appear after the first notification arrives."
|
|
divider: false
|
|
}
|
|
|
|
Repeater {
|
|
model: Notifs.applications
|
|
|
|
Column {
|
|
required property var modelData
|
|
|
|
readonly property var app: modelData
|
|
|
|
width: parent.width
|
|
|
|
SettingRow {
|
|
label: app.name
|
|
detail: app.id
|
|
controlWidth: 48
|
|
|
|
SettingsToggle {
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
checked: Notifs.appRule(app.id).enabled
|
|
onToggled: value => Notifs.setAppRule(app.id, { enabled: value })
|
|
}
|
|
}
|
|
|
|
SettingRow {
|
|
label: "Show on lock screen"
|
|
detail: "Allow this app's notifications on the lock screen"
|
|
controlWidth: 48
|
|
|
|
SettingsToggle {
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
checked: Notifs.appRule(app.id).showOnLockScreen
|
|
onToggled: value => Notifs.setAppRule(app.id, { showOnLockScreen: value })
|
|
}
|
|
}
|
|
|
|
SettingRow {
|
|
label: "Show content on lock screen"
|
|
detail: "Show message details when this app is visible there"
|
|
divider: false
|
|
controlWidth: 48
|
|
|
|
SettingsToggle {
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
checked: Notifs.appRule(app.id).showContentOnLockScreen
|
|
onToggled: value => Notifs.setAppRule(app.id, { showContentOnLockScreen: value })
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SettingsCard {
|
|
title: "Focus sessions"
|
|
subtitle: "A focus session binds quiet mode and Caffeine to the current workspace."
|
|
|
|
SettingRow {
|
|
label: "Keep the screen awake"
|
|
detail: Caffeine.enabled
|
|
? "The display will not blank or lock while this is on"
|
|
: "Idle timings on Power & Lock apply normally"
|
|
controlWidth: 48
|
|
|
|
SettingsToggle {
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
checked: Caffeine.enabled
|
|
onToggled: value => Caffeine.enabled = value
|
|
}
|
|
}
|
|
|
|
SettingRow {
|
|
id: durationRow
|
|
|
|
label: "Default duration"
|
|
detail: "Used by Super+Shift+F and Quick Settings"
|
|
controlWidth: 264
|
|
|
|
Row {
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: 6
|
|
|
|
Repeater {
|
|
model: [25, 45, 60, 90]
|
|
|
|
SettingsButton {
|
|
required property int modelData
|
|
|
|
text: `${modelData}m`
|
|
tone: DesktopPreferences.get("focusDurationMinutes") === modelData ? "accent" : "normal"
|
|
onClicked: SystemSettings.commitPreference("focusDurationMinutes", modelData)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SettingRow {
|
|
label: FocusSession.active ? `Active on ${FocusSession.workspaceLabel}` : "No active focus session"
|
|
detail: FocusSession.active ? `${FocusSession.remainingText} remaining` : "Start one without leaving Settings"
|
|
divider: false
|
|
controlWidth: 120
|
|
|
|
SettingsButton {
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
text: FocusSession.active ? "Show controls" : "Start focus"
|
|
tone: FocusSession.active ? "normal" : "accent"
|
|
onClicked: FocusSession.reveal()
|
|
}
|
|
}
|
|
}
|
|
}
|