macOS: Tie QCocoaWindowManager lifetime to QCocoaIntegration

To avoid any static initialization fiasco when Qt is being used
in a plugin.

Fixes: QTBUG-101150
Pick-to: 6.2 6.3
Change-Id: I68fa03f982d0c07e4b725ed5f4a1f738e0220438
Reviewed-by: <stefan.wastl@native-instruments.de>
Reviewed-by: Doris Verria <doris.verria@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
bb10
Tor Arne Vestbø 2022-04-25 14:44:19 +02:00
parent c48795c515
commit b41b1a3f6f
4 changed files with 12 additions and 17 deletions

View File

@ -51,6 +51,7 @@
#if QT_CONFIG(vulkan)
#include "qcocoavulkaninstance.h"
#endif
#include "qcocoawindowmanager.h"
#include <QtCore/QScopedPointer>
#include <qpa/qplatformintegration.h>
@ -155,6 +156,8 @@ private:
mutable QCocoaVulkanInstance *mCocoaVulkanInstance = nullptr;
#endif
QHash<QWindow *, NSToolbar *> mToolbars;
QCocoaWindowManager m_windowManager;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QCocoaIntegration::Options)

View File

@ -82,11 +82,6 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpa, "qt.qpa", QtWarningMsg);
// Lives here so that the linker is forced to include the QCocoaWindowManager
// object file also in static builds.
static void initializeWindowManager() { Q_UNUSED(QCocoaWindowManager::instance()); }
Q_CONSTRUCTOR_FUNCTION(initializeWindowManager)
static void logVersionInformation()
{
if (!lcQpa().isInfoEnabled())

View File

@ -41,18 +41,21 @@
#define QCOCOAWINDOWMANAGER_H
#include <QtCore/qglobal.h>
#include <QtCore/private/qcore_mac_p.h>
QT_BEGIN_NAMESPACE
class QCocoaWindowManager
{
public:
static QCocoaWindowManager *instance();
QCocoaWindowManager();
private:
QCocoaWindowManager();
QMacNotificationObserver m_applicationDidFinishLaunchingObserver;
void initialize();
QMacKeyValueObserver m_modalSessionObserver;
void modalSessionChanged();
};

View File

@ -49,19 +49,13 @@
QT_BEGIN_NAMESPACE
QCocoaWindowManager *QCocoaWindowManager::instance()
{
static auto *instance = new QCocoaWindowManager;
return instance;
}
QCocoaWindowManager::QCocoaWindowManager()
{
if (NSApp) {
initialize();
} else {
static auto applicationDidFinishLaunching(QMacNotificationObserver(nil,
NSApplicationDidFinishLaunchingNotification, [this] { initialize(); }));
m_applicationDidFinishLaunchingObserver = QMacNotificationObserver(nil,
NSApplicationDidFinishLaunchingNotification, [this] { initialize(); });
}
}
@ -74,9 +68,9 @@ void QCocoaWindowManager::initialize()
// event dispatcher sessions allows us to track session started by native
// APIs as well. We need to check the initial state as well, in case there
// is already a modal session running.
static auto modalSessionObserver(QMacKeyValueObserver(
m_modalSessionObserver = QMacKeyValueObserver(
NSApp, @"modalWindow", [this] { modalSessionChanged(); },
NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew));
NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew);
}
void QCocoaWindowManager::modalSessionChanged()