Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Williams2018-01-23 20:47:56 +0000
committerEric Williams2018-01-26 20:07:46 +0000
commit931aef681a2316e9fe2a414072464b0126f40ff8 (patch)
tree7fafa2114f88e840cd9c68cca4c597cca48eeee4
parentbe67e7a453048309b3d338b0f6f24c60f69e6f1a (diff)
downloadeclipse.platform.swt-931aef681a2316e9fe2a414072464b0126f40ff8.tar.gz
eclipse.platform.swt-931aef681a2316e9fe2a414072464b0126f40ff8.tar.xz
eclipse.platform.swt-931aef681a2316e9fe2a414072464b0126f40ff8.zip
Bug 530059: [Wayland] Show In menu appears in the wrong place
Events used to spawn menus can contain inaccurate window information on Wayland. If we are running on Wayland, set the event window to be that of the mouse pointer location. Tested on GTK3.22 using the Wayland backend. X11 is unaffected by this fix. No AllNonBrowser JUnit tests fail. Change-Id: I6410694a88faacc672144d9f57e6c61032ea33cf Signed-off-by: Eric Williams <ericwill@redhat.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c64
-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.c7
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h7
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java32
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java31
6 files changed, 143 insertions, 0 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 21535dfb98..7d440c0a8f 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
@@ -5021,6 +5021,26 @@ fail:
}
#endif
+#ifndef NO__1gdk_1event_1get_1event_1type
+JNIEXPORT jint JNICALL OS_NATIVE(_1gdk_1event_1get_1event_1type)
+ (JNIEnv *env, jclass that, jintLong arg0)
+{
+ jint rc = 0;
+ OS_NATIVE_ENTER(env, that, _1gdk_1event_1get_1event_1type_FUNC);
+/*
+ rc = (jint)gdk_event_get_event_type((GdkEvent *)arg0);
+*/
+ {
+ OS_LOAD_FUNCTION(fp, gdk_event_get_event_type)
+ if (fp) {
+ rc = (jint)((jint (CALLING_CONVENTION*)(GdkEvent *))fp)((GdkEvent *)arg0);
+ }
+ }
+ OS_NATIVE_EXIT(env, that, _1gdk_1event_1get_1event_1type_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO__1gdk_1event_1get_1scroll_1deltas
JNIEXPORT jboolean JNICALL OS_NATIVE(_1gdk_1event_1get_1scroll_1deltas)
(JNIEnv *env, jclass that, jintLong arg0, jdoubleArray arg1, jdoubleArray arg2)
@@ -6269,6 +6289,26 @@ JNIEXPORT jint JNICALL OS_NATIVE(_1gdk_1screen_1width_1mm)
}
#endif
+#ifndef NO__1gdk_1seat_1get_1pointer
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1gdk_1seat_1get_1pointer)
+ (JNIEnv *env, jclass that, jintLong arg0)
+{
+ jintLong rc = 0;
+ OS_NATIVE_ENTER(env, that, _1gdk_1seat_1get_1pointer_FUNC);
+/*
+ rc = (jintLong)gdk_seat_get_pointer(arg0);
+*/
+ {
+ OS_LOAD_FUNCTION(fp, gdk_seat_get_pointer)
+ if (fp) {
+ rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong))fp)(arg0);
+ }
+ }
+ OS_NATIVE_EXIT(env, that, _1gdk_1seat_1get_1pointer_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO__1gdk_1seat_1grab
JNIEXPORT jint JNICALL OS_NATIVE(_1gdk_1seat_1grab)
(JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jint arg2, jboolean arg3, jintLong arg4, jintLong arg5, jintLong arg6, jintLong arg7)
@@ -19405,6 +19445,30 @@ fail:
}
#endif
+#if (!defined(NO_memmove__ILorg_eclipse_swt_internal_gtk_GdkEventKey_2I) && !defined(JNI64)) || (!defined(NO_memmove__JLorg_eclipse_swt_internal_gtk_GdkEventKey_2J) && defined(JNI64))
+#ifndef JNI64
+JNIEXPORT void JNICALL OS_NATIVE(memmove__ILorg_eclipse_swt_internal_gtk_GdkEventKey_2I)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1, jintLong arg2)
+#else
+JNIEXPORT void JNICALL OS_NATIVE(memmove__JLorg_eclipse_swt_internal_gtk_GdkEventKey_2J)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1, jintLong arg2)
+#endif
+{
+ GdkEventKey _arg1, *lparg1=NULL;
+#ifndef JNI64
+ OS_NATIVE_ENTER(env, that, memmove__ILorg_eclipse_swt_internal_gtk_GdkEventKey_2I_FUNC);
+#else
+ OS_NATIVE_ENTER(env, that, memmove__JLorg_eclipse_swt_internal_gtk_GdkEventKey_2J_FUNC);
+#endif
+ if (arg1) if ((lparg1 = getGdkEventKeyFields(env, arg1, &_arg1)) == NULL) goto fail;
+ memmove((void *)arg0, (const void *)lparg1, (size_t)arg2);
+fail:
+#ifndef JNI64
+ OS_NATIVE_EXIT(env, that, memmove__ILorg_eclipse_swt_internal_gtk_GdkEventKey_2I_FUNC);
+#else
+ OS_NATIVE_EXIT(env, that, memmove__JLorg_eclipse_swt_internal_gtk_GdkEventKey_2J_FUNC);
+#endif
+}
+#endif
+
#if (!defined(NO_memmove__ILorg_eclipse_swt_internal_gtk_GdkEventMotion_2I) && !defined(JNI64)) || (!defined(NO_memmove__JLorg_eclipse_swt_internal_gtk_GdkEventMotion_2J) && defined(JNI64))
#ifndef JNI64
JNIEXPORT void JNICALL OS_NATIVE(memmove__ILorg_eclipse_swt_internal_gtk_GdkEventMotion_2I)(JNIEnv *env, jclass that, jintLong arg0, jobject arg1, jintLong arg2)
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 9a040590de..f3a552b8b1 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
@@ -296,12 +296,14 @@
#define gdk_screen_get_monitor_workarea_LIB LIB_GDK
#define gdk_seat_grab_LIB LIB_GDK
#define gdk_seat_ungrab_LIB LIB_GDK
+#define gdk_seat_get_pointer_LIB LIB_GDK
#define gdk_window_set_background_pattern_LIB LIB_GTK
#define gtk_widget_input_shape_combine_region_LIB LIB_GTK
#define gtk_entry_set_placeholder_text_LIB LIB_GTK
#define gtk_entry_get_icon_area_LIB LIB_GTK
#define gdk_event_get_scroll_deltas_LIB LIB_GTK
#define gdk_event_get_seat_LIB LIB_GDK
+#define gdk_event_get_event_type_LIB LIB_GDK
#define gtk_cell_renderer_get_preferred_height_for_width_LIB LIB_GTK
#define gtk_css_provider_load_from_data_LIB LIB_GTK
#define gtk_css_provider_new_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 2e67575423..cf6835baa8 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
@@ -454,6 +454,7 @@ char * OS_nativeFunctionNames[] = {
"_1gdk_1event_1free",
"_1gdk_1event_1get",
"_1gdk_1event_1get_1coords",
+ "_1gdk_1event_1get_1event_1type",
"_1gdk_1event_1get_1scroll_1deltas",
"_1gdk_1event_1get_1seat",
"_1gdk_1event_1get_1state",
@@ -531,6 +532,7 @@ char * OS_nativeFunctionNames[] = {
"_1gdk_1screen_1height",
"_1gdk_1screen_1width",
"_1gdk_1screen_1width_1mm",
+ "_1gdk_1seat_1get_1pointer",
"_1gdk_1seat_1grab",
"_1gdk_1seat_1ungrab",
"_1gdk_1selection_1owner_1get",
@@ -1609,6 +1611,11 @@ char * OS_nativeFunctionNames[] = {
"memmove__JLorg_eclipse_swt_internal_gtk_GdkEventExpose_2J",
#endif
#ifndef JNI64
+ "memmove__ILorg_eclipse_swt_internal_gtk_GdkEventKey_2I",
+#else
+ "memmove__JLorg_eclipse_swt_internal_gtk_GdkEventKey_2J",
+#endif
+#ifndef JNI64
"memmove__ILorg_eclipse_swt_internal_gtk_GdkEventMotion_2I",
#else
"memmove__JLorg_eclipse_swt_internal_gtk_GdkEventMotion_2J",
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 61a1ca03e1..0b17e4ecd9 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
@@ -464,6 +464,7 @@ typedef enum {
_1gdk_1event_1free_FUNC,
_1gdk_1event_1get_FUNC,
_1gdk_1event_1get_1coords_FUNC,
+ _1gdk_1event_1get_1event_1type_FUNC,
_1gdk_1event_1get_1scroll_1deltas_FUNC,
_1gdk_1event_1get_1seat_FUNC,
_1gdk_1event_1get_1state_FUNC,
@@ -541,6 +542,7 @@ typedef enum {
_1gdk_1screen_1height_FUNC,
_1gdk_1screen_1width_FUNC,
_1gdk_1screen_1width_1mm_FUNC,
+ _1gdk_1seat_1get_1pointer_FUNC,
_1gdk_1seat_1grab_FUNC,
_1gdk_1seat_1ungrab_FUNC,
_1gdk_1selection_1owner_1get_FUNC,
@@ -1619,6 +1621,11 @@ typedef enum {
memmove__JLorg_eclipse_swt_internal_gtk_GdkEventExpose_2J_FUNC,
#endif
#ifndef JNI64
+ memmove__ILorg_eclipse_swt_internal_gtk_GdkEventKey_2I_FUNC,
+#else
+ memmove__JLorg_eclipse_swt_internal_gtk_GdkEventKey_2J_FUNC,
+#endif
+#ifndef JNI64
memmove__ILorg_eclipse_swt_internal_gtk_GdkEventMotion_2I_FUNC,
#else
memmove__JLorg_eclipse_swt_internal_gtk_GdkEventMotion_2J_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 11043ae4d4..959aa999a8 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
@@ -4239,6 +4239,20 @@ public static final int gdk_event_get_time(long /*int*/ event) {
}
}
/**
+ * @method flags=dynamic
+ * @param event cast=(GdkEvent *)
+ */
+public static final native int _gdk_event_get_event_type(long /*int*/ event);
+/** [GTK3.10+] */
+public static final int gdk_event_get_event_type(long /*int*/ event) {
+ lock.lock();
+ try {
+ return _gdk_event_get_event_type(event);
+ } finally {
+ lock.unlock();
+ }
+}
+/**
* @param func cast=(GdkEventFunc)
* @param data cast=(gpointer)
* @param notify cast=(GDestroyNotify)
@@ -5238,6 +5252,18 @@ public static final void gdk_seat_ungrab(long /*int*/ seat) {
lock.unlock();
}
}
+/**
+ * @method flags=dynamic
+ */
+public static final native long /*int*/ _gdk_seat_get_pointer(long /*int*/ seat);
+public static final long /*int*/ gdk_seat_get_pointer(long /*int*/ seat) {
+ lock.lock();
+ try {
+ return _gdk_seat_get_pointer(seat);
+ } finally {
+ lock.unlock();
+ }
+}
/** @param program_class cast=(const char *) */
public static final native void _gdk_set_program_class(byte[] program_class);
public static final void gdk_set_program_class(byte[] program_class) {
@@ -15292,6 +15318,12 @@ public static final native void memmove(long /*int*/ dest, GdkEventButton src, l
* @param src cast=(const void *),flags=no_out
* @param size cast=(size_t)
*/
+public static final native void memmove(long /*int*/ dest, GdkEventKey src, long /*int*/ size);
+/**
+ * @param dest cast=(void *)
+ * @param src cast=(const void *),flags=no_out
+ * @param size cast=(size_t)
+ */
public static final native void memmove(long /*int*/ dest, GdkEventExpose src, long /*int*/ size);
/**
* @param dest cast=(void *)
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 26fe500029..7fbc335e74 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
@@ -246,6 +246,37 @@ void _setVisible (boolean visible) {
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);
+ } else {
+ if (!OS.isX11()) {
+ /*
+ * Lack of absolute coordinates make Wayland event windows inaccurate.
+ * If we are running on the Wayland the best way to pop-up a menu
+ * is by using the location of the mouse pointer. See bug 530059.
+ */
+ long /*int*/ seat = OS.gdk_event_get_seat(eventPtr);
+ long /*int*/ pointer = OS.gdk_seat_get_pointer(seat);
+ long /*int*/ deviceWindow = OS.gdk_device_get_window_at_position(pointer, null, null);
+ OS.g_object_ref(deviceWindow);
+ /*
+ * The event is most likely a button or key press. If it isn't
+ * we don't want it -- fall back to the event found with
+ * gtk_get_current_event().
+ */
+ int eventType = OS.gdk_event_get_event_type(eventPtr);
+ switch (eventType) {
+ case OS.GDK_BUTTON_PRESS:
+ GdkEventButton eventButton = new GdkEventButton();
+ OS.memmove (eventButton, eventPtr, GdkEventButton.sizeof);
+ eventButton.window = deviceWindow;
+ OS.memmove(eventPtr, eventButton, GdkEventButton.sizeof);
+ case OS.GDK_KEY_PRESS:
+ GdkEventKey eventKey = new GdkEventKey();
+ OS.memmove (eventKey, eventPtr, GdkEventKey.sizeof);
+ eventKey.window = deviceWindow;
+ OS.memmove(eventPtr, eventKey, GdkEventKey.sizeof);
+ }
+ }
}
OS.gtk_menu_popup_at_pointer (handle, eventPtr);
OS.gdk_event_free (eventPtr);

Back to the top