Fix scrollback snapping back to bottom after scrolling up
Wheel-up now clears stickToBottom immediately on the raw scroll event, wheel-down re-checks the resting position, and the auto-scroll effect re-checks stickToBottom right before scrollToItem(0). The scroll-state effect could miss a wheel scroll that began and ended within one frame, so the next incoming line pulled the buffer back to the bottom. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JW57ZvxRmxcDF7AFACLSoV
This commit is contained in:
@@ -818,7 +818,7 @@ fun MessageScrollback(
|
||||
.first { item ->
|
||||
item == null || (item.index < capturedList.size && item.key == capturedList[item.index].seq)
|
||||
}
|
||||
listState.scrollToItem(0)
|
||||
if (stickToBottom) listState.scrollToItem(0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -923,6 +923,31 @@ fun MessageScrollback(
|
||||
.height(snappedHeight)
|
||||
.onGloballyPositioned { containerCoords[0] = it }
|
||||
.pointerHoverIcon(PointerIcon.Text)
|
||||
// Wheel-up means the user is reading backscroll: stop sticking to the bottom RIGHT NOW,
|
||||
// on the raw wheel event. The scroll-state effect up top can miss a wheel scroll that starts
|
||||
// and finishes inside one frame (isScrollInProgress is never seen as true), which left
|
||||
// stickToBottom set and let the next incoming line yank the buffer back down.
|
||||
// Wheel-down re-checks the resting position shortly after and re-enables sticking if the
|
||||
// user is back at the bottom.
|
||||
.pointerInput(Unit) {
|
||||
awaitPointerEventScope {
|
||||
while (true) {
|
||||
val event = awaitPointerEvent(PointerEventPass.Initial)
|
||||
if (event.type == PointerEventType.Scroll) {
|
||||
val dy = event.changes.firstOrNull()?.scrollDelta?.y ?: 0f
|
||||
if (dy < 0f) {
|
||||
stickToBottom = false
|
||||
} else if (dy > 0f) {
|
||||
coroutineScope.launch {
|
||||
delay(200)
|
||||
stickToBottom = listState.firstVisibleItemIndex == 0 &&
|
||||
listState.firstVisibleItemScrollOffset <= stickToBottomThresholdPx
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Remembers the row under a right-click for the menu's "Copy line". Watches the
|
||||
// Initial pass, because ContextMenuArea takes the right-press there, before
|
||||
// the handler below would see it.
|
||||
|
||||
Reference in New Issue
Block a user