From 2ea6ec1ba71ea2d63b5fa921917bf0c5f1535271 Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Fri, 7 Aug 2026 11:20:13 +0200 Subject: [PATCH] gui: fix scrolling in chat and message input - Restore ScrollView for message input to enable overflow scrolling - Remove manual wheel handlers that broke ListView virtualization - Let wheel events propagate naturally to ListView --- gui/main.qml | 73 ++++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/gui/main.qml b/gui/main.qml index 5971af6..021104a 100644 --- a/gui/main.qml +++ b/gui/main.qml @@ -1428,14 +1428,6 @@ property bool blockExpanded: { chatView.interactive = true mouse.accepted = false } - onWheel: function(wheel) { - // Always allow wheel scrolling, even during selection - chatView.contentY = Math.max(0, Math.min( - chatView.contentHeight - chatView.height, - chatView.contentY - wheel.angleDelta.y - )) - wheel.accepted = true - } } // Context menu (right button) - separate to avoid deselection @@ -1461,49 +1453,56 @@ property bool blockExpanded: { Layout.margins: 6 spacing: 4 - // TextArea without ScrollView - wheel scrolls when content overflows + // TextArea in ScrollView for overflow, with context menu overlay Item { Layout.fillWidth: true Layout.maximumHeight: 200 Layout.preferredHeight: Math.min(promptInput.contentHeight + 16, 200) + clip: true - TextArea { - id: promptInput + ScrollView { + id: promptScroll anchors.fill: parent - placeholderText: { - if (!ollie.daemonConnected) return "Not connected" - if (!ollie.activeSessionId) return "No session" - if (!ollie.activeAgentId) return "No agent" - if (ollie.isSessionPaused(ollie.activeSessionId)) return "Session paused" - return "Message..." - } - enabled: ollie.daemonConnected && ollie.activeSessionId !== "" && ollie.activeAgentId !== "" && !ollie.isSessionPaused(ollie.activeSessionId) - wrapMode: TextEdit.Wrap - selectByMouse: true - persistentSelection: true + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + + TextArea { + id: promptInput + width: promptScroll.width + placeholderText: { + if (!ollie.daemonConnected) return "Not connected" + if (!ollie.activeSessionId) return "No session" + if (!ollie.activeAgentId) return "No agent" + if (ollie.isSessionPaused(ollie.activeSessionId)) return "Session paused" + return "Message..." + } + enabled: ollie.daemonConnected && ollie.activeSessionId !== "" && ollie.activeAgentId !== "" && !ollie.isSessionPaused(ollie.activeSessionId) + wrapMode: TextEdit.Wrap + selectByMouse: true + persistentSelection: true - property string _lastText: "" - property int _lastCursorPos: 0 + property string _lastText: "" + property int _lastCursorPos: 0 - onTextChanged: { - _lastText = text - _lastCursorPos = cursorPosition - } + onTextChanged: { + _lastText = text + _lastCursorPos = cursorPosition + } - Keys.onReturnPressed: function(event) { - if (event.modifiers & Qt.ShiftModifier) { - event.accepted = false - } else { - if (text.trim() !== "") { - ollie.submit(text.trim()) - text = "" + Keys.onReturnPressed: function(event) { + if (event.modifiers & Qt.ShiftModifier) { + event.accepted = false + } else { + if (text.trim() !== "") { + ollie.submit(text.trim()) + text = "" + } + event.accepted = true } - event.accepted = true } } } - // Context menu overlay - only catches right-click + // Context menu overlay - only catches right-click, on top of ScrollView MouseArea { anchors.fill: parent acceptedButtons: Qt.RightButton