Commit Graph

27 Commits

Author SHA1 Message Date
Shawn Rutledge 7ef31a5763 Ensure that HoverHandler reacts if a touchpoint moves out of bounds
We rely on QQuickDeliveryAgentPrivate::flushFrameSynchronousEvents()
mostly, but it doesn't get invoked without a window update request.
So there is a special case when a touchpoint moves _out_ of an item
that has a HoverHandler but is not reacting to touch in other ways:
we just need to send another artificial hover event for each touchpoint
to each hovered item to inform handlers about the new hover position.

Fixes: QTBUG-120346
Pick-to: 6.6 6.5 6.2
Change-Id: I479362a2663943eb495fe0be418009165c7134bd
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
(cherry picked from commit ff4c2c311f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2023-12-29 04:31:14 +00:00
Shawn Rutledge cd7c5f94a0 Update cursor if frame-synchronous hover update discovers hover change
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>
2023-11-18 08:23:02 -07:00
Marc Mutz 2d3d9e12ed Monthly re-run of clang-tidy qt-* checks (11/2022)
Change-Id: Ie7d9117f627984c4af2cf600c8e9119abf306319
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2022-11-02 18:11:01 +01:00
Richard Moe Gustavsen f0c2fe9b8a QQuickItem: don't disable hover if a hover handler is active
QQuickItemPrivate::subtreeHoverEnabled should be true for an item
if the item itself, or any descendants, are listening for hover.
And the item itself is listening for hover if hoverEnabled is
true, or if it has hover handlers.

But QQuickItemPrivate::setHasHoverInChild() didn't take the latter
into account. This meant that if a leaf item with a hover handler
called setHasHoverInChild(false) at runtime (if the _item_ itself
didn't need hover anymore), we also cleared subtreeHoverEnabled for
the handler (unless the item had a descendant that subscribed for hover).
This meant that it would be skipped during hover event delivery.

This patch will make sure that an item cannot set
subtreeHoverEnabled to false if it's in conflict with one of
its hover handlers.

Pick-to: 6.4
Change-Id: I89fb387430d9de31c5e1f4b137a37620dcc8a55c
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2022-10-31 22:52:34 +01:00
Richard Moe Gustavsen 7db67e59d4 QQuickHoverHandler: listen for parent changes, and update hasHoverInChild
A QQuickHoverHandler is normally created by the QML engine, but
can sometimes also be created directly from C++. And for
the latter case, QQuickHoverHandler::componentComplete() will
not be called. This causes a problem, since it takes care of
subscribing for hover events on the parent item.

To support creating hover handlers from c++, we therefore need
to also subscribe to hover events from the constructor.
Moreover, since the parentItem can change at runtime, we also
need a virtual function that informs it when the parent item
changes, so that we can remove hover subscription from the old
parent, and subscribe for it on the new parent.

Pick-to: 6.4
Change-Id: I52f3cd16d6bbfbbe2e4c3c019efdc7f06c5f2c31
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2022-10-31 22:52:33 +01:00
Shawn Rutledge d475b74d66 Attempt to stabilize tst_HoverHandler::deviceCursor (part 2)
CI logs tell us that QTRY_COMPARE(mouseHandler->isHovered(), true)
has been failing sometimes.  It's not supposed to fail, because we are
sending a mouse move event that should result in HoverHandler detecting
hovering (as opposed to using QCursor::setPos(), which is known for
being a more thorough test on window systems that support it, but also
not working on some systems).

On the hypothesis that this has something to do with timing,
avoid checking isHovered() until after we have verified that the
mouse-handling HoverHandler has received an event with a timestamp at
least 100 ms after the one that went to the last tablet-handling
HoverHandler, and only in that case continue with checking hover states
and the cursor. And anyway, if it keeps failing, we might at least
get the qCDebug line in the logs to be able to check the timestamps.

Amends 79893e1773

Pick-to: 6.4
Task-number: QTBUG-107763
Change-Id: Id7c657bfadf7b49ba3440e28d13121c041d38816
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-10-19 18:16:34 +02:00
Shawn Rutledge e3343eb83f Attempt to stabilize tst_HoverHandler::deviceCursor
If the test can't send QTabletEvents, we can't use
AA_SynthesizeMouseForUnhandledTabletEvents to test device-specific
cursor conflicts. There is so little left to test that we might as well
skip it.

Since QTest::mouseMove() takes a delay argument, we don't need to use
qWait(). It should not have resulted in any flakiness, but we might
as well remove it to save a little time.

Amends 79893e1773

Pick-to: 6.4
Task-number: QTBUG-107763
Change-Id: Ic83a80f83fe51ad9413e21c5ca48c338d9ca3728
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-10-19 03:49:15 +02:00
Marc Mutz 958cd3ee10 Port from container::count() and length() to size()
This is a semantic patch using ClangTidyTransformator as in
qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8:

  auto QtContainerClass = anyOf(
      expr(hasType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))))).bind(o),
      expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o));
  makeRule(cxxMemberCallExpr(on(QtContainerClass),
                             callee(cxxMethodDecl(hasAnyName({"count", "length"),
                                                  parameterCountIs(0))))),
           changeTo(cat(access(o, cat("size"), "()"))),
           cat("use 'size()' instead of 'count()/length()'"))

a.k.a qt-port-to-std-compatible-api with config Scope: 'Container',
with the extended set of container classes recognized.

Change-Id: Idb1f75dfe2323bd1d9e8b4d58d54f1b4b80c7ed7
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-10-07 23:38:48 +02:00
Richard Moe Gustavsen 843b8d126d QQuickItem: document and test how hover events work wrt the enabled property
The current documentation for the "enabled" property claims
that "This property holds whether the item receives mouse and
keyboard events.". This is not completely true. Hover events
have been enabled for disabled items for a long time, to
e.g show tooltips, also for disabled items. Since changing
this would cause regressions, and since hover events can anyway
be switched on and off with a separate, explicit, API, document
(and test) that this is how hover events actually work.

Task-number: QTBUG-30801
Pick-to: 6.4
Change-Id: I59409cbb33fb3e2275809156c245e28c21891bbc
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2022-09-16 23:02:23 +00:00
Richard Moe Gustavsen 205e31df16 DA: ignore disabled HoverHandlers when delivering hover events
According to the documentation for HoverHandler::enabled, a
disabled hover handler will not accept any mouse events. It
therefore follows naturally that a disabled HoverHandler
should also not affect event propagation elsewhere.

This patch will change the implementation, so that
we don't deliver hover events to HoverHandlers that are disabled.
This also means that disabled HoverHandlers will no longer block
propagation to its siblings.

[ChangeLog][QtQuick][HoverHandler] Disabled hover handlers
will no longer receive hover events, or block siblings from
being hovered.

Pick-to: 6.4 6.3 6.2
Fixes: QTBUG-106548
Change-Id: I7f2e459ba39f1e23cdb13bf94f8754e185dcd0c1
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2022-09-16 15:27:15 +02:00
Shawn Rutledge 79893e1773 Ensure that multiple HoverHandlers can react to multiple device types
1c44804600 had some known incompleteness in
QQuickItemPrivate::effectiveCursorHandler because it couldn't be
finished in Qt 5; but HoverHandlers with different acceptedDevices and
acceptedPointerTypes were working together in Qt 6.0 and  6.1 to an
extent. Perhaps for this case it helped that HoverHandlers got passive
grabs, but we stopped that in bbcc2657fa.
So now, as with mouse events, we need to ensure that when a HoverHandler
detects a particular stylus device in a QTabletEvent and chooses a
different cursor, it is applied to the window.

At this time, since QQuickDeliveryAgentPrivate::deliverHoverEvent()
sends a synth-mouse event, it's not suitable for tablet hover; so we
depend on correct implementation of allPointsGrabbed() to ensure that
QQuickDeliveryAgentPrivate::deliverUpdatedPoints() will visit all the
HoverHandlers, in this case only.

Pick-to: 6.3 6.4
Fixes: QTBUG-101932
Change-Id: Ia8f31610e9252825afc7151be58765ac5217b0e8
Reviewed-by: Doris Verria <doris.verria@qt.io>
2022-08-25 23:57:11 +00:00
Lucie Gérard 0dc4fd240a Use SPDX license identifiers
Replace the current license disclaimer in files by
a SPDX-License-Identifier.
Files that have to be modified by hand are modified.
License files are organized under LICENSES directory.

Pick-to: 6.4
Task-number: QTBUG-67283
Change-Id: I63563bbeb6f60f89d2c99660400dca7fab78a294
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2022-06-11 08:05:15 +02:00
Richard Moe Gustavsen 56a0753415 QQuickMouseArea: let MouseArea reject hover events
From testing Qt 6.1, a MouseArea should not accept hover
events, and as such, block hover events from propagating.
This patch will make sure that QQuickMouseArea rejects hover
events, and thereby restore the behavior Qt had up till Qt 6.1.

Fixes: QTBUG-95726
Fixes: QTBUG-95398
Pick-to: 6.3 6.2
Change-Id: I1b929092a3004dd47ef1b6d1a957837ccedc7390
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2022-03-28 06:43:41 +01:00
Richard Moe Gustavsen 499828b855 QQuickDeliverAgent: don't propagate hover to siblings
From testing Qt 6.1, hover events should not propagate
between siblings. As soon as a leaf item is found that
receives a hover events, the event should only propagate
up the parent chain starting from the leaf item.

Pick-to: 6.3 6.2
Change-Id: I7448f5322f529addb2260b0ee2b02d2cfadb55e1
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2022-03-26 23:38:43 +01:00
Fabian Kosmale 4f50697e6c Do not rely on transitive includes in tests
Change-Id: Icb68dbecab6f675352cd58333c82fa6648025367
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2022-02-14 12:38:10 +01:00
Volker Hilsheimer bea06407bc macOS: Skip test only if cursor can't be moved
It's not ideal to use QCursor::setPos in tests (see QTBUG-76312) to test
mouse related user input code, but it usually works locally (perhaps
after giving permissions) and in CI as well (once provisioned correctly)
so at least try to move the cursor, and only skip if the position isn't
taken.

Task-number: QTBUG-76312
Task-number: QTBUG-98492
Pick-to: 6.2
Change-Id: Ic0db2f6de71da389486e0cb74815f59878ac63d2
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2021-12-11 00:51:26 +01:00
Shawn Rutledge 2b50181be8 Add HoverHandler.blocking property
As with WheelHandler, sometimes users want to let the hover events
propagate (which has been the default all along), but sometimes it's not
appropriate to allow parents of nested items to show hover feedback.

[ChangeLog][QtQuick][HoverHandler] HoverHandler now has a property
called blocking, which is false by default; but if set to true, it
prevents hover events from propagating to items "under" this handler's
parent, and their HoverHandlers.

Task-number: QTBUG-85926
Change-Id: I26f89482e294c7a6b30a55a7e23ac444a0d1ac7f
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
2021-12-09 23:16:36 +01:00
Shawn Rutledge 3e95a57dc1 HoverHandler: allow cursorShape binding before parentItem is set
When a HoverHandler is declared in a Window, the handler's bindings
are evaluated before QQuickItemPrivate::data_append() is called to
add the handler to the window's content item. So we need null pointer
checks again (as we have for a lot of calls to parentItem() already).
And to ensure that the declared cursorShape actually is shown, we need
to check again in componentComplete(). And don't forget to call the
parent class implementation whenever overriding any virtual function.

Fixes: QTBUG-98717
Pick-to: 6.2 5.15
Change-Id: Id0defac7a238df522e8eee69f71e83a3947560af
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-12-03 18:25:59 +01:00
Mitch Curtis e310dadef7 Consolidate test helpers into private libraries
Previously each test would include and build sources from the shared
folder. Now we make those sources a library, build it once, then have
each test link to it instead.

We also take the opportunity to move some helpers that qtquickcontrols2
had added into the quicktestutils library where it makes sense, and
for the helpers that don't make sense to be there, move them into
quickcontrolstestutils.

We add the libraries to src/ so that they are internal modules built as
part of Qt, rather than tests. That way we can use them in a standalone
test outside of qtdeclarative.

Task-number: QTBUG-95621
Pick-to: 6.2
Change-Id: I0a2ab3976fdbff2e4414df7bdc0808f16453b80a
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-09-13 21:17:04 +02:00
Richard Moe Gustavsen bbcc2657fa QQuickHoverHandler: don't use passive grabs
QQuickDeliveryAgent will clear the list of passive grabbers
when we deliver:
1. a QPointerEvent::isEndEvent() from deliverPointerEvent()
2. a QEventPoint::Pressed event from deliverPressOrReleaseEvent()

In other words, QQuickDeliveryAgent will clear the list of grabbers
whenever it receives a mouse press or release. This doesn't work
well with hover handlers, which were using passive grabs to
ensure receiving updates: they also lost their grabs on press and
release.  This has some implications:

1. the list of hover items (QQuickDeliveryAgentPrivate::hoverItems)
    will no longer be in sync with the items we deliver events to.
2. a hover handler stacked underneath another hover handler
    will stop working. The reason is that QQuickDeliveryAgent
    detects that hoverItems is not empty, and as such, assumes
    that all handlers will receive events from their passive grabs.
    (which is no longer the case after the clear)

So letting hover handlers rely on passive grabbing currently fails.
It was also confusing that we delivered some of the hover events
from deliverHoverEvent(), and others from passive grabs in
deliverPointerEvent(). In Qt Quick 3D, when the hover is delivered
because of a passive grab, we need to use sceneTransform; but when
picking is done, the transform was already done at the same time.
But hover events that come from flushFrameSynchronousEvents()
always need to go through picking, and that happens frequently,
so it's more consistent if we just rely on it all the time.

In addition, the previous solution was assuming that only one leaf item
would be under the mouse. This fails when you have siblings that overlap
(and each sibling has HoverHandlers).

While we could try to be more careful about when, and which, grabbers
we clear here and there from QQuickDeliveryAgent, it seems better to
dodge the whole passive grabber logic for hover handlers, and instead
send all hover events directly from deliverHoverEvent(). This because
we anyway need to traverse all the items in the application on each
pointer move to check if new items are being hovered. So we might as
well send out hover events in the same go. That way the logic becomes
a bit easier to follow, and don't need to worry about keeping the
hoveredItems list in sync with passive grabbing.

tst_qquickhoverhandler:
hoverHandlerAndUnderlyingMouseArea:
- HoverHandlers have (conceptually) never stopped hover events
  from propagating to the parent. Still, this test checks that
  a MouseArea underneath a HoverHandler is not hovered. Since
  this now actually works, the test is changed.

mouseAreaAndUnderlyingHoverHandler:
- MouseArea now accepts hover events, which will stop propagation.
  This is done to preserve the same behavior as before. But this
  also means that a MouseArea that has another MouseArea as a direct
  child (which was a special case from before) will no longer get hover
  events after the child has accepted them. For the same reason, an
  item's HoverHandlers will also not get hover events if there is a
  child that is accepting them, as in this test case.

Fixes: QTBUG-34882
Fixes: QTBUG-63670
Pick-to: 6.2
Change-Id: Id38042bcbd1c3ca5403b4b81b875b84196fcfc76
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2021-07-01 20:24:06 +02:00
Shawn Rutledge 9d9ebbff2f Stabilize tst_HoverHandler::movingItemWithHoverHandler()
It tries to move the "paddle" from its old position, out from under
the cursor, and back under the cursor again; but it was moving its
left edge to be under the cursor.  That didn't necessarily work with
arbitrary high-dpi scale factors.

Change-Id: I8d52ed34c5d4dcc6d20c6aefa1c7bce7516138bd
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2021-07-01 20:24:06 +02:00
Richard Moe Gustavsen f2422ca99b Autotests: stabilize hover event delivery
The most likely reason why hover event tests are failing, is
because we get duplicated hover move events on the side from
QQuickDeliveryAgentPrivate::flushFrameSynchronousEvents().

Since such events are delivered at rather random points in
time, they can easily affect the tests. Especially since
QTest::mouseMove() will deliver the move event sync to the
application, followed by a qGuiApp->processEvents(), which
will flush out any other mouse events queued up from QPA.

Fixes: QTBUG-92000
Change-Id: I8fa1ce6771f18664c6cd4d9e3d32218938547ddd
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2021-03-26 19:54:19 +01:00
Shawn Rutledge b1493678fc Change the cursor within HoverHandler.margin
The visual cursor feedback was inconsistent with the hovered property
when a margin is set.

Amends 1c44804600

Pick-to: 5.15
Fixes: QTBUG-85303
Task-number: QTBUG-68073
Change-Id: I25506baecaecbd6450a0e95786f103024b46b1b8
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2020-06-30 09:08:23 +02:00
Shawn Rutledge 1c44804600 Add PointerHandler.cursorShape property
Also, QQuickItemPrivate::setHasCursorInChild() was unable to check
the QQuickItemPrivate::hasCursor variable, because the function
argument hasCursor was shadowing that, even though the comment
"nope! sorry, I have a cursor myself" hints that the intention
was to check that.  So this change exposed a problem there, and
we have to fix that too, in order to keep the tst_qquickwindow::cursor()
test passing.

[ChangeLog][Event Handlers] Pointer Handlers now have a cursorShape
property to set the cursor when the handler is active and the mouse is
hovering, and restore to the previous cursor when the mouse leaves.

Fixes: QTBUG-68073
Change-Id: Ib5c66bd59c4691c4210ee5465e1c95e7bdcf5ae1
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
2020-01-31 11:13:26 +01:00
Friedemann Kleint 5a5441f38e Tests: Fix warnings about ignoring return value of QTest::qWaitForWindowExposed()
Fix warnings like:
../shared/particlestestsshared.h: In function 'QQuickView* createView(const QUrl&, int)':
../shared/particlestestsshared.h:64:33: warning: ignoring return value of 'bool QTest::qWaitForWindowExposed(QWindow*, int)', declared with attribute nodiscard [-Wunused-result]

by checking the return and adding some handling.

Change-Id: I1390f9738430042fcc45e243567a9d5a4f632a6d
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2019-04-08 12:16:23 +00:00
Jan Arve Sæther 1c7213dbc0 Fix a bug where hover events were not sent if the mouse was never moved
This happened if the "real mouse" was never moved, since moving the real
mouse caused it to update the internal
QQuickWindowPrivate::lastMousePosition. If the window never got any
mouse events, it would therefore fail to generate proper hover events.
However, if the window got exposed under a mouse cursor it would generate
a hover enter event. We therefore update lastMousePosition when that
happens also.

Change-Id: I77d9b1bd779a813756c4056b015f2e81664b6d36
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2019-03-04 12:39:53 +00:00
Shawn Rutledge 7c55485b75 Add a HoverHandler autotest
Change-Id: I223bad4f8117af76ad2a5079ecc0b73c2eba94bc
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
2018-08-23 12:24:22 +00:00