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())
|
||||
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;
|
||||
|
||||
window = w;
|
||||
|
@ -61,6 +61,8 @@ private slots:
|
||||
|
||||
void staticFunctions();
|
||||
|
||||
void topLevelAt();
|
||||
|
||||
void settableStyleHints_data();
|
||||
void settableStyleHints(); // Needs to run last as it changes style hints.
|
||||
};
|
||||
@ -1325,6 +1327,37 @@ void tst_QGuiApplication::staticFunctions()
|
||||
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()
|
||||
{
|
||||
QTest::addColumn<bool>("appInstance");
|
||||
|
Loading…
Reference in New Issue
Block a user