Skip to content

Queued-message UX fixes + prompt/mouse polish - #1

Merged
tdwd merged 4 commits into
mainfrom
fix/queue-tray-overlap
Jul 20, 2026
Merged

Queued-message UX fixes + prompt/mouse polish#1
tdwd merged 4 commits into
mainfrom
fix/queue-tray-overlap

Conversation

@tdwd

@tdwd tdwd commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Four focused commits, split by concern.

Queued-message fixes

  • Budget the pending-tray height so it can't overrun the chat (f9a6aff) — resizeViewport and pendingTray sized the queued-message strip independently; on a short window (or tall prompt) the viewport clamped to its 1-row floor while the tray drew full height, so the frame exceeded the terminal and the strip lapped over the transcript. Now both read one shared budget (trayBudget), the tray truncates to fit (keeping the N queued header + … N more), and viewport + tray always sum to the available height.
  • Up-arrow edits a queued message instead of duplicating it (c313f1a) — while busy, queuing a message then ↑ to edit recalled the text from history but left the original queued, so the unedited original went out and the edit landed as a second item. ↑ on an empty prompt with a queue now pulls the last queued message out of the queue (dequeueLast) for editing, so re-sending replaces it.

Prompt / mouse polish (in-progress work)

  • Re-anchor the prompt's scroll after it grows (1fad67a) — a newline/soft-wrap grew the textarea while its internal scroll still pointed at the old height, showing only the last row(s). syncPromptHeight now re-anchors to the top and restores the cursor.
  • Drop into select mode on shift+scroll (83dedbc) — where the terminal forwards shift+wheel, treat it as a shortcut into select mode (same state /mouse off reaches), via a shared setMouseCapture.

Tests

New coverage: chrome_test.go (tray budget invariant + frame-fits-window), queue_test.go (recall-and-replace), TestNewlineKeepsFirstRowVisible. go vet clean, full suite green.

tdwd added 4 commits July 20, 2026 11:46
resizeViewport and pendingTray sized the queued-message strip
independently. On a short window (or with a tall prompt), the viewport
clamped to its 1-row floor while the tray still drew full height, so the
composed frame exceeded the terminal and the queue strip lapped over the
transcript — worse with each queued message.

Share one budget: trayBudget() reserves the tray's rows out of the
transcript's space (keeping a 1-row viewport floor), trayRows clamps the
draw to it, and pendingTray drops message lines — keeping the "N queued"
header and a "… N more" tail — instead of spilling past its reserved
height. viewport + tray now always sum to the available height.

Adds chrome_test.go covering the budget invariant and frame-fits-window.
While Claude was busy, queuing a message then pressing ↑ to edit it
recalled the text from history but left the original on the queue — so
the unedited original was sent as-is and the edit landed as a second
queued item.

Make ↑ queue-aware: on an empty prompt with a non-empty queue, pull the
last queued message out of the queue into the prompt for editing (via
dequeueLast) rather than recalling from history. Re-sending then
replaces it. Further ↑ presses fall through to normal history recall.

Adds queue_test.go covering the recall-and-replace path.
…isible

SetHeight doesn't reset the textarea's internal scroll: a newline or
soft-wrap moved the cursor to a new row while the widget was still its
old, shorter height, scrolling its viewport so the grown prompt showed
only the last row(s). syncPromptHeight now re-anchors to the top when
the content fits the new height and a scroll could have happened (the
height just changed, or we've come back under the cap), restoring the
cursor afterward. Tracks lastPromptRows to detect the over-cap re-entry.

Adds TestNewlineKeepsFirstRowVisible, driving the real Update loop.
Shift+wheel is the terminal's native text-selection gesture. Where the
terminal forwards it (rather than grabbing it for its own scrollback),
treat it as a shortcut into select mode — the same state /mouse off
reaches — so text can be selected/copied without first running /mouse.
It's one-way (capture off stops the mouse events); /mouse turns it back
on.

Extracts setMouseCapture as the shared entry point for both /mouse and
the gesture, and documents shift+scroll in the help modal and the
/mouse description.
@tdwd
tdwd merged commit 67b79e1 into main Jul 20, 2026
1 check passed
@tdwd
tdwd deleted the fix/queue-tray-overlap branch July 20, 2026 10:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant