Skip to content

fix(Console): auto-scroll disengages on output#1823

Open
v1ne wants to merge 1 commit intofluidd-core:developfrom
v1ne:fix-auto-scroll-disengaging
Open

fix(Console): auto-scroll disengages on output#1823
v1ne wants to merge 1 commit intofluidd-core:developfrom
v1ne:fix-auto-scroll-disengaging

Conversation

@v1ne
Copy link
Copy Markdown

@v1ne v1ne commented Apr 24, 2026

Better detect the origin of a scroll event to, by making use of how the virtual scroller works. It is not nice, but it works. Fixes #1783

@v1ne v1ne marked this pull request as draft April 24, 2026 13:33
@v1ne v1ne force-pushed the fix-auto-scroll-disengaging branch 2 times, most recently from 8eb5224 to cb5471b Compare April 25, 2026 20:52
@v1ne v1ne changed the title fix(Console): Pause auto-scroll on user input only, fixing #1783 fix(Console): auto-scroll disengages on output Apr 25, 2026
@v1ne v1ne marked this pull request as ready for review April 26, 2026 01:15
@v1ne v1ne force-pushed the fix-auto-scroll-disengaging branch from cb5471b to 448182c Compare May 4, 2026 22:13
@pedrolamas pedrolamas requested a review from Copilot May 5, 2026 21:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to fix sporadic console auto-scroll disengagement (#1783) by distinguishing user-driven scrolls from programmatic scroll adjustments triggered by vue-virtual-scroller item measurement.

Changes:

  • Adds a “programmatic scroll window” (rAF frame counter) to ignore scroll events that are caused by internal scrollTop adjustments.
  • Hooks into DynamicScroller internals (vscrollData.sizes) to detect upcoming measurement-driven scroll adjustments and pre-mark them as programmatic.
  • Reworks the scroll pause/unpause logic to only pause on non-latest, non-programmatic scrolls, and to resume when the view returns to latest output.


<script lang="ts">
import { Component, Prop, Mixins, Watch, Ref, PropSync } from 'vue-property-decorator'
import consola from 'consola'
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Folded into commit.

Comment on lines +119 to +131
// DynamicScroller's internal `itemsWithSize` watcher adjusts scrollTop on item
// measurement, producing a scroll event indistinguishable from user input.
// Mirror vscrollData.sizes so we can open a programmatic window before that event.
const scroller = this.dynamicScroller as unknown as {
vscrollData?: { sizes: Record<string | number, number> }
}
const vscrollData = scroller.vscrollData
if (vscrollData) {
this._stopSizesWatcher = this.$watch(
() => vscrollData.sizes,
() => this.markProgrammatic(),
{ deep: true }
)
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am open for any cheaper solution that actually works. But there is no public API on the scroller to support this.

Comment on lines +170 to +182
markProgrammatic (frames = 2) {
this._programmaticFrames = Math.max(this._programmaticFrames, frames)
if (this._programmaticRaf === null) {
const tick = () => {
this._programmaticFrames--
if (this._programmaticFrames > 0) {
this._programmaticRaf = requestAnimationFrame(tick)
} else {
this._programmaticRaf = null
}
}
})
this._programmaticRaf = requestAnimationFrame(tick)
}
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will not be reused.

The original onScroll delegated to updateScrollingPaused() with no way
to distinguish user input from DynamicScroller's internal scrollTop
corrections. Appending a line triggers item measurement, which causes
DynamicScroller's itemsWithSize watcher to rewrite scrollTop; the
resulting scroll event would falsely pause auto-scroll if the view was
momentarily off-bottom.

The fix introduces a frame counter primed by watching vscrollData.sizes,
the same reactive store itemsWithSize observes. Because Vue 2 flushes
watchers in ascending creation-ID order, this watcher always fires before
the correction's scroll event arrives as a macrotask, so the programmatic
window is guaranteed to be open when onScroll runs. onScroll then only
pauses when no programmatic window is active and the view is not at the
latest position, a state reachable only via native scrollbar input, which
produces no pointer events.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Dennis Schneider <v1ne2go@gmail.com>
@v1ne v1ne force-pushed the fix-auto-scroll-disengaging branch from f4adc67 to db949e5 Compare May 5, 2026 23:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Console still stops scrolling

2 participants