Auto-snap child viewport to bottom when typing into scrollback
Typing into a focused child while its emulator viewport was scrolled up left the keystroke heading to the PTY but the input box invisible below the visible region — it looked like typing did nothing. processStdin's flushForward now sets pendingViewportBottom whenever bytes are actually injected, so the existing post-loop handler snaps the viewport and repaints. Wheel events and Ctrl-B paths are untouched: both are intercepted before reaching forward, so wheel still scrolls into history and Ctrl-B is still the explicit escape hatch. Only bytes that would actually reach the child PTY trigger the snap.
This commit is contained in:
@@ -7,6 +7,12 @@ loosely follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
- Typing into a focused child while its emulator viewport is
|
||||||
|
scrolled up into scrollback history now auto-snaps the viewport
|
||||||
|
back to the live area. Previously the keystroke reached the
|
||||||
|
child PTY but the input box was off-screen below the visible
|
||||||
|
region, so it looked like typing did nothing. Wheel scrolling
|
||||||
|
and Ctrl-B are unchanged; only forwarded keystrokes snap.
|
||||||
- Top tab bar now keeps the top-level agent's tab highlighted
|
- Top tab bar now keeps the top-level agent's tab highlighted
|
||||||
when focus is on one of its sub-agents (or on a Processes pane
|
when focus is on one of its sub-agents (or on a Processes pane
|
||||||
entry, matching the existing agent-tree behavior). Previously
|
entry, matching the existing agent-tree behavior). Previously
|
||||||
|
|||||||
@@ -1323,6 +1323,15 @@ func (st *uiState) processStdin(chunk []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
forward := make([]byte, 0, len(chunk))
|
forward := make([]byte, 0, len(chunk))
|
||||||
|
|
||||||
|
var pendingAction *paletteAction
|
||||||
|
var pendingNav navEntry
|
||||||
|
var pendingRestartID string
|
||||||
|
var pendingViewportDelta int
|
||||||
|
var pendingViewportBottom bool
|
||||||
|
var pendingPadStep int
|
||||||
|
var pendingPadExit bool
|
||||||
|
|
||||||
flushForward := func() {
|
flushForward := func() {
|
||||||
if len(forward) == 0 {
|
if len(forward) == 0 {
|
||||||
return
|
return
|
||||||
@@ -1337,19 +1346,16 @@ func (st *uiState) processStdin(chunk []byte) {
|
|||||||
if prev != OwnerUser {
|
if prev != OwnerUser {
|
||||||
go st.drawStatusLine()
|
go st.drawStatusLine()
|
||||||
}
|
}
|
||||||
|
// Auto-snap the emulator viewport to the live area
|
||||||
|
// on any forwarded keystroke. Without this, typing
|
||||||
|
// while scrolled into history leaves the cursor /
|
||||||
|
// echoed bytes off-screen below the visible region.
|
||||||
|
pendingViewportBottom = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
forward = forward[:0]
|
forward = forward[:0]
|
||||||
}
|
}
|
||||||
|
|
||||||
var pendingAction *paletteAction
|
|
||||||
var pendingNav navEntry
|
|
||||||
var pendingRestartID string
|
|
||||||
var pendingViewportDelta int
|
|
||||||
var pendingViewportBottom bool
|
|
||||||
var pendingPadStep int
|
|
||||||
var pendingPadExit bool
|
|
||||||
|
|
||||||
// childOnPrimary captures whether the focused child is on its primary
|
// childOnPrimary captures whether the focused child is on its primary
|
||||||
// screen at the start of this chunk. Wheel events on the primary
|
// screen at the start of this chunk. Wheel events on the primary
|
||||||
// screen scroll the emulator viewport (inline scrollback); on the
|
// screen scroll the emulator viewport (inline scrollback); on the
|
||||||
|
|||||||
Reference in New Issue
Block a user