Unsolved macOS - issues with scrolling when nesting ListViews
-
Hi
I'm running into a weird issue on macOS (on Windows works fine) in Qt 5.12.
I have a vertical ListView (scrolling top-down) that contains ListViews (scrolling left-right).It looks like I can't scroll vertically when cursor is over nested ListView, however when cursor is located inside spacing area I can scroll until cursor hits another child ListView.
Below you can find an example of this behavior, with commented out MouseArea hacks to make it work on macOS.
import QtQuick 2.12 import QtQuick.Controls 2.12 ApplicationWindow { id: window visible: true width: 640 height: 480 title: "Test" ListView { id: listView anchors.fill: parent focus: true property var horizontalListViewUnderCursor model: ListModel { ListElement { color: 'yellow' } ListElement { color: 'green' } ListElement { color: 'cyan' } } spacing: 80 KeyNavigation.up: listView.headerItem flickableDirection: Flickable.VerticalFlick // MouseArea { // anchors.fill: parent // onWheel: { // if (wheel.angleDelta.x !== 0) { // if (listView.horizontalListViewUnderCursor) { // listView.horizontalListViewUnderCursor.cancelFlick(); // listView.horizontalListViewUnderCursor.flick(wheel.angleDelta.x * 10, 0); // } // } // if (wheel.angleDelta.y !== 0) { // listView.cancelFlick(); // listView.flick(0, wheel.angleDelta.y * 10); // } // wheel.accepted = true // } // } delegate: ListView { id: internalList height: 200 width: 500 spacing: 10 orientation: ListView.Horizontal flickableDirection: Flickable.HorizontalFlick // MouseArea { // anchors.fill: parent // hoverEnabled: true // onWheel: { // wheel.accepted = false; // } // onEntered: { // listView.horizontalListViewUnderCursor = parent; // } // onExited: { // listView.horizontalListViewUnderCursor = null; // } // } model: ListModel { ListElement { alpha: 0.1 } ListElement { alpha: 0.2 } ListElement { alpha: 0.3 } ListElement { alpha: 0.4 } ListElement { alpha: 0.5 } ListElement { alpha: 0.6 } ListElement { alpha: 0.7 } ListElement { alpha: 0.8 } ListElement { alpha: 0.9 } ListElement { alpha: 1.0 } } delegate: Item { property variant myData: model height: 200 width: 200 Rectangle { anchors.fill: parent color: 'blue' opacity: model.alpha } } } } }
-
I am on macOS 10.13.6 and your example works fine with the MouseArea code still commented out.
I can flick using the mouse and scroll with wheel. -
Thanks for reply! Have you tried it on Magic Trackpad/Macbook trackpad? Just connected a mouse and scroll indeed works fine, however on trackpad this issue is still present.
I'm running macOS 10.14.1.
-
Bump, since the issue still exists.
-
Hi, I have looked into this example since I needed to build the same functionality.
I have solved it by creating a MouseArea that overlaps the topmost list view. The logic for horizontal and vertical scrolling is implemented in the wheel event of the MouseArea, which then lets all other events propagate through, so that drag & dropping, clicking etc are not blocked for the items in the list views.
import QtQuick 2.12 import QtQuick.Controls 2.12 ApplicationWindow { id: window visible: true width: 640 height: 480 title: "Test" MouseArea { id: overlappingMouseArea anchors.fill: listView z: 1 // optional: enable only for macOS //enabled: Qt.platform.os === "osx" propagateComposedEvents: true onClicked: mouse.accepted = false onPressed: mouse.accepted = false onReleased: mouse.accepted = false onPressAndHold: mouse.accepted = false onDoubleClicked: mouse.accepted = false onWheel: { // picked a random threshold for the scroll // pick other thresholds for windows trackpads // the thresholds here work well on my macOS 10.12.6 if(Math.abs(wheel.angleDelta.x) > 6) { if(listView.width < listView.contentItem.width) { listView.contentX += -0.5 * wheel.angleDelta.x if(listView.contentX < 0) { listView.contentX = 0 } if((listView.contentX + listView.width) > listView.contentItem.width) { listView.contentX = listView.contentItem.width - listView.width } } } if(Math.abs(wheel.angleDelta.y) > 6) { var wheelXRelToContentScroll = wheel.x + listView.contentX // itemAt requires x, y to be relative to the whole contentItem in order to fetch // the right item var itemAtWheel = listView.itemAt(wheelXRelToContentScroll, wheel.y) if(itemAtWheel) { if(itemAtWheel.height < itemAtWheel.contentItem.height) { itemAtWheel.contentY += -0.5 * wheel.angleDelta.y if(itemAtWheel.contentY < 0) { itemAtWheel.contentY = 0 } if((itemAtWheel.contentY + itemAtWheel.height) > itemAtWheel.contentItem.height) { itemAtWheel.contentY = itemAtWheel.contentItem.height - itemAtWheel.height } } } } } } ListView { id: listView anchors.fill: parent focus: true property var horizontalListViewUnderCursor orientation: ListView.Horizontal spacing: 80 model: ListModel { ListElement { color: 'yellow' } ListElement { color: 'green' } ListElement { color: 'cyan' } } flickableDirection: Flickable.HorizontalFlick /* MouseArea { anchors.fill: parent onWheel: { if (wheel.angleDelta.x !== 0) { if (listView.horizontalListViewUnderCursor) { listView.horizontalListViewUnderCursor.cancelFlick(); listView.horizontalListViewUnderCursor.flick(wheel.angleDelta.x * 10, 0); } } if (wheel.angleDelta.y !== 0) { listView.cancelFlick(); listView.flick(0, wheel.angleDelta.y * 10); } wheel.accepted = true } } */ delegate: ListView { id: internalList height: window.height width: 300 spacing: 5 flickableDirection: Flickable.VerticalFlick /* MouseArea { anchors.fill: parent hoverEnabled: true onWheel: { wheel.accepted = false; } onEntered: { listView.horizontalListViewUnderCursor = parent; } onExited: { listView.horizontalListViewUnderCursor = null; } } */ model: ListModel { ListElement { alpha: 0.1 } ListElement { alpha: 0.2 } ListElement { alpha: 0.3 } ListElement { alpha: 0.4 } ListElement { alpha: 0.5 } ListElement { alpha: 0.6 } ListElement { alpha: 0.7 } ListElement { alpha: 0.8 } ListElement { alpha: 0.9 } ListElement { alpha: 1.0 } } delegate: Item { property variant myData: model height: 200 width: 300 Rectangle { anchors.fill: parent color: 'blue' opacity: model.alpha } } } } }