diff --git a/src/vs/workbench/contrib/aideAgent/browser/aideAgentWidget.ts b/src/vs/workbench/contrib/aideAgent/browser/aideAgentWidget.ts index 2ac92c6c07f..ff05dde6d87 100644 --- a/src/vs/workbench/contrib/aideAgent/browser/aideAgentWidget.ts +++ b/src/vs/workbench/contrib/aideAgent/browser/aideAgentWidget.ts @@ -161,6 +161,7 @@ export class ChatWidget extends Disposable implements IChatWidget { } private previousTreeScrollHeight: number = 0; + private _userScrolledAway: boolean = false; private readonly viewModelDisposables = this._register(new DisposableStore()); private _viewModel: ChatViewModel | undefined; @@ -406,6 +407,7 @@ export class ChatWidget extends Disposable implements IChatWidget { if (this.lastItem) { const offset = Math.max(this.lastItem.currentRenderedHeight ?? 0, 1e6); this.tree.reveal(this.lastItem, offset); + this._userScrolledAway = false; } } @@ -634,6 +636,14 @@ export class ChatWidget extends Disposable implements IChatWidget { })); this._register(this.tree.onDidScroll(() => { this._onDidScroll.fire(); + + // Check if user has scrolled away from the bottom + const scrollTop = this.tree.scrollTop; + const renderHeight = this.tree.renderHeight; + const scrollHeight = this.tree.scrollHeight; + + // Consider the user scrolled away if they're not within 2px of the bottom + this._userScrolledAway = scrollTop + renderHeight < scrollHeight - 2; })); } @@ -665,12 +675,12 @@ export class ChatWidget extends Disposable implements IChatWidget { private onDidChangeTreeContentHeight(): void { if (this.tree.scrollHeight !== this.previousTreeScrollHeight) { - // Due to rounding, the scrollTop + renderHeight will not exactly match the scrollHeight. - // Consider the tree to be scrolled all the way down if it is within 2px of the bottom. - const lastElementWasVisible = this.tree.scrollTop + this.tree.renderHeight >= this.previousTreeScrollHeight - 2; - if (lastElementWasVisible) { + // Check if we're near the bottom of the list (within 2px) + const isNearBottom = this.tree.scrollTop + this.tree.renderHeight >= this.previousTreeScrollHeight - 2; + + if (isNearBottom && !this._userScrolledAway) { dom.scheduleAtNextAnimationFrame(dom.getWindow(this.listContainer), () => { - // Can't set scrollTop during this event listener, the list might overwrite the change + // Scroll to the new bottom this.scrollToEnd(); }, 0); } @@ -1225,4 +1235,4 @@ export class ChatWidgetService implements IAideAgentWidgetService { toDisposable(() => this._widgets.splice(this._widgets.indexOf(newWidget), 1)) ); } -} +} \ No newline at end of file