Use native handles for parent change check in QWindowsWindow.
authorMiikka Heikkinen <miikka.heikkinen@digia.com>
Wed, 8 Aug 2012 10:48:29 +0000 (13:48 +0300)
committerQt by Nokia <qt-info@nokia.com>
Thu, 9 Aug 2012 11:17:39 +0000 (13:17 +0200)
QWindow::setParent() sets the parent to zero instead of the desired
parent, if platform window has not yet been created for the parent.
This caused QWindowsWindow::setParent() to skip setting the parent
later, when correct window was specified, as the QWindow parent-child
relationship hadn't changed. Fixed by changing the the check to use
native handles instead.

Task-number: QTBUG-26791
Change-Id: I292a1ddf746583a7268f2d07c20166995c0dd7d6
Reviewed-by: Joerg Bornemann <joerg.bornemann@nokia.com>
src/plugins/platforms/windows/qwindowswindow.cpp

index 6e0d9b5..edb3e8c 100644 (file)
@@ -888,31 +888,35 @@ void QWindowsWindow::setParent(const QPlatformWindow *newParent)
     if (QWindowsContext::verboseWindows)
         qDebug() << __FUNCTION__ << window() << newParent;
 
-    if (newParent != parent() && m_data.hwnd)
+    if (m_data.hwnd)
         setParent_sys(newParent);
 }
 
 void QWindowsWindow::setParent_sys(const QPlatformWindow *parent) const
 {
-    HWND parentHWND = 0;
+    // Use GetAncestor instead of GetParent, as GetParent can return owner window for toplevels
+    HWND oldParentHWND = GetAncestor(m_data.hwnd, GA_PARENT);
+    HWND newParentHWND = 0;
     if (parent) {
         const QWindowsWindow *parentW = static_cast<const QWindowsWindow *>(parent);
-        parentHWND = parentW->handle();
+        newParentHWND = parentW->handle();
 
     }
 
-    const bool wasTopLevel = window()->isTopLevel();
-    const bool isTopLevel = parentHWND == 0;
+    if (newParentHWND != oldParentHWND) {
+        const bool wasTopLevel = window()->isTopLevel();
+        const bool isTopLevel = newParentHWND == 0;
 
-    setFlag(WithinSetParent);
-    SetParent(m_data.hwnd, parentHWND);
-    clearFlag(WithinSetParent);
+        setFlag(WithinSetParent);
+        SetParent(m_data.hwnd, newParentHWND);
+        clearFlag(WithinSetParent);
 
-    // WS_CHILD/WS_POPUP must be manually set/cleared in addition
-    // to dialog frames, etc (see  SetParent() ) if the top level state changes.
-    if (wasTopLevel != isTopLevel) {
-        const unsigned flags = isTopLevel ? unsigned(0) : unsigned(WindowCreationData::ForceChild);
-        setWindowFlags_sys(window()->windowFlags(), flags);
+        // WS_CHILD/WS_POPUP must be manually set/cleared in addition
+        // to dialog frames, etc (see  SetParent() ) if the top level state changes.
+        if (wasTopLevel != isTopLevel) {
+            const unsigned flags = isTopLevel ? unsigned(0) : unsigned(WindowCreationData::ForceChild);
+            setWindowFlags_sys(window()->windowFlags(), flags);
+        }
     }
 }