Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qcocoawindowmanager.mm
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <AppKit/AppKit.h>
5
7#include "qcocoawindow.h"
8
9#include <QtCore/private/qcore_mac_p.h>
10
11#include <QtGui/qguiapplication.h>
12#include <QtGui/qwindow.h>
13
15
17{
18 if (NSApp) {
19 initialize();
20 } else {
21 m_applicationDidFinishLaunchingObserver = QMacNotificationObserver(nil,
22 NSApplicationDidFinishLaunchingNotification, [this] { initialize(); });
23 }
24}
25
26void QCocoaWindowManager::initialize()
27{
28 Q_ASSERT(NSApp);
29
30 // Whenever the modalWindow property of NSApplication changes we have a new
31 // modal session running. Observing the app modal window instead of our own
32 // event dispatcher sessions allows us to track session started by native
33 // APIs as well. We need to check the initial state as well, in case there
34 // is already a modal session running.
35 m_modalSessionObserver = QMacKeyValueObserver(
36 NSApp, @"modalWindow", [this] { modalSessionChanged(); },
37 NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew);
38}
39
40void QCocoaWindowManager::modalSessionChanged()
41{
42 // Make sure that no window is overlapping the modal window. This can
43 // happen for e.g. splash screens, which have the NSPopUpMenuWindowLevel.
44 for (auto *window : QGuiApplication::topLevelWindows()) {
45 auto *platformWindow = static_cast<QCocoaWindow*>(window->handle());
46 if (!platformWindow)
47 continue;
48
49 auto naturalWindowLevel = platformWindow->windowLevel(window->flags());
50 if (naturalWindowLevel > NSModalPanelWindowLevel) {
51 NSWindow *nativeWindow = platformWindow->nativeWindow();
52 if (NSApp.modalWindow) {
53 // Lower window to that of the modal windows, but no less
54 nativeWindow.level = NSModalPanelWindowLevel;
56 [nativeWindow orderBack:nil];
57 } else {
58 // Restore window's natural window level, whatever that was
59 nativeWindow.level = naturalWindowLevel;
60 }
61 }
62 }
63
64 // Our worksWhenModal implementation is declarative and will normally be picked
65 // up by AppKit when needed, but to make sure AppKit also reflects the state
66 // in the window tag, so that the window can be ordered front by clicking it,
67 // we need to explicitly call setWorksWhenModal.
68 for (id window in NSApp.windows) {
69 if ([window isKindOfClass:[QNSPanel class]]) {
70 auto *panel = static_cast<QNSPanel *>(window);
71 // Call setter to tell AppKit that our state has changed
72 [panel setWorksWhenModal:panel.worksWhenModal];
73 }
74 }
75}
76
78
NSInteger windowLevel(Qt::WindowFlags flags)
\macro qGuiApp
Combined button and popup list for selecting options.
GLuint in
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QWindowsDirect2DWindow * nativeWindow(QWindow *window)
QWidget * panel
Definition settings.cpp:7
edit isVisible()
aWidget window() -> setWindowTitle("New Window Title")
[2]