We just finally got the wip/pointerhandler branch merged to dev branch (yes
it’s a couple of days past the feature freeze, but has been in the works for
years, and we really planned to get it in 5.10).
A PointerHandler is a QObject which can be declared as a child of an Item in Qt
Quick, which will handle events from pointing devices (mouse, keyboard, or
stylus) on behalf of that Item. An Item can have multiple handlers. So,
handlers are intended to be smaller and more specific in implementation,
compared to the existing Areas such as MouseArea which try to do everything you
could ever want to do with the mouse (and then get used for handling touch
events in practice besides); and also somewhat smaller in memory, not being
full-fledged Items themselves.
It’s going to be Tech Preview because of still being incomplete. So far we
TapHandler - the one you need to build a button, it handles press and release,
tapping (clicking), long-press and multi-tapping (the most common use cases for
MouseArea). There are improvements like being able to constrain it to react
only to certain device types, certain mouse buttons, or while holding down a
modifier key; being able to count taps rather than only supporting single and
double click; and being able to tap or press multiple Items with TapHandlers at
the same time (which until now has required that you switch from MouseArea to
DragHandler - declare one of these inside an Item and suddenly you can drag it.
It has some properties too.
PinchHandler - to enable 2-finger pinch gestures for rotation, scaling and
dragging. The major improvements over PinchArea are that you can zoom into any
point (the point which is the centroid of your finger positions) rather than
only zooming into the center or corner of an Item; and, you can require more
than two fingers if you like, so it’s possible to have a 2-finger pinch which
does one thing and a 3-finger pinch which does something else, for example.
So what have we left out? everything else that you could do with a mouse: for
example hovering, and use of the mouse wheel, at least. Scrolling via a
2-finger flick gesture on a touch pad (which is implemented via fake mouse
wheel events on most platforms… but that’s not always good enough). We need to
write a few more handlers I think.
Handling of QTabletEvents (from a stylus on a Wacom tablet, Tablet PC or a
Galaxy Note) is also not implemented yet (although I have had patches to get
started with that for a long time now). And I think we need another handler
for the stylus anyway. Now that we have path rendering in Qt Quick, maybe the
next step is to be able to draw paths with a stylus; but we didn’t flesh out
the mechanism for doing that yet.
DragHandler drags items around the scene, but we have made no attempt at proper
DnD support yet.
Another reason is that we hope to have public C++ API eventually, so that you
can subclass one of the pointer handler abstract classes and handle the kinds
of gestures that we don’t already support, to do whatever you like. But we
have not yet made it suitable for that: it needs more API review, the classes
need refactoring to follow the PIMPL pattern, more docs, etc.
So for 5.10 you will only be able to do
import Qt.labs.handlers 1.0
and instantiate those three types in QML; and you can play with the private API
in C++, with the expectation that some of it will probably be public later on.
There is a prototype FakeFlickable which we have as a manual test so far, which
shows how you can use two Items plus a DragHandler to implement something which
behaves like Flickable, in pure QML. Maybe we will re-implement Flickable
itself that way, under the covers, which should result in some code
de-duplication and more flexible event handling; but we haven’t gotten to that
yet, and the behavior isn’t perfect yet anyway. But it’s very difficult to fix
Flickable to handle multi-touch properly: you can’t flick two of them at once
with two fingers, and it only knows how to steal the grab from a mouse event,
so there are some problems with stealing synthetic mouse events from handlers
or items which are grabbing touchpoints already. So we think that replacing it
might streamline the code while also enabling more kinds of interaction. But
can we keep the API the same while totally replacing the implementation? (or
should we?) won’t know until we try…
We still need to do a lot more dogfooding: for example try to replace all the
custom C++ event handling code in qtlocation with pointer handlers. We can’t
say it’s ready to use if we don’t succeed with that. Likewise, sets of
controls such as QtQuick.Controls could make use of handlers… but we’ll see how
that goes. From one side, we need to do something like that in order to
validate more of the possible use cases. From another side, the total QObject
count would go up (which means instantiation time and memory usage would
probably increase), compared to the Controls 2.0 implementation with its
monolithic base classes. So we’ll see about that. Maybe we can find some sort
of middle ground which gives us code reuse without bloating the object count,
somehow. Such an approach amounts to having a different kind of C++ API.
The original idea was more about using attached properties, rather than having
to declare the handlers. We are still playing with some ideas there.
And actually, there are still known bugs we are fixing. We will keep trying to
get more of them fixed before 5.10 ships. But now is the chance for some early
feedback. After talking about this at the contributors’ summit for 3 years
straight, we think it’s about time that we shipped something.
Sorry for getting it in at the last minute like this. (It could have been a
couple of months ago. I was on vacation, and little has changed since this
spring, except for some bug fixes which finally enabled integration.) But if
you don’t do the import, you can ignore it. We kept all the old autotests
passing, so we expect that the existence of this new stuff won’t impact
existing QML. And during the big event-delivery refactoring (some of which was
in 5.9 already), we have tried to make event delivery more efficient for all
use cases, so it will be interesting to get some feedback about that too.
Later on, it may be part of Qt Quick, not requiring a separate import anymore.
And then if it all goes really well, at some point maybe we should deprecate
the old Areas (not sure when that will be). And in Qt 6 I hope we can broaden
the scope of the event delivery refactoring: promote the pointer event concept
to qtbase, instead of just having it be a wrapper around the existing
QInputEvents in qtdeclarative, as it is now. I even hope we can go as far as
to remove the one-mouse limitation eventually. QtQuick will be ready for that
by the time it’s possible in qtbase, anyway.
The main thrust of this gambit is to unify the delivery and handling of all
pointer events instead of needing separate delivery paths for QMouseEvent,
QTouchEvent and QTabletEvent (with their own behavioral idioscynrasies and
bugs), and to enable proper multi-touch support such that we can some day stop
relying on the synthesis of mouse events from touch events (because the
delivery process is now agnostic about the type of event, even though an
individual handler may care about some device-specific event details).
Development mailing list