fix: repaint boo ui after a session resets the terminal (RIS)#70
Merged
Conversation
In `boo ui` the wheel over the viewport pages local scrollback only when the focused session is on the primary screen and has not asked for mouse reporting. The daemon strips alternate-screen toggles from passthrough and tells the client which screen the application is on out of band, via a `.screen` message sent only when its filter detects a 47/1047/1049 toggle (plus on attach and redraw). A full reset (RIS, `ESC c`) returns the terminal to the primary screen without such a toggle, so the filter never reported a switch and the client's `app_alt` stayed stuck true. The wheel then sent arrow keys forever instead of scrolling, and only re-attaching (exit and re-enter `boo ui`, or a C-a l redraw) recovered it. Repaint whenever the active screen changes, even when the alt-screen filter saw no toggle, so a fresh repaint and `.screen` reach the client. Generated by Coder Agents on behalf of @kylecarbs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
In
boo ui, mouse-wheel scrolling could get stuck on a specific sessionuntil you exit and re-enter
boo ui. A session that returns to theprimary screen via a full terminal reset (RIS,
ESC c) instead of theusual
CSI ?1049 lleft the client believing the app was still on thealternate screen, so the wheel kept emitting arrow keys instead of
paging local scrollback.
Why
The wheel-over-viewport handler picks its behaviour from the per-session
app_altflag (src/ui.zig), which is updated only by the daemon's.screenmessage..screenis sent fromrepaintTo, which the daemoncalls only on attach, on a
C-a lredraw, or when its alt-screen filterstrips a
47/1047/1049toggle (src/daemon.zig,src/altscreen.zig).RIS resets the terminal to the primary screen without any such toggle,
so the filter never reported a switch, no
.screenwas sent, andapp_altstayed stucktrue. Mouse state recovered fine because RISpasses through to the view terminal; only the out-of-band
app_altwasorphaned. Re-attaching (exit/re-enter, or
C-a l) was the only fix.Fix
In the daemon output path, capture the active screen before feeding each
chunk and repaint when it changed even if the filter saw no toggle. That
re-sends
.screen(and re-seeds the view) after a RIS, and also hardensagainst any other non-toggle screen change.
Test
ui: wheel scrolls again after a session resets the terminal: enters the alt screen, issuesESC c, thenasserts a wheel-up pages local scrollback. It times out (arrows sent)
on the pre-fix daemon and passes with the fix.
zig build test(117 passed),zig build test-integration(69passed), and
zig fmt --checkare green locally.Diagnosis / decision log
Wheel routing in
wheelViewport(src/ui.zig):view.term.flags.mouse_event != .none-> forward the mouse to the appview.app_alt-> send arrow keys per tickscrollbackhint)app_alt(defaultfalse) is a clientViewfield set only by adaemon
.screenmessage..screenis emitted exclusively byrepaintTo, whose only callers are attach,.redraw(C-a l), and afilter-detected alt toggle. The alt-screen filter recognises only modes
47/1047/1049.
A
RIS(ESC c):mode, but is not a 47/1047/1049 toggle, so
result.switchedstaysfalse and no repaint/
.screenis sent;mouse_eventclears correctlythere;
app_altstucktrue, so the wheel takes branch 2 forever.Re-attaching (exit/re-enter) builds a fresh
View(app_altdefaultsfalse) and the attach repaint sends.screen= primary;C-a lforwards C-a l as input, which the daemon maps to
.redraw-> repaint ->.screen= primary. Both prove the daemon terminal really is on theprimary screen after the reset.
Real-world trigger: anything that emits RIS while a session has been on
the alt screen, e.g.
reset/tput reset, or a TUI/agent thathard-resets the terminal on startup or exit instead of using
rmcup.Considered and rejected as the cause (covered by passing tests during
diagnosis): normal alt-screen exit, alt+mouse exit in either ordering,
and primary-screen mouse enable/disable all resync correctly because
every repaint's
reset_state_sequenceclears mouse and the formatterre-emits the daemon's current modes.
Generated by Coder Agents on behalf of @kylecarbs.