The latest is that I added
bool QQuickPointerHandler::filterPointerEvent(QPointerEvent *event)
which QQuickItem calls first, to decide whether it should call void QQuickPointerHandler::handlePointerEvent(QPointerEvent *event). This makes it less confusing, compared to having handlePointerEvent return a bool, and having the old ambiguity about whose responsibility it is to accept, and what's the difference between accepting the event or returning true from the function. filterPointerEvent just returns a preliminary decision on whether the handler wants to process the event. And it probably means the event should be accepted, at least. Should it mean the mouse or touchpoint should be grabbed too?
The trouble with grabbing is that we have only exclusive grabs, so an item can't monitor mouse or touchpoint movements without grabbing, and only one item can be the grabber. Maybe that's why child-event-filtering was added: as a workaround. We discussed some alternatives.
Sometimes I think there needs to be an alternative to monitor the mouse or the touchpoint without grabbing; or else, grabbers need to be in a list, and the exceptional case would be when an Item is sure that it needs an exclusive grab: then the list would be emptied and that one item re-added. Or maybe the grabbers could be in a stack, so that only one Item is the current grabber, but it's possible to pop the stack to revert to the previous grabber.
What about using QObject event filtering to bypass the grab and still monitor events? Handlers could do that, but is it a good idea or a dirty hack?
What if QQuickWindow had a list of Handlers or Items which wish to always monitor (certain types of) events in spite of any grabs? How would that be different than just having multiple grabbers?
What if the grabbers were stored like this:
QHash<QQuickPointerDevice *, QList<QQuickItem *> > m_deviceGrabs;
There would be multiple grabbers per device. Items have handlers, and each of those can filter, so still certain handlers can get certain kinds of events (certain mouse buttons for example) without QQuickWindow having to do that filtering. There could still be another QQuickWindow method to grab exclusively, which means forget about all the other grabbers and just send the events to me... so add another map:
QHash<QQuickPointerDevice *, QQuickItem *> m_exclusiveGrabs;
That's like the grab which we have now. When an event is being delivered, if its device is found in that map, then it will be sent only to that item. If it's not found there, then look up the list of non-exlusive grabbers in m_deviceGrabs, and deliver it to all of them, regardless of whether the event is accepted. So an MPTA which only wants to monitor touchpoints would put itself into that list, whereas when its minimum/maximumTouchPoints constraints are satisfied, it would put itself into m_exclusiveGrabs.
Or there could be a priority stack. The most recent grabber would get the event first. (So an item could be greedy by making sure it always stays on top.) QQuickWindow could ask it each time it delivers an event whether that item wants to be exclusive, and otherwise, keep going to the next item down the stack. That would be cheaper than storing the generic grabbers and exclusive grabbers separately.
- is replaced by
QTBUG-101398 grabPermissions cannot prevent an Item stealing grab from a handler in Qt 6