summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r--src/plugins/platforms/cocoa/.prev_CMakeLists.txt24
-rw-r--r--src/plugins/platforms/cocoa/CMakeLists.txt24
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro2
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.h11
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm30
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm83
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm23
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm18
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm39
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindowmanager.h63
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindowmanager.mm108
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac.mm8
13 files changed, 339 insertions, 96 deletions
diff --git a/src/plugins/platforms/cocoa/.prev_CMakeLists.txt b/src/plugins/platforms/cocoa/.prev_CMakeLists.txt
index a8ee50e715..b8ab5af395 100644
--- a/src/plugins/platforms/cocoa/.prev_CMakeLists.txt
+++ b/src/plugins/platforms/cocoa/.prev_CMakeLists.txt
@@ -37,6 +37,7 @@ add_qt_plugin(qcocoa
qcocoasystemtrayicon.h qcocoasystemtrayicon.mm
qcocoatheme.h qcocoatheme.mm
qcocoawindow.h qcocoawindow.mm
+ qcocoawindowmanager.h qcocoawindowmanager.mm
qiosurfacegraphicsbuffer.h qiosurfacegraphicsbuffer.mm
qmacclipboard.h qmacclipboard.mm
qmultitouch_mac.mm qmultitouch_mac_p.h
@@ -71,14 +72,21 @@ add_qt_plugin(qcocoa
)
# Resources:
-add_qt_resource(qcocoa "qcocoaresources" PREFIX "/qt-project.org/mac/cursors" FILES
- images/sizeallcursor.png
- images/spincursor.png
- images/waitcursor.png)
+set(qcocoaresources_resource_files
+ "images/sizeallcursor.png"
+ "images/spincursor.png"
+ "images/waitcursor.png"
+)
+
+add_qt_resource(qcocoa "qcocoaresources"
+ PREFIX
+ "/qt-project.org/mac/cursors"
+ FILES
+ ${qcocoaresources_resource_files}
+)
#### Keys ignored in scope 1:.:.:cocoa.pro:<TRUE>:
-# CONFIG = "no_app_extension_api_only"
# OTHER_FILES = "cocoa.json"
# PLUGIN_CLASS_NAME = "QCocoaIntegrationPlugin"
# PLUGIN_TYPE = "platforms"
@@ -118,17 +126,17 @@ extend_target(qcocoa CONDITION TARGET Qt::Widgets
#### Keys ignored in scope 5:.:.:cocoa.pro:TARGET Qt::Widgets:
# QT_FOR_CONFIG = "widgets"
-extend_target(qcocoa CONDITION (TARGET Qt::Widgets) AND (QT_FEATURE_colordialog)
+extend_target(qcocoa CONDITION QT_FEATURE_colordialog AND TARGET Qt::Widgets
SOURCES
qcocoacolordialoghelper.h qcocoacolordialoghelper.mm
)
-extend_target(qcocoa CONDITION (TARGET Qt::Widgets) AND (QT_FEATURE_filedialog)
+extend_target(qcocoa CONDITION QT_FEATURE_filedialog AND TARGET Qt::Widgets
SOURCES
qcocoafiledialoghelper.h qcocoafiledialoghelper.mm
)
-extend_target(qcocoa CONDITION (TARGET Qt::Widgets) AND (QT_FEATURE_fontdialog)
+extend_target(qcocoa CONDITION QT_FEATURE_fontdialog AND TARGET Qt::Widgets
SOURCES
qcocoafontdialoghelper.h qcocoafontdialoghelper.mm
)
diff --git a/src/plugins/platforms/cocoa/CMakeLists.txt b/src/plugins/platforms/cocoa/CMakeLists.txt
index 9b546990ba..6bf0976224 100644
--- a/src/plugins/platforms/cocoa/CMakeLists.txt
+++ b/src/plugins/platforms/cocoa/CMakeLists.txt
@@ -41,6 +41,7 @@ add_qt_plugin(qcocoa
qcocoasystemtrayicon.h qcocoasystemtrayicon.mm
qcocoatheme.h qcocoatheme.mm
qcocoawindow.h qcocoawindow.mm
+ qcocoawindowmanager.h qcocoawindowmanager.mm
qiosurfacegraphicsbuffer.h qiosurfacegraphicsbuffer.mm
qmacclipboard.h qmacclipboard.mm
qmultitouch_mac.mm qmultitouch_mac_p.h
@@ -75,14 +76,21 @@ add_qt_plugin(qcocoa
)
# Resources:
-add_qt_resource(qcocoa "qcocoaresources" PREFIX "/qt-project.org/mac/cursors" FILES
- images/sizeallcursor.png
- images/spincursor.png
- images/waitcursor.png)
+set(qcocoaresources_resource_files
+ "images/sizeallcursor.png"
+ "images/spincursor.png"
+ "images/waitcursor.png"
+)
+
+add_qt_resource(qcocoa "qcocoaresources"
+ PREFIX
+ "/qt-project.org/mac/cursors"
+ FILES
+ ${qcocoaresources_resource_files}
+)
#### Keys ignored in scope 1:.:.:cocoa.pro:<TRUE>:
-# CONFIG = "no_app_extension_api_only"
# OTHER_FILES = "cocoa.json"
# PLUGIN_CLASS_NAME = "QCocoaIntegrationPlugin"
# PLUGIN_TYPE = "platforms"
@@ -122,17 +130,17 @@ extend_target(qcocoa CONDITION TARGET Qt::Widgets
#### Keys ignored in scope 5:.:.:cocoa.pro:TARGET Qt::Widgets:
# QT_FOR_CONFIG = "widgets"
-extend_target(qcocoa CONDITION (TARGET Qt::Widgets) AND (QT_FEATURE_colordialog)
+extend_target(qcocoa CONDITION QT_FEATURE_colordialog AND TARGET Qt::Widgets
SOURCES
qcocoacolordialoghelper.h qcocoacolordialoghelper.mm
)
-extend_target(qcocoa CONDITION (TARGET Qt::Widgets) AND (QT_FEATURE_filedialog)
+extend_target(qcocoa CONDITION QT_FEATURE_filedialog AND TARGET Qt::Widgets
SOURCES
qcocoafiledialoghelper.h qcocoafiledialoghelper.mm
)
-extend_target(qcocoa CONDITION (TARGET Qt::Widgets) AND (QT_FEATURE_fontdialog)
+extend_target(qcocoa CONDITION QT_FEATURE_fontdialog AND TARGET Qt::Widgets
SOURCES
qcocoafontdialoghelper.h qcocoafontdialoghelper.mm
)
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index 083b7c1655..02e00039ae 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -6,6 +6,7 @@ SOURCES += main.mm \
qcocoatheme.mm \
qcocoabackingstore.mm \
qcocoawindow.mm \
+ qcocoawindowmanager.mm \
qnsview.mm \
qnswindow.mm \
qnswindowdelegate.mm \
@@ -41,6 +42,7 @@ HEADERS += qcocoaintegration.h \
qcocoatheme.h \
qcocoabackingstore.h \
qcocoawindow.h \
+ qcocoawindowmanager.h \
qnsview.h \
qnswindow.h \
qnswindowdelegate.h \
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
index 2398e6351e..9be6814ae7 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.h
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h
@@ -49,7 +49,14 @@
QT_BEGIN_NAMESPACE
-class QNSWindowBackingStore : public QRasterBackingStore
+class QCocoaBackingStore : public QRasterBackingStore
+{
+protected:
+ QCocoaBackingStore(QWindow *window);
+ QCFType<CGColorSpaceRef> colorSpace() const;
+};
+
+class QNSWindowBackingStore : public QCocoaBackingStore
{
public:
QNSWindowBackingStore(QWindow *window);
@@ -64,7 +71,7 @@ private:
void redrawRoundedBottomCorners(CGRect) const;
};
-class QCALayerBackingStore : public QPlatformBackingStore
+class QCALayerBackingStore : public QCocoaBackingStore
{
public:
QCALayerBackingStore(QWindow *window);
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index 01b4894324..6015257f4e 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -48,11 +48,24 @@
QT_BEGIN_NAMESPACE
-QNSWindowBackingStore::QNSWindowBackingStore(QWindow *window)
+QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
: QRasterBackingStore(window)
{
}
+QCFType<CGColorSpaceRef> QCocoaBackingStore::colorSpace() const
+{
+ NSView *view = static_cast<QCocoaWindow *>(window()->handle())->view();
+ return QCFType<CGColorSpaceRef>::constructFromGet(view.window.colorSpace.CGColorSpace);
+}
+
+// ----------------------------------------------------------------------------
+
+QNSWindowBackingStore::QNSWindowBackingStore(QWindow *window)
+ : QCocoaBackingStore(window)
+{
+}
+
QNSWindowBackingStore::~QNSWindowBackingStore()
{
}
@@ -175,11 +188,10 @@ void QNSWindowBackingStore::flush(QWindow *window, const QRegion &region, const
Q_ASSERT_X(graphicsContext, "QCocoaBackingStore",
"Focusing the view should give us a current graphics context");
- // Prevent potentially costly color conversion by assigning the display color space
- // to the backingstore image. This does not copy the underlying image data.
- CGColorSpaceRef displayColorSpace = view.window.screen.colorSpace.CGColorSpace;
+ // Tag backingstore image with color space based on the window.
+ // Note: This does not copy the underlying image data.
QCFType<CGImageRef> cgImage = CGImageCreateCopyWithColorSpace(
- QCFType<CGImageRef>(m_image.toCGImage()), displayColorSpace);
+ QCFType<CGImageRef>(m_image.toCGImage()), colorSpace());
// Create temporary image to use for blitting, without copying image data
NSImage *backingStoreImage = [[[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize] autorelease];
@@ -293,7 +305,7 @@ void QNSWindowBackingStore::redrawRoundedBottomCorners(CGRect windowRect) const
// ----------------------------------------------------------------------------
QCALayerBackingStore::QCALayerBackingStore(QWindow *window)
- : QPlatformBackingStore(window)
+ : QCocoaBackingStore(window)
{
qCDebug(lcQpaBackingStore) << "Creating QCALayerBackingStore for" << window;
m_buffers.resize(1);
@@ -432,11 +444,7 @@ bool QCALayerBackingStore::recreateBackBufferIfNeeded()
<< "based on requested" << m_requestedSize << "and dpr =" << devicePixelRatio;
static auto pixelFormat = QImage::toPixelFormat(QImage::Format_ARGB32_Premultiplied);
-
- NSView *view = static_cast<QCocoaWindow *>(window()->handle())->view();
- auto colorSpace = QCFType<CGColorSpaceRef>::constructFromGet(view.window.screen.colorSpace.CGColorSpace);
-
- m_buffers.back().reset(new GraphicsBuffer(requestedBufferSize, devicePixelRatio, pixelFormat, colorSpace));
+ m_buffers.back().reset(new GraphicsBuffer(requestedBufferSize, devicePixelRatio, pixelFormat, colorSpace()));
return true;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h
index c1041ac2da..bb309c0713 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.h
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h
@@ -56,6 +56,8 @@ public:
QCocoaGLContext(QOpenGLContext *context);
~QCocoaGLContext();
+ void initialize() override;
+
bool makeCurrent(QPlatformSurface *surface) override;
void swapBuffers(QPlatformSurface *surface) override;
void doneCurrent() override;
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index 0f8fec0548..7b124ea517 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -40,6 +40,8 @@
#include "qcocoaglcontext.h"
#include "qcocoawindow.h"
#include "qcocoahelpers.h"
+#include "qcocoascreen.h"
+
#include <qdebug.h>
#include <QtPlatformHeaders/qcocoanativecontext.h>
#include <dlfcn.h>
@@ -53,32 +55,19 @@ static inline QByteArray getGlString(GLenum param)
return QByteArray();
}
-@implementation NSOpenGLPixelFormat (QtHelpers)
-- (GLint)qt_getAttribute:(NSOpenGLPixelFormatAttribute)attribute
-{
- int value = 0;
- [self getValues:&value forAttribute:attribute forVirtualScreen:0];
- return value;
-}
-@end
-
-@implementation NSOpenGLContext (QtHelpers)
-- (GLint)qt_getParameter:(NSOpenGLContextParameter)parameter
-{
- int value = 0;
- [self getValues:&value forParameter:parameter];
- return value;
-}
-@end
-
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaOpenGLContext, "qt.qpa.openglcontext", QtWarningMsg);
QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context)
- : QPlatformOpenGLContext(), m_format(context->format())
+ : QPlatformOpenGLContext()
+ , m_format(context->format())
+{
+}
+
+void QCocoaGLContext::initialize()
{
- QVariant nativeHandle = context->nativeHandle();
+ QVariant nativeHandle = context()->nativeHandle();
if (!nativeHandle.isNull()) {
if (!nativeHandle.canConvert<QCocoaNativeContext>()) {
qCWarning(lcQpaOpenGLContext, "QOpenGLContext native handle must be a QCocoaNativeContext");
@@ -95,7 +84,7 @@ QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context)
// Note: We have no way of knowing whether the NSOpenGLContext was created with the
// share context as reported by the QOpenGLContext, but we just have to trust that
// it was. It's okey, as the only thing we're using it for is to report isShared().
- if (QPlatformOpenGLContext *shareContext = context->shareHandle())
+ if (QPlatformOpenGLContext *shareContext = context()->shareHandle())
m_shareContext = static_cast<QCocoaGLContext *>(shareContext)->nativeContext();
updateSurfaceFormat();
@@ -110,7 +99,7 @@ QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context)
if (m_format.renderableType() != QSurfaceFormat::OpenGL)
return;
- if (QPlatformOpenGLContext *shareContext = context->shareHandle()) {
+ if (QPlatformOpenGLContext *shareContext = context()->shareHandle()) {
m_shareContext = static_cast<QCocoaGLContext *>(shareContext)->nativeContext();
// Allow sharing between 3.2 Core and 4.1 Core profile versions in
@@ -150,6 +139,9 @@ QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context)
return;
}
+ // The native handle should reflect the underlying context, even if we created it
+ context()->setNativeHandle(QVariant::fromValue<QCocoaNativeContext>(m_context));
+
// --------------------- Set NSOpenGLContext properties ---------------------
const GLint interval = m_format.swapInterval() >= 0 ? m_format.swapInterval() : 1;
@@ -285,7 +277,32 @@ void QCocoaGLContext::updateSurfaceFormat()
NSOpenGLPixelFormat *pixelFormat = m_context.pixelFormat;
- int colorSize = [pixelFormat qt_getAttribute:NSOpenGLPFAColorSize];
+ GLint virtualScreen = [&, this]() {
+ auto *platformScreen = static_cast<QCocoaScreen*>(context()->screen()->handle());
+ auto displayId = platformScreen->nativeScreen().qt_displayId;
+ auto requestedDisplay = CGDisplayIDToOpenGLDisplayMask(displayId);
+ for (int i = 0; i < pixelFormat.numberOfVirtualScreens; ++i) {
+ GLint supportedDisplays;
+ [pixelFormat getValues:&supportedDisplays forAttribute:NSOpenGLPFAScreenMask forVirtualScreen:i];
+ // Note: The mask returned for NSOpenGLPFAScreenMask is a bit mask of
+ // physical displays that the renderer can drive, while the one returned
+ // from CGDisplayIDToOpenGLDisplayMask has a single bit set, representing
+ // that particular display.
+ if (requestedDisplay & supportedDisplays)
+ return i;
+ }
+ qCWarning(lcQpaOpenGLContext) << "Could not find virtual screen for"
+ << platformScreen << "with displayId" << displayId;
+ return 0;
+ }();
+
+ auto pixelFormatAttribute = [&](NSOpenGLPixelFormatAttribute attribute) {
+ int value = 0;
+ [pixelFormat getValues:&value forAttribute:attribute forVirtualScreen:virtualScreen];
+ return value;
+ };
+
+ int colorSize = pixelFormatAttribute(NSOpenGLPFAColorSize);
colorSize /= 4; // The attribute includes the alpha component
m_format.setRedBufferSize(colorSize);
m_format.setGreenBufferSize(colorSize);
@@ -297,22 +314,28 @@ void QCocoaGLContext::updateSurfaceFormat()
// size, as that will make the user believe the alpha channel can be used for
// something useful, when in reality it can't, due to the surface being opaque.
if (m_format.alphaBufferSize() > 0)
- m_format.setAlphaBufferSize([pixelFormat qt_getAttribute:NSOpenGLPFAAlphaSize]);
+ m_format.setAlphaBufferSize(pixelFormatAttribute(NSOpenGLPFAAlphaSize));
- m_format.setDepthBufferSize([pixelFormat qt_getAttribute:NSOpenGLPFADepthSize]);
- m_format.setStencilBufferSize([pixelFormat qt_getAttribute:NSOpenGLPFAStencilSize]);
- m_format.setSamples([pixelFormat qt_getAttribute:NSOpenGLPFASamples]);
+ m_format.setDepthBufferSize(pixelFormatAttribute(NSOpenGLPFADepthSize));
+ m_format.setStencilBufferSize(pixelFormatAttribute(NSOpenGLPFAStencilSize));
+ m_format.setSamples(pixelFormatAttribute(NSOpenGLPFASamples));
- if ([pixelFormat qt_getAttribute:NSOpenGLPFATripleBuffer])
+ if (pixelFormatAttribute(NSOpenGLPFATripleBuffer))
m_format.setSwapBehavior(QSurfaceFormat::TripleBuffer);
- else if ([pixelFormat qt_getAttribute:NSOpenGLPFADoubleBuffer])
+ else if (pixelFormatAttribute(NSOpenGLPFADoubleBuffer))
m_format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
else
m_format.setSwapBehavior(QSurfaceFormat::SingleBuffer);
// ------------------- Query the context -------------------
- m_format.setSwapInterval([m_context qt_getParameter:NSOpenGLCPSwapInterval]);
+ auto glContextParameter = [&](NSOpenGLContextParameter parameter) {
+ int value = 0;
+ [m_context getValues:&value forParameter:parameter];
+ return value;
+ };
+
+ m_format.setSwapInterval(glContextParameter(NSOpenGLCPSwapInterval));
if (oldContext)
[oldContext makeCurrentContext];
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 08e7447a75..9a2f19c2f2 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -215,25 +215,6 @@ QCocoaIntegration::QCocoaIntegration(const QStringList &paramList)
connect(qGuiApp, &QGuiApplication::focusWindowChanged,
this, &QCocoaIntegration::focusWindowChanged);
-
- static auto splashScreenHider = QMacKeyValueObserver(NSApp, @"modalWindow", []{
- const QWindowList allWindows = QGuiApplication::topLevelWindows();
- for (QWindow *window : allWindows) {
- if ((window->flags() & Qt::SplashScreen) == Qt::SplashScreen) {
- QCocoaWindow *platformWindow = static_cast<QCocoaWindow*>(window->handle());
- NSWindow *splashWindow = platformWindow->view().window;
- if (!splashWindow)
- continue;
- if (NSApp.modalWindow) {
- NSInteger originalLevel = splashWindow.level;
- splashWindow.level = NSNormalWindowLevel;
- window->setProperty("_q_levelBeforeModalSession", (qlonglong)originalLevel);
- } else if (NSInteger originalLevel = window->property("_q_levelBeforeModalSession").toLongLong()) {
- splashWindow.level = originalLevel;
- }
- }
- }
- });
}
QCocoaIntegration::~QCocoaIntegration()
@@ -331,9 +312,7 @@ QPlatformOffscreenSurface *QCocoaIntegration::createPlatformOffscreenSurface(QOf
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *QCocoaIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- QCocoaGLContext *glContext = new QCocoaGLContext(context);
- context->setNativeHandle(QVariant::fromValue<QCocoaNativeContext>(glContext->nativeContext()));
- return glContext;
+ return new QCocoaGLContext(context);
}
#endif
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index de5cf85854..db64702b8d 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -118,11 +118,13 @@ class QSystemTrayIconSys
public:
QSystemTrayIconSys(QCocoaSystemTrayIcon *sys) {
item = [[QNSStatusItem alloc] initWithSysTray:sys];
- [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:item];
+ NSUserNotificationCenter.defaultUserNotificationCenter.delegate = item;
}
~QSystemTrayIconSys() {
[[[item item] view] setHidden: YES];
- [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:nil];
+ NSUserNotificationCenter *center = NSUserNotificationCenter.defaultUserNotificationCenter;
+ if (center.delegate == item)
+ center.delegate = nil;
[item release];
}
QNSStatusItem *item;
@@ -264,7 +266,6 @@ bool QCocoaSystemTrayIcon::supportsMessages() const
void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &message,
const QIcon& icon, MessageIcon, int)
{
- Q_UNUSED(icon);
if (!m_sys)
return;
@@ -272,7 +273,16 @@ void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &mess
notification.title = [NSString stringWithUTF8String:title.toUtf8().data()];
notification.informativeText = [NSString stringWithUTF8String:message.toUtf8().data()];
- [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
+ if (!icon.isNull()) {
+ auto *nsimage = qt_mac_create_nsimage(icon);
+ [nsimage setTemplate:icon.isMask()];
+ notification.contentImage = [nsimage autorelease];
+ }
+
+ NSUserNotificationCenter *center = NSUserNotificationCenter.defaultUserNotificationCenter;
+ center.delegate = m_sys->item;
+ [center deliverNotification:notification];
+ [notification release];
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 363a026e71..8f3c192745 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -454,13 +454,35 @@ NSInteger QCocoaWindow::windowLevel(Qt::WindowFlags flags)
if (type == Qt::ToolTip)
windowLevel = NSScreenSaverWindowLevel;
- // Any "special" window should be in at least the same level as its parent.
- if (type != Qt::Window) {
- const QWindow * const transientParent = window()->transientParent();
- const QCocoaWindow * const transientParentWindow = transientParent ?
- static_cast<QCocoaWindow *>(transientParent->handle()) : nullptr;
- if (transientParentWindow)
- windowLevel = qMax([transientParentWindow->nativeWindow() level], windowLevel);
+ auto *transientParent = window()->transientParent();
+ if (transientParent && transientParent->handle()) {
+ // We try to keep windows in at least the same window level as
+ // their transient parent. Unfortunately this only works when the
+ // window is created. If the window level changes after that, as
+ // a result of a call to setWindowFlags, or by changing the level
+ // of the native window, we will not pick this up, and the window
+ // will be left behind (or in a different window level than) its
+ // parent. We could KVO-observe the window level of our transient
+ // parent, but that requires us to know when the parent goes away
+ // so that we can unregister the observation before the parent is
+ // dealloced, something we can't do for generic NSWindows. Another
+ // way would be to override [NSWindow setLevel:] and notify child
+ // windows about the change, but that doesn't work for foreign
+ // windows, which can still be transient parents via fromWinId().
+ // One area where this problem is apparent is when AppKit tweaks
+ // the window level of modal windows during application activation
+ // and deactivation. Since we don't pick up on these window level
+ // changes in a generic way, we need to add logic explicitly to
+ // re-evaluate the window level after AppKit has done its tweaks.
+
+ auto *transientCocoaWindow = static_cast<QCocoaWindow *>(transientParent->handle());
+ auto *nsWindow = transientCocoaWindow->nativeWindow();
+
+ // We only upgrade the window level for "special" windows, to work
+ // around Qt Designer parenting the designer windows to the widget
+ // palette window (QTBUG-31779). This should be fixed in designer.
+ if (type != Qt::Window)
+ windowLevel = qMax(windowLevel, nsWindow.level);
}
return windowLevel;
@@ -1626,6 +1648,9 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
[nsWindow setDepthLimit:NSWindowDepthTwentyfourBitRGB];
}
+ if (format().colorSpace() == QSurfaceFormat::sRGBColorSpace)
+ nsWindow.colorSpace = NSColorSpace.sRGBColorSpace;
+
return nsWindow;
}
diff --git a/src/plugins/platforms/cocoa/qcocoawindowmanager.h b/src/plugins/platforms/cocoa/qcocoawindowmanager.h
new file mode 100644
index 0000000000..54f17eeccd
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoawindowmanager.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOCOAWINDOWMANAGER_H
+#define QCOCOAWINDOWMANAGER_H
+
+#include <QtCore/qglobal.h>
+
+#include <AppKit/AppKit.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCocoaWindowManager
+{
+public:
+ static QCocoaWindowManager *instance();
+
+private:
+ QCocoaWindowManager();
+ void initialize();
+
+ void modalSessionChanged();
+};
+
+QT_END_NAMESPACE
+
+#endif // QCOCOAWINDOWMANAGER_H
diff --git a/src/plugins/platforms/cocoa/qcocoawindowmanager.mm b/src/plugins/platforms/cocoa/qcocoawindowmanager.mm
new file mode 100644
index 0000000000..879bfaa546
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoawindowmanager.mm
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcocoawindowmanager.h"
+#include "qcocoawindow.h"
+
+#include <QtCore/private/qcore_mac_p.h>
+
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qwindow.h>
+
+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(); }));
+ }
+}
+
+void QCocoaWindowManager::initialize()
+{
+ Q_ASSERT(NSApp);
+
+ // Whenever the modalWindow property of NSApplication changes we have a new
+ // modal session running. Observing the app modal window instead of our own
+ // 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(
+ NSApp, @"modalWindow", [this] { modalSessionChanged(); },
+ NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew));
+}
+
+void QCocoaWindowManager::modalSessionChanged()
+{
+ // Make sure that no window is overlapping the modal window. This can
+ // happen for e.g. splash screens, which have the NSPopUpMenuWindowLevel.
+ for (auto *window : QGuiApplication::topLevelWindows()) {
+ auto *platformWindow = static_cast<QCocoaWindow*>(window->handle());
+ if (!platformWindow)
+ continue;
+
+ auto naturalWindowLevel = platformWindow->windowLevel(window->flags());
+ if (naturalWindowLevel > NSModalPanelWindowLevel) {
+ NSWindow *nativeWindow = platformWindow->nativeWindow();
+ if (NSApp.modalWindow) {
+ // Lower window to that of the modal windows, but no less
+ nativeWindow.level = NSModalPanelWindowLevel;
+ [nativeWindow orderBack:nil];
+ } else {
+ // Restore window's natural window level, whatever that was
+ nativeWindow.level = naturalWindowLevel;
+ }
+ }
+ }
+}
+
+static void initializeWindowManager() { Q_UNUSED(QCocoaWindowManager::instance()); }
+Q_CONSTRUCTOR_FUNCTION(initializeWindowManager)
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm
index f2f29b26ee..58ad53a6e1 100644
--- a/src/plugins/platforms/cocoa/qprintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm
@@ -522,16 +522,16 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
if (mode == property(PPK_Duplex).toInt() || !d->m_printDevice->supportedDuplexModes().contains(mode))
break;
switch (mode) {
- case QPrinter::DuplexNone:
+ case QPrint::DuplexNone:
PMSetDuplex(d->settings(), kPMDuplexNone);
break;
- case QPrinter::DuplexAuto:
+ case QPrint::DuplexAuto:
PMSetDuplex(d->settings(), d->m_pageLayout.orientation() == QPageLayout::Landscape ? kPMDuplexTumble : kPMDuplexNoTumble);
break;
- case QPrinter::DuplexLongSide:
+ case QPrint::DuplexLongSide:
PMSetDuplex(d->settings(), kPMDuplexNoTumble);
break;
- case QPrinter::DuplexShortSide:
+ case QPrint::DuplexShortSide:
PMSetDuplex(d->settings(), kPMDuplexTumble);
break;
default: