gui: fix scrolling - use contentHeight not timer
Replace timer-based scroll hack with event-driven approach: - onContentHeightChanged triggers scroll when content grows - onMovementEnded detects when user scrolled away from bottom Scrolling is now driven by actual content changes, not arbitrary delays.
This commit is contained in:
parent
e10912de08
commit
cde0284bad
60
gui/main.qml
60
gui/main.qml
|
|
@ -93,17 +93,6 @@ ApplicationWindow {
|
||||||
// Sidebar visibility
|
// Sidebar visibility
|
||||||
property bool sidebarVisible: true
|
property bool sidebarVisible: true
|
||||||
|
|
||||||
// Deferred scroll timer — fires once after model changes settle
|
|
||||||
Timer {
|
|
||||||
id: scrollTimer
|
|
||||||
interval: 16 // ~1 frame at 60fps, allows layout to settle
|
|
||||||
repeat: false
|
|
||||||
onTriggered: {
|
|
||||||
if (chatView.shouldAutoScroll)
|
|
||||||
chatView.positionViewAtEnd()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Session ID to kill — set on right-click, consumed by context menu
|
// Session ID to kill — set on right-click, consumed by context menu
|
||||||
property string killTargetSessionId: ""
|
property string killTargetSessionId: ""
|
||||||
// Target session for "New Agent" dialog
|
// Target session for "New Agent" dialog
|
||||||
|
|
@ -478,7 +467,6 @@ ApplicationWindow {
|
||||||
chatModel.trimFront(20)
|
chatModel.trimFront(20)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scrollTimer.start()
|
|
||||||
// Ensure we have the latest session list
|
// Ensure we have the latest session list
|
||||||
ollie.refreshSessions()
|
ollie.refreshSessions()
|
||||||
buildSessionTree()
|
buildSessionTree()
|
||||||
|
|
@ -496,7 +484,6 @@ ApplicationWindow {
|
||||||
chatModel.trimFront(20)
|
chatModel.trimFront(20)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scrollTimer.start()
|
|
||||||
}
|
}
|
||||||
function onActiveAgentIdChanged() {
|
function onActiveAgentIdChanged() {
|
||||||
chatModel.reset()
|
chatModel.reset()
|
||||||
|
|
@ -508,7 +495,6 @@ ApplicationWindow {
|
||||||
chatModel.trimFront(20)
|
chatModel.trimFront(20)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scrollTimer.start()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -897,40 +883,26 @@ ApplicationWindow {
|
||||||
boundsBehavior: Flickable.StopAtBounds
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
visible: ollie.daemonConnected && ollie.activeAgentId !== ""
|
visible: ollie.daemonConnected && ollie.activeAgentId !== ""
|
||||||
|
|
||||||
// Auto-scroll when near bottom (within ~50px or at end)
|
// Auto-scroll state: true = follow new content, false = user scrolled up
|
||||||
// Reset to true on new blocks, user can scroll up to disable
|
property bool shouldAutoScroll: true
|
||||||
property bool shouldAutoScroll: true
|
|
||||||
readonly property bool nearBottom: contentHeight - contentY - height < 50
|
|
||||||
|
|
||||||
onContentYChanged: {
|
onContentHeightChanged: {
|
||||||
// User scrolled up - disable auto-scroll
|
// Content grew — scroll to end if we're following
|
||||||
// User scrolled to bottom - re-enable
|
if (shouldAutoScroll && contentHeight > height) {
|
||||||
if (dragging || flicking) {
|
positionViewAtEnd()
|
||||||
shouldAutoScroll = nearBottom || atYEnd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onCountChanged: {
|
|
||||||
// New block added - always scroll if we were following
|
|
||||||
if (count > 0) {
|
|
||||||
if (shouldAutoScroll)
|
|
||||||
scrollTimer.start()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
onMovementEnded: {
|
||||||
target: chatModel
|
// User finished scrolling — update auto-scroll based on position
|
||||||
function onDataChanged() {
|
// atYEnd is true when scrolled to bottom
|
||||||
// Content updated (streaming) - scroll if following
|
shouldAutoScroll = atYEnd
|
||||||
if (chatView.shouldAutoScroll && chatView.count > 0)
|
}
|
||||||
scrollTimer.start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate: ChatBlockDelegate {
|
delegate: ChatBlockDelegate {
|
||||||
width: chatView.width - 8
|
width: chatView.width - 8
|
||||||
parentListView: chatView
|
parentListView: chatView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Reference in New Issue