Make Shell a category, the bar legible, and the dock a real dock

Desktop & Dock becomes Shell — Bar, Dock, Control Center, Tiling,
Workspaces — the home for everything Quickshell draws. The settings-
management cluster moves to System as Sync & Backup, Appearance's
Shell tab dissolves, and 24-hour time finally lives on Date & Time,
which always owned it.

The bar gets what it never had: a way to survive the wallpaper. A
second neutral text family (follow theme, or forced light or dark),
a one-layer shadow under every glyph, and a gradient scrim for
wallpapers nothing else survives — all off by default, pixel-identical
until asked. Widgets earn toggles (weather, media, clipboard, calendar
countdown), the vitals cluster stops leaving a dead pill behind, and
Control Center's sections learn to step aside.

The dock graduates from MVP: a context menu with window rows, pin,
unpin, quit and new-window; scroll an icon to cycle its windows; drag
to reorder on the dock itself; hover previews with one-shot captures;
and "Add App to Dock" in the launcher. Three real bugs died en route —
menus that slid away with the autohide, a readonly-property crash on
every menu open, and a drag that drifted half a slot per icon on side
docks. The pinned-apps editor in Settings becomes a drag strip.

166 contracts; the full suite is green except two live display and
switcher tests that cannot run behind a locked session — re-verified
on unlock.

Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
Gabriel Brown
2026-08-24 04:28:20 -04:00
parent 4d7a194300
commit f8f5b25510
77 changed files with 2982 additions and 800 deletions
+30 -7
View File
@@ -23,6 +23,9 @@
# centred while its reveal strip spans the whole edge -- so a region that
# forgets the body's own offset lands somewhere the pointer is not, hover
# drops on the frame the dock arrives, and it hides under a still cursor.
# 8. The dock's own drag-to-reorder commits once, on release, and measures a
# slot from a real icon rather than assuming one -- a DockItem is taller
# than it is wide, so a constant is wrong on one of the two orientations.
#
# The geometry checks launch isolated shells against a temporary config. The
# real settings are read to build them and never written.
@@ -33,14 +36,14 @@ repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
shell_dir="$repo_dir/config/dot/quickshell"
dock="$shell_dir/modules/dock/Dock.qml"
body="$shell_dir/modules/dock/DockBody.qml"
editor="$shell_dir/modules/settings/DockPinsEditor.qml"
strip="$shell_dir/modules/settings/DockPinsStrip.qml"
fail() {
printf 'dock position contract: %s\n' "$1" >&2
exit 1
}
for path in "$dock" "$body" "$editor"; do
for path in "$dock" "$body" "$strip"; do
[[ -r "$path" ]] || fail "missing $path"
done
@@ -57,12 +60,32 @@ grep -q 'implicitWidth: root.vertical ? ' "$dock" \
grep -q 'wanted.length === 0' "$dock" \
|| fail 'an empty screen list is not treated as every screen'
grep -q 'preventStealing: true' "$editor" \
grep -q 'preventStealing: true' "$strip" \
|| fail 'the drag grip does not set preventStealing, so the page will scroll instead of reordering'
# The arrows are the keyboard-reachable path and predate the grip. A grip is not
# a replacement for them.
grep -q 'text: "↑"' "$editor" \
|| fail 'the move-up button was removed, leaving no keyboard-reachable reorder'
# A drag is not reachable from the keyboard, so the strip owes the keyboard its
# own path. The old editor spelled it as ↑/↓ buttons; the strip spells it as
# arrow keys on a focused icon. Either way it has to exist.
grep -q 'Keys.onLeftPressed' "$strip" && grep -q 'Keys.onRightPressed' "$strip" \
|| fail 'the pinned strip offers no keyboard-reachable reorder'
grep -q 'activeFocusOnTab: true' "$strip" \
|| fail 'a pinned icon cannot be reached by Tab, so the keyboard reorder is unreachable'
# ── 8. The dock's own drag ─────────────────────────────────────────────────
# Dragging an icon along the dock moves the same pin the strip does, so it has
# the same two ways to go wrong.
# One write per gesture. Committing per slot crossed rewrites settings.json a
# dozen times for one drag, and every rewrite re-evaluates the model underneath
# the gesture.
[[ "$(grep -c 'DesktopPreferences.set("dockPinned"' "$body")" -eq 1 ]] \
|| fail 'the dock commits its reorder more than once per gesture, or not through DesktopPreferences'
# A DockItem is taller than it is wide -- the running dots sit under the icon --
# so a slot down a side dock is further than a slot across a bottom one. Reading
# the pitch from the item that started the drag is what keeps both honest; a
# constant here was wrong on one of the two orientations.
grep -q 'signal dragStarted(real pitch)' "$shell_dir/modules/dock/DockItem.qml" \
|| fail 'the dock drag assumes a slot size instead of measuring the item, so a side dock steps wrong'
# ── 5. Reordering keeps every entry, exactly once ───────────────────────────