fix bottom input box alignment when status bar hidden (T-298)

The composer (and any bottom-most pane content) ran flush into the
window's bottom resize-drag strip when the status bar was hidden, since
the bar normally covers that edge. Reserve ClideResizeBorder.edgeThickness
as a bottom inset in RootLayout whenever the status bar is not visible, so
the interaction zone bottom-anchors consistently either way.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-09 23:36:13 +02:00
co-authored by Claude Opus 4.8
parent cbeb2c2d5a
commit 76346122aa
6 changed files with 113 additions and 2 deletions
+18
View File
@@ -2270,3 +2270,21 @@ Fix (both, per user direction):
Verification: standalone reproducer with both the native chooser AND the filter — size warnings gone, an unrelated GLib-GIO CRITICAL still passes through (filter is scoped, not a blanket mute). `make build-linux` green. CHANGELOG updated under Fixed.', NULL, '2026-06-09 21:21:04', '2026-06-09 21:21:04', '2026-06-09 21:21:04', NULL, '872947bf48bd74c3fb6942ec90149ac5', 1) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-287', 'status', 'in_progress', 'done', NULL, '2026-06-09 21:21:08', '2026-06-09 21:21:08', '2026-06-09 21:21:08', NULL, '931bae221c6780445f00b547da62c8cb', 1) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-298', 'status', 'backlog', 'ready', NULL, '2026-06-09 21:21:30', '2026-06-09 21:21:30', '2026-06-09 21:21:30', NULL, '9aeac5d0a8d6dfeb6adb96ed63dda4eb', 1) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-298', 'status', 'ready', 'in_progress', NULL, '2026-06-09 21:22:26', '2026-06-09 21:22:26', '2026-06-09 21:22:26', NULL, 'b14a5b998bd76cda5bb558fc0faa4be9', 1) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-304', 'parent_id', NULL, 'T-276', NULL, '2026-06-09 21:22:31', '2026-06-09 21:22:31', '2026-06-09 21:22:31', NULL, '0b04f300702a4b9a46d5b591f15e82af', 1) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-304', 'description', NULL, 'The logo-mark spinner shown on in-progress activity/holder cards in the Claude conversation is too small to read as a spinner — it reads as a static speck. Enlarge it so the running state is legible at a glance.
**Where**
- `ClideSpinner` (lib/widgets/src/clide_spinner.dart) — defaults to size 14; renders the logo SVG at width/height = size.
- `ClideStatusIndicator` (lib/widgets/src/clide_status_indicator.dart) — default size 14; maps running→ClideSpinner, success→check, error→cross at the same size.
- Call sites: holder_card.dart:117 and :199 pass `size: 12` — the small value the user is seeing.
**Direction (settle in review)**
- Bump the spinner size on the activity cards (the `size: 12` call sites, and/or the indicator default) to something clearly legible — pull a concrete value from the ui-design control-geometry tokens rather than a magic number.
- Keep the running spinner, success check, and error cross visually balanced at the new size (they share `size`), so the card doesn''t jump when the state settles.
- Check the other ClideSpinner/StatusIndicator consumers (status surfaces) so the bump doesn''t bloat unrelated spots — may warrant sizing the cards explicitly rather than changing the shared default.
**Acceptance**
- The in-progress spinner on conversation activity cards is comfortably distinguishable as a spinning indicator; success/error glyphs stay aligned at the same footprint.', NULL, '2026-06-09 21:22:44', '2026-06-09 21:22:44', '2026-06-09 21:22:44', NULL, '1aec6212db45140ee906592f9ce125ef', 1) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-280', 'status', 'backlog', 'ready', NULL, '2026-06-09 21:32:29', '2026-06-09 21:32:29', '2026-06-09 21:32:29', NULL, '0fcac3a23b0303186fefb36827374616', 1) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-298', 'status', 'in_progress', 'done', NULL, '2026-06-09 21:36:05', '2026-06-09 21:36:05', '2026-06-09 21:36:05', NULL, 'ecf870d28771c1368654195d93ec4dec', 1) ON CONFLICT(hash) DO NOTHING;
+46
View File
@@ -3737,3 +3737,49 @@ Expected: the input box sits correctly flush to the window bottom (or with consi
Notes:
- Audit the bottom-of-window layout stack (composer / interaction zone + status bar). The composer should bottom-anchor independently of the status bar''s visibility.
- Related to the bottom interaction zone work (D-78) and may interact with T-297 (scroll on input resize). Also relevant once the status-bar collapse toggles (T-294) can change what''s in the bar.', 'ready', 'medium', NULL, NULL, NULL, '2026-06-09 16:06:41', '2026-06-09 21:21:30', NULL, 'cc9ab1dee5d58863b3277c896e3e4461', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-298', 'bug', 'T-276', 'Bottom input box is misaligned when the status bar is hidden', 'The bottom input/prompt box (the composer, shown with the edit-pencil affordance on the right) is aligned weird when the status bar is not visible.
Symptom: with the status bar hidden, the input box''s alignment/padding looks off (see screenshot — single-line box spanning full width, content not sitting where it should relative to the window bottom).
Likely cause: the composer''s vertical alignment / bottom padding assumes the status bar is present below it and reserves/relies on that space. When the status bar is hidden, that assumption breaks and the box no longer sits flush/centered correctly.
Expected: the input box sits correctly flush to the window bottom (or with consistent padding) regardless of whether the status bar is visible. Layout should not depend on the status bar being present.
Notes:
- Audit the bottom-of-window layout stack (composer / interaction zone + status bar). The composer should bottom-anchor independently of the status bar''s visibility.
- Related to the bottom interaction zone work (D-78) and may interact with T-297 (scroll on input resize). Also relevant once the status-bar collapse toggles (T-294) can change what''s in the bar.', 'in_progress', 'medium', NULL, NULL, NULL, '2026-06-09 16:06:41', '2026-06-09 21:22:26', NULL, 'c5773b9623efafd5e269a1618f243f66', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-304', 'bug', NULL, 'Activity-card spinner too small to make out — enlarge it', NULL, 'backlog', 'medium', NULL, NULL, NULL, '2026-06-09 21:22:28', '2026-06-09 21:22:28', NULL, '95e2fdd86dbe98e3f911637bcb844072', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-304', 'bug', 'T-276', 'Activity-card spinner too small to make out — enlarge it', NULL, 'backlog', 'medium', NULL, NULL, NULL, '2026-06-09 21:22:28', '2026-06-09 21:22:31', NULL, '20c85ebff9e0a45f7e27ee099b7a2563', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-304', 'bug', 'T-276', 'Activity-card spinner too small to make out — enlarge it', 'The logo-mark spinner shown on in-progress activity/holder cards in the Claude conversation is too small to read as a spinner — it reads as a static speck. Enlarge it so the running state is legible at a glance.
**Where**
- `ClideSpinner` (lib/widgets/src/clide_spinner.dart) — defaults to size 14; renders the logo SVG at width/height = size.
- `ClideStatusIndicator` (lib/widgets/src/clide_status_indicator.dart) — default size 14; maps running→ClideSpinner, success→check, error→cross at the same size.
- Call sites: holder_card.dart:117 and :199 pass `size: 12` — the small value the user is seeing.
**Direction (settle in review)**
- Bump the spinner size on the activity cards (the `size: 12` call sites, and/or the indicator default) to something clearly legible — pull a concrete value from the ui-design control-geometry tokens rather than a magic number.
- Keep the running spinner, success check, and error cross visually balanced at the new size (they share `size`), so the card doesn''t jump when the state settles.
- Check the other ClideSpinner/StatusIndicator consumers (status surfaces) so the bump doesn''t bloat unrelated spots — may warrant sizing the cards explicitly rather than changing the shared default.
**Acceptance**
- The in-progress spinner on conversation activity cards is comfortably distinguishable as a spinning indicator; success/error glyphs stay aligned at the same footprint.', 'backlog', 'medium', NULL, NULL, NULL, '2026-06-09 21:22:28', '2026-06-09 21:22:44', NULL, '4d335acecf697af397d391dab086bd5d', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-280', 'bug', NULL, 'app_test ''Open Folder non-repo'' hangs 10min — runAsync/ReceivePort teardown wedge', 'Pre-existing (reproduces at base commit 3a78dfa, predates the T-267 conversation-rendering epic). The widget test `test/app_test.dart` › "Open Folder on a non-repo path surfaces the ''no git repo'' dialog" times out after 10 minutes; teardown is wedged on `_RawReceivePort._handleMessage`.
Bisected (each a 45s-timeout repro, all on this box):
- A bare `Process.run` inside `tester.runAsync` (no app, no extensions) hangs → `Process.run`-in-`runAsync` leaks its exit ReceivePort here.
- `pumpApp` + empty `runAsync`, and `pumpApp` + a 1.5s real delay → both PASS (boot + runAsync alone is fine).
- The full openFolder tap flow hangs even when project validation is stubbed to a synchronous, pure-Dart `.git` walk (no subprocess) AND `runAsync` is removed — so the wedge is not solely the git subprocess; something in the booted-app + extensions + open-folder command path holds a native port that teardown waits on forever.
Quarantined with `skip:` so the suite/gate stays green. Real fix: find the leaked native async resource (likely a Process/Isolate/FakeDaemonClient port reachable from the open-folder command or app boot under the test harness) and ensure it''s drained/cancelled before teardown — or drive the "no git repo" assertion without booting the resource. Then remove the skip.', 'ready', 'high', NULL, NULL, NULL, '2026-06-08 11:29:22', '2026-06-09 21:32:29', NULL, '9a47d2033458934d77d1110e1ac98cfe', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-298', 'bug', 'T-276', 'Bottom input box is misaligned when the status bar is hidden', 'The bottom input/prompt box (the composer, shown with the edit-pencil affordance on the right) is aligned weird when the status bar is not visible.
Symptom: with the status bar hidden, the input box''s alignment/padding looks off (see screenshot — single-line box spanning full width, content not sitting where it should relative to the window bottom).
Likely cause: the composer''s vertical alignment / bottom padding assumes the status bar is present below it and reserves/relies on that space. When the status bar is hidden, that assumption breaks and the box no longer sits flush/centered correctly.
Expected: the input box sits correctly flush to the window bottom (or with consistent padding) regardless of whether the status bar is visible. Layout should not depend on the status bar being present.
Notes:
- Audit the bottom-of-window layout stack (composer / interaction zone + status bar). The composer should bottom-anchor independently of the status bar''s visibility.
- Related to the bottom interaction zone work (D-78) and may interact with T-297 (scroll on input resize). Also relevant once the status-bar collapse toggles (T-294) can change what''s in the bar.', 'done', 'medium', NULL, NULL, NULL, '2026-06-09 16:06:41', '2026-06-09 21:36:05', NULL, '162be954ae0cc51fa9db0c36b0173cbe', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);