Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-72843

HoverHandler is unreliable

    XMLWordPrintable

Details

    • macOS, Windows
    • 8449180c5ebd609b6788680173a79df2f239abb8 (qt/qtdeclarative/dev) a0be1dc746b2dc23ef8fff2f0e3b4224d9d74c81 (qt/qtdeclarative/6.2)

    Description

      Please try the following example (tested on macOS only).

      This a a simple ListView with delegates made of Buttons with hoverEnabled. The HoverHandler is supposed to detect whether the mouse is inside the listview (yellow framing) or outside (gray framing). The buttons have a lovely green color when hovered.

      • Minor problem: If the mouse cursor is actually inside the ListView after program start, HoverHandler's hovered is reported as false. Surprisingly, the delegate button's hovered state is correct (green). Only after some movement where the spacing between the delegates is hit the state is updated.
      • Major problem: After clicking a button, the HoverHandler's hovered property is no longer updated (ListView gray frame). This seems to be fixed again by hovering some part of the list view that is not covered by a delegate (e.g. spacing).

      With QT_LOGGING_RULES=qt.quick.handler.dispatch=true I can see

      qt.quick.handler.dispatch: QQuickHoverHandler "" on QQuickListView "" DECLINES QQuickPointerEvent(0 dev:Mouse [QQuickEventPoint(accepted:true state:Updated scenePos:QPointF(33,226) id:1000000 timeHeld:3.943) ])
      

      in the debug output until the problem is magically fixed again (note the DECLINES).

      My workaround is to use an EventFilter on the ListView to capture QEvent::HoverEnter and QEvent::HoverLeave, which works fine as those events are always being delivered as expected.

      The InputHandler mechanics seem to be quite complex (grabbing, non-grabbing Pointer handlers etc.) so I suspect something evil at work there.

      Test case:

      import QtQuick 2.12
      import QtQuick.Controls 2.12
      import QtQuick.Window 2.12
      
      Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
      
      
        Rectangle {
          color: hh.hovered ? "yellow" : "gray"
          anchors { fill: lv; margins: -5 }
        }
      
        ListView {
          id: lv
          anchors.fill: parent
          anchors.margins: 40
          model: 100
          spacing: 1
          clip: true
          interactive: false
      
          delegate: Button {
            id: control
            width: lv.width
            height: 40
            hoverEnabled: true // if not set by style
      //      hoverEnabled: false // without hoverEnabled false, bug does not occur
            leftPadding: 8
            rightPadding: 8
            text: "This is a Text " + model.index
            onClicked: console.log("Clicked")
            background: Rectangle {
              color: control.hovered ? "green" : "red"
            }
          }
      
          HoverHandler {
            id: hh
          }
        }
      }
      

      Attachments

        1. workaround.qml
          0.8 kB
        2. fakebuttons.qml
          0.8 kB
        3. 33e2422.diff.zip
          2 kB

        Issue Links

          Activity

            People

              srutledg Shawn Rutledge
              njeisecke Nils Jeisecke
              Votes:
              2 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: