Give the active-session composer the shared [↑] send hitbox - #5773
Conversation
Startup already paints `[↑]` from tideline_composer_geometry. The active-session ComposerWidget now restores that same three-cell affordance after input and routes pointer clicks through decide_composer_submit plus the existing Enter dispatch branches. Compact/quiet composers still shed the control. Empty clicks do not move the caret or consume the draft. Refs #5771 Signed-off-by: Hunter Bown <hmbown@gmail.com>
…eline-active-composer-send-20260830
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a506204289
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
| } | ||
|
|
||
| let Some(input) = app.handle_composer_enter() else { |
There was a problem hiding this comment.
Preserve completion state before submitting send clicks
When mention autocomplete or history search is active, clicking [↑] reaches this direct handle_composer_enter() call after only slash completion was checked. Keyboard Enter instead applies the selected mention or accepts the history match before submission, so the mouse path can dispatch a partial @ token or the search query as a real message. Route clicks through the same pre-submit state handling as the keyboard path.
AGENTS.md reference: crates/tui/AGENTS.md:L19-L21
Useful? React with 👍 / 👎.
| crate::tui::composer_chrome::render_tideline_composer_submit( | ||
| area, | ||
| buf, | ||
| &self.app.ui_theme, | ||
| true, | ||
| crate::tui::color_compat::ascii_safe_enabled(), |
There was a problem hiding this comment.
Reserve input cells for the send affordance
When a single-line draft or the final wrapped line reaches the right edge, this post-content render overwrites three input cells with [↑]; the wrapping and cursor geometry still use the entire inner width, so recently typed characters and sometimes the caret disappear beneath the button. Reserve the submit columns in the shared content geometry rather than painting chrome over user content.
AGENTS.md reference: crates/tui/AGENTS.md:L19-L21
Useful? React with 👍 / 👎.
| if !composer_enclosure_enabled(app) || area.width < 6 || area.height < 3 { | ||
| return None; | ||
| } | ||
| Some(crate::tui::composer_chrome::tideline_composer_geometry(area).submit) |
There was a problem hiding this comment.
Disable the submit hitbox when the panel is shed
At composer widths 6–11 with composer_border enabled, this returns a submit rectangle even though enclosed_composer_panel_fits requires width 12 and the renderer therefore sheds the panel and never paints [↑]. Clicking those invisible bottom-row cells is still intercepted and can send the draft, so the hitbox predicate must match the renderer's panel predicate.
AGENTS.md reference: crates/tui/AGENTS.md:L19-L21
Useful? React with 👍 / 👎.
active_composer_submit_rect created a click target at widths 6-11 and heights >= 3, but the painter only draws the enclosure and its [↑] affordance when enclosed_composer_panel_fits holds (width >= 12). The hitbox now uses that same predicate, so no invisible submit target can exist where the panel sheds. Also repair the empty-composer quiet-row test for this branch's own design: the quiet content row now hosts the shared send affordance on exactly its recorded hitbox cells. Refs #5771 Signed-off-by: Hunter Bown <hmbown@gmail.com>
…inter dispatch_session_composer_submit mirrored the keyboard Enter branches by hand and had already drifted (edit_in_progress undo ordering). Extract submit_decided_composer_input — slash-menu selection, draft consumption, and the memory/shell/command/message branches — used by both the Enter arm and the mouse send dispatcher. Caller-specific gates stay put: transcript-only shortcuts and forced-submit chords remain keyboard-only; SendQueuedNow and the paste-burst probe remain in the dispatcher. No event behavior changes. Refs #5771 Signed-off-by: Hunter Bown <hmbown@gmail.com>
…20260830' into feat/tideline-active-composer-send-20260830
Closes #5771 (source + local/PTY paint only; no merge or release action).
Stacked on #5770.
Scope
ComposerWidgetrestores the shared three-cell[\u2191]fromtideline_composer_geometryafter painting input, so a long draft cannot erase it.pending_composer_submitto the Enter chord. The event loop consumes it throughdecide_composer_submit+handle_composer_enter/dispatch_composer_message(same branches as keyboard submit, without transcript-only empty-Enter shortcuts).composer_border = falseor degenerate sizes) omit the control.Local evidence
RUST_MIN_STACK=33554432 cargo test -p codewhale-tui --lib --locked enclosed_composer— 2 passed (paints_the_shared_send_hitbox,send_hitbox_matches_painted_cells).quiet_composer_does_not_paint_a_fake_send_control— passed.active_composer_send_click_queues_the_keyboard_submit_chord— passed.composer_click_focuses_and_send_click_matches_the_keyboard_submit(startup regression) — passed.composer_submit_hint_renders_at_release_floor_widths,composer_keeps_prompt_anchored_after_first_keystroke— passed.cargo clippy -p codewhale-tui --lib --lockedwarning-free under the CI allow list.codewhale-tui --skip-onboarding --no-project-config --mouse-capture) after Startupw(New session):[\u2191]is painted on the live composer at 40x12, 60x16, 80x24, 100x32, and 120x32. Geometry matcheswidth-5on the input row.hello+ Enter queued the draft locally (empty input, hello as queued crumb, no provider). A harness SGR click on the painted[\u2191]cells did not consume the draft; that path is covered by the unit test, not this PTY run.Still explicitly open
TUI-UX-01 is not closed: PTY mouse submit is unverified, hosted CI is unproven, and this does not prove rail/receipts, clean-first-run, provider safety (#5755/#5772), auth, artifacts, or launch readiness. No retired fluke/crown art.