From 3d39a39ad579d032d1b3b00fa982867c3a90d222 Mon Sep 17 00:00:00 2001 From: Alexey Edelev Date: Tue, 4 May 2021 17:42:30 +0200 Subject: Map window coordinates to the same coordinate system as the QPointerEvent point If the window has parent windows its geometry should be mapped to the global coordinates before check if it contains the point coordinates. Fixes: QTBUG-91716 Change-Id: I300547361dbe895b67caeee0d47f416426444552 Reviewed-by: Shawn Rutledge Reviewed-by: Qt CI Bot (cherry picked from commit c740a9d30571079fa22fd26cb8e72df6ca28c7b2) Reviewed-by: Qt Cherry-pick Bot --- src/quick/handlers/qquickpointerhandler.cpp | 5 +- .../qquicktaphandler/data/simpleTapHandler.qml | 39 +++++++++++++++ .../qquicktaphandler/tst_qquicktaphandler.cpp | 55 ++++++++++++++++++++-- 3 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp index 254f91cfe1..9eab3c86f8 100644 --- a/src/quick/handlers/qquickpointerhandler.cpp +++ b/src/quick/handlers/qquickpointerhandler.cpp @@ -517,8 +517,11 @@ bool QQuickPointerHandler::parentContains(const QPointF &scenePosition) const { if (QQuickItem *par = parentItem()) { if (par->window()) { + QRect windowGeometry = par->window()->geometry(); + if (!par->window()->isTopLevel()) + windowGeometry = QRect(QWindowPrivate::get(par->window())->globalPosition(), par->window()->size()); QPoint screenPosition = par->window()->mapToGlobal(scenePosition.toPoint()); - if (!par->window()->geometry().contains(screenPosition)) + if (!windowGeometry.contains(screenPosition)) return false; } QPointF p = par->mapFromScene(scenePosition); diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml new file mode 100644 index 0000000000..1c18133f92 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/simpleTapHandler.qml @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 + +Item { + id: root + width: 100 + height: 100 + property int tapCount: 0 + TapHandler { + onTapped: { ++root.tapCount } + } +} diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp index 7e7441685f..5fb905cbab 100644 --- a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp @@ -71,15 +71,25 @@ private slots: void componentUserBehavioralOverride(); void rightLongPressIgnoreWheel(); void negativeZStackingOrder(); + void nonTopLevelParentWindow(); private: - void createView(QScopedPointer &window, const char *fileName); + void createView(QScopedPointer &window, const char *fileName, + QWindow *parent = nullptr); QPointingDevice *touchDevice = QTest::createTouchDevice(); + void mouseEvent(QEvent::Type type, Qt::MouseButton button, const QPoint &point, + QWindow *targetWindow, QWindow *mapToWindow); }; -void tst_TapHandler::createView(QScopedPointer &window, const char *fileName) +void tst_TapHandler::createView(QScopedPointer &window, const char *fileName, + QWindow *parent) { - window.reset(new QQuickView); + window.reset(new QQuickView(parent)); + if (parent) { + parent->show(); + QVERIFY(QTest::qWaitForWindowActive(parent)); + } + window->setSource(testFileUrl(fileName)); QTRY_COMPARE(window->status(), QQuickView::Ready); QQuickViewTestUtil::centerOnScreen(window.data()); @@ -90,6 +100,20 @@ void tst_TapHandler::createView(QScopedPointer &window, const char * QVERIFY(window->rootObject() != nullptr); } +void tst_TapHandler::mouseEvent(QEvent::Type type, Qt::MouseButton button, const QPoint &point, + QWindow *targetWindow, QWindow *mapToWindow) +{ + QVERIFY(targetWindow); + QVERIFY(mapToWindow); + auto buttons = button; + if (type == QEvent::MouseButtonRelease) { + buttons = Qt::NoButton; + } + QMouseEvent me(type, point, mapToWindow->mapToGlobal(point), button, buttons, + Qt::KeyboardModifiers(), QPointingDevice::primaryPointingDevice()); + QVERIFY(qApp->notify(targetWindow, &me)); +} + void tst_TapHandler::initTestCase() { // This test assumes that we don't get synthesized mouse events from QGuiApplication @@ -777,6 +801,31 @@ void tst_TapHandler::negativeZStackingOrder() // QTBUG-83114 QVERIFY(order.at(1) == "childTapHandler"); } +void tst_TapHandler::nonTopLevelParentWindow() // QTBUG-91716 +{ + QScopedPointer parentWindowPtr(new QQuickWindow); + auto parentWindow = parentWindowPtr.get(); + parentWindow->setGeometry(400, 400, 250, 250); + + QScopedPointer windowPtr; + createView(windowPtr, "simpleTapHandler.qml", parentWindow); + auto window = windowPtr.get(); + window->setGeometry(10, 10, 100, 100); + + QQuickItem *root = window->rootObject(); + + auto p1 = QPoint(20, 20); + mouseEvent(QEvent::MouseButtonPress, Qt::LeftButton, p1, window, parentWindow); + mouseEvent(QEvent::MouseButtonRelease, Qt::LeftButton, p1, window, parentWindow); + + QCOMPARE(root->property("tapCount").toInt(), 1); + + QTest::touchEvent(window, touchDevice).press(0, p1, parentWindow).commit(); + QTest::touchEvent(window, touchDevice).release(0, p1, parentWindow).commit(); + + QCOMPARE(root->property("tapCount").toInt(), 2); +} + QTEST_MAIN(tst_TapHandler) #include "tst_qquicktaphandler.moc" -- cgit v1.2.3