204333 - Display.post(Event) hangs on GTK (back port to 3.4.x)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
index ca87570..3eaffa6 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
@@ -2897,67 +2897,79 @@
*
*/
public boolean post (Event event) {
- synchronized (Device.class) {
- if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
- if (event == null) error (SWT.ERROR_NULL_ARGUMENT);
- if (!OS.GDK_WINDOWING_X11()) return false;
- int /*long*/ xDisplay = OS.GDK_DISPLAY ();
- int type = event.type;
- switch (type) {
- case SWT.KeyDown:
- case SWT.KeyUp: {
- int keyCode = 0;
- int /*long*/ keysym = untranslateKey (event.keyCode);
- if (keysym != 0) keyCode = OS.XKeysymToKeycode (xDisplay, keysym);
- if (keyCode == 0) {
- char key = event.character;
- switch (key) {
- case SWT.BS: keysym = OS.GDK_BackSpace; break;
- case SWT.CR: keysym = OS.GDK_Return; break;
- case SWT.DEL: keysym = OS.GDK_Delete; break;
- case SWT.ESC: keysym = OS.GDK_Escape; break;
- case SWT.TAB: keysym = OS.GDK_Tab; break;
- case SWT.LF: keysym = OS.GDK_Linefeed; break;
- default:
- keysym = key;
+ /*
+ * Get the operating system lock before synchronizing on the device
+ * lock so that the device lock will not be held should another
+ * thread already be in the operating system. This avoids deadlock
+ * should the other thread need the device lock.
+ */
+ Lock lock = OS.lock;
+ lock.lock();
+ try {
+ synchronized (Device.class) {
+ if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
+ if (event == null) error (SWT.ERROR_NULL_ARGUMENT);
+ if (!OS.GDK_WINDOWING_X11()) return false;
+ int /*long*/ xDisplay = OS.GDK_DISPLAY ();
+ int type = event.type;
+ switch (type) {
+ case SWT.KeyDown:
+ case SWT.KeyUp: {
+ int keyCode = 0;
+ int /*long*/ keysym = untranslateKey (event.keyCode);
+ if (keysym != 0) keyCode = OS.XKeysymToKeycode (xDisplay, keysym);
+ if (keyCode == 0) {
+ char key = event.character;
+ switch (key) {
+ case SWT.BS: keysym = OS.GDK_BackSpace; break;
+ case SWT.CR: keysym = OS.GDK_Return; break;
+ case SWT.DEL: keysym = OS.GDK_Delete; break;
+ case SWT.ESC: keysym = OS.GDK_Escape; break;
+ case SWT.TAB: keysym = OS.GDK_Tab; break;
+ case SWT.LF: keysym = OS.GDK_Linefeed; break;
+ default:
+ keysym = key;
+ }
+ keyCode = OS.XKeysymToKeycode (xDisplay, keysym);
+ if (keyCode == 0) return false;
}
- keyCode = OS.XKeysymToKeycode (xDisplay, keysym);
- if (keyCode == 0) return false;
+ OS.XTestFakeKeyEvent (xDisplay, keyCode, type == SWT.KeyDown, 0);
+ return true;
}
- OS.XTestFakeKeyEvent (xDisplay, keyCode, type == SWT.KeyDown, 0);
- return true;
- }
- case SWT.MouseDown:
- case SWT.MouseMove:
- case SWT.MouseUp: {
- if (type == SWT.MouseMove) {
- OS.XTestFakeMotionEvent (xDisplay, -1, event.x, event.y, 0);
- } else {
- int button = event.button;
- switch (button) {
- case 1:
- case 2:
- case 3: break;
- case 4: button = 6; break;
- case 5: button = 7; break;
- default: return false;
+ case SWT.MouseDown:
+ case SWT.MouseMove:
+ case SWT.MouseUp: {
+ if (type == SWT.MouseMove) {
+ OS.XTestFakeMotionEvent (xDisplay, -1, event.x, event.y, 0);
+ } else {
+ int button = event.button;
+ switch (button) {
+ case 1:
+ case 2:
+ case 3: break;
+ case 4: button = 6; break;
+ case 5: button = 7; break;
+ default: return false;
+ }
+ OS.XTestFakeButtonEvent (xDisplay, button, type == SWT.MouseDown, 0);
}
- OS.XTestFakeButtonEvent (xDisplay, button, type == SWT.MouseDown, 0);
+ return true;
}
- return true;
+ /*
+ * This code is intentionally commented. After posting a
+ * mouse wheel event the system may respond unpredictably
+ * to subsequent mouse actions.
+ */
+// case SWT.MouseWheel: {
+// if (event.count == 0) return false;
+// int button = event.count < 0 ? 5 : 4;
+// OS.XTestFakeButtonEvent (xDisplay, button, type == SWT.MouseWheel, 0);
+// }
}
- /*
- * This code is intentionally commented. After posting a
- * mouse wheel event the system may respond unpredictably
- * to subsequent mouse actions.
- */
-// case SWT.MouseWheel: {
-// if (event.count == 0) return false;
-// int button = event.count < 0 ? 5 : 4;
-// OS.XTestFakeButtonEvent (xDisplay, button, type == SWT.MouseWheel, 0);
-// }
+ return false;
}
- return false;
+ } finally {
+ lock.unlock();
}
}