mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-07 02:51:50 +00:00
fix(tui): keep streaming progress stable during interaction
This commit is contained in:
parent
1c964ed43f
commit
355e0ae960
15 changed files with 278 additions and 106 deletions
|
|
@ -29,7 +29,7 @@ import {
|
|||
FOCUS_IN,
|
||||
FOCUS_OUT
|
||||
} from '../termio/csi.js'
|
||||
import { DBP, DFE, DISABLE_MOUSE_TRACKING, EBP, EFE, HIDE_CURSOR, SHOW_CURSOR } from '../termio/dec.js'
|
||||
import { DBP, DFE, DISABLE_MOUSE_TRACKING, EBP, EFE, SHOW_CURSOR } from '../termio/dec.js'
|
||||
|
||||
import AppContext from './AppContext.js'
|
||||
import { ClockProvider } from './ClockContext.js'
|
||||
|
|
@ -206,10 +206,9 @@ export default class App extends PureComponent<Props, State> {
|
|||
)
|
||||
}
|
||||
override componentDidMount() {
|
||||
// In accessibility mode, keep the native cursor visible for screen magnifiers and other tools
|
||||
if (this.props.stdout.isTTY) {
|
||||
this.props.stdout.write(HIDE_CURSOR)
|
||||
}
|
||||
// Keep the native terminal cursor visible. Ink parks it at the declared
|
||||
// input caret after each frame, so the terminal emulator provides the
|
||||
// normal blinking block/bar without React-driven blink re-renders.
|
||||
}
|
||||
override componentWillUnmount() {
|
||||
if (this.props.stdout.isTTY) {
|
||||
|
|
@ -470,7 +469,7 @@ export default class App extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
if (this.props.stdout.isTTY) {
|
||||
this.props.stdout.write(HIDE_CURSOR + EFE)
|
||||
this.props.stdout.write(EFE)
|
||||
}
|
||||
|
||||
this.inputEmitter.emit('resume')
|
||||
|
|
@ -569,18 +568,19 @@ function processKeysInBatch(app: App, items: ParsedInput[], _unused1: undefined,
|
|||
|
||||
/** Exported for testing. Mutates app.props.selection and click/hover state. */
|
||||
export function handleMouseEvent(app: App, m: ParsedMouse): void {
|
||||
// Allow disabling click handling while keeping wheel scroll (which goes
|
||||
// through the keybinding system as 'wheelup'/'wheeldown', not here).
|
||||
if (isMouseClicksDisabled()) {
|
||||
return
|
||||
}
|
||||
|
||||
const sel = app.props.selection
|
||||
// Terminal coords are 1-indexed; screen buffer is 0-indexed
|
||||
const col = m.col - 1
|
||||
const row = m.row - 1
|
||||
const baseButton = m.button & 0x03
|
||||
|
||||
// Allow disabling app click/selection handling while keeping wheel scroll
|
||||
// and DOM mouse dispatch alive. Put this after coordinate/button decoding
|
||||
// and exempt non-left buttons so scrollbar/right-click handlers still work.
|
||||
if (isMouseClicksDisabled() && baseButton === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if (m.action === 'press') {
|
||||
if ((m.button & 0x20) !== 0 && baseButton === 3) {
|
||||
if (app.mouseCaptureTarget) {
|
||||
|
|
|
|||
|
|
@ -122,6 +122,19 @@ function ScrollBox({ children, ref, stickyScroll, ...style }: PropsWithChildren<
|
|||
})
|
||||
}
|
||||
|
||||
const scrollByNow = (dy: number) => {
|
||||
const el = domRef.current
|
||||
|
||||
if (!el) {
|
||||
return
|
||||
}
|
||||
|
||||
el.stickyScroll = false
|
||||
el.scrollAnchor = undefined
|
||||
el.pendingScrollDelta = (el.pendingScrollDelta ?? 0) + Math.floor(dy)
|
||||
scrollMutated(el)
|
||||
}
|
||||
|
||||
useImperativeHandle(
|
||||
ref,
|
||||
(): ScrollBoxHandle => ({
|
||||
|
|
@ -155,22 +168,7 @@ function ScrollBox({ children, ref, stickyScroll, ...style }: PropsWithChildren<
|
|||
}
|
||||
scrollMutated(box)
|
||||
},
|
||||
scrollBy(dy: number) {
|
||||
const el = domRef.current
|
||||
|
||||
if (!el) {
|
||||
return
|
||||
}
|
||||
|
||||
el.stickyScroll = false
|
||||
// Wheel input cancels any in-flight anchor seek — user override.
|
||||
el.scrollAnchor = undefined
|
||||
// Accumulate in pendingScrollDelta; renderer drains it at a capped
|
||||
// rate so fast flicks show intermediate frames. Pure accumulator:
|
||||
// scroll-up followed by scroll-down naturally cancels.
|
||||
el.pendingScrollDelta = (el.pendingScrollDelta ?? 0) + Math.floor(dy)
|
||||
scrollMutated(el)
|
||||
},
|
||||
scrollBy: scrollByNow,
|
||||
scrollToBottom() {
|
||||
const el = domRef.current
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue