diff options
author | Marc-Andre Laperle | 2015-04-04 01:04:40 +0000 |
---|---|---|
committer | Arun Thondapu | 2015-04-08 14:21:32 +0000 |
commit | 5b490bb962a97813a4885b327f855701a501fd7e (patch) | |
tree | d1d88d50e456d23a74a3146c76179871810bb16d | |
parent | 41bdd68738c0b4aa849e6a0d483da956ec49ea3d (diff) | |
download | eclipse.platform.swt-5b490bb962a97813a4885b327f855701a501fd7e.tar.gz eclipse.platform.swt-5b490bb962a97813a4885b327f855701a501fd7e.tar.xz eclipse.platform.swt-5b490bb962a97813a4885b327f855701a501fd7e.zip |
Bug 463783 - [GTK3] reproducible crash at gdk_window_get_support_multidevice+0x23
Apply the same fix for bug 427776 on the Shell class.
Also extract some common code.
Change-Id: Ic6f98d8c5da0fe19ddd14cad86aba8698b35f6fa
Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
-rw-r--r-- | bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java | 50 | ||||
-rw-r--r-- | bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java | 11 |
2 files changed, 35 insertions, 26 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java index e578aa05e6..66fcd115b1 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java @@ -373,7 +373,7 @@ void hookEvents () { long /*int*/ topHandle = topHandle (); OS.g_signal_connect_closure_by_id (topHandle, display.signalIds [MAP], 0, display.getClosure (MAP), true); - if (enterNotifyEventFunc == null) { + if (enterNotifyEventFunc == null && OS.GTK3 && OS.GTK_VERSION < OS.VERSION (3, 11, 9)) { enterNotifyEventFunc = new Callback (Control.class, "enterNotifyEventProc", 4); if (enterNotifyEventFunc.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS); @@ -4344,27 +4344,7 @@ public void setEnabled (boolean enabled) { if (isDisposed ()) return; if (enabled) { if (enableWindow != 0) { - if (OS.GTK3 && OS.GTK_VERSION < OS.VERSION (3, 11, 9)) { - if (enterNotifyEventId > 0) - OS.g_signal_remove_emission_hook(enterNotifyEventSignalId, enterNotifyEventId); - enterNotifyEventId = 0; - - /* - * 427776: now we can remove any reference to the GdkWindow - * in a widget's internal hash table. this internal hash - * table was removed in GTK 3.11.9 so once only newer GTK is - * targeted, this workaround can be removed. - */ - long /*int*/ grabWidget = OS.g_object_get_qdata(enableWindow, SWT_GRAB_WIDGET); - if (grabWidget != 0) { - OS.g_object_set_qdata(grabWidget, GTK_POINTER_WINDOW, 0); - OS.g_object_set_qdata(enableWindow, SWT_GRAB_WIDGET, 0); - } - } - - OS.gdk_window_set_user_data (enableWindow, 0); - OS.gdk_window_destroy (enableWindow); - enableWindow = 0; + cleanupEnableWindow(); } } else { OS.gtk_widget_realize (handle); @@ -4387,7 +4367,7 @@ public void setEnabled (boolean enabled) { * see if this new GdkWindow has been added to a widget's internal * hash table, so when the GdkWindow is destroyed we can also remove * that reference. */ - if (OS.GTK3 && OS.GTK_VERSION < OS.VERSION (3, 11, 9)) + if (enterNotifyEventFunc != null) enterNotifyEventId = OS.g_signal_add_emission_hook (enterNotifyEventSignalId, 0, enterNotifyEventFunc.getAddress (), enableWindow, 0); OS.gdk_window_set_user_data (enableWindow, parentHandle); @@ -4402,6 +4382,30 @@ public void setEnabled (boolean enabled) { if (fixFocus) fixFocus (control); } +void cleanupEnableWindow() { + if (enterNotifyEventFunc != null) { + if (enterNotifyEventId > 0) + OS.g_signal_remove_emission_hook(enterNotifyEventSignalId, enterNotifyEventId); + enterNotifyEventId = 0; + + /* + * 427776: now we can remove any reference to the GdkWindow + * in a widget's internal hash table. this internal hash + * table was removed in GTK 3.11.9 so once only newer GTK is + * targeted, this workaround can be removed. + */ + long /*int*/ grabWidget = OS.g_object_get_qdata(enableWindow, SWT_GRAB_WIDGET); + if (grabWidget != 0) { + OS.g_object_set_qdata(grabWidget, GTK_POINTER_WINDOW, 0); + OS.g_object_set_qdata(enableWindow, SWT_GRAB_WIDGET, 0); + } + } + + OS.gdk_window_set_user_data (enableWindow, 0); + OS.gdk_window_destroy (enableWindow); + enableWindow = 0; +} + /** * Causes the receiver to have the <em>keyboard focus</em>, * such that all keyboard events will be delivered to it. Focus diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java index 6ee16b3d2c..7720c393e6 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java @@ -1860,9 +1860,7 @@ public void setEnabled (boolean enabled) { if (isDisposed ()) return; if (enabled) { if (enableWindow != 0) { - OS.gdk_window_set_user_data (enableWindow, 0); - OS.gdk_window_destroy (enableWindow); - enableWindow = 0; + cleanupEnableWindow(); } } else { long /*int*/ parentHandle = shellHandle; @@ -1886,6 +1884,13 @@ public void setEnabled (boolean enabled) { OS.XFlush (xDisplay); } } + /* 427776: we need to listen to all enter-notify-event signals to + * see if this new GdkWindow has been added to a widget's internal + * hash table, so when the GdkWindow is destroyed we can also remove + * that reference. */ + if (enterNotifyEventFunc != null) + enterNotifyEventId = OS.g_signal_add_emission_hook (enterNotifyEventSignalId, 0, enterNotifyEventFunc.getAddress (), enableWindow, 0); + OS.gdk_window_set_user_data (enableWindow, parentHandle); OS.gdk_window_show (enableWindow); } |