Fix a crash when calling effectiveWinId() on parentless widgets.
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Thu, 7 Jun 2012 10:37:10 +0000 (12:37 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 8 Jun 2012 06:02:13 +0000 (08:02 +0200)
Remove the assert as it also triggers when the widget is one
that currently has no parent (setParent(0)).
Check that the WinId is != 0 in the cursor code.

Change-Id: I711fc600f1d803c8f01c15df87984e742a4c23d2
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
Reviewed-by: Girish Ramakrishnan <girish.1.ramakrishnan@nokia.com>
src/widgets/kernel/qwidget.cpp
src/widgets/kernel/qwidget_qpa.cpp

index e6a760a..1de6005 100644 (file)
@@ -2318,29 +2318,12 @@ void QWidget::createWinId()
 */
 WId QWidget::effectiveWinId() const
 {
-    WId id = internalWinId();
+    const WId id = internalWinId();
     if (id || !testAttribute(Qt::WA_WState_Created))
         return id;
-    QWidget *realParent = nativeParentWidget();
-    if (!realParent && d_func()->inSetParent) {
-        // In transitional state. This is really just a workaround. The real problem
-        // is that QWidgetPrivate::setParent_sys (platform specific code) first sets
-        // the window id to 0 (setWinId(0)) before it sets the Qt::WA_WState_Created
-        // attribute to false. The correct way is to do it the other way around, and
-        // in that case the Qt::WA_WState_Created logic above will kick in and
-        // return 0 whenever the widget is in a transitional state. However, changing
-        // the original logic for all platforms is far more intrusive and might
-        // break existing applications.
-        // Note: The widget can only be in a transitional state when changing its
-        // parent -- everything else is an internal error -- hence explicitly checking
-        // against 'inSetParent' rather than doing an unconditional return whenever
-        // 'realParent' is 0 (which may cause strange artifacts and headache later).
-        return 0;
-    }
-    // This widget *must* have a native parent widget.
-    Q_ASSERT(realParent);
-    Q_ASSERT(realParent->internalWinId());
-    return realParent->internalWinId();
+    if (const QWidget *realParent = nativeParentWidget())
+        return realParent->internalWinId();
+    return 0;
 }
 
 #ifndef QT_NO_STYLE_STYLESHEET
index 355af17..8a6ceac 100644 (file)
@@ -989,8 +989,11 @@ void qt_qpa_set_cursor(QWidget *w, bool force)
     static QPointer<QWidget> lastUnderMouse = 0;
     if (force) {
         lastUnderMouse = w;
-    } else if (lastUnderMouse && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
-        w = lastUnderMouse;
+    } else if (lastUnderMouse) {
+        const WId lastWinId = lastUnderMouse->effectiveWinId();
+        const WId winId = w->effectiveWinId();
+        if (lastWinId && lastWinId == winId)
+            w = lastUnderMouse;
     } else if (!w->internalWinId()) {
         return; // The mouse is not under this widget, and it's not native, so don't change it.
     }