Cocoa: bugfix staysOnTopFlag in combination with transient parent
authorRichard Moe Gustavsen <richard.gustavsen@digia.com>
Tue, 2 Oct 2012 09:28:58 +0000 (11:28 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Tue, 2 Oct 2012 11:22:49 +0000 (13:22 +0200)
A staysOnTop window with a parent would never stay on top. The reason
was that we placed the window on the same level as the parent, which
would undermine the staysOnTop flag.

The fix for this is to always level the window to _at least_ as the same
level as the parent, but never lower. A code path for this already
existed in the windowLevel function for popups. so we factor that out
and use it for all cases.

Task-number: QTBUG-27410
Change-Id: I0c30194be33703f54b6c2fe7f3088a9febcd1e2c
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
src/plugins/platforms/cocoa/qcocoawindow.mm

index daed7c3..4ef445c 100644 (file)
@@ -319,18 +319,11 @@ NSInteger QCocoaWindow::windowLevel(Qt::WindowFlags flags)
 
     NSInteger windowLevel = NSNormalWindowLevel;
 
-    if (type == Qt::Tool) {
+    if (type == Qt::Tool)
         windowLevel = NSFloatingWindowLevel;
-    } else if ((type & Qt::Popup) == Qt::Popup) {
+    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<QCocoaWindow *>(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;
@@ -338,6 +331,12 @@ NSInteger QCocoaWindow::windowLevel(Qt::WindowFlags flags)
     if (type == Qt::ToolTip)
         windowLevel = NSScreenSaverWindowLevel;
 
+    // A window should be in at least the same level as its parent.
+    const QWindow * const transientParent = window()->transientParent();
+    const QCocoaWindow * const transientParentWindow = transientParent ? static_cast<QCocoaWindow *>(transientParent->handle()) : 0;
+    if (transientParentWindow)
+        windowLevel = qMax([transientParentWindow->m_nsWindow level], windowLevel);
+
     return windowLevel;
 }
 
@@ -592,12 +591,6 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
         setWindowFlags(window()->windowFlags());
         setWindowTitle(window()->windowTitle());
         setWindowState(window()->windowState());
-
-        if (window()->transientParent()) {
-            // keep this window on the same level as its transient parent (which may be a modal dialog, for example)
-            QCocoaWindow *parentCocoaWindow = static_cast<QCocoaWindow *>(window()->transientParent()->handle());
-            [m_nsWindow setLevel:[parentCocoaWindow->m_nsWindow level]];
-        }
     } else {
         // Child windows have no NSWindow, link the NSViews instead.
         const QCocoaWindow *parentCococaWindow = static_cast<const QCocoaWindow *>(parentWindow);