From fac7c8570b50479b4841ffde9c4cef5931d854b6 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 6 Jul 2012 13:39:31 +0200 Subject: [PATCH] Cleaner support for window flags in QCocoaWindow Window flags were not properly forwarded to the platform window instance. Particularly in the use cases found in QtQuick desktop components. Change-Id: Ibeadfee7de95ba497e9c0f765acee77c84884466 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/cocoa/qcocoawindow.h | 5 +- src/plugins/platforms/cocoa/qcocoawindow.mm | 107 +++++++++++++------- 2 files changed, 75 insertions(+), 37 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 32d9044ff6..ef80616221 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -118,7 +118,10 @@ public: void windowDidMove(); void windowDidResize(); void windowWillClose(); - bool windowIsPopupType() const; + bool windowIsPopupType(Qt::WindowType type = Qt::Widget) const; + + NSInteger windowLevel(Qt::WindowFlags flags); + NSUInteger windowStyleMask(Qt::WindowFlags flags); void setCurrentContext(QCocoaGLContext *context); QCocoaGLContext *currentContext() const; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 15b35d6585..d2c1d37b2b 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -310,8 +310,73 @@ void QCocoaWindow::setVisible(bool visible) } } +NSInteger QCocoaWindow::windowLevel(Qt::WindowFlags flags) +{ + Qt::WindowType type = static_cast(int(flags & Qt::WindowType_Mask)); + + NSInteger windowLevel = NSNormalWindowLevel; + + if (type == Qt::Tool) { + windowLevel = NSFloatingWindowLevel; + } else if ((type & Qt::Popup) == Qt::Popup) { + windowLevel = NSPopUpMenuWindowLevel; + + // Popup should be in at least the same level as its parent. + const QWindow * const transientParent = window()->transientParent(); + const QCocoaWindow * const transientParentWindow = transientParent ? static_cast(transientParent->handle()) : 0; + if (transientParentWindow) + windowLevel = qMax([transientParentWindow->m_nsWindow level], windowLevel); + } + + // StayOnTop window should appear above Tool windows. + if (flags & Qt::WindowStaysOnTopHint) + windowLevel = NSPopUpMenuWindowLevel; + // Tooltips should appear above StayOnTop windows. + if (type == Qt::ToolTip) + windowLevel = NSScreenSaverWindowLevel; + + return windowLevel; +} + +NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) +{ + Qt::WindowType type = static_cast(int(flags & Qt::WindowType_Mask)); + NSInteger styleMask = NSBorderlessWindowMask; + + if ((type & Qt::Popup) == Qt::Popup) { + if (!windowIsPopupType(type)) + styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask | NSTitledWindowMask); + } else { + // Filter flags for supported properties + flags &= Qt::WindowType_Mask | Qt::FramelessWindowHint | Qt::WindowTitleHint | + Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint; + if (flags == Qt::Window) { + styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask); + } else if (!(flags & Qt::FramelessWindowHint)) { + if (flags & Qt::WindowMaximizeButtonHint) + styleMask |= NSResizableWindowMask; + if (flags & Qt::WindowTitleHint) + styleMask |= NSTitledWindowMask; + if (flags & Qt::WindowCloseButtonHint) + styleMask |= NSClosableWindowMask; + if (flags & Qt::WindowMinimizeButtonHint) + styleMask |= NSMiniaturizableWindowMask; + } + } + + return styleMask; +} + Qt::WindowFlags QCocoaWindow::setWindowFlags(Qt::WindowFlags flags) { + if (m_nsWindow) { + NSUInteger styleMask = windowStyleMask(flags); + NSInteger level = this->windowLevel(flags); + [m_nsWindow setStyleMask:styleMask]; + [m_nsWindow setLevel:level]; + } + m_windowFlags = flags; return m_windowFlags; } @@ -467,9 +532,10 @@ void QCocoaWindow::windowWillClose() QWindowSystemInterface::handleSynchronousCloseEvent(window()); } -bool QCocoaWindow::windowIsPopupType() const +bool QCocoaWindow::windowIsPopupType(Qt::WindowType type) const { - Qt::WindowType type = window()->windowType(); + if (type == Qt::Widget) + type = window()->windowType(); if (type == Qt::Tool) return false; // Qt::Tool has the Popup bit set but isn't, at least on Mac. @@ -528,42 +594,11 @@ NSWindow * QCocoaWindow::createNSWindow() Qt::WindowType type = window()->windowType(); Qt::WindowFlags flags = window()->windowFlags(); - NSUInteger styleMask; + NSUInteger styleMask = windowStyleMask(flags); NSWindow *createdWindow = 0; - NSInteger windowLevel = -1; - - if (type == Qt::Tool) { - windowLevel = NSFloatingWindowLevel; - } else if ((type & Qt::Popup) == Qt::Popup) { - // styleMask = NSBorderlessWindowMask; - windowLevel = NSPopUpMenuWindowLevel; - - // Popup should be in at least the same level as its parent. - const QWindow * const transientParent = window()->transientParent(); - const QCocoaWindow * const transientParentWindow = transientParent ? static_cast(transientParent->handle()) : 0; - if (transientParentWindow) - windowLevel = qMax([transientParentWindow->m_nsWindow level], windowLevel); - } - - // StayOnTop window should appear above Tool windows. - if (flags & Qt::WindowStaysOnTopHint) - windowLevel = NSPopUpMenuWindowLevel; - // Tooltips should appear above StayOnTop windows. - if (type == Qt::ToolTip) - windowLevel = NSScreenSaverWindowLevel; - // All other types are Normal level. - if (windowLevel == -1) - windowLevel = NSNormalWindowLevel; // Use NSPanel for popup-type windows. (Popup, Tool, ToolTip, SplashScreen) if ((type & Qt::Popup) == Qt::Popup) { - if (windowIsPopupType()) { - styleMask = NSBorderlessWindowMask; - } else { - styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask | NSTitledWindowMask); - } - QNSPanel *window; window = [[QNSPanel alloc] initWithContentRect:frame styleMask: styleMask @@ -581,7 +616,6 @@ NSWindow * QCocoaWindow::createNSWindow() window->m_cocoaPlatformWindow = this; createdWindow = window; } else { - styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask); QNSWindow *window; window = [[QNSWindow alloc] initWithContentRect:frame styleMask: styleMask @@ -601,7 +635,8 @@ NSWindow * QCocoaWindow::createNSWindow() createdWindow = window; } - [createdWindow setLevel:windowLevel]; + NSInteger level = windowLevel(flags); + [createdWindow setLevel:level]; return createdWindow; }