macOS: Take window mask into account when computing QCocoaScreen::topLevelAt
Although not explicitly documented, this is the behavior in practice on XCB and Windows, and we rely on this behavior in our implementation of QApplication::widgetAt(), where we punch a temporary hole in the widget using a mask if it has Qt::WA_TransparentForMouseEvents set. Pick-to: 6.5 6.6 Fixes: QTBUG-41696 Task-number: QTBUG-119092 Change-Id: Ie7abc31b6930ee6b56fcdf391befc625c1ddf502 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
parent
6658ccf5a1
commit
189f9873ae
@ -542,7 +542,12 @@ QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const
|
|||||||
if (!w->isVisible())
|
if (!w->isVisible())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!QHighDpi::toNativePixels(w->geometry(), w).contains(point))
|
auto nativeGeometry = QHighDpi::toNativePixels(w->geometry(), w);
|
||||||
|
if (!nativeGeometry.contains(point))
|
||||||
|
return;
|
||||||
|
|
||||||
|
QRegion mask = QHighDpi::toNativeLocalPosition(w->mask(), w);
|
||||||
|
if (!mask.isEmpty() && !mask.contains(point - nativeGeometry.topLeft()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
window = w;
|
window = w;
|
||||||
|
@ -61,6 +61,8 @@ private slots:
|
|||||||
|
|
||||||
void staticFunctions();
|
void staticFunctions();
|
||||||
|
|
||||||
|
void topLevelAt();
|
||||||
|
|
||||||
void settableStyleHints_data();
|
void settableStyleHints_data();
|
||||||
void settableStyleHints(); // Needs to run last as it changes style hints.
|
void settableStyleHints(); // Needs to run last as it changes style hints.
|
||||||
};
|
};
|
||||||
@ -1325,6 +1327,37 @@ void tst_QGuiApplication::staticFunctions()
|
|||||||
QPixmap::defaultDepth();
|
QPixmap::defaultDepth();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QGuiApplication::topLevelAt()
|
||||||
|
{
|
||||||
|
int argc = 1;
|
||||||
|
char *argv[] = { const_cast<char*>("tst_qguiapplication") };
|
||||||
|
QGuiApplication app(argc, argv);
|
||||||
|
|
||||||
|
QWindow bottom;
|
||||||
|
bottom.setObjectName("Bottom");
|
||||||
|
bottom.setFlag(Qt::FramelessWindowHint);
|
||||||
|
bottom.setGeometry(200, 200, 200, 200);
|
||||||
|
bottom.showNormal();
|
||||||
|
QVERIFY(QTest::qWaitForWindowExposed(&bottom));
|
||||||
|
QTRY_COMPARE(app.topLevelAt(QPoint(300, 300)), &bottom);
|
||||||
|
|
||||||
|
QWindow top;
|
||||||
|
top.setObjectName("Top");
|
||||||
|
top.setFlag(Qt::FramelessWindowHint);
|
||||||
|
top.setGeometry(200, 200, 200, 200);
|
||||||
|
top.showNormal();
|
||||||
|
QVERIFY(QTest::qWaitForWindowExposed(&top));
|
||||||
|
top.raise();
|
||||||
|
QTRY_COMPARE(app.topLevelAt(QPoint(300, 300)), &top);
|
||||||
|
|
||||||
|
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowMasks))
|
||||||
|
QSKIP("QWindow::setMask() is not supported.");
|
||||||
|
|
||||||
|
top.setMask(QRect(0, 0, 50, 50));
|
||||||
|
QTRY_COMPARE(app.topLevelAt(QPoint(300, 300)), &bottom);
|
||||||
|
QTRY_COMPARE(app.topLevelAt(QPoint(225, 225)), &top);
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QGuiApplication::settableStyleHints_data()
|
void tst_QGuiApplication::settableStyleHints_data()
|
||||||
{
|
{
|
||||||
QTest::addColumn<bool>("appInstance");
|
QTest::addColumn<bool>("appInstance");
|
||||||
|
Loading…
Reference in New Issue
Block a user