[Interest] QML Pointer Handlers: how to use 'GrabPermissions'
Shawn Rutledge
Shawn.Rutledge at qt.io
Tue Sep 18 23:46:58 CEST 2018
> On 18 Sep 2018, at 18:48, Shawn Rutledge <Shawn.Rutledge at qt.io> wrote:
> Because it accepts the point, that means the event will not propagate to the other TapHandler.
Oops that’s quite a wrong explanation… after more debugging and reading the code yet again, now I realize I was right the first time when I said that even when the TapHandler that takes an exclusive grab, it "doesn’t stop delivery to other handlers”.
While QQuickWindowPrivate::deliverPressOrReleaseEvent() iterates all the target items: if after visiting one item and its handlers, all points are accepted, it does NOT stop: it merely stops delivering directly to Items, but continues delivering to the remaining target Items’ Handlers. http://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quick/items/qquickwindow.cpp?h=5.12#n2554 So it does propagate to the other TapHandler. But if the point already has an exclusive grabber at the time that the underlying TapHandler sees it, then wantsPointerEvent() returns false (see http://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quick/handlers/qquicksinglepointhandler.cpp?h=5.12#n113 ) with the result that the underlying TapHandler will not handle the event. But if the gesturePolicy of the topmost TapHandler is DragThreshold, then that one only takes a passive grab, so the underlying TapHandler does handle the event. (A passive grab means the top one is “just lurking”, watching what will happen.)
So currently Pointer Handlers don’t have the ability to stop propagation to other handlers, but they do honor the intention of the exclusive grab.
Based on that, the question of whether TapHandler should have a property to control whether or not it accepts the point is less relevant. In general, handlers accept the points that they’ve decided to handle, and it’s documented that they should. (One exception is PointHandler, because it’s nothing more than a lurker: its goal is never to interfere, only to monitor the movements of the event points.)
It’s still confusing that you have to change gesturePolicy to get what you want though.
For a while, the default gesturePolicy was ReleaseWithinBounds, so it would have taken an exclusive grab on press, and you would have gotten the behavior you wanted by default. We changed it because of how handlers interact with QtQuick.Controls and other event-handling Items ( https://codereview.qt-project.org/#/c/217632/ ). You shouldn’t normally need to pile up MouseAreas or TapHandlers on top of existing controls, because Controls are supposed to work well already, and they are designed to handle all the events for all supported use cases in C++ rather than by composition of handlers… but people keep trying to do that anyway. If you put a TapHandler on a Button, and then you can’t click the Button anymore, you might report a bug about it. To stave that off, and because we can expect that Handlers and event-handling Items have to coexist in many cases, we tried to go towards an architecture where events propagate further. (I think it might be quite useful to put a DragHandler on any kind of Control to be able to drag it around, because dragging is not a feature that most Controls have built-in. But again, putting a DragHandler in a Button should not prevent you from clicking it.) So it seemed appropriate at the time that TapHandler should only take a passive grab by default, because that works well enough in many single-layer simple use cases too. And giving the handlers full control to decide when an event is relevant or not, rather than cutting off delivery before some of them are visited, ought to be more flexible, right?
You still have grabPermissions as a workaround in case too much grab-stealing is going on.
And maybe there will be an Item.modal property eventually… that’s intended to be a way to absolutely stop propagation of all events at a particular layer of your Item hierarchy, for example, the parent frame of some sort of in-scene dialog or popover. But it didn’t get done in time for 5.12.
More information about the Interest
mailing list