summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
authorGareth Stockwell <gareth.stockwell@sosco.com>2009-10-14 12:18:18 (GMT)
committerGareth Stockwell <gareth.stockwell@sosco.com>2009-10-15 08:50:58 (GMT)
commit6c694eaae2b40be57c3292f43e085893095d9722 (patch)
treed40dd51a95a181d139af161c348f14d07201bf8b /src/gui/kernel
parentb7142463c738cc1a0540fe456002fe94e7f5a894 (diff)
downloadQt-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.cpp5
-rw-r--r--src/gui/kernel/qwidget.cpp7
-rw-r--r--src/gui/kernel/qwidget.h3
-rw-r--r--src/gui/kernel/qwidget_p.h1
-rw-r--r--src/gui/kernel/qwidget_s60.cpp13
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))