--- a/qtbase-everywhere-src/src/plugins/platforms/cocoa/qcocoascreen.h 2021-03-03 12:16:02.000000000 +0800 +++ b/qtbase-everywhere-src/src/plugins/platforms/cocoa/qcocoascreen.h 2021-03-18 09:40:37.000000000 +0800 @@ -44,6 +44,7 @@ #include "qcocoacursor.h" +#include #include QT_BEGIN_NAMESPACE @@ -98,6 +99,8 @@ static bool updateScreensIfNeeded(); static NSArray *s_screenConfigurationBeforeUpdate; + static QMacNotificationObserver s_screenParameterObserver; + static CGDisplayReconfigurationCallBack s_displayReconfigurationCallBack; static void add(CGDirectDisplayID displayId); QCocoaScreen(CGDirectDisplayID displayId); --- a/qtbase-everywhere-src/src/plugins/platforms/cocoa/qcocoascreen.mm 2021-03-03 12:16:02.000000000 +0800 +++ b/qtbase-everywhere-src/src/plugins/platforms/cocoa/qcocoascreen.mm 2021-03-18 09:49:55.000000000 +0800 @@ -73,12 +73,14 @@ } NSArray *QCocoaScreen::s_screenConfigurationBeforeUpdate = nil; +QMacNotificationObserver QCocoaScreen::s_screenParameterObserver; +CGDisplayReconfigurationCallBack QCocoaScreen::s_displayReconfigurationCallBack = nullptr; void QCocoaScreen::initializeScreens() { updateScreens(); - CGDisplayRegisterReconfigurationCallback([](CGDirectDisplayID displayId, CGDisplayChangeSummaryFlags flags, void *userInfo) { + s_displayReconfigurationCallBack = [](CGDirectDisplayID displayId, CGDisplayChangeSummaryFlags flags, void *userInfo) { Q_UNUSED(userInfo); // Displays are reconfigured in batches, and we want to update our screens @@ -129,9 +131,11 @@ updateScreensIfNeeded(); } } - }, nullptr); + }; - static QMacNotificationObserver screenParameterObserver(NSApplication.sharedApplication, + CGDisplayRegisterReconfigurationCallback(s_displayReconfigurationCallBack, nullptr); + + s_screenParameterObserver = QMacNotificationObserver(NSApplication.sharedApplication, NSApplicationDidChangeScreenParametersNotification, [&]() { qCDebug(lcQpaScreen) << "Received screen parameter change notification"; updateScreensIfNeeded(); // As a last resort we update screens here @@ -239,6 +243,13 @@ // Remove screens in reverse order to avoid crash in case of multiple screens for (QScreen *screen : backwards(QGuiApplication::screens())) static_cast(screen->handle())->remove(); + + // Remove the notification handlers when qApp is released + if (s_displayReconfigurationCallBack) { + CGDisplayRemoveReconfigurationCallback(s_displayReconfigurationCallBack, nullptr); + s_displayReconfigurationCallBack = nullptr; + } + s_screenParameterObserver.remove(); } void QCocoaScreen::remove()