You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Operator report: the composer Stop (■) is pushed off the right edge of the screen. It sits in the trailing icon pack next to the composer field (Busy: ▶ enqueue + ■ Stop). The button is still in the widget tree — it is not hittable because it is past the viewport’s right edge.
That is a product break: while a turn is Busy the only in-canvas cancel is that ■ (and Esc). Off-canvas Stop means the operator cannot tap-cancel on the width they are actually using.
Queue-band header (feat(harness): in-canvas Pause for the submit queue (plan #777) #778) — new Pause column on the row immediately above the composer. If that header’s min-size grows the window/canvas wider than the visible viewport, composer is laid out at the wide avail.w and ■ sits at the right of that width — off-screen.
Goals
#
Goal
Success signal
1
Busy ■ Stop is fully inside the visible canvas
stop.x ≥ 0 and stop.x + stop.w ≤ viewport.w at ~390 px and at 600+ px (left rail open or closed)
2
Busy ▶ enqueue stays on-canvas too
Same inequality for the send tag; ▶ left of ■, no overlap with the field
Summary
Operator report: the composer Stop (■) is pushed off the right edge of the screen. It sits in the trailing icon pack next to the composer field (Busy: ▶ enqueue + ■ Stop). The button is still in the widget tree — it is not hittable because it is past the viewport’s right edge.
That is a product break: while a turn is Busy the only in-canvas cancel is that ■ (and Esc). Off-canvas Stop means the operator cannot tap-cancel on the width they are actually using.
Current baseline (live code)
native/harness/src/ui/composer_chrome.zig~197–210gravity_y = 1.0,min_size_contentTOUCH_H×TOUCH_H(40).fieldW(avail_w, busy) = avail_w − (TOUCH_H×n + 8)so a long unbreakable line cannot steal the icon columns.native/harness/src/composer_layout.test.zigstop.x + stop.w ≤ win.w. Window isWIN_LW = 600only — no ~390 px row.docs/harness-limits.mdTouch / mobileui.zigqueue_band.paint(…, avail.w)thenpaintComposerChrome{n} queued+ optional· full/· paused+ Pause (min 64) + Clear (min 56).max_size_content.w = max_float_safe(queue_band.zig~102). Pause landed in #778 (plan #777), now onmain.Two seams are in play (do not assume one without a layout-rect proof):
2×TOUCH_H + 8. Button tag rects include default margin. Tests never run at ~390 px. A too-small reserve or a field min-width floor (min_size_content.w = 120on the textEntry) can slide ■ pastwin.won a phone-width canvas.avail.wand ■ sits at the right of that width — off-screen.Goals
stop.x ≥ 0andstop.x + stop.w ≤ viewport.wat ~390 px and at 600+ px (left rail open or closed)n>0, paused and unpaused, including· fullNon-goals / out of scope
TOUCH_H/SUBMIT_CAP/MAX_ITEMSTesting
composer_layout(or equivalent testing-backend rects)· full/harnessGates:
zig build test-rich(layout tests) +zig build harness -Doptimize=Debug. The interaction itself is also operator-gated at ~390 px.Cloud ops
N/A — no Production mutate. Layout-only harness chrome.
Living docs
docs/harness-limits.mdLayout / composer chrome + Touch / mobile.env.exampleRefs plan #737 / source #734 (icons must not leave the viewport) · PR #778 (Pause/Clear on the queue-band header) · plan #777