aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/handlers
Commit message (Collapse)AuthorAgeFilesLines
* Do not crash on WindowsJan Arve Saether2017-06-233-3/+2
| | | | | | | | | | | | | It seems that moving the registration to the block where the rest of the type registration was done avoids the crash. According to the documentation, a Q_GADGET doesn't have to be explicitly registered into the meta type system, but I never managed to get that working (and our existing Q_GADGETS seems to require explicit registration too) Change-Id: Iab1c258dbe40bd1c8062fab2c4b68fce208f5144 Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
* Add tst_multipointtoucharea_interop autotestShawn Rutledge2017-05-271-1/+0
| | | | | | | | to test interoperability of PointerHandlers with conventional touch- handling Items (with MultiPointTouchArea being the prototypical instance) Change-Id: Id19f312b17b70df072d66cd91816d2b19250a500 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Move properties into grouped "point" propertyJan Arve Saether2017-05-234-91/+109
| | | | | Change-Id: I80000110a2e0ca69210322a0fcc587d86158358e Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Start over with event delivery when touchpoint releases occurShawn Rutledge2017-05-225-28/+24
| | | | | | | | | | | | | | | | | | | | The new rule is that when the number of touchpoints changes, we start over with event delivery as if the touch had just begun, to give more opportunities to hand off processing from one item or handler to another. And MultiPointTouchArea can now handle the handoff: for example in tests/manual/pointer/pinchDragFlingMPTA.qml when the user is pressing three fingers, the PinchHandler is active; when the user then lifts one finger, the MPTA can resume handling the two remaining touchpoints as if they were just pressed. The change in QQuickMultiPointerHandler::wantsPointerEvent is both a behavior change and an optimization: released points aren't eligible; but if some points are released, then pressed, updated and stationary points are all eligible. And, figure this out without looping over the points twice. Change-Id: I26b7593de8e72b471adfec4a4482dd87a8288442 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* TapHandler: don't give up passive grab on setPressed(false)Shawn Rutledge2017-05-151-5/+2
| | | | | | | | | | | | | | | | | | | | If a button with a TapHandler with the DragThreshold policy is inside a Flickable, and you press on the button and start dragging, when you exceed the drag threshold, TapHandler will not "want" the EventPoint anymore. That triggers it to call setPressed(false). Flickable does not have a grab because it was relying on filtering the children's events; and QQuickWindow does not deliver touch updates to non-grabber items. So when TapHandler gives up its passive grab, Flickable does not get a chance to filter TapHandler's touch update events anymore. Thus, we cannot do that. When the touchpoint is actually released though, passive grabs are ungrabbed anyway. This is required to get the new tst_FlickableInterop::touchDragFlickableBehindButton() autotest working. Change-Id: I55a175ae358f75b9d7ab64f0b8124d91b6a9e1d6 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Don't allow one handler to cancel another's grab, unless it is stealingShawn Rutledge2017-05-151-0/+3
| | | | | | | | | | | | | | | This is required to keep the tst_flickableinterop touchDragSlider test passing after the change to TapHandler to never give up passive grab. And QQuickEventPoint::setGrabberPointerHandler(nullptr, true) will just go ahead and allow TapHandler to cancel the grab which the DragHandler currently has at that time, when you have pressed the TapHandler but started dragging so that the drag threshold is exceeded. (Perhaps this points to an API problem.) For now, we at least can enforce the rule in QQuickPointerHandler::setExclusiveGrab that if grab is false, it won't nullify the grab of a different handler. Change-Id: I7c93188cfdce51b3b5a17c13e5efc7fcbd123d4b Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Add and use QQuickPointerSingleHandler::moveTarget()Shawn Rutledge2017-04-283-1/+9
| | | | | | | | | | | | Until now, DragHandler::pos() was not staying constant during a drag, because we update m_pos from the EventPoint, then move the Item. scenePos() also returns mapToScene(m_pos). If the Item is being dragged to follow the finger or the mouse cursor exactly, unconstrained, then pos() should always be the same as the parent-relative position where the press occurred. Change-Id: Ia02738c0cf458e039cf90371f9c8a7becb75a035 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* QQPSingleHandler: accept only left mouse button by defaultShawn Rutledge2017-04-282-2/+1
| | | | | | | | | | It makes as much sense for DragHandler as it does for TapHandler. If you want to allow right-button dragging, you need to enable it in QML. In general, UIs have always relied on the left button for normal interaction, while the other buttons are for special cases. Change-Id: I708d5d080832c32ef581ca333c9be06e987ef007 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* TapHandler: CancelGrabPassive => setPressed(false)Shawn Rutledge2017-04-281-1/+1
| | | | | | | | | | | When a TapHandler's Item is inside a Flickable, the user has pressed the mouse button over the TapHandler, and then the Flickable takes the mouse grab during dragging from there, if the TapHandler has only a passive grab, it is cancelled. In this case the TapHandler should no longer be pressed, because it's being dragged instead. Change-Id: I129f44cc9b8d8e99b00e23cd5943dd57d4ae5d16 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* DragHandler: allow parent to be different from targetShawn Rutledge2017-04-272-7/+34
| | | | | | | | | | | | | | | The most obvious way to implement a Slider is to allow dragging the knob - as on a real-world physical sliding potentiometer. But to make it easier on a touchscreen, it should be possible to touch anywhere along the slider's travel, as on a QtQuick.Controls 2 Slider. For that purpose, we need to respond to events within the bounds of one Item while actually dragging a different Item (the knob). It's similar to the way that PinchHandler can handle pinch gestures within one Item while transforming another (which may be too small to get both fingers inside). Change-Id: Iac9a5f11a7a45e22d93fe52bf62d157c48d72d3d Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* QQPSingleHandler: store m_scenePressPos separatelyShawn Rutledge2017-04-272-1/+4
| | | | | | | | | | The scene-relative position at which an EventPoint was pressed does not change during a drag. The target item is moving, so we cannot convert a point relative to the target item back to a scene position and expect it to stay constant. Change-Id: I07389993c6b15316b686824c37dbad83b4b10861 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* QQMultiPointerHandler: don't steal grab if keepMouseGrab/keepTouchGrabShawn Rutledge2017-04-273-6/+15
| | | | | | | | | | An Item (such as MPTA with onGestureStarted: gesture.grab()) may set these flags, traditionally to prevent Flickable from stealing the grab. QQuickMultiPointerHandler (and thus PinchHandler) now respects these flags too. Change-Id: Iac3ab796c5aa410be45639d679ecf82b7c44a442 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* QQuickMultiPointerHandler::wantsPointerEvent ignores grabs on pressShawn Rutledge2017-04-271-6/+12
| | | | | | | | | | | | | | | A PinchHandler for example has strict requirements, so when they are finally met, it needs to be willing to take over the grab from something else. This occurs when a point is pressed or released (in which case a grabbing PointerHandler might probably give up its grab anyway, if its requirements are not met anymore). MPTA can typically handle a variable number of points though, so it will not give up its grabs, and PinchHandler must be able to steal from it. The first step in stealing is for the handler to say that it wants the points despite any existing grabs. Change-Id: Ic3a2586d43e4cfe1877f90ce2e2862a9abc4b81b Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* PointerHandler: add wants/declines logging to qt.quick.handler.dispatchShawn Rutledge2017-04-271-1/+5
| | | | | | | | | and remove the similar "delivering to" log from QQuickItem. It's more useful to know whether delivery will continue rather than simply that we made an attempt. Change-Id: I58c37fb50d4d0c99ef6aa68662ab304194b6d128 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Remove redundant entriesJan Arve Saether2017-04-251-8/+6
| | | | | | | Sort the entries to ease lookup Change-Id: I306ca508e8b382b9a60fe737f28f5fa2c9471dc1 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* QQuickPointerDeviceHandler: add acceptedModifiersShawn Rutledge2017-04-252-1/+44
| | | | | | | | | Sometimes you want to require holding down a key in order to enable some interaction. As with the other "accepted" flags, it's better to do this with a property than with Javascript. Change-Id: Ie29880f5f9f496ddca1bee462e2c0e6dd30fa9f5 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* QQuickPointerSingleHandler: add setIgnoreAdditionalPointsShawn Rutledge2017-04-242-1/+10
| | | | | | | | | After 3523b676382db4aa39adeb9126d8bb2185e84403 it became impossible to write a subclass which handles one point and ignores the rest. In some cases this is necessary. Change-Id: I27511e6112a93ef98a4cf45c8531287781698b5b Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* DragHandler: onGrabChanged, enforceConstraintsShawn Rutledge2017-04-242-0/+7
| | | | | | | | | If the grab is stolen by a parent such as a Flickable, ensure that the DragHandler doesn't keep dragging. This helps to prevent dragging sliders out of their "groove" constraints. Change-Id: Id24f53e137ed186b1c02ab9c73a69a59022e80b0 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* QQPSingleHandler: don't accept a touchpoint other than the chosen oneShawn Rutledge2017-04-211-6/+9
| | | | | | | | | | | | | | | | This also caused a failure in the new TapHandler test: wantsPointerEvent() can see stationary touchpoints, and they may end up being "candidates" (although not if wantsEventPoint() returns false for all stationary points), but don't get confused by that: we chose a particular point, always the first for which wantsEventPoint() returns true, not any subsequent points for which wantsEventPoint() returns true. It's important to accept only that point, because in other places where we don't have access to the return value from wantsEventPoint(), we treat the accepted state as the _memory_ of what wantsEventPoint() returned. So it must be consistently the same. Change-Id: Ia121bde50d956b45b2cf62eddf326293a5c02274 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* TapHandler: do not react to stationary touchpointsShawn Rutledge2017-04-212-3/+9
| | | | | | | | | | In autotests, stationary points normally have invalid position. A TapHandler does not need to react to them anyway. But we must also avoid having a grab cancelation due to a stationary point, and that applies to all PointerHandlers in general. Change-Id: I99493ad7d859e0c4ef155afc699aa34f28ffdbc7 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* QQPSingleHandler: verify wantsEventPoint() even when pointId is chosenShawn Rutledge2017-04-211-4/+3
| | | | | | | | | | | This allows TapHandler to veto the "wanting" during an update, if the policy is violated. For example, if the policy is WithinBounds, and the point leaves the bounds, it will say that it does not want the point; but without this change, it is not asked again when the point is moved outside the bounds. Change-Id: Id764b3d24966ce9c3c4795e9f2a0aa37821caa42 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* TapHandler: don't "want" every updated/stationary pointShawn Rutledge2017-04-211-1/+1
| | | | | | | | | | | | | | | | | | If the policy is ReleaseWithinBounds, we assumed wrongly that wantsEventPoint() would not be asked about a point which QQuickPointerSingleHandler::wantsEventPoint() would already rule out, or about a point which was not grabbed either passively or exclusively. But in fact it is asked about every point. A tap is not going to occur unless the press occurs within bounds; if that happened, then QQuickPointerSingleHandler::m_pointId will have been set. So a TapHandler with this policy should remain interested in an updated or stationary point only if it is the same one which it was already interested in when it was pressed. This gets the multipoint button example and autotest working. Change-Id: I399c06071fd804cd6994d5f0153c307cec9d2f90 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* TapHandler:wants: don't setPressed(false) unless pointId matchesShawn Rutledge2017-04-211-1/+1
| | | | | | | | | | | This fixes the multibuttons manual test: the first button would see that a second point was pressed, and that it didn't want it, because it's outside the bounds. This is not a good reason to discontinue responding to the first touchpoint, which is the one it was first interested in. Change-Id: I7004a667873f235d3dda84b4261113d37d911763 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* PinchHandler: add centroidVelocityShawn Rutledge2017-04-204-0/+15
| | | | | Change-Id: I34cc9146155bded8311c1173e4b8d34d8b17b034 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* TapHandler: add qt.quick.handler.tap logging categoryShawn Rutledge2017-04-201-14/+23
| | | | | | | PinchHandler has its own. Maybe every pointerhandler should. Change-Id: Ic87494c8e333dcd502d4e259789b68337c3de349 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* PointerHandlers always ungrab if wantsPointerEvent returns falseShawn Rutledge2017-03-301-2/+9
| | | | | | | | | | That means the PinchHandler for example will require exactly requiredPointCount touchpoints. If it was satisfied, then one finger is released, it must give up its grabs so that another PointerHandler has a chance to take over. Change-Id: I28e32d6d3f255c7de8023f054dc480528bb14852 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* DragHandler: don't steal exclusive grabShawn Rutledge2017-03-301-2/+3
| | | | | Change-Id: I643d0e93e180bba5d9fea4543b93cbb66668c94d Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* DragHandler: restrict dragging to *only* one fingerJan Arve Saether2017-03-281-8/+24
| | | | | | | | | This means we can do a one-finger drag, then add two fingers to do a 3-finger pinch. Change-Id: I62c0184cfeeb3cc240cba20c6c2238852f68a79a Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* PinchHandler: Do not grab immediatelyJan Arve Saether2017-03-141-6/+12
| | | | | | | | Do not grab until at least one of the points have moved beyond the drag threshold Change-Id: I30de6332cc8e2b0238cacf5c4f0f70efbdc4d41d Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Don't include exclusiveGrabbers when matching requiredPointCountJan Arve Saether2017-03-141-1/+13
| | | | | | | | More specifically, only count points that are not exclusively grabbed or points that are exclusively grabbed by this handler. Change-Id: I8c873e0553635102cb7cf5c98f0bf318e039cb18 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Deactivate when reset() is calledJan Arve Saether2017-03-091-0/+1
| | | | | Change-Id: If35a45e1a7bbb404b804efbd1aab70116165d684 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* PointerHandlers: fix some grab notification and signal order problemsShawn Rutledge2017-03-081-2/+5
| | | | | | | | | | | | | | The singlePointHandlerProperties manual test showed how this was broken in a couple of ways after 8c659c6c723e4f5f97f46a4555a4765e85c26f1d : - When QQuickPointerTouchEvent::reset() is swapping one point instance for another, and consequently transferring the grabbers from one to another, it should not cause onGrabChanged to occur. Every point update was triggering DragHandler.onGrabChanged. - The order of signal emission is important so that sceneGrabPos will be correct in onGrabChanged. Change-Id: I62a302d6e54126ae10834b6d622e82aa0e434bab Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* TapHandler: grab before emitting on press, after emitting on releaseShawn Rutledge2017-03-071-4/+14
| | | | | | | | | The issue was that in an onTapped handler, the position property would be wrong and active would be false, because setActive(false) occurred too early. Change-Id: I71b43da703aa2f007a367c239d2ded64e6e7e850 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* QQuickPointerSingleHandler warning: show pointId in hexShawn Rutledge2017-03-061-1/+1
| | | | | Change-Id: I86b14b10de86428c30d7aeb939eeb1fd14c50920 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* API: Make some virtuals protected instead of publicJan Arve Saether2017-02-271-3/+2
| | | | | Change-Id: Ib61471a929e387ac64c31d07c9ec5a941cc92d3a Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* QQuickWindowPrivate::deliverTouchCancelEvent: deliver to handlers tooShawn Rutledge2017-02-231-0/+1
| | | | | | | | Now that onGrabChanged() is unified, we have a means to tell the handler when it loses its grab due to a touch event being canceled. Change-Id: Idf3649242233ac7fb8c1fa80ad257ee14b861090 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* API: Move acceptedButtons to QQuickPointerSingleHandlerJan Arve Saether2017-02-235-23/+22
| | | | | Change-Id: I8cb393986e587e69d550ec03f691258c79d9237a Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Make QQuickPointerSingleHandler::pointId() publicJan Arve Saether2017-02-231-1/+2
| | | | | Change-Id: I47441db09e6880eccd3077ea9c5c2248ea05d295 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Change QQuickEventPoint::pointId to be plain intJan Arve Saether2017-02-222-4/+4
| | | | | | | | | | | After change 8984c42d1779b13fd29d95274af2d01d32528e52 in qtbase, a QTouchEvent::TouchPoint::id is already guaranteed to be unique across devices. We therefore don't need a larger value space for QQuickEventPoint::pointId, since that value is the same value as we got from the QTouchEvent Change-Id: I044630a812706f3c114bb28cffb29536f9feeeb3 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Make all handler constructors explicitJan Arve Saether2017-02-217-7/+7
| | | | | Change-Id: I17b3865d70bdc07912d7454b459dea40b9c98df0 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* unify handler grab state handling into onGrabChangedShawn Rutledge2017-02-216-67/+89
| | | | | | | | | | | | | | | | | | | | | | onGrabChanged and handleGrab looked redundant. It was also not clear how important it is for handlers to react to passive ungrabs, overrides or cancellations. Rather than debating about when to call one of these and when not to, let's centralize the responsibility in QQuickEventPoint (because the grabber pointers are stored there, so it's the ultimate destination of any grab change), and let's notify all the relevant handlers about all changes, with enough information that each handler can decide for itself what's important and what isn't. But so far most handlers don't need to override this virtual. The base class QQuickPointerHandler takes care of setting the active property to false, rejecting the eventpoint, and unsetting keepMouseGrab and keepTouchGrab whenever grab is lost; and emitting grabChanged or canceled as appropriate to notify any QML code which needs to know. Subclasses mainly care about the change of active state: they must initiate active state themselves, and may react when it reverts to false. Change-Id: I6c7f29472d12564d74ae091b0c81fa08fe131ce7 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* clarify further exclusive vs. passive grabsShawn Rutledge2017-02-201-2/+2
| | | | | | | | | | Add documentation to the grab-related event and eventpoint methods. Rename "grabber" functions which relate only to the exclusive grab, in cases where it would otherwise be ambiguous. And a few other documentation changes. Change-Id: I1a203c8c06a19d4abdb000f08b387c38341ef476 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* DragHandler: keep the grab (prevent stealing) when draggingShawn Rutledge2017-02-173-0/+20
| | | | | | | | | | | | | Whenever the DragHandler gets an exclusive grab, it needs to prevent a parent Flickable (for example) from taking over that grab. Since it waits until the drag threshold is exceeded in an allowed dragging direction, this does not prevent the Flickable from being draggable in the other direction. We restore the state of keepTouchGrab and keepMouseGrab when ungrabbing. Change-Id: Id9d456c99322e0cb6996d1f690b38fcd6becc6f9 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Notify timeHeld property changed whenever press state changesJan Arve Saether2017-02-161-0/+1
| | | | | | | | Otherwise, we might read the previous timeHeld value (when we released) in for instance the onPressed handler. Change-Id: I2678ad95fad9bd5062573b7ca6d2bff08ce29b87 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* notify all passive-grabbing PointerHandlers when exclusive grab changesShawn Rutledge2017-02-102-0/+8
| | | | | Change-Id: I45df7abdbd91e068a69101ed27e2ec44272e3899 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* start making explicit exclusive or passive grabsShawn Rutledge2017-02-107-18/+42
| | | | | Change-Id: I4a6e3c72d69e893fec2e39f4faab24af6d00c7e0 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* TapHandler: add timeHeld propertyShawn Rutledge2017-02-092-2/+38
| | | | | | | It enables long-press gestures to have continuous feedback. Change-Id: Idd0838aff6213ebfc2fce66639bbc932e77208b4 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* TapHandler: add gesturePolicyShawn Rutledge2017-02-092-20/+110
| | | | | | | | | | | | | | Until now it behaved as if this was set to DragThreshold: give up on the tap as soon as you are clearly dragging rather than tapping. But that's not what is normally wanted when building a Button control, for example. So provide 3 options: give up past the drag threshold, when the pointer goes outside the bounds, or when it's released outside the bounds. The longPressThreshold also constrains all three cases: holding (or dragging) for too long will not result in an immediate cancellation, but it also will not be a tap gesture. Change-Id: I95aec978e783892b55371391a27642751d91d9ff Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* TapHandler: add long-press featureShawn Rutledge2017-02-092-1/+54
| | | | | | | | Add a longPressed signal, emitted when the point is held long enough. Add the longPressThreshold to control how long that is. Change-Id: I95a65f1e4c62eb41fb9ea02b14bdc3f16aa72ec2 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Introduce TapHandlerShawn Rutledge2017-02-084-1/+287
| | | | | | | | | Device-agnostic tap/click detection. Also detect whether the taps or clicks occur close enough together in both time and space to be considered part of a multi-tap gesture. Change-Id: I41a378feea3340b9f0409118273746a289641d6c Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>