Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Pun2017-05-23 23:01:55 +0000
committerLeo Ufimtsev2017-06-20 18:20:09 +0000
commit7714fdbf1ce0110744da9c164486c12254d5bd6f (patch)
treecc76eb3242eba1a9a5f775f6b3d5e354d796d5df
parent56755d505b2f2ece25e1a012100d096898dafaf7 (diff)
downloadeclipse.platform.swt-7714fdbf1ce0110744da9c164486c12254d5bd6f.tar.gz
eclipse.platform.swt-7714fdbf1ce0110744da9c164486c12254d5bd6f.tar.xz
eclipse.platform.swt-7714fdbf1ce0110744da9c164486c12254d5bd6f.zip
Bug 505992 - [Gtk] Replace deprecated gtk_menu_popup
Using gtk_menu_popup_at_pointer() instead of gtk_menu_popup() for >GTK3.22. Previous implementation had the popup event be put into the display stack, whereas the new implementation handles it during the GdkEvent. If no GdkEvent exists, it will create one. Tested with snippets that use setVisible() : Snippet 67, 97, 131. Some snippets such as 140 and 143 were not working prior to this fix caused by unrelated issues. Also tested on Eclipse instance with no issues. Tested using AllNonBrowserTests for GTK2 to GTK3.22 and Wayland. Change-Id: I723bdfa929df6a966b53382bd2eee4f2c1ee0576 Signed-off-by: Ian Pun <ipun@redhat.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c26
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java17
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java82
6 files changed, 104 insertions, 25 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
index 002c5abbd3..8f2b065170 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
@@ -11138,11 +11138,37 @@ JNIEXPORT void JNICALL OS_NATIVE(_1gtk_1menu_1popup)
(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jintLong arg2, jintLong arg3, jintLong arg4, jint arg5, jint arg6)
{
OS_NATIVE_ENTER(env, that, _1gtk_1menu_1popup_FUNC);
+/*
gtk_menu_popup((GtkMenu *)arg0, (GtkWidget *)arg1, (GtkWidget *)arg2, (GtkMenuPositionFunc)arg3, (gpointer)arg4, (guint)arg5, (guint32)arg6);
+*/
+ {
+ OS_LOAD_FUNCTION(fp, gtk_menu_popup)
+ if (fp) {
+ ((void (CALLING_CONVENTION*)(GtkMenu *, GtkWidget *, GtkWidget *, GtkMenuPositionFunc, gpointer, guint, guint32))fp)((GtkMenu *)arg0, (GtkWidget *)arg1, (GtkWidget *)arg2, (GtkMenuPositionFunc)arg3, (gpointer)arg4, (guint)arg5, (guint32)arg6);
+ }
+ }
OS_NATIVE_EXIT(env, that, _1gtk_1menu_1popup_FUNC);
}
#endif
+#ifndef NO__1gtk_1menu_1popup_1at_1pointer
+JNIEXPORT void JNICALL OS_NATIVE(_1gtk_1menu_1popup_1at_1pointer)
+ (JNIEnv *env, jclass that, jintLong arg0, jintLong arg1)
+{
+ OS_NATIVE_ENTER(env, that, _1gtk_1menu_1popup_1at_1pointer_FUNC);
+/*
+ gtk_menu_popup_at_pointer(arg0, arg1);
+*/
+ {
+ OS_LOAD_FUNCTION(fp, gtk_menu_popup_at_pointer)
+ if (fp) {
+ ((void (CALLING_CONVENTION*)(jintLong, jintLong))fp)(arg0, arg1);
+ }
+ }
+ OS_NATIVE_EXIT(env, that, _1gtk_1menu_1popup_1at_1pointer_FUNC);
+}
+#endif
+
#ifndef NO__1gtk_1menu_1shell_1deactivate
JNIEXPORT void JNICALL OS_NATIVE(_1gtk_1menu_1shell_1deactivate)
(JNIEnv *env, jclass that, jintLong arg0)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h
index 5cba0bdc46..6a180efbd8 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h
@@ -292,6 +292,8 @@
#define gtk_gesture_zoom_get_scale_delta_LIB LIB_GTK
#define gtk_gesture_zoom_new_LIB LIB_GTK
#define gtk_gesture_single_set_button_LIB LIB_GTK
+#define gtk_menu_popup_LIB LIB_GTK
+#define gtk_menu_popup_at_pointer_LIB LIB_GTK
#define gtk_widget_draw_LIB LIB_GTK
#define gtk_widget_override_color_LIB LIB_GTK
#define gtk_widget_override_background_color_LIB LIB_GTK
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c
index 691e554105..e1be442a9b 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c
@@ -893,6 +893,7 @@ char * OS_nativeFunctionNames[] = {
"_1gtk_1menu_1new",
"_1gtk_1menu_1popdown",
"_1gtk_1menu_1popup",
+ "_1gtk_1menu_1popup_1at_1pointer",
"_1gtk_1menu_1shell_1deactivate",
"_1gtk_1menu_1shell_1insert",
"_1gtk_1menu_1shell_1set_1take_1focus",
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h
index e9637def11..0cc3005f3f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h
@@ -903,6 +903,7 @@ typedef enum {
_1gtk_1menu_1new_FUNC,
_1gtk_1menu_1popdown_FUNC,
_1gtk_1menu_1popup_FUNC,
+ _1gtk_1menu_1popup_1at_1pointer_FUNC,
_1gtk_1menu_1shell_1deactivate_FUNC,
_1gtk_1menu_1shell_1insert_FUNC,
_1gtk_1menu_1shell_1set_1take_1focus_FUNC,
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
index cb8290cc54..4e01f6be8d 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
@@ -9349,7 +9349,10 @@ public static final void gtk_menu_popdown(long /*int*/ menu) {
lock.unlock();
}
}
+
+// [GTK2/GTK3; 3.22 deprecated]
/**
+ * @method flags=dynamic
* @param menu cast=(GtkMenu *)
* @param parent_menu_shell cast=(GtkWidget *)
* @param parent_menu_item cast=(GtkWidget *)
@@ -9367,6 +9370,20 @@ public static final void gtk_menu_popup(long /*int*/ menu, long /*int*/ parent_m
lock.unlock();
}
}
+
+/**
+ * @method flags=dynamic
+ */
+public static final native void _gtk_menu_popup_at_pointer(long /*int*/ menu, long /*int*/ trigger_event);
+public static void gtk_menu_popup_at_pointer(long /*int*/ menu, long /*int*/ trigger_event) {
+ lock.lock();
+ try {
+ _gtk_menu_popup_at_pointer(menu, trigger_event);
+ } finally {
+ lock.unlock();
+ }
+}
+
/** @param menu_shell cast=(GtkMenuShell *) */
public static final native void _gtk_menu_shell_deactivate(long /*int*/ menu_shell);
public static final void gtk_menu_shell_deactivate(long /*int*/ menu_shell) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java
index 99b8e187a7..54776f421c 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java
@@ -206,28 +206,50 @@ void _setVisible (boolean visible) {
if ((parent._getShell ().style & SWT.ON_TOP) != 0) {
OS.gtk_menu_shell_set_take_focus (handle, false);
}
- long /*int*/ address = 0;
- hasLocation = false;
- long /*int*/ data = 0;
- /*
- * Popup-menu to the status icon should be aligned to
- * Tray rather than to cursor position. There is a
- * possibility (unlikely) that TrayItem might have
- * been disposed in the listener, for which case
- * the menu should be shown in the cursor position.
- */
- TrayItem item = display.currentTrayItem;
- if (item != null && !item.isDisposed()) {
- data = item.handle;
- address = OS.gtk_status_icon_position_menu_func ();
+ if (OS.GTK_VERSION < OS.VERSION(3, 22, 0)) {
+ long /*int*/ address = 0;
+ hasLocation = false;
+ long /*int*/ data = 0;
+ /*
+ * Popup-menu to the status icon should be aligned to
+ * Tray rather than to cursor position. There is a
+ * possibility (unlikely) that TrayItem might have
+ * been disposed in the listener, for which case
+ * the menu should be shown in the cursor position.
+ */
+ TrayItem item = display.currentTrayItem;
+ if (item != null && !item.isDisposed()) {
+ data = item.handle;
+ address = OS.gtk_status_icon_position_menu_func ();
+ }
+ /*
+ * Bug in GTK. The timestamp passed into gtk_menu_popup is used
+ * to perform an X pointer grab. It cannot be zero, else the grab
+ * will fail. The fix is to ensure that the timestamp of the last
+ * event processed is used.
+ */
+ OS.gtk_menu_popup (handle, 0, 0, address, data, 0, display.getLastEventTime ());
+ }
+ else {
+ /*
+ * GTK Feature: gtk_menu_popup is deprecated as of GTK3.22 and the new method gtk_menu_popup_at_pointer
+ * requires an event to hook on to. This requires the popup & events related to the menu be handled
+ * immediately and not as a post event in display, requiring the current event.
+ */
+ long /*int*/ eventPtr = OS.gtk_get_current_event();
+ if (eventPtr == 0) {
+ eventPtr = OS.gdk_event_new(OS.GDK_BUTTON_PRESS);
+ GdkEventButton event = new GdkEventButton ();
+ event.type = OS.GDK_BUTTON_PRESS;
+ event.window = OS.g_object_ref(OS.gtk_widget_get_window (getShell().handle));
+ long /*int*/ device_manager = OS.gdk_display_get_device_manager (OS.gdk_display_get_default ());
+ event.device = OS.gdk_device_manager_get_client_pointer (device_manager);
+ event.time = display.getLastEventTime ();
+ OS.memmove (eventPtr, event, GdkEventButton.sizeof);
+ }
+ OS.gtk_menu_popup_at_pointer (handle, eventPtr);
+ OS.gdk_event_free (eventPtr);
}
- /*
- * Bug in GTK. The timestamp passed into gtk_menu_popup is used
- * to perform an X pointer grab. It cannot be zero, else the grab
- * will fail. The fix is to ensure that the timestamp of the last
- * event processed is used.
- */
- OS.gtk_menu_popup (handle, 0, 0, address, data, 0, display.getLastEventTime ());
} else {
sendEvent (SWT.Hide);
}
@@ -1087,11 +1109,21 @@ void setOrientation (boolean create) {
public void setVisible (boolean visible) {
checkWidget();
if ((style & (SWT.BAR | SWT.DROP_DOWN)) != 0) return;
- if (visible) {
- display.addPopup (this);
+ /*
+ * GTK Feature: gtk_menu_popup is deprecated as of GTK3.22 and the new method gtk_menu_popup_at_pointer
+ * requires an event to hook on to. This requires the popup & events related to the menu be handled
+ * immediately and not as a post event in display.
+ */
+ if (OS.GTK_VERSION < OS.VERSION(3, 22, 0)) {
+ if (visible) {
+ display.addPopup (this);
+ } else {
+ display.removePopup (this);
+ _setVisible (false);
+ }
} else {
- display.removePopup (this);
- _setVisible (false);
+ _setVisible(visible);
}
}
}
+

Back to the top