-
Notifications
You must be signed in to change notification settings - Fork 496
fix(terminal): defer keyword scroll refresh while Enter is pending #2880
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
315e596
4935066
6c4e27c
fbaa038
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -157,6 +157,13 @@ export class KeywordHighlighter implements IDisposable { | |
| clearTimeout(this.enterInputIdleTimer); | ||
| this.enterInputIdleTimer = null; | ||
| } | ||
| // Drop any pending user-scroll refresh so Enter echo cannot finish a | ||
| // scroll pass that rescans/repaints still-visible keyword decorations | ||
| // before onWriteParsed owns the write path (Ubuntu RTT). | ||
| if (this.pendingRefreshReason === "scroll") { | ||
| this.cancelQueuedRefreshSchedule(); | ||
| this.pendingRefreshReason = "write"; | ||
| } | ||
| } | ||
| }), | ||
| // When new data is written, refresh on the next frame so highlights land | ||
|
|
@@ -706,6 +713,20 @@ export class KeywordHighlighter implements IDisposable { | |
| } | ||
|
|
||
| private triggerViewportChangeRefresh() { | ||
| // Enter echo often emits onScroll before onWriteParsed. After an idle gap | ||
| // lastWriteAt looks stale and lastRenderRange is usually null (cleared by | ||
| // the previous write refresh), so the user-scroll path would synchronously | ||
| // rescan the viewport and flash keywords still on screen. While Enter | ||
| // output is pending, skip scroll refresh but mark dirty so writeParsed / | ||
| // idle-clear can catch up (including user scroll during the window). | ||
| if (this.enterInputPending) { | ||
| if (this.pendingRefreshReason === "scroll") { | ||
| this.cancelQueuedRefreshSchedule(); | ||
| this.pendingRefreshReason = "write"; | ||
| } | ||
| this.markVisibleRangeDirty(); | ||
| return; | ||
| } | ||
| const now = performance.now(); | ||
| const buffer = this.term.buffer.active; | ||
| const isBrowsingScrollback = buffer.viewportY < buffer.baseY; | ||
|
|
@@ -1061,6 +1082,10 @@ export class KeywordHighlighter implements IDisposable { | |
| this.enterInputIdleTimer = setTimeout(() => { | ||
| this.enterInputIdleTimer = null; | ||
| this.enterInputPending = false; | ||
| // Catch up any viewport motion deferred while Enter protection blocked | ||
| // scroll refresh (e.g. user scrolled during the post-Enter window). | ||
| this.markVisibleRangeDirty(); | ||
| this.triggerRefresh("debounced", "write"); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When Enter launches output that trips large-output pressure while scrollback is saturated, the pressure state intentionally remains active for two Useful? React with 👍 / 👎. |
||
| }, KeywordHighlighter.WRITE_PRUNE_IDLE_MS); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the remote PTY produces no write after Enter—for example, with echo disabled or a stalled connection—
onWriteParsednever runs.enterInputPendingis set byonData, but its only clear timer is armed insideonWriteParsed, so this new early return suppresses every subsequent user-scroll refresh indefinitely. Newly revealed scrollback lines therefore remain unscanned and unhighlighted until unrelated output arrives; arm a fallback timer fromonDataor otherwise time-bound this guard.Useful? React with 👍 / 👎.