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

Make it possible to use HoverHandler to filter events

    XMLWordPrintable

Details

    Description

      I'm trying to track the position of the mouse cursor regardless of what items are occupying the scene, like an event filter, but without having to resort to C++.

      At first I tried using a HoverHandler on the window, but it was never hovered:

      import QtQuick 2.13
      import QtQuick.Controls 2.13
      
      ApplicationWindow {
          id: window
          width: 400
          height: 400
          visible: true
          title: "hovered: " + hoverHandler.hovered
      
          StackView {
              anchors.fill: parent
          }
      
          HoverHandler {
              id: hoverHandler
              target: window.contentItem
          }
      }
      

      It seems like it is designed so that it will only get events that weren't already accepted, which makes sense. However, it would be nice if there was a way to filter hover events, similar to how PointHandler apparently allows mouse clicks to be filtered:

      By being only a passive grabber, it has the ability to keep independent oversight of all movements. The passive grab cannot be stolen or overridden even when other gestures are detected and exclusive grabs occur.

      If your goal is orthogonal surveillance of eventpoints, an older alternative was QObject::installEventFilter(), but that has never been a built-in QtQuick feature: it requires some C++ code, such as a QQuickItem subclass. PointHandler is more efficient than that, because only pointer events will be delivered to it, during the course of normal event delivery in QQuickWindow; whereas an event filter needs to filter all QEvents of all types, and thus sets itself up as a potential event delivery bottleneck.

      One possible use case is to add this handler to a transparent Item which is on top of the rest of the scene (by having a high z value), so that when a point is freshly pressed, it will be delivered to that Item and its handlers first, providing the opportunity to take the passive grab as early as possible. Such an item (like a pane of glass over the whole UI) can be a convenient parent for other Items which visualize the kind of reactive feedback which must always be on top; and likewise it can be the parent for popups, popovers, dialogs and so on.

      The docs mention MultiPointTouchArea as an alternative for some issue about macOS and trackpads, so I tried it just out of curiosity, but as expected, it didn't react to hover:

      import QtQuick 2.13
      import QtQuick.Controls 2.13
      
      ApplicationWindow {
          id: window
          width: 400
          height: 400
          visible: true
          title: "x: " + point1.x
      
          StackView {
              anchors.fill: parent
          }
      
          MultiPointTouchArea {
              id: hoverHandler
              anchors.fill: parent
              touchPoints: [
                  TouchPoint { id: point1 }
              ]
          }
      }
      

      Attachments

        Issue Links

          For Gerrit Dashboard: QTBUG-85926
          # Subject Branch Project Status CR V

          Activity

            People

              qt.team.quick.subscriptions Qt Quick and Widgets Team
              mitch_curtis Mitch Curtis
              Votes:
              2 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There are no open Gerrit changes