Commit Graph
13 Commits
Author SHA1 Message Date
Gabriel Brown 8b1205e4b8 Tier 0: render what the services already decided, honestly
Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
2026-08-25 00:24:30 -04:00
Gabriel Brown 9ffaf45a4d Make every settings row reachable, and every accessibility switch honest
Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
2026-08-24 21:03:36 -04:00
Gabriel Brown d5b6e62515 Bound the notification app list, and give Focus a real editor
Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
2026-08-24 14:25:26 -04:00
Gabriel Brown 07db1068f1 Review everything shipped this weekend, and fix what the reviewers caught
Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
2026-08-24 13:29:42 -04:00
Gabriel Brown b58371bb35 Give Sound the whole story, and keep the buttons inside the card
Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
2026-08-24 11:39:16 -04:00
Gabriel Brown 3d21e20041 Make every control tell the truth
The audit's first tier, in one change: every case found where the interface
asserted something the system did not do.

Twenty-one compositor-owned preferences -- the whole Mouse & Touchpad page,
plus window layout, snapping, dim-inactive and the magnifier -- had the live
half (hyprctl eval) and not the config-time half, so they quietly reverted on
every hyprctl reload. All 70 hypr-backed keys now have a prefs.get() in the
Lua, and hypr-prefs-contract pins both the presence and that the Lua fallback
equals the schema default, which is how the touchpad page misreported natural
scrolling on first boot.

The idle generator fell back from unwritten battery keys to the AC values
while the Power page displayed the schema defaults: a fresh laptop showed
"suspend at 20 minutes" and generated no suspend listener, then discharged to
zero in a bag. Unwritten keys now use the defaults the page shows
(idle-defaults-contract pins generator to schema; idle-config-contract
re-pinned to the new rule with the tradeoff recorded), and change-settings
enables managed idle on any machine with a battery -- without starting
hypridle in whatever session the installer runs under.

The per-app lock-screen notification switches wrote fields nothing read:
hyprlock cannot render notifications. Removed, with the rule model shrunk to
{enabled}, stale stored fields dropped at normalization, and the contract now
forbidding the page from growing lock-screen switches it cannot honor.

The battery warning thresholds were searchable, documented as "Found on
Power & Lock", and rendered nowhere -- and crossing the low threshold changed
only a glyph's color. Both sliders now exist where search was already sending
people, and low battery publishes a real notification at important priority.

Three handoffs opened GNOME panels that are inert in a Hyprland session. The
keyboard handoff is gone (that panel writes gsettings nothing here reads, and
the working controls sat on the same page); Connectivity gains a Wi-Fi row
that opens GNOME's actual Wi-Fi panel -- hidden SSIDs and 802.1X finally have
a road -- beside the network row that legitimately drives NetworkManager; the
universal-access handoff is gone, its few working toggles being controls this
app already owns. And the accessibility page now gives the true reason sticky
keys are missing: each Wayland compositor implements its own and Hyprland
does not yet -- not "an X11 feature with no Wayland equivalent," which sent
people to the wrong conclusion about the platform.

Claude-Session: https://claude.ai/code/session_01Epx9ZC1gwm81K3jm9x9CKh
2026-08-23 11:43:39 -04:00
Gabriel Brown f53ca16392 Make the focus exception list real, or it was a page telling a lie
The mode data model shipped with an allow list and nothing that read it. The
summary would say "2 apps may interrupt" while notification delivery never
consulted the list and no editor could set it. That is the dead row this work
has spent its time removing, introduced by the work itself.

The banner gate consults the mode in force now, and the list can be edited from
the applications that have actually sent a notification -- an exception for
something that never notifies is not a choice worth offering.

Exceptions belong to a mode. allowedApps is empty whenever no mode is active, so
a Do Not Disturb switched on by hand stays absolute and nothing can leak into
it. That scoping is asserted, not just written.

Verifying this took three attempts, and the second was a real defect in the
guard rather than in the code. The contract grep for FocusModes.allows matched
the comment that explains it, so the check passed with the enforcement deleted.
It matches the gate expression now. A guard a comment can satisfy is not a
guard, and this is the third time prose has satisfied one here.

Claude-Session: https://claude.ai/code/session_01BRvzt4H8XXLPVH5MyYdk9L
2026-08-20 02:23:30 -04:00
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
Gabriel Brown 8b59b78d9f Settle process-signal races across the services layer
A Process's exited and streamFinished signals aren't guaranteed to
fire in order, and several services decided an outcome on whichever
fired first: KdeConnect could report a successful file transfer as
failed if exited landed before the real stdout payload; Clipboard
could present a failed history query as an empty-but-healthy one;
Brightness could strand the last queued write of a drag; SoundFeedback
and SystemLocale could drop or misapply a rapid second toggle/click
because re-arming an already-running Process is a no-op. All five now
wait for both signals and let the authoritative one decide, matching
the pattern HomeAssistantConfig.qml already used correctly.

Health's "copy report" never enabled stdin, so it copied nothing
while claiming success. Capture announced every recording as saved
regardless of the recorder's actual exit code. Connectivity never
restarted Bluetooth discovery when the adapter was enabled from an
already-open page. CalendarAgenda left the UI in "loading" forever if
its helper died at startup, and the helper itself could crash
unguarded instead of reporting unavailable. Geocoding silently
dropped a query typed while the previous one was still in flight.
Notifs leaked tracked-but-undisplayed notifications under Do Not
Disturb, and dismissAll() skipped them.

Claude-Session: https://claude.ai/code/session_01E6TJUAh41HaP25MVHWkhRZ
2026-08-18 21:23:07 -04:00
Gabriel Brown eff0bc44ff fix: resolve persisted notification app labels 2026-08-18 06:14:07 -04:00
Gabriel Brown c038c57278 fix: harden notification application rule integration 2026-08-18 06:14:07 -04:00
Gabriel Brown 420b7aa1a6 feat: add notification application rules 2026-08-18 06:14:07 -04:00
Gabriel Brown 5248883e4b Build the Panama Hyprland desktop 2026-08-17 10:32:55 -04:00