diff options
author | Gareth Stockwell <gareth.stockwell@sosco.com> | 2009-10-14 12:18:18 (GMT) |
---|---|---|
committer | Gareth Stockwell <gareth.stockwell@sosco.com> | 2009-10-15 08:50:58 (GMT) |
commit | 6c694eaae2b40be57c3292f43e085893095d9722 (patch) | |
tree | d40dd51a95a181d139af161c348f14d07201bf8b /src/gui/kernel | |
parent | b7142463c738cc1a0540fe456002fe94e7f5a894 (diff) | |
download | Qt-6c694eaae2b40be57c3292f43e085893095d9722.zip Qt-6c694eaae2b40be57c3292f43e085893095d9722.tar.gz Qt-6c694eaae2b40be57c3292f43e085893095d9722.tar.bz2 |
When reparenting native widget, delayed deletion of Symbian control
until control returns to the event loop.
This is necessary because reparenting can be triggered from the context
of a control's event handler. If reparenting causes that control to be
deleted, a crash can result.
Task-number: QTBUG-4664
Reviewed-by: axis
Diffstat (limited to 'src/gui/kernel')
-rw-r--r-- | src/gui/kernel/qapplication_s60.cpp | 5 | ||||
-rw-r--r-- | src/gui/kernel/qwidget.cpp | 7 | ||||
-rw-r--r-- | src/gui/kernel/qwidget.h | 3 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_p.h | 1 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_s60.cpp | 13 |
5 files changed, 28 insertions, 1 deletions
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index b1706af..1a8aae0 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1122,6 +1122,11 @@ void qt_init(QApplicationPrivate * /* priv */, int) ; } */ + + // Register WId with the metatype system. This is to enable + // QWidgetPrivate::create_sys to used delayed slot invokation in order + // to destroy WId objects during reparenting. + qRegisterMetaType<WId>("WId"); } /***************************************************************************** diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 7c11c00..7c9356e 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -11994,3 +11994,10 @@ void QWidget::clearMask() XRender extension is not supported on the X11 display, or if the handle could not be created. */ + +#ifdef Q_OS_SYMBIAN +void QWidgetPrivate::_q_delayedDestroy(WId winId) +{ + delete winId; +} +#endif diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h index 76418af..e7daf9f 100644 --- a/src/gui/kernel/qwidget.h +++ b/src/gui/kernel/qwidget.h @@ -773,6 +773,9 @@ private: private: Q_DISABLE_COPY(QWidget) Q_PRIVATE_SLOT(d_func(), void _q_showIfNotHidden()) +#ifdef Q_OS_SYMBIAN + Q_PRIVATE_SLOT(d_func(), void _q_delayedDestroy(WId winId)) +#endif QWidgetData *data; diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index a4cc0da..c7b8d42 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -295,6 +295,7 @@ public: #ifdef Q_OS_SYMBIAN void setSoftKeys_sys(const QList<QAction*> &softkeys); void activateSymbianWindow(WId wid = 0); + void _q_delayedDestroy(WId winId); #endif void raise_sys(); diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 5527cc8..c3686b3 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -56,6 +56,12 @@ #include <aknappui.h> #endif +// This is necessary in order to be able to perform delayed invokation on slots +// which take arguments of type WId. One example is +// QWidgetPrivate::_q_delayedDestroy, which is used to delay destruction of +// CCoeControl objects until after the CONE event handler has finished running. +Q_DECLARE_METATYPE(WId) + QT_BEGIN_NAMESPACE extern bool qt_nograb(); @@ -438,7 +444,12 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de if (destroyw) { destroyw->ControlEnv()->AppUi()->RemoveFromStack(destroyw); - CBase::Delete(destroyw); + + // Delay deletion of the control in case this function is called in the + // context of a CONE event handler such as + // CCoeControl::ProcessPointerEventL + QMetaObject::invokeMethod(q, "_q_delayedDestroy", + Qt::QueuedConnection, Q_ARG(WId, destroyw)); } if (q->testAttribute(Qt::WA_AcceptTouchEvents)) |