macOS: Unregister screen notification handlers on QGuiApplication shutdown
In the case of a plugin, the plugin might be unloaded, and destroy its QGuiApplication. We don't want the screen notification handlers to outlive the application, as that results in crashes. Fixes: QTBUG-91919 Pick-to: 6.2 6.1 5.15 Done-with: Yang Yang Change-Id: I3a4c0fcf97b785357516d1dac34489511400f154 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
This commit is contained in:
parent
d0676874d6
commit
96469ae338
@ -43,6 +43,7 @@
|
|||||||
#include "qcocoacursor.h"
|
#include "qcocoacursor.h"
|
||||||
|
|
||||||
#include <qpa/qplatformintegration.h>
|
#include <qpa/qplatformintegration.h>
|
||||||
|
#include <QtCore/private/qcore_mac_p.h>
|
||||||
|
|
||||||
#include <CoreGraphics/CoreGraphics.h>
|
#include <CoreGraphics/CoreGraphics.h>
|
||||||
#include <CoreVideo/CoreVideo.h>
|
#include <CoreVideo/CoreVideo.h>
|
||||||
@ -102,6 +103,9 @@ private:
|
|||||||
static void updateScreens();
|
static void updateScreens();
|
||||||
static void cleanupScreens();
|
static void cleanupScreens();
|
||||||
|
|
||||||
|
static QMacNotificationObserver s_screenParameterObserver;
|
||||||
|
static CGDisplayReconfigurationCallBack s_displayReconfigurationCallBack;
|
||||||
|
|
||||||
static bool updateScreensIfNeeded();
|
static bool updateScreensIfNeeded();
|
||||||
static NSArray *s_screenConfigurationBeforeUpdate;
|
static NSArray *s_screenConfigurationBeforeUpdate;
|
||||||
|
|
||||||
|
@ -75,12 +75,14 @@ namespace CoreGraphics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NSArray *QCocoaScreen::s_screenConfigurationBeforeUpdate = nil;
|
NSArray *QCocoaScreen::s_screenConfigurationBeforeUpdate = nil;
|
||||||
|
QMacNotificationObserver QCocoaScreen::s_screenParameterObserver;
|
||||||
|
CGDisplayReconfigurationCallBack QCocoaScreen::s_displayReconfigurationCallBack = nullptr;
|
||||||
|
|
||||||
void QCocoaScreen::initializeScreens()
|
void QCocoaScreen::initializeScreens()
|
||||||
{
|
{
|
||||||
updateScreens();
|
updateScreens();
|
||||||
|
|
||||||
CGDisplayRegisterReconfigurationCallback([](CGDirectDisplayID displayId, CGDisplayChangeSummaryFlags flags, void *userInfo) {
|
s_displayReconfigurationCallBack = [](CGDirectDisplayID displayId, CGDisplayChangeSummaryFlags flags, void *userInfo) {
|
||||||
Q_UNUSED(userInfo);
|
Q_UNUSED(userInfo);
|
||||||
|
|
||||||
// Displays are reconfigured in batches, and we want to update our screens
|
// Displays are reconfigured in batches, and we want to update our screens
|
||||||
@ -131,9 +133,10 @@ void QCocoaScreen::initializeScreens()
|
|||||||
updateScreensIfNeeded();
|
updateScreensIfNeeded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, nullptr);
|
};
|
||||||
|
CGDisplayRegisterReconfigurationCallback(s_displayReconfigurationCallBack, nullptr);
|
||||||
|
|
||||||
static QMacNotificationObserver screenParameterObserver(NSApplication.sharedApplication,
|
s_screenParameterObserver = QMacNotificationObserver(NSApplication.sharedApplication,
|
||||||
NSApplicationDidChangeScreenParametersNotification, [&]() {
|
NSApplicationDidChangeScreenParametersNotification, [&]() {
|
||||||
qCDebug(lcQpaScreen) << "Received screen parameter change notification";
|
qCDebug(lcQpaScreen) << "Received screen parameter change notification";
|
||||||
updateScreensIfNeeded(); // As a last resort we update screens here
|
updateScreensIfNeeded(); // As a last resort we update screens here
|
||||||
@ -241,6 +244,12 @@ void QCocoaScreen::cleanupScreens()
|
|||||||
// Remove screens in reverse order to avoid crash in case of multiple screens
|
// Remove screens in reverse order to avoid crash in case of multiple screens
|
||||||
for (QScreen *screen : backwards(QGuiApplication::screens()))
|
for (QScreen *screen : backwards(QGuiApplication::screens()))
|
||||||
static_cast<QCocoaScreen*>(screen->handle())->remove();
|
static_cast<QCocoaScreen*>(screen->handle())->remove();
|
||||||
|
|
||||||
|
Q_ASSERT(s_displayReconfigurationCallBack);
|
||||||
|
CGDisplayRemoveReconfigurationCallback(s_displayReconfigurationCallBack, nullptr);
|
||||||
|
s_displayReconfigurationCallBack = nullptr;
|
||||||
|
|
||||||
|
s_screenParameterObserver.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QCocoaScreen::remove()
|
void QCocoaScreen::remove()
|
||||||
|
Loading…
Reference in New Issue
Block a user