Planned maintenance has been done but it did not solve the problem. So work will continue on this and a new time for trying updates will be announced asap.

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
                    }
                }
            }
        }
    }
    

  • Qt Champions 2018

    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
                    }
                }
            }
        }
    }
    
    

Log in to reply