> On 2 Sep 2018, at 18:52, Alexander Ivash <elder...@gmail.com> wrote:
> 
> Is there any example of usage 'GrabPermissions' from QML ? 

So far we don’t have many examples with pointer handlers in general (we need to 
work on that for 5.12 and onwards) but the manual tests cover some of the 
initial obvious use cases:  qtdeclarative/tests/manual/pointer

> I've tried to do this:
> 
> TapHandler {
> grabPermissions: GrabPermissions.CanTakeOverFromHandlersOfSameType |
> GrabPermissions.CanTakeOverFromItems |
> GrabPermissions.CanTakeOverFromHandlersOfDifferentType |
> GrabPermissions.ApprovesTakeOverByAnything
> onTapped: {
> console.debug('text tap handler')
> }
> }
> 
> but it resulted in syntax errors.

The enum is nested in the PointerHandler base class, so at the moment you can 
use whatever scoping is convenient, the base or any subclass:

grabPermissions: PointerHandler.CanTakeOverFromHandlersOfSameType | 
TapHandler.CanTakeOverFromItems | 
PinchHandler.CanTakeOverFromHandlersOfDifferentType | 
PointHandler.ApprovesTakeOverByAnything

Yeah that’s silly (in practice you’d probably use either PointerHandler or 
<Leaf>Handler scoping consistently).  Does anybody think we could or should try 
to lock it down further somehow?  (Omitting the scoping altogether might be 
nice, wouldn’t it?  But we probably can’t.)

> Btw, documentation seems to be broken - it shows 'grabPermissions' as boolean 
> property

Yes that’s wrong.  https://codereview.qt-project.org/#/c/239399/

> Also, do I understand correctly that grabPermissions is the only way to make 
> one TapHandler to consume events so that other TapHandler will not get any?

I was hoping that conflicts between handlers will be rare, because you have 
more declarative control over the geometry within which a handler handles 
events, which device type the event can come from, which buttons are allowed, 
modifiers etc., and therefore the need to use grabPermissions should also be 
rare.  But of course we can’t imagine all the use cases either.  So how did you 
get into the situation that two TapHandlers are grabbing from each other?  They 
are on different Items, I suppose?  A parent and a child?  Do you have a simple 
testable example to show?

There are two kinds of grabs now, and gesturePolicy controls which kind of grab 
TapHandler will take.  As the docs explain, if the TapHandler that gets the 
event first (the top one in effective “Z-order” [even though only Items have a 
z property]) has gesturePolicy set to WithinBounds or ReleaseWithinBounds, then 
it needs to take an exclusive grab on press (same thing that MouseArea would 
do) to get the intended behavior.  That means it will get the updates and the 
release.  However it doesn’t stop delivery to other handlers, so yeah, another 
handler which receives that same press event can steal from the handler that 
just took the grab.  You can use grabPermissions to make the topmost handler 
“more greedy” (refusing to give up its grab) or to make the second one “more 
polite” (refusing to steal).  I would suggest trying to build your UI as 
cleanly and tersely as possible and then see how few places you can use 
grabPermissions to fix the remaining conflicts, not sprinkle them all over.

On the other hand if gesturePolicy is DragThreshold, it only takes a passive 
grab on press.  This doesn’t obstruct the delivery process to Items (or other 
handlers) at all: it means the handler will get any future events involving the 
same point (the moves and the release) _in addition to_ any other grabbers that 
get them.  So it can see when the point is released and emit tapped(); and it 
can also see if the point moves past the drag threshold (and gives up the 
passive grab in that case), so that tapped() will not be emitted.  Passive grab 
works well enough to implement that behavior, so it doesn’t bother with an 
exclusive grab.

The purpose of tech preview in 5.10 and 5.11 was in the hope that there would 
be some experience with using handlers before the 5.12 LTS release, and some 
interesting cases would emerge so that they could be solved in time.  But now 
we already have an API freeze for 5.12.  But maybe there is still a little time 
for some small tweaks if necessary.

I’m not 100% sure that accepting the event _should_ mean “stop delivery to 
everyone else”.  But it’s traditional.  (Is it common in non-Qt APIs too?)  You 
have to understand delivery order a little for the idea of accepting individual 
events to make sense, so I have doubts that it’s a friendly API; for UI 
designers and QML newbies it would be better if they never had to think about 
that.  Delivery of events to items and handlers is interleaved according to 
effective Z order, and we have to keep the traditional behavior when delivering 
to Items to keep source compatibility.  But when architecting the handlers we 
figured we could change the rules a little in that context, because it’s new 
API.  And there is the goal to have mostly declarative API: setting some 
property that controls the behavior is preferred over the old MouseArea { 
onPressed: event.accepted = false } because IMO it is 1) unfortunate that you 
need imperative Javascript for that, and 2) unintuitive that the event is 
accepted by default.  We changed those things with the event handler classes: 
we expect more handler instances, to be configured with very-choosey property 
settings, so that most of the instances will ignore most of the events, so 
rejecting by default makes more sense to me (and consistent with widget API).  
But letting events propagate deeper (especially, ignoring the accepted state 
and letting more handlers see the event) can result in more grab-conflicts too.

Several things are still confusingly intertwined for now: gesturePolicy, what 
kind of grab should be taken on press, whether or not the event should be 
accepted, and whether accepting the event should mean that delivery stops.  But 
we’re reluctant to add more declarative API to micro-manage the geeky details.  
Naming such API so that it makes sense to all audiences is hard, and ideally 
QML is friendlier if you don’t have to think about those things anyway.

On the other hand, people who already understand the details might expect more 
complete control of those details.  Maybe we could do it with an 
attached-property API later.  At least with C++ API you could do it.  (That 
isn’t public yet, but you can include private headers and subclass handler 
classes if you want.)

Opinions?  Does anyone else have experience with handlers yet?

_______________________________________________
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest

Reply via email to