Skip to main content

PP/Qt segmentation fault in QtToolkitEventHandler::postMouseButtonEvent

1 reply [Last post]
seb64
Offline
Joined: 2008-10-02

I found a bug in the postMouseButtonEvent method in QtToolkit.cc (PhoneME Advenced Personal Profile b103 with qt for the native peers):

When a component is clicked, its peer is recorded in the static variable lastMousePressPeer, so that it can be notified if the mouse is released on another component.
The problem is that if the component is destroyed in beetwen (which is the case in my application), the lastMousePressPeer may now refer a destroyed peer which then leads to a segmentation fault.

I have made a quick patch that checks for the peer destruction by listening for its destroyed signal and seems to solve the problem but i'm afraid it lacks any kind of synchronization and could fail to work in some cases.

Is there a cleaner/more robust way to do this ?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
seb64
Offline
Joined: 2008-10-02

Oops, I forgot to include my patch, here it is:

--- a/build/share/defs_personal_qt.mk
+++ b/build/share/defs_personal_qt.mk
@@ -143,6 +143,7 @@ AWT_LIB_OBJS += \
QtClipboard_moc.o \
QtComponentPeer.o \
QtToolkit.o \
+ QtToolkit_moc.o \
QtDisposer.o \
QtPanelPeer.o \
QtFramePeer.o \
diff --git a/src/share/personal/native/awt/qt/QtToolkit.cc b/src/share/personal/native/awt/qt/QtToolkit.cc
index c274c65..3f4675e 100644
--- a/src/share/personal/native/awt/qt/QtToolkit.cc
+++ b/src/share/personal/native/awt/qt/QtToolkit.cc
@@ -66,42 +66,6 @@ QPtrDict *mouseEventDict = new QPtrDict(31);
QPtrDict *focusEventDict = new QPtrDict(31);
// 6176847

-class QtToolkitEventHandler : public QObject
-{
- public:
- QtToolkitEventHandler();
- bool eventFilter(QObject *obj, QEvent *evt);
-
- private:
- static QtComponentPeer *lastMousePressPeer;
- static QPoint* lastMousePressPoint;
-
- static void postMouseEvent (JNIEnv *env,
- jobject thisObj,
- jint id,
- jlong when,
- jint modifiers,
- jint x,
- jint y,
- jint clickCount,
- jboolean popupTrigger,
- QtEventObject *event);
- static void postKeyEvent (JNIEnv *env,
- QtEventObject *event,
- QtComponentPeer *component);
- static void postMouseButtonEvent (JNIEnv *env,
- QtEventObject *event,
- QtComponentPeer *component);
- static void postMouseCrossingEvent (JNIEnv *env,
- QtEventObject *event,
- QtComponentPeer *component);
- static void postMouseMovedEvent (JNIEnv *env,
- QtEventObject *event,
- QtComponentPeer *component);
- static jlong getCurrentTime();
- static jint getModifiers(ButtonState state);
-};
-

QtComponentPeer *QtToolkitEventHandler::lastMousePressPeer = NULL;
QPoint *QtToolkitEventHandler::lastMousePressPoint = NULL;
@@ -744,7 +708,6 @@ QtToolkitEventHandler::QtToolkitEventHandler()
{
}

-
// The following Clone routines clone and return a new QEvent instance
// wrapped within a "QtEventObject". They return NULL if memory cannot
// be allocated
@@ -1407,7 +1370,7 @@ QtToolkitEventHandler::postMouseButtonEvent (JNIEnv *env,
popupTrigger = JNI_FALSE;
}

- lastMousePressPeer = component;
+ setLastMousePressPeer(component);

if (lastMousePressPoint != NULL)
delete lastMousePressPoint;
@@ -1418,11 +1381,13 @@ QtToolkitEventHandler::postMouseButtonEvent (JNIEnv *env,
bool isSame = FALSE;
QtComponentPeer *notifyComponent = component;

- if (lastMousePressPeer != NULL &&
- lastMousePressPeer != component) {
- notifyComponent = lastMousePressPeer;
- } else if (lastMousePressPeer == component) {
- lastMousePressPeer = NULL;
+ QtComponentPeer *oldComponent = getLastMousePressPeer();
+
+ if (oldComponent != NULL &&
+ oldComponent != component) {
+ notifyComponent = oldComponent;
+ } else if (oldComponent == component) {
+ setLastMousePressPeer(NULL);
isSame = TRUE;
}

@@ -1577,3 +1542,31 @@ QtToolkitEventHandler::postKeyEvent (JNIEnv *env,
#endif /* QT_KEYPAD_MODE */

}
+
+void
+QtToolkitEventHandler::setLastMousePressPeer (QtComponentPeer *peer)
+{
+ if (lastMousePressPeer != NULL)
+ {
+ disconnect(lastMousePressPeer, SIGNAL(destroyed()), this, SLOT(lastMousePressPeerDestroyed()));
+ }
+
+ lastMousePressPeer = peer;
+
+ if (lastMousePressPeer != NULL)
+ {
+ connect(lastMousePressPeer, SIGNAL(destroyed()), this, SLOT(lastMousePressPeerDestroyed()));
+ }
+}
+
+QtComponentPeer *
+QtToolkitEventHandler::getLastMousePressPeer (void)
+{
+ return lastMousePressPeer;
+}
+
+void
+QtToolkitEventHandler::lastMousePressPeerDestroyed(void)
+{
+ lastMousePressPeer = NULL;
+}
diff --git a/src/share/personal/native/awt/qt/QtToolkit.h b/src/share/personal/native/awt/qt/QtToolkit.h
index db0f19b..9edc697 100644
--- a/src/share/personal/native/awt/qt/QtToolkit.h
+++ b/src/share/personal/native/awt/qt/QtToolkit.h
@@ -26,6 +26,9 @@
#ifndef _QT_TOOLKIT_H
#define _QT_TOOLKIT_H

+#include "qobject.h"
+#include "QtComponentPeer.h"
+
#if (QT_VERSION >= 0x030000)
#define IS_SPONTANEOUS(_e) (_e->spontaneous())
#else
@@ -47,4 +50,49 @@
} \
return retValue; \
}
+
+class QtToolkitEventHandler : public QObject
+{
+ Q_OBJECT
+
+ public:
+ QtToolkitEventHandler();
+ bool eventFilter(QObject *obj, QEvent *evt);
+
+ public slots:
+ void lastMousePressPeerDestroyed();
+
+ private:
+ static QtComponentPeer *lastMousePressPeer;
+ static QPoint* lastMousePressPoint;
+
+ void setLastMousePressPeer(QtComponentPeer *);
+ QtComponentPeer *getLastMousePressPeer(void);
+
+ void postMouseEvent (JNIEnv *env,
+ jobject thisObj,
+ jint id,
+ jlong when,
+ jint modifiers,
+ jint x,
+ jint y,
+ jint clickCount,
+ jboolean popupTrigger,
+ QtEventObject *event);
+ void postKeyEvent (JNIEnv *env,
+ QtEventObject *event,
+ QtComponentPeer *component);
+ void postMouseButtonEvent (JNIEnv *env,
+ QtEventObject *event,
+ QtComponentPeer *component);
+ void postMouseCrossingEvent (JNIEnv *env,
+ QtEventObject *event,
+ QtComponentPeer *component);
+ void postMouseMovedEvent (JNIEnv *env,
+ QtEventObject *event,
+ QtComponentPeer *component);
+ static jlong getCurrentTime();
+ static jint getModifiers(ButtonState state);
+};
+
#endif