diff --git a/gui/main.qml b/gui/main.qml index a0b2aec..8d62fcd 100644 --- a/gui/main.qml +++ b/gui/main.qml @@ -96,9 +96,12 @@ ApplicationWindow { // Deferred scroll timer — fires once after model changes settle Timer { id: scrollTimer - interval: 0 + interval: 16 // ~1 frame at 60fps, allows layout to settle repeat: false - onTriggered: chatView.positionViewAtEnd() + onTriggered: { + if (chatView.shouldAutoScroll) + chatView.positionViewAtEnd() + } } // Session ID to kill — set on right-click, consumed by context menu @@ -485,6 +488,7 @@ ApplicationWindow { target: ollie function onActiveSessionIdChanged() { chatModel.reset() + chatView.shouldAutoScroll = true // Reset scroll state on session switch if (ollie.activeSessionId && ollie.activeAgentId) { var log = ollie.readLogForSession(ollie.activeSessionId, ollie.activeAgentId) if (log) { @@ -496,6 +500,7 @@ ApplicationWindow { } function onActiveAgentIdChanged() { chatModel.reset() + chatView.shouldAutoScroll = true // Reset scroll state on agent switch if (ollie.activeSessionId && ollie.activeAgentId) { var log = ollie.readLogForSession(ollie.activeSessionId, ollie.activeAgentId) if (log) { @@ -1244,15 +1249,32 @@ ApplicationWindow { boundsBehavior: Flickable.StopAtBounds visible: ollie.daemonConnected && ollie.activeAgentId !== "" + // Auto-scroll when near bottom (within ~50px or at end) + // Reset to true on new blocks, user can scroll up to disable + property bool shouldAutoScroll: true + readonly property bool nearBottom: contentHeight - contentY - height < 50 + + onContentYChanged: { + // User scrolled up - disable auto-scroll + // User scrolled to bottom - re-enable + if (dragging || flicking) { + shouldAutoScroll = nearBottom || atYEnd + } + } + onCountChanged: { - if (count > 0) - scrollTimer.start() + // New block added - always scroll if we were following + if (count > 0) { + if (shouldAutoScroll) + scrollTimer.start() + } } Connections { target: chatModel function onDataChanged() { - if (chatView.atYEnd && chatView.count > 0) + // Content updated (streaming) - scroll if following + if (chatView.shouldAutoScroll && chatView.count > 0) scrollTimer.start() } }