From c930a49ce9b705debc9444ac56bcfb8d2fc9c3ad Mon Sep 17 00:00:00 2001
From: Fermin Quant <14808645+ferminquant@users.noreply.github.com>
Date: Tue, 2 Jun 2026 23:09:24 -0400
Subject: [PATCH] fix(desktop): honor upward wheel scroll in long threads
---
.../assistant-ui/streaming.test.tsx | 34 +++++++++++++++++++
.../assistant-ui/thread-virtualizer.tsx | 1 +
2 files changed, 35 insertions(+)
diff --git a/apps/desktop/src/components/assistant-ui/streaming.test.tsx b/apps/desktop/src/components/assistant-ui/streaming.test.tsx
index 70f66040e..51edee952 100644
--- a/apps/desktop/src/components/assistant-ui/streaming.test.tsx
+++ b/apps/desktop/src/components/assistant-ui/streaming.test.tsx
@@ -415,6 +415,40 @@ describe('assistant-ui streaming renderer', () => {
expect(viewport.scrollTop).toBe(420)
})
+ it('honors the first upward wheel scroll even when a programmatic bottom-pin scroll event is still pending', async () => {
+ const { container } = render()
+
+ const content = container.querySelector('[data-slot="aui_thread-content"]') as HTMLDivElement
+ const viewport = content.parentElement as HTMLDivElement
+ let scrollHeight = 1_000
+
+ Object.defineProperty(viewport, 'clientHeight', { configurable: true, value: 200 })
+ Object.defineProperty(viewport, 'scrollHeight', {
+ configurable: true,
+ get: () => scrollHeight
+ })
+
+ await wait(80)
+ await wait(0)
+
+ await act(async () => {
+ fireEvent.wheel(viewport, { deltaY: -120 })
+ viewport.scrollTop = 420
+ fireEvent.scroll(viewport)
+ })
+
+ scrollHeight = 1_200
+
+ await act(async () => {
+ for (const observer of resizeObservers) {
+ observer.trigger(1_200)
+ }
+ })
+ await wait(0)
+
+ expect(viewport.scrollTop).toBe(420)
+ })
+
it('renders reasoning text without a leading token space', () => {
const { container } = render()
diff --git a/apps/desktop/src/components/assistant-ui/thread-virtualizer.tsx b/apps/desktop/src/components/assistant-ui/thread-virtualizer.tsx
index 3ee02e755..784ed71f3 100644
--- a/apps/desktop/src/components/assistant-ui/thread-virtualizer.tsx
+++ b/apps/desktop/src/components/assistant-ui/thread-virtualizer.tsx
@@ -237,6 +237,7 @@ function useThreadScrollAnchor({ enabled, groupCount, scrollerRef, sessionKey, v
const disarm = () => {
armedRef.current = false
+ programmaticScrollPendingRef.current = 0
}
const onScroll = () => {