Fold thirty-one settings pages into fifteen categories with tabs

The sidebar was a flat scan of thirty-one rows; now it reads like a
settings app. Multi-subject categories (Input, Network & Sharing,
Applications, Users & Accounts, Privacy & Security, System) carry an
Appearance-style tab strip above the page, drawn by the shell so the
leaf pages themselves are untouched. The taxonomy lives in one new
file, services/SettingsRoutes.qml; the sidebar, the strip, route
validation, search breadcrumbs, and both generators derive from it.

ShellState.settingsPage still holds leaf ids, so every deep link, IPC
call, and search result keeps working — and now lands on the exact
tab. Dictation moves out of Sound onto its own page under Input, with
a handoff back to Sound for the microphone. The strip scrolls when
System's nine tabs outgrow a tiled window. All 161 contracts pass.

Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
Gabriel Brown
2026-08-23 20:21:31 -04:00
parent 50077a0c31
commit 5490fd285d
35 changed files with 816 additions and 288 deletions
@@ -1,8 +1,9 @@
// The first thing a new machine shows.
//
// Panama has thirty settings pages, which is the opposite of the usual
// problem: somebody arriving from GNOME, macOS or Windows cannot tell which
// four things matter. This is those four things, once, on the first start.
// Panama has fifteen settings categories and thirty-odd pages inside them,
// which is the opposite of the usual problem: somebody arriving from GNOME,
// macOS or Windows cannot tell which four things matter. This is those four
// things, once, on the first start.
//
// Deliberately not a tour. Nobody reads a tour, and a multi-step wizard on a
// desktop somebody just installed is another thing standing between them and
@@ -14,8 +15,9 @@
// have -- and so this cannot drift the way a hand-written list would.
//
// Shown once, tracked by the `welcomeSeen` preference. It stays reachable
// afterwards from the launcher and from Settings > About, because the moment
// somebody wants it again is exactly the moment a one-shot has thrown it away.
// afterwards from the launcher and from Settings > System > About, because
// the moment somebody wants it again is exactly the moment a one-shot has
// thrown it away.
import Quickshell
import Quickshell.Wayland