aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/handlers
Commit message (Collapse)AuthorAgeFilesLines
* Add effectivelyClipsEventHandlingChildren; skip event delivery when irrelevantShawn Rutledge2025-11-171-0/+5
| | | | | | | | | | | | | | | If a QEventPoint is clearly outside an item _and_ the bounds of all its children, or is simply outside the bounds of an item that clips its children, we can stop recursion, for purposes of QPointerEvent delivery, finding which items/handlers are hovered, or which could control the cursor shape. effectivelyClipsEventHandlingChildren() is also recursive, but at least the result gets cached. Task-number: QTBUG-140340 Task-number: QTBUG-115179 Change-Id: I085e38964de6993fa82ad3bd1256868125fde090 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Reduce QTransform use in event delivery and cursor-finding functionsShawn Rutledge2025-11-112-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Pass localPos to deliverHoverEventRecursive, deliverHoverEventToItem and sendHoverEvent, so that deliverHoverEventRecursive() can merely transform from its own coordinate space to each child's space by calling itemToParentTransform(). That doesn't require up-the-tree recursion like mapFromScene() does. Apply the same trick to QQuickWindowPrivate::findCursorItemAndHandler(). Apply the same trick to QQuickPointerHandler::parentContains(local, scene): now QQuickPointerHandler::parentContains(QEventPoint) also calls that with both local and scene positions, which it already has, so this likely optimizes some use cases outside of the hover and cursor cases. But to make that work, we need to apply the same trick to QQuickDeliveryAgentPrivate::eventTargets() as well, and now it needs to localize the QEventPoint before calling the predicate. Usually, global position is QGuiApplicationPrivate::lastCursorPosition; but when no mouse events occur, only touch events, lastCursorPosition may remain offscreen. So we use the QEventPoint::globalPosition when possible; so it's useful to pass globalPos along to each of these hover functions, so that deliverHoverEventToItem() can construct the QMouseEvent with it, and sendHoverEvent() can construct the QHoverEvent with it. Also amends f5140d62082e9b06e0ca6c8e2175b5836286f52e: that looked rather CPU-intensive to call several mapping functions. The test is retained. Task-number: QTBUG-134099 Task-number: QTBUG-140340 Change-Id: I2c520d430e58ec7c00ada2207541b2936c7ae596 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Doc: Mark internal APIs with \internal commandJerome Pasion2025-11-072-1/+16
| | | | | | | | | | | These internal APIs have function documentation but are missing class documentation. Adding an internal class documentation fixes QDoc warnings. Task-number: QTBUG-141697 Change-Id: Iecb289d39e34ddaa964fbe0a1404830cd2269caa Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* doc: Fix mention of DragHandler in TapHandler docsShawn Rutledge2025-10-241-1/+1
| | | | | | | | Amends 6eaa95662c2d4ba287ac5d1de5ec49bd3a9f59e6 Pick-to: 6.5 6.8 6.10 Change-Id: I195e26fa1a703607b1d65d57e5dc43a072b05e72 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* Set explicit default security level of all files with default securityJan Arve Sæther2025-09-1729-0/+29
| | | | | | | | | | | | | | | | | | | | | | | | | The files (folders) already processed are listed in each issue in epic QTBUG-134547 These files were processed half a year ago. In order to make it clear that all of these files are already processed, mark them with an explicit default security header. For the record, this was generated with this script: find -E . -regex ".*\.(cpp|h|hpp|mm|qml|js)$" | xargs python3 ~/bin/add-cra-header.py in the folders listed in each subtask of QTBUG-134547 (add-cra-header.py only exist at my desktop, but it simply adds the default security header if it doesn't already have any existing security header) QUIP: 23 Fixes: QTBUG-134547 Pick-to: 6.10 6.9 6.8 Change-Id: Ieb8c78ea6561fdbdd27c7b13185ece853eedf80f Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io>
* PointerHandler: Add handler to parent also on componentComplete()Oliver Eftevaag2025-07-181-4/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | It was possible for a handler to not be added to its parent item via data_append() when the handler is created as a property binding: ``` Item { id: parentItem property HoverHandler handler: HoverHandler { parent: parentItem } } ``` In that case, the HoverHandler won't be added to the parent item's default list property (data), since it's being assigned to a different property instead (handler). data_append() was the main way that pointer handlers installed themselves to items, but it is skipped in this case. Now we also call QQuickItemPrivate::addPointerHandler() in componentComplete() if the pointer handler was not already added. Pick-to: 6.10 Change-Id: I5c797f6abcfb19af7e897354fba39dd536e66140 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Only activate DragHandler if drag starts within itShawn Rutledge2025-06-242-0/+18
| | | | | | | | | | | | | | Previously, starting a mouse drag outside a DragHandler's parent and moving inside would activate it. This is unexpected behavior, inconsistent with touch behavior, and might interfere with other drags, so we only activate a DragHandler if at least one point was pressed inside the parent. Pick-to: 6.10 6.9 6.8 Fixes: QTBUG-127863 Change-Id: I2215636397ce9fc6a29b9a35165507e5b8d886f4 Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Map DragHandler delta to the sceneAleksandr Timofeev2025-05-151-1/+5
| | | | | | | | | | | | | Previously, DragHandler didn't account for scene transforms when calculating drag threshold. In the case when one axis is disabled, and the scene is rotated 90 degrees, the remaining axis should be activated by movements that are nominally the same as the disabled direction, because of rotation. Fixes: QTBUG-136354 Pick-to: 6.8 6.9 Change-Id: I6669949908b0d026850411c10056685648a109d9 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Ensure TapHandler.pressed==false when deactivated; tolerate null eventShawn Rutledge2025-03-062-3/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Dating back at least to 507efe5a8a2390813fb620a91b0b3b6b383f599d the initial plan was that an ungrab calls setActive(false), and that ought to be enough, because every pointer handler can react to deactivation in its own way. But QQuickTapHandler did not override onActiveChanged(); and it would still not work very well to do that, because setPressed() takes various arguments that are not available in onActiveChanged(). So an odd state of dubious utility was possible: it could be inactive and pressed at the same time. That's now prevented, as long as TapHandler relies on an exclusive grab. If a TapHandler's window is deactivated while it has an exclusive grab, onGrabChanged() is called with a null event, because the deactivation event is not a pointer event. Don't crash, and don't get stuck in pressed state either. Currently in this scenario, the grab transition is UngrabExclusive, not CancelGrabExclusive. If we are sure that a TapHandler should no longer be pressed if its window is no longer active, and one symptom is that it's ungrabbed, probably it makes sense to be consistent that when it loses any kind of grab that it has taken, it should no longer be pressed. But then we would run into the issue with the null event as described above. So these changes are best done together. If a TapHandler's window is deactivated while it has a passive grab, the TapHandler cannot be deactivated or un-pressed, because it is not in active state in the first place. (As documented, `active` means it has an exclusive grab.) Fixes: QTBUG-118454 Fixes: QTBUG-124777 Change-Id: I855a0e0ddcb13866af5501f6164b6b18b41dda2a Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* doc: Fix string, real, point and size QML property documentationDavid Boddie2024-12-052-9/+9
| | | | | | Pick-to: 6.8 Change-Id: I2de731368e403696ecf9d74a0ac68d1982d5ce24 Reviewed-by: Andreas Eliasson <andreas.eliasson@qt.io>
* doc: Fix string, vector2d and matrix4x4 QML property documentationDavid Boddie2024-12-053-7/+7
| | | | | | Pick-to: 6.8 Change-Id: I30dc4f1573e5bfbf11bc0c69060fd5b77f1681e2 Reviewed-by: Andreas Eliasson <andreas.eliasson@qt.io>
* Doc: Add WheelHandler code snippets; override properties and signalsShawn Rutledge2024-12-041-1/+111
| | | | | | | | | | | | | Some of the docs are inherited from parent classes (such as QQuickPointerDeviceHandler). Override the property docs that have TapHandler snippets, and replace with WheelHandler snippets. Hide properties and signals that are not relevant for WheelHandler. Done-with: Andreas Eliasson <andreas.eliasson@qt.io> Pick-to: 6.5 6.8 Fixes: QTBUG-130266 Change-Id: I30423cd9c0c0810691a2a36171e65de0b44e0dc9 Reviewed-by: Andreas Eliasson <andreas.eliasson@qt.io>
* PinchHandler: Set target properties only if respective axis enabledVladimir Belyavsky2024-10-261-2/+10
| | | | | | | | | | | If the user has disabled the rotation or scale axis, the target item's rotation or scale property must not be set at all, to avoid breaking bindings that were set differently. Fixes: QTBUG-130517 Pick-to: 6.8 6.5 Change-Id: I8f84f6845532f748bbdcc3af91a398d6659156ca Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* PointHandler: don't deactivate because of synth-mouse eventsShawn Rutledge2024-10-083-13/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is necessary after 0b7ee7a48f5f32fc916cc1914b110bdf68e37486. If QQuickPointHandler::wantsEventPoint() ever returns false, QQuickPointerHandler::handlePointerEvent() calls setActive(false). If AA_SynthesizeMouseForUnhandledTabletEvents is enabled, and PointHandler is the only handler trying to handle tablet events, it does not accept the events; so QGuiApplicationPrivate::processTabletEvent() sends a synth-mouse press for each tablet press. If the position doesn't match the last-known mouse position, QGuiAppPriv::processMouseEvent() sends a synth-mouse move, too. PointHandler doesn't care about either of these synth-mouse events, but it has to say that it "wants" them to avoid getting deactivated. But in spite of that, we don't want QQuickSinglePointHandler::handlePointerEventImpl() to call QQuickHandlerPoint::reset() with those synth-mouse events, because then the tablet-specific data from the previous QTabletEvent would get overwritten. In general, pointer handlers handle original device-specific events only, and we just have to avoid letting these synth-mouse events interfere. There were a couple of places that were assuming that if an event is not a QTouchEvent, then it's safe to cast it to QSinglePointEvent; that's usually true, but isSinglePointEvent() exists since qtbase 9a1a15b42fb526ad4f80944afb7761bfff1b5c9d so we might as well use it. Previously, we'd set acceptedButtons: Qt.LeftButton | Qt.RightButton to indicate that the PointHandler should respond to either one; but now it's better to set Qt.NoButton to indicate that it doesn't care. The synth-mouse move has no buttons set; if PointHandler only "wants" events with specific buttons, that buttonless move will deactivate it temporarily, and then the synth-mouse move would re-activate it, causing extra activeChanged and pointChanged signals. But so far, its default for acceptedButtons is still Qt.LeftButton. Perhaps we should change it. The special meaning in QQPointerDeviceHandler::wantsPointerEvent() for Qt.NoButton started already with HoverHandler in 1982d1b1aa55ae44a1a775a5745e5c2f11001398 and then fc636af3a723ee8b4ee42cf71864ae0df5ca4621 for PinchHandler. Those handlers fundamentally don't need to care about buttons, so they declare it by setting acceptedButtons = Qt::NoButton in their ctors, and the user should not set it differently; whereas with PointHandler, we do expect the user to set acceptedButtons. tst_PointHandler::tabletStylus now has code to test both with and without AA_SynthesizeMouseForUnhandledTabletEvents. But in the "true" case (the default), it won't pass until we also change QGuiApplicationPrivate::processMouseEvent() to send synth-mouse-moves from the same device that sends the mouse press, which itself is synthesized from the tablet press. [ChangeLog][QtQuick][PointHandler] If PointHandler is declared with acceptedButtons: Qt.NoButton it now means that the PointHandler does not care which buttons are pressed or not pressed: but it ignores synth-mouse events and responds only to events that come from the appropriate kind of device. If specific acceptedButtons are set, synthetic mouse-moves can deactivate it temporarily. Pick-to: 6.8 Fixes: QTBUG-111336 Change-Id: Ic48565f74d247803e338d2e368a5ef9d249296c2 Reviewed-by: Doris Verria <doris.verria@qt.io>
* DragHandler: Don't change QEventPoint accepted state in touch eventsDoris Verria2024-08-301-3/+4
| | | | | | | | | | | | | | | | | | | | | | QQuickDragHandler::handlePointerEventImpl() accepts the event to begin with. Since ca7cdd71ee33f0d77eb6bf1367d2532e26155cb2 we meant to stop event propagation for mouse events, at least to prevent Flickable from receiving the event via direct delivery after it has already filtered. But back then, QEvent::setAccepted() did not automatically accept the touchpoints; now it does (a questionable choice in Qt 6 that accept() and setAccepted(true) do not do the same thing). Now we leave QEventPoint:isAccepted state alone if it's a touch event, so the workaround to stop propagation of mouse events is the only case where it needs to be changed. And update the comment: since 3073a81e90c8d835dfccccf8b3a080a93ed0d2af Flickable handles touch events directly, it doesn't depend on touch->mouse synthesis. Fixes: QTBUG-124731 Pick-to: 6.8 6.7 Change-Id: I833a4d28f708e27cf01b108da1b886807725dc06 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Avoid detach in range-for loops over QQMultiPtHandler::currentPoints()Shawn Rutledge2024-08-292-3/+3
| | | | | | | | We used std::as_const() in some places, but not consistently. Pick-to: 6.8 Change-Id: Idd948dbe4675c0d287e046c6c7db53d4476b6d30 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Doc: Replace \instantiates with \nativetypePaul Wicking2024-08-2011-11/+11
| | | | | | | | | | | Since the implementation of the `\nativetype`-command in QDoc, the `\instantiates`-command is deprecated. Replace the use of the deprecated command in favor of its replacement. Pick-to: 6.8 Task-number: QTBUG-128216 Change-Id: I23d9f66d3f6db2e5f827d7868497a432bb9b0626 Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io>
* doc: fix reference to nonexistent DragHandler.SnapNeverPierre-Yves Siret2024-07-221-1/+1
| | | | | | | | | | The documentation mentions SnapNever as a value for DragHandler SnapMode The correct value is NoSnap. Amends f228af06c2c712302ee1dcdaf761cd24504b473e Pick-to: 5.15 6.2 6.5 6.7 6.8 Change-Id: I240d63b5ac989d37f2b7a611cab75ccd4bab2368 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* doc: Stop telling users that DragHandler is not for DnDShawn Rutledge2024-06-281-1/+2
| | | | | | | | | | Link to the Drag attached property, which has been referring to a snippet using DragHandler since 5971a6faaa1124f5ef3f0b42d4ed0298cf8096a3 Task-number: QTBUG-68078 Pick-to: 5.15 6.2 6.5 6.7 6.8 Change-Id: I2199e0e08f39ed1b136c5ea71da6631a032c4d48 Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io>
* Make more logging categories staticUlf Hermann2024-06-244-4/+4
| | | | | | | Non-static, non-forward-declared logging categories are deprecated. Change-Id: Iaeb0183ef7ca05bbd0f4587166096c29825cc175 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QQuickMenu: cancel all grabs before QPlatformMenu::showPopup()Shawn Rutledge2024-06-212-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | If a TapHandler is used to open a menu: TapHandler { acceptedButtons: Qt.RightButton onPressedChanged: if (pressed) backgroundContextMenu.popup() } and popup() blocks and then eats the mouse release (as QCocoaMenu::showPopup() does), it means QQuickTapHandler::setPressed() is not allowed to finish executing before being blocked, and it has no chance to get the mouse release afterwards either (that release may have been the one that selected a menu item, which presumably is why macOS eats it). But it behaves well enough if we cancel the grab, and thereby cause QQuickTapHandler::onGrabChanged() to be called with CancelGrabExclusive or CancelGrabPassive. setPressed(false) will be called before setPressed(true) has finished: that works OK in practice, because it doesn't do much else after the `emit pressedChanged()` line. But when QQuickTapHandler::onGrabChanged() calls setPressed(false) after the grab is already canceled, the event is not passed along; so check for null before calling setExclusiveGrab(event, point, false). TapHandler has just been informed that the grab was canceled, so it doesn't need to ungrab again. Pick-to: 6.8 Fixes: QTBUG-126539 Change-Id: I657a6e9b4581df4dd284d6f488e4101c2a2faf4c Reviewed-by: Mitch Curtis <mitch.curtis@qt.io> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Doc: Override DragHandler.accepted* and marginShawn Rutledge2024-06-201-0/+69
| | | | | | | | | | | | | | | | | DragHandler docs have been showing TapHandler code snippets, because both DragHandler and TapHandler inherit properties from PointerDeviceHandler, which is abstract and uses TapHandler code snippets in some of its property documentation. Override documentation for acceptedDevices, acceptedModifiers, acceptedPointerTypes and margin by adding to the DragHandler class, and add testable snippets for a couple of them. draggableGridView is adapted from examples/quick/draganddrop/views/gridview.qml. Fixes: QTBUG-119866 Pick-to: 6.8 6.7 6.5 6.2 Change-Id: I9f98d831ec1691c84da6a38a7625f9aba086cebf Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
* QtQuick: Straighten out some logging categoriesUlf Hermann2024-06-195-7/+6
| | | | | | | | | | | | Either make them static or declare them in a header. We want them to be static wherever possible, in order to reduce the number of visible symbols. If they can't be static, however, they should at least be declared in only one place. Task-number: QTBUG-67692 Change-Id: I485bb7e4379e86f72619f848399ad58c76586851 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Doc: Add snippet for DragHandler.acceptedButtonsShawn Rutledge2024-06-131-0/+18
| | | | | | | | | | | | | | | DragHandler docs have been showing TapHandler code snippets, because both DragHandler and TapHandler inherit properties from PointerDeviceHandler, which is abstract and uses TapHandler code snippets in some of its property documentation. Override the acceptedButtons property documentation by adding it to the DragHandler class, and add a testable snippet. Task-number: QTBUG-119866 Pick-to: 6.8 6.7 6.5 6.2 Change-Id: Ic2c8ee98c33929fd90c8ec11509d510647c4a074 Reviewed-by: Andreas Eliasson <andreas.eliasson@qt.io>
* Doc: fix snippet markers in pinchHandler snippetVolker Hilsheimer2024-06-111-1/+1
| | | | | | | | | | | | | Rename the snippet file so that qdoc doesn't look into the example file with the same name (and where there is no snippet to quote). Also add space between //! and [tag], and an empty line after the SPDX header. Pick-to: 6.8 Change-Id: I013df640c2fea6c25fd459c8a3a46312d14a93de Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: MohammadHossein Qanbari <mohammad.qanbari@qt.io> Reviewed-by: Andreas Eliasson <andreas.eliasson@qt.io>
* TapHandler: don't (dis)connect signals to a null windowShawn Rutledge2024-04-252-5/+18
| | | | | | | | | | This is unexpected, but we're told that it happens somehow. Pick-to: 6.5 6.6 6.7 Fixes: QTBUG-108696 Change-Id: I738099f43003056f7a24c09b1dc36024a81cbbb1 Reviewed-by: Vladimir Belyavsky <belyavskyv@gmail.com> Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
* DragHandler: don't skip passive grab if state includes releaseShawn Rutledge2024-03-261-1/+3
| | | | | | | | | | | | | | | | If QQuickDragHandler::handlePointerEventImpl() is looking at an event with one released point and one stationary point, and minimumPointCount is 1, then it needs to have a passive grab of the stationary point in case it starts moving. The released point is irrelevant: it's not in d->currentPoints. We cannot rely on QTouchEvent::isEndEvent() as a precheck, because m_touchPointStates is Stationary | Released, and that includes Released, but it's not true that the whole touch sequence is ending. Fixes: QTBUG-123499 Change-Id: I20aeecc1f9c29200c324f3f7dc1e6b73fed21d30 Reviewed-by: Doris Verria <doris.verria@qt.io> Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
* Fix PointHandler rejecting click events near window edge with HiDPIFushan Wen2024-03-161-3/+3
| | | | | | | | | | | | | | When using HiDPI and a click happens near the window edge, the global position might have fractional parts, but after the global position is converted to QPoint, the position can be rounded so it happens to stay at the window edge, so the window geometry will not contain the rounded position. Related bugreport: https://bugs.kde.org/show_bug.cgi?id=482580 Pick-to: 6.6 6.7 Change-Id: I51a26f955fd58f2a135c64ceb32ee881a03fcaf8 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* HoverHandler: setHovered(false) for any pointer event outside boundsShawn Rutledge2024-02-211-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | 8e822e981d91e688799c8670f11dfdf6aaf9e0d1 was expecting HoverHandler to receive a QTabletEvent when hover leaves. That worked before bbcc2657fa0dbf715e6db7d675662e4be94a1e04: a HoverHandler had a passive grab, so it would receive the next QTabletEvent that moved outside the item. Now that we stopped doing passive grabs, the event that indicates that the cursor is leaving the item is always a QMouseEvent sent from QQuickDeliveryAgentPrivate::deliverHoverEvent(). If the mouse event says the cursor is outside the item, it doesn't matter what device it came from: this handler is no longer hovered. But as before, if the position is still inside, and a particular HoverHandler is hovered because a tablet stylus was previously detected, do not un-hover merely because of a synth-mouse event at the same position. Amends 79893e1773be9d04208243cb88c1daf793d830a4 Fixes: QTBUG-116505 Task-number: QTBUG-101932 Pick-to: 6.5 6.6 6.7 Change-Id: Id0b622fad524ae4be8b37b9cb55e68384056964a Reviewed-by: Doris Verria <doris.verria@qt.io> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Accept mouse or touchpad in snippets with acceptedDevicesShawn Rutledge2024-02-212-1/+7
| | | | | | | | | | | | | | | This is a workaround for platforms (such as Wayland and macOS) that are sometimes failing to distinguish mouse and touchpad. It's better for illustrative purposes anyway, since a laptop user may really be using a touchpad rather than a mouse, and we hope to eventually distinguish them on as many platforms as possible. Task-number: QTBUG-63363 Task-number: QTBUG-112432 Pick-to: 6.5 6.6 6.7 Change-Id: Ic7a374f1257d4aa57f29385b44da85ccaf4f5ec6 Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io> Reviewed-by: Doris Verria <doris.verria@qt.io>
* Partially revert "Make properties in Qt Quick FINAL to prevent shadowing"Fabian Kosmale2024-02-1711-61/+61
| | | | | | | | | | | | | | | | Making properties FINAL is an API break not covered by any QUIP rule. However, this does not apply to the attached and uncreatable types (either explicitly, or because they are singletons or value types) whose properties were marked FINAL in the referenced commit, as it is not possible to derive from them anyway. So those are left with their properties still marked as final. This partially reverts commit 351979e05ad2a861fc3e6f8d1de6197a751316a8. Pick-to: 6.6 6.7 Change-Id: I1ce8c0873c4600ec2aad8e078c379239ad03f74a Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Remove the use of Q_QUICK_PRIVATE_EXPORTAlexey Edelev2024-01-0917-18/+18
| | | | | | Task-number: QTBUG-117983 Change-Id: Ia904c9390efb13b92de2e16fa0690e48394f9bab Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* QQuickSinglePointHandler: check isSinglePointEvent before castShawn Rutledge2023-12-151-4/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QQuickSinglePointHandler is not only for QSinglePointEvent, but rather it's the intermediate base class of any handler that only knows how to handle one QEventPoint, regardless which device it came from. The naked cast was quite wrong for touch events, such that the result returned from buttons() could come from reinterpreted data of some kind. Amends a97759a336c597327cb82eebc9f45c793aec32c9 (and then 79cde77f23358adbe57ab8ce08730d2de5bb1288). QQuickPointerEvent had buttons(), but QPointerEvent doesn't; so the cast became necessary, but should have been done safely. f2ba3bd9792500b4d3fcfd23b03098a32641ef4f began checking the buttons here. In case of a touch event, buttons() always returned NoButton (regardless whether the touchpoint was being pressed or released); so in Qt 5, QQuickSinglePointHandler::handlePointerEventImpl() in fact caused the ungrab and reset() to occur when a touchpoint was released. We continue doing that: if the event is not a QSinglePointEvent, buttons() are irrelevant, and we deactivate the handler when handling the release of the chosen point (as remembered by pointInfo). But for QSinglePointEvents, checking buttons() is necessary to keep QTBUG-66360 fixed. Task-number: QTBUG-66360 Task-number: QTBUG-83980 Fixes: QTBUG-117387 Pick-to: 6.2 6.5 6.6 6.7 Change-Id: I1bc7a72629f5840e660635f2228bf2c0abb7d2bd Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Update cursor if frame-synchronous hover update discovers hover changeShawn Rutledge2023-11-182-0/+4
| | | | | | | | | | | | Also mark cursor as dirty and force update after shape change. Done-with: Matthias Rauter <matthias.rauter@qt.io> Fixes: QTBUG-53987 Fixes: QTBUG-90457 Task-number: QTBUG-54019 Pick-to: 6.5 6.6 Change-Id: I64d9f5d0a39dbf141a8e82bee824b47a8884139b Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Disable TapHandler.longPressed signal if longPressThreshold == 0Shawn Rutledge2023-11-172-10/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | There needs to be a way to disable the long-press feature, because it's exclusive: if we emit longPressed(), we do not emit tapped(). But we should also be able to accommodate slow users who pause for too long unintentionally, or while simply observing the behavior. Also clarify that resetting longPressThreshold reverts to the default. Add more exhaustive test coverage, verify that longPressed and tapped are mutually exclusive, and verify the effects of violating the gesturePolicy. Change longPressThreshold on LauncherList's back button so that it always triggers, regardless whether the user pauses on it for a while. [ChangeLog][QtQuick][Event Handlers] TapHandler.longPressThreshold can now be set to 0 to disable its press-and-hold feature, and can be reset to undefined to restore the platform default. Fixes: QTBUG-119132 Task-number: QTBUG-105810 Pick-to: 6.5 6.6 Change-Id: Id5fd7e51c70fdb0cb6c4beb5615717a222aec871 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Make TapHandler longPressed/tapped exclusive and reliable; fix exampleShawn Rutledge2023-11-172-3/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The back button in the examples' LauncherList.qml has been flaky. As described in the docs, a TapHandler used to implement a Button should have `gesturePolicy: TapHandler.ReleaseWithinBounds` to get the common behavior that you can drag out of the button to cancel the click, and you can also drag back into the button to change your mind and let it click after all. But when trying to test this behavior, another problem became evident: if you spend a longer time than longPressThreshold for the whole gesture, then at the time of release you could see the debug output "long press threshold exceeded" and the tapped signal was not emitted. Our intention was that if you are dragging around, the TapHandler is not eligible to emit the longPressed signal; it follows that it should not become ineligible to emit tapped, either (tapped can be emitted if other constraints are satisfied). The intention of the ReleaseWithinBounds policy is that it doesn't matter how much you drag, as long as the point is within the bounds of the parent at the time of release. So we begin keeping track of whether we have actually emitted the longPressed signal, rather than merely looking at the time difference. This changed behavior in tst_qquickdeliveryagent::passiveGrabberOrder: 1 second is more than enough time for long press with the default longPressThreshold, and now the tapped signals are no longer emitted after longPressed. So we just wait for pressed state rather than waiting so long. qWaits in tests are best avoided anyway (although I think the intention in 152e12dc22cc0fd07cf90bcd35ae0e05b8b46fa0 might have been to wait long enough to ensure that nothing undesired would occur, rather than waiting for something specific to occur). Task-number: QTBUG-65012 Task-number: QTBUG-105810 Pick-to: 6.5 6.6 Change-Id: If6a86d955e19810cb06de659f5e39b50a72fa762 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Include what you need: <QPointer>Marc Mutz2023-10-062-0/+4
| | | | | | | | | | | | | | | | | | | | | | | All these TUs relied on transitive includes of qpointer.h, maybe to a large extent via qevent.h, though, given that qevent.h is more or less the only public QtBase header that includes qpointer.h, something else seems to be at play here. Said qevent.h actually needs QPointer in-name-only, so a forward declaration would suffice. Prepare for qevent.h dropping the include. The algorithm I used was: If the TU mentions 'passiveGrabbers', the name of the QEvent function that returns QPointers, and the TU doesn't have qpointer.h included explicitly, include it. That may produce False Positives, but better safe than sorry. Otherwise, in src/, add an include to all source and header files which mention QPointer. Exception: if foo.h of a foo.cpp already includes it, don't include again. Task-number: QTBUG-117670 Change-Id: I9b98cda524a0e6a61be7805edda708916bb2bc2b Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Doc: Fix minor documentation issuesTopi Reinio2023-09-151-1/+1
| | | | | | | | | | | | | | | | * src/qmlcompiler/qqmlsa.cpp:925: Fix linking to global Qt object * src/quick/handlers/qquickpointerhandler.cpp:881: Mark a member of QQuickPointerHandlerPrivate as \internal * src/quick/items/qquickrendercontrol.cpp:636: Fix malformed link to QRhi::[begin|end]OffscreenFrame(). In passing, replace unnecessary usage of \badcode with \code. Pick-to: 6.6 Change-Id: I8fd333929fb082215ccac16cca351afcf0e00696 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* Doc: Fix qdoc warningsAndreas Eliasson2023-08-091-5/+8
| | | | | | | | | | Make sure \li is inside \list \endlist. Also, fix some punctuation. Pick-to: 6.6 6.5 Change-Id: Ic877e391b17b4b008f9f8543019f3944eb264475 Reviewed-by: Safiyyah Moosa <safiyyah.moosa@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QQuickTapHandler: Pass flag to Q_FLAG instead of enumFabian Kosmale2023-07-271-1/+1
| | | | | | | | | Amends d3f2c6ac4205bbe5a1c7174965dbce6f90972be3 Pick-to: 6.6 6.5 Fixes: QTBUG-115557 Change-Id: Ibd8e79bcb6bfec292bff12e8d4f166c0b4b6ba56 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* doc: Remove readonly tag from PinchHandler persistent propertiesShawn Rutledge2023-07-261-3/+1
| | | | | | | | | | | | | Amends a432970b258edb9ff041d221b2155df30cad4799 As a drive-by, remove redundant categorized logging output, which wrongly implied that starting scale could be set from the target scale. Pick-to: 6.5 6.6 Task-number: QTBUG-76739 Task-number: QTBUG-94168 Change-Id: I1fad79b58fa20e165fd21bc593a27cff8378b7ea Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Add more internal docs in QQuickDeliveryAgent and its PrivateShawn Rutledge2023-07-121-3/+9
| | | | | | | | Try to explain pointer event delivery better. Change-Id: I015170fbf94f3e7d06d329223730426362f884fe Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io> Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
* Add internal PointerHandler docs; arrange accessors together with docsShawn Rutledge2023-07-071-31/+149
| | | | | | | | | | | When subclassing to make a custom handler, there are several things to know, so it's good to get some docs in place. Task-number: QTBUG-68110 Task-number: QTBUG-111013 Pick-to: 6.6 Change-Id: I4bd296cf1b312df8b76be9bf403ae01bbb34eb72 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* doc: Rename to Qt Quick Examples - Pointer HandlersShawn Rutledge2023-07-026-8/+8
| | | | | | | | This seems to be still a consistent naming convention for example docs. Pick-to: 6.6 Change-Id: I508526ec992222da1c971bc327dd9c83a21640aa Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io>
* Make properties in Qt Quick FINAL to prevent shadowingOliver Eftevaag2023-06-0812-75/+75
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Without setting the FINAL flag, properties can be shadowed by users. In the following example: Image { property string source: "Shadowing QQuickImage::source" } The source property of QQuickImage, will be shadowed by a new property with the same name. This can both cause confusion for non-experienced users, and it causes issues with qmlsc. Shadowing a property is usually unwanted. But there are some situations where it might be intended. The QML Object Attributes doc page demonstrates that you can override the color property in QQuickRectangle, for instance. [ChangeLog][Important Behavior Changes][QtQuick] Most properties for types in the QtQuick module are now FINAL, meaning that they can no longer be shadowed by declaring new properties with the same names. With few exceptions. A warning will be printed out to the console, when a FINAL property is shadowed. We recommend that users rename those properties to avoid potential unexpected behavior changes. Task-number: QTBUG-108739 Pick-to: 6.6 Change-Id: I1070926606f4d88ef7edf088ff80fb3ec82305c8 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* QQuickSinglePointHandler: reset pointinfo on a stray TouchBeginAxel Spoerl2023-05-271-3/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Extremely fast finger drumming on a touch screen with e.g. a tap handler can result in one event being inserted between two others. Such unwanted events are caught in QQuickSinglePointHandler::wantsPointerEvent() and results in a warning. However, once the sequence of TouchBegin, TouchUpdate, TouchEnd is upside down, the single point handler will always expect another event than physically possible: For example, when the handler expects TouchEnd and no more fingers are on the touch screen, the expected event will always be preceded by a TouchBegin, which makes the handler wait for another TouchEnd. Ultimately, the application can no longer interpret incoming touch events, because they will be ignored as unexpected. This patch adds functionality to the handling of unexpected events. If an unexpected TouchBegin event with exactly one event point is observed, the current gesture is canceled and uses the stray event as a new starting point. An autotest is added in tst_QQuickTapHandler::touchMultiTap(). Fixes: QTBUG-108689 Fixes: QTBUG-113005 Pick-to: 6.5 Change-Id: I344e77e87acbaab8e4033606ca3f244427b94458 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Quick: Update documentation of TapHandler to reflect renamed enumDavid Edmundson2023-05-051-1/+1
| | | | | | | | | PointerDevice.GenericPointer was the enum value in Qt5, but in Qt6 this changed to PointerDevice.Generic Pick-to: 6.2 6.5 Change-Id: Ic5e4a5fe5fd91f7478d00e0d2c643b99eaa7ab14 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Remove reference to QQuickPointerScrollEvent in documentationMatthias Rauter2023-04-201-1/+1
| | | | | | | | It does not exist in Qt6 and was apparently replaced by WheelEvent. Pick-to: 6.5 Change-Id: I6b833e664d8e5e5d6e2bd23ed90695d43073decd Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Use correct names for QEventPoint::State, PointerDevice::GrabTransitionShawn Rutledge2023-04-141-0/+15
| | | | | | | | | | | | | | | | | | | | | | | | | Qt::TouchPointState is not the actual type here, and we should not encourage e.g. making a comparison between eventPoint.state and Qt.TouchPointMoved in an onGrabChanged handler. The equivalence is an internal detail; and eventPoint can come from any pointing device, not only from a touchscreen. QEventPoint is a Q_GADGET; we keep the registration to expose it as a value type (eventPoint). But such types cannot be created in QML, and we also need to give it an uppercase name to scope the enum values that it declares: that's a new foreign namespace called EventPoint. So it's possible to compare an eventPoint instance's state property against EventPoint.Pressed, and so on. Also show complete QML syntax in the \value tables where PointerDevice::GrabTransition is emitted to QML, namely PointerDevice::grabChanged and PointerHandler::grabChanged. Amends b43a873264d012dc0a0e574ea53335a40af8aa38 Task-number: QTBUG-102160 Change-Id: If1a97f21d8e005e3692298b8512f7f8b56a92c97 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Fix TapHandler signals in combination with exclusiveSignalsShawn Rutledge2023-04-112-20/+29
| | | | | | | | | | | | | TapHandler does not emit any singleTapped or doubleTapped signals after emitting it once, if exclusiveSignals is set to `SingleTap | DoubleTap`. This change corrects the behavior by resetting m_tapCount properly. Fixes: QTBUG-111800 Pick-to: 6.5 Change-Id: Ice7af2f41c2f30448004033d8330e733abe44110 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>