diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index a2fbbc3f200..765b7e6619f 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -247,6 +247,8 @@ public: // for QNSView int m_registerTouchCount = 0; bool m_resizableTransientParent = false; + QMacKeyValueObserver m_safeAreaInsetsObserver; + void updateSafeAreaMarginsIfNeeded(); QMargins m_lastReportedSafeAreaMargins; static const int NoAlertRequest; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 8904570e558..8bcc200b57c 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -132,6 +132,15 @@ void QCocoaWindow::initialize() setMask(QHighDpi::toNativeLocalRegion(window()->mask(), window())); + m_safeAreaInsetsObserver = QMacKeyValueObserver( + m_view, @"safeAreaInsets", [this] { + // Defer to next runloop pass, so that any changes to the + // margins during resizing have settled down. + QMetaObject::invokeMethod(this, [this]{ + updateSafeAreaMarginsIfNeeded(); + }, Qt::QueuedConnection); + }, NSKeyValueObservingOptionNew); + } else { // Pick up essential foreign window state QPlatformWindow::setGeometry(QRectF::fromCGRect(m_view.frame).toRect()); @@ -152,6 +161,8 @@ QCocoaWindow::~QCocoaWindow() [m_nsWindow makeFirstResponder:nil]; [m_nsWindow setContentView:nil]; + m_safeAreaInsetsObserver = {}; + // Remove from superview only if we have a Qt window parent, // as we don't want to affect window container foreign windows. if (QPlatformWindow::parent()) @@ -346,6 +357,14 @@ QMargins QCocoaWindow::safeAreaMargins() const return (screenSafeAreaMargins | viewSafeAreaMargins).toMargins(); } +void QCocoaWindow::updateSafeAreaMarginsIfNeeded() +{ + if (safeAreaMargins() != m_lastReportedSafeAreaMargins) { + m_lastReportedSafeAreaMargins = safeAreaMargins(); + QWindowSystemInterface::handleSafeAreaMarginsChanged(window()); + } +} + bool QCocoaWindow::startSystemMove() { switch (NSApp.currentEvent.type) { @@ -1521,10 +1540,7 @@ void QCocoaWindow::handleGeometryChange() QWindowSystemInterface::handleGeometryChange(window(), newGeometry); // Changing the window geometry may affect the safe area margins - if (safeAreaMargins() != m_lastReportedSafeAreaMargins) { - m_lastReportedSafeAreaMargins = safeAreaMargins(); - QWindowSystemInterface::handleSafeAreaMarginsChanged(window()); - } + updateSafeAreaMarginsIfNeeded(); // Guard against processing window system events during QWindow::setGeometry // calls, which Qt and Qt applications do not expect.