From 94a81928ac3ba8fc0ccb17eba7328cba5be56323 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 7 Jun 2012 12:37:10 +0200 Subject: [PATCH] Fix a crash when calling effectiveWinId() on parentless widgets. 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 Reviewed-by: Girish Ramakrishnan --- src/widgets/kernel/qwidget.cpp | 25 ++++--------------------- src/widgets/kernel/qwidget_qpa.cpp | 7 +++++-- 2 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index e6a760a..1de6005 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -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 diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index 355af17..8a6ceac 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -989,8 +989,11 @@ void qt_qpa_set_cursor(QWidget *w, bool force) static QPointer 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. } -- 2.7.4