aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/handlers/qquickmultipointhandler.cpp
Commit message (Collapse)AuthorAgeFilesLines
* Merge remote-tracking branch 'origin/5.13' into devQt Forward Merge Bot2019-04-291-6/+7
|\ | | | | | | | | | | | | | | Conflicts: src/qml/compiler/qv4compilercontext.cpp src/qml/qml/qqmlmetatype.cpp Change-Id: I02e0216961b92ff68a3f91a70edc33fe9e8db147
| * MultiPointHandler: eliminate "no points" warning with native gesturesShawn Rutledge2019-04-261-6/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In handlePointerEventImpl, there is the call d->centroid.reset(d->currentPoints); with the expectation that currentPoints is not empty. But we weren't populating it in case of a native gesture. It still ends up being empty at the end of the gesture, but it's normal to return false from wantsPointerEvent() when there are no eligible points. Fixes: QTBUG-70083 Change-Id: I12ca6460a24d2eb6c44a639f83ce3ff17eb37613 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* | QQuickMultiPointHandler::moveTarget(): work with interceptorsShawn Rutledge2019-04-151-2/+27
| | | | | | | | | | | | | | | | | | | | | | As with WheelHandler, DragHandler also needs to allow the target movements to be constrained with interceptors like BoundaryRule. Also do a null pointer check in moveTarget(): we haven't needed it before, but we are becoming more open to subclassing, so need to prevent user foot-shooting. Change-Id: I6b39b6dd2ca8245c56ecb3812e6de9624b36fa50 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* | Refactor QQuickMultiPointHandler into public and private classesShawn Rutledge2019-04-021-46/+97
|/ | | | | Change-Id: Iec19664862bfbbf9a6c582dac441dda26eec57db Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Fix bug where QQMPH kept an exclusive grab when no buttons were pressedJan Arve Sæther2019-02-061-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This happened if you moved the mouse while doing a multitouch operation. More specifically this caused the bug: 1. Open qtdeclarative/tests/manual/pointer/map.qml 2. Rotate the map with two fingers (Do not release fingers). 3. Move mouse (no buttons pressed). 4. Release both fingers. 5. Move mouse again (error: the draghandler has a grab and thus the map is dragged even if no buttons are down). This happened because if you moved the mouse while having two fingers down, Windows would generate a *mouse*move* event with Left button or Right button pressed (which wasn't the case on the physical device but it's probably because of a bug in how mouse events are synthesized from touch on Windows). This caused the QQuickMultiPointHandler to do a passive grab. Then, when releasing the fingers it would not send a mouse release event (just plain touch release events), so the QQuickMultiPointHandler would keep the passive grab it had. All subsequent mouse move events would then be dispatched to the QQuickMultiPointHandler where it would assume that the button was pressed until it got a release event (but button was never pressed so that wouldn't happen). Eventually it would perform an exclusive grab, and dragging was initiated. Change-Id: I42b3133c5fde93c7f92f1cb28705156a69f9ad1c Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* When there are no points to grab, then we should return falseAndy Shaw2018-12-191-0/+2
| | | | | | | | | | | | If there are no points to grab then it should not indicate that it was able to grab points. Otherwise it can cause a handler to be active when it has not valid points to work with. This can happen if you do a pinch gesture on a DragHandler as the points are not valid by default then. Fixes: QTBUG-71972 Change-Id: Ib1c48e5a3777f4118944accfa2bc92edf0209884 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Doc: Fix the QML type of MultiPointHandler.centroidShawn Rutledge2018-09-111-1/+1
| | | | | | | | We use QML types not C++ types in QML docs. This fixes links so that you can see the centroid's properties. Change-Id: I3efe04dbfefba965176030adc3e65672519b81dc Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Rename QQEventPoint::GrabState to GrabTransitionShawn Rutledge2018-08-311-2/+2
| | | | | | | | | | | | | | | | | | | This enum represents a transient state transition, and only sometimes corresponds to the current grab state of an event point. For example after exclusive grab has been canceled, the current state is that there is no exclusive grab: it doesn't make sense to remember that the way it got there was by cancellation. There was an idea to add a grabState property, but not all values would be eligible. An EventPoint can be exclusively grabbed by one item or handler at a time, and by multiple passive grabbers at the same time, so even a Q_FLAG would not fully express all possible states. Besides, there is already an exclusiveGrabber property, and we could add a passiveGrabbers list property if we had a real need. So adding a grabState property seems unlikely, and therefore is not a good enough reason to keep this enum named as GrabState. Change-Id: Ie37742b4bd431a7e51910d79a7223fba9a6bd848 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Doc: clarify the type and meaning of QQuickMultiPointHandler::centroidShawn Rutledge2018-08-221-0/+9
| | | | | | | | | | | | Amends 52d35526f256bf4c8155f5e660a214ab8a2efbdf : it's now a QQuickHandlerPoint rather than QPointF, and is inherited from MultiPointHandler to DragHandler and PinchHandler. So the docs can be inherited too, but in PinchHandler it seems more appropriate to keep the overridden docs which explain that transformation around the centroid depends on pinchOrigin. Task-number: QTBUG-70074 Change-Id: I8875b38439fe80c311a685ab9e3dedc9357415e8 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* MultiPointHandler: ensure centroid properties are reset after releaseShawn Rutledge2018-08-221-1/+5
| | | | | | | | | | | ...and verify the centroid changes in the DragHandler autotest. It was observable in manual tests that draw velocity vectors that they weren't getting reset to zero after the release, after ca7cdd71ee33f0d77eb6bf1367d2532e26155cb2. Change-Id: I16186d36d51a567b0d653307421147264a5e6326 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* MultiPointHandler::wantsPointerEvent: reset if different cand countShawn Rutledge2018-08-021-5/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We always intended to "start over" with event delivery when the number of touchpoints changes. Change 48011c2dfeb83b4fe717034d4b3c353714fead48 began this process, but in addition to QQuickWindow delivering the event to all items and their handlers in reverse paint order, ignoring existing grabs, the handlers themselves have responsibility to act as if it was an initial press whenever the number of relevant touchpoints changes; and because QQuickWindow starts over, handlers do not need to rely on passive grabs to retain interest in one point at the time when a transition to a different number of points occurs. For example, DragHandler by default handles just one point, so if you press one point such that it takes a passive grab and adds that point to m_currentPoints, then you press a second finger within the bounds of the same parentItem, the DragHandler should not go on "wanting" the first point anymore, because a two-finger gesture is different, and not suitable for the DragHandler unless its maximumPointCount >= 2. Even if the second point is released, QQuickWindow will "start over" with delivery, so a multi-point handler does not need to rely on retaining a passive grab to handle the transition from two points back to one again. This also helps enable smoother transitions between different gestures: e.g. in the map.qml manual test, you can drag one finger and transition from dragging to pinching and back while the second finger is pressed, dragged and released. Change-Id: Id9b8f30029ed1ff9fd2d64a5e413a47055622083 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Fix PointerHandler constructors and destructorsShawn Rutledge2018-07-271-5/+1
| | | | | | | | | | | | | - Constructors should take QQuickItem* not QObject* to be symmetric with the parentItem() accessor (and other code) which assumes its type - Use header initialization everywhere possible - Reorder variables to minimize padding (somewhat) - Remove empty destructor bodies (the compiler can write them) - Remove override and virtual from destructors in accordance with https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rh-override Change-Id: I682a53a803d65e29136bfaec3a5b534e975ecf30 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Rearrange docs: Pointer Handlers -> Input HandlersShawn Rutledge2018-07-261-2/+1
| | | | | | | | | | | | | | | At QtCS 2018 we decided to rename Pointer Handlers to Input Handlers and include the Keys attached property as part of this set (since we plan to have attached-property pointer handlers too, eventually). It's no longer a module, it's included in Qt Quick 2.12. We need to start promoting Input Handlers and reducing the visibility of legacy stuff like MouseArea and MultiPointTouchArea (in the hope of being able to deprecate them eventually). Task-number: QTBUG-66651 Change-Id: I801351ac2531191cbb1faac9318441c67a109af6 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io> Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io>
* QQMultiPointHandler: don't respond to a QWheelEventShawn Rutledge2018-07-241-0/+3
| | | | | | | | | The most noticeable consequence was having DragHandler activate when attempting to scroll a parent Flickable. Task-number: QTBUG-69607 Change-Id: I5a01695de00db179ddf0b3a39bdcd5e67ba345ef Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Make sure pressPosition and scenePressPosition are correctly initializedJan Arve Sæther2018-07-231-1/+3
| | | | | | | | | | | | | | | | | | | | The problem was that QQuickMultiPointHandler::m_currentPoints were only initialized when the candidate points matched the min and max number of points. So if we wanted to do a two-finger pinch it would only initialize them when *both* fingers were pressed. Due to the checking of point->state() in QQuickHandlerPoint::reset(const QQuickEventPoint *point) it meant that it would only initialize the press position correctly for the *last* pressed point. This was because the first pressed point would at the point when reset() was called have a point->state() == QQuickEventPoint::Updated, so it would not initialize the pressPosition nor the scenePressPosition. Luckilly we can get the scenePressPosition from the QQuickEventPoint, but the pressPosition we have to explicitly localize. Change-Id: I493c736814cfbc265ec33e8a72fc4283edbbdc43 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Make DragHandler a MultiPointHandlerShawn Rutledge2018-07-191-3/+27
| | | | | | | | | | That is, minimumPointCount can now be set to a value > 1 to require multiple fingers to do the dragging, or to track the displacement of multiple fingers to adjust some value (such as the tilt of a map). Task-number: QTBUG-68106 Change-Id: Ib35823e36deb81c8b277d3070fcc758c7c019564 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* QQuickMultiPointHandler: store QQuickHandlerPoints, not QQEventPoint*sShawn Rutledge2018-07-191-22/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QQuickPointerTouchEvent::reset(QEvent *event) reuses instances of QQuickEventPoint from one touch event to the next, but it makes no attempt to match up each instance with the same pointId from the event. So from the perspective of Handlers, each event can have its touchpoints in a different order, and therefore it's always wrong to hold onto any QQuickEventPoint pointer between events. Instead we use QQuickHandlerPoint for storage: both for exposing to QML, and for internal storage in handlers that need to remember touchpoint state. Without this change, any MultiPointHandler could "forget" which point IDs it had chosen to react to, in any case where the event contains additional points. It was using a QVector<QQuickEventPoint *> to remember the chosen points, but each of those instances might be assigned a different touchpoint during the handling of the next touch event (and thus its ID would change "underneath"). Perhaps this went unnoticed until now because 1) the only subclass of MultiPointHandler was PinchHandler, and we didn't often test use cases with extra touchpoints beyond the ones involved in the pinch and 2) on Linux/X11 they stayed in the same order in each event. But as soon as we try to make DragHandler inherit MultiPointHandler, it becomes clear that it does not succeed in holding on to a particular touchpoint while dragging multiple DragHandlers with multiple fingers, without this patch. Change-Id: If7e0daa9ed77b263efc09f5ea73dfba6a3c8205c Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Rename Pointer Handlers to Input Handlers (as a concept)Shawn Rutledge2018-07-121-2/+2
| | | | | | | | | | | | | | | | This is a documentation change to alleviate some confusion that we've seen during the Tech Preview period. It doesn't make sense to actually rename the base class though, because it is intended to handle QQuickPointerEvents, not QEvents. The reason for that is that refactoring the QEvent hierarchy has to wait until Qt 6. So maybe in Qt 6 we can remove QQuickPointerEvent and have a QQuickInputHandler base class which handles QInputEvents; but for now, this conceptual renaming seems about as far as we can go. Task-number: QTBUG-66651 Change-Id: I84a41dc282c480d08f4d4a0d9a857e37e074aa7a Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io>
* Replace MultiPtHndlr.pointDistanceThreshold with PointerHandler.marginShawn Rutledge2018-06-291-27/+1
| | | | | | | | | | | | | | | | It's not just useful for PinchHandler: TapHandler has a good use for it too. But unfortunately if the handler's parent Item has a custom mask, we don't have a way to augment the mask with a margin; so if margin is set, we assume the bounds are rectangular. QQuickMultiPointHandler::eligiblePoints() now calls wantsEventPoint() rather than bounds-checking the point directly: this adds flexibility, potentially allowing an override in subclasses, if we need it later. Task-number: QTBUG-68077 Change-Id: I65c95f00c532044a5862654e58c9c5f8c973df81 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* MultiPointHandler::hasCurrentPoints: OK if event has more pointsShawn Rutledge2018-06-251-3/+3
| | | | | | | | | | | | | | | | | We plan for DragHandler to be able to handle multiple points and thus to inherit from MultiPointHandler. But most DragHandlers only handle single points. Without this change, the mixer manual test would be broken: each DragHandler's m_currentPoints will have only one point, but as soon as the event has multiple points, all the DragHandlers would return false from wantsPointerEvent, and therefore it becomes impossible to drag two DragHandlers with two fingers. This test was just meant as a shortcut/optimization anyway. But if the event contains fewer points than the handler already knows that it wants to handle, we can still return early. Change-Id: Ieea26a09bb9af9ee3c7ff2913f8e90f35c0f070e Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* MultiPointHandler: add a centroid propertyShawn Rutledge2018-05-181-21/+14
| | | | | | | | | | | | | | | One of the reasons we were so fond of using SinglePointHandler for the "simple" handlers like TapHandler and DragHandler is that it has the point property, which is easy to bind to in QML. But multi-point handlers tend to use the centroid as the focal point or fulcrum of the transformation, so exposing the centroid as a QQuickHandlerPoint gadget rather than just a QPointF has all the same advantages as the point property in SinglePointHandler, including letting the QQuickHandlerPoint instance store state between events (press position, grab position, last known position etc.) Change-Id: I4a955fa21b54b7ebb50b0ee2c942fb98eeccb560 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Fix build without features.gesturesTasuku Suzuki2018-05-141-0/+2
| | | | | | Change-Id: Id2fb6419be9a35ddaa24106d3022e72070cb908d Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
* PointerHandler: add grabPermissions, enforce in setExclusiveGrabShawn Rutledge2017-11-141-6/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | As soon as we enable the concept that PointerHandlers can use passive grabs to lurk, monitor all movements, and then steal the passive grab, they can fight over the grab. For example if there are two items with PinchHandlers, and two or more touches occur within bounds for both, then each update event can cause the other PinchHandler to steal the grabs and become active. So we replace stealing with negotiation: the handler which wants to take over the grab checks its own flags to see whether that's allowed, and the handler which is about to lose its grab also has the right to approve or deny the takeover (just as QQuickItem has had keepMouseGrab and keepTouchGrab for a long time.) Additionally, if one handler wants to cancel another handler's grab without taking over (simply set the grabber to null), it must be approved. A single-point handler can simply call setExclusiveGrab, with the expectation that permission may be granted or denied. A multi-point handler only wants to grab all points if grabbing all of them will be allowed, otherwise grab none; so it calls canGrab on each point to check beforehand. Thus, when two handlers are competing for the same grabs, one or both can be prevented from stealing from each other, or from Handlers in general, or from Items, or some combination. Change-Id: I5c733b2b8995ce686da0be42244394eeee82a268 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* PinchHandler: add native pinch gesture supportShawn Rutledge2017-09-291-0/+3
| | | | | | | | | macOS generates QNativeGestureEvents for 2-finger trackpad zoom and rotation gestures. Now PinchHandler will react to them in the same way that PinchArea does. Change-Id: I4c7dab1d3561d20897e3671f4eb68d01ea06b9bd Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* replace MultiPointHandler::requiredPointCount with min/max range propsShawn Rutledge2017-09-291-16/+41
| | | | | | | | This is more flexible in case someone wants a PinchHandler to respond in the same way for either 2 or 3 touchpoints, for example. Change-Id: I360ce6f0239d86aa92dbebc225e3646883e71100 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* improve documentation of the PointerHandler base classes and indexShawn Rutledge2017-09-291-1/+39
| | | | | | | also QQuickPointerEvent and QQuickPointerDevice Change-Id: I8bdb7c26cf6a5775a77dbf748c47c170270c5fff Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* QQuickMultiPointHandler::eligiblePoints: use parent not targetShawn Rutledge2017-09-121-2/+2
| | | | | | | | | | | | | | If a PinchHandler for example is declared with target: null, it was crashing here. The eligible points are contained within the Item within which the Handler is declared; it's OK to do a pinch gesture within one Item but manipulate another Item instead. In such a case, the parent and target are different. Alternatively, target can be set to null, if the user is only interested in reacting to the Handler's properties in some other way rather than directly manipulating some target. Change-Id: Ia077006be1285c242fe7ba71ea89850cd7717c7c Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* rename QQuickEventPoint pos properties to positionShawn Rutledge2017-09-051-5/+5
| | | | | | | | For consistency we always spell it out, although it does make some of these properties inconveniently verbose. Change-Id: I64a08c3aa261c0ab89e09472dd47510abafbf7ca Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Rename single and multi pointer handler classnamesJan Arve Sæther2017-09-031-0/+248
Renames: QQuickPointerSingleHandler -> QQuickSinglePointHandler QQuickMultiPointerHandler -> QQuickMultiPointHandler Change-Id: I10c54944f85ca7cac374ebc6241d61793e2d38bf Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>