diff options
7 files changed, 91 insertions, 19 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 cbaa2a9053..3a9e943c6d 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 @@ -997,6 +997,22 @@ fail: } #endif +#ifndef NO__1gdk_1event_1get_1crossing_1mode +JNIEXPORT jboolean JNICALL GDK_NATIVE(_1gdk_1event_1get_1crossing_1mode) + (JNIEnv *env, jclass that, jintLong arg0, jintArray arg1) +{ + jint *lparg1=NULL; + jboolean rc = 0; + GDK_NATIVE_ENTER(env, that, _1gdk_1event_1get_1crossing_1mode_FUNC); + if (arg1) if ((lparg1 = (*env)->GetIntArrayElements(env, arg1, NULL)) == NULL) goto fail; + rc = (jboolean)gdk_event_get_crossing_mode((GdkEvent *)arg0, (GdkCrossingMode *)lparg1); +fail: + if (arg1 && lparg1) (*env)->ReleaseIntArrayElements(env, arg1, lparg1, 0); + GDK_NATIVE_EXIT(env, that, _1gdk_1event_1get_1crossing_1mode_FUNC); + return rc; +} +#endif + #ifndef NO__1gdk_1event_1get_1event_1type JNIEXPORT jint JNICALL GDK_NATIVE(_1gdk_1event_1get_1event_1type) (JNIEnv *env, jclass that, jintLong arg0) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h index d1f09f7100..542b9a00f3 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h @@ -446,6 +446,7 @@ #define NO__1gdk_1event_1get_1focus_1in #define NO__1gdk_1event_1get_1string #define NO__1gdk_1event_1get_1key_1group +#define NO__1gdk_1event_1get_1crossing_1mode #endif #include "os_custom.h" 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 4b5964e794..9bcbfa3c73 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 @@ -104,6 +104,7 @@ char * GDK_nativeFunctionNames[] = { "_1gdk_1event_1get", "_1gdk_1event_1get_1button", "_1gdk_1event_1get_1coords", + "_1gdk_1event_1get_1crossing_1mode", "_1gdk_1event_1get_1event_1type", "_1gdk_1event_1get_1focus_1in", "_1gdk_1event_1get_1key_1group", 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 7ad9719ce8..dba5be2a6d 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 @@ -114,6 +114,7 @@ typedef enum { _1gdk_1event_1get_FUNC, _1gdk_1event_1get_1button_FUNC, _1gdk_1event_1get_1coords_FUNC, + _1gdk_1event_1get_1crossing_1mode_FUNC, _1gdk_1event_1get_1event_1type_FUNC, _1gdk_1event_1get_1focus_1in_FUNC, _1gdk_1event_1get_1key_1group_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GDK.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GDK.java index 3e69853a92..5eba0c0bec 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GDK.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GDK.java @@ -985,6 +985,20 @@ public class GDK extends OS { } /** * @param event cast=(GdkEvent *) + * @param mode cast=(GdkCrossingMode *) + */ + public static final native boolean _gdk_event_get_crossing_mode(long /*int*/ event, int [] mode); + /** [GTK4 only, if-def'd in os.h] */ + public static final boolean gdk_event_get_crossing_mode(long /*int*/ event, int [] mode) { + lock.lock(); + try { + return _gdk_event_get_crossing_mode(event, mode); + } finally { + lock.unlock(); + } + } + /** + * @param event cast=(GdkEvent *) * @param button cast=(guint *) */ public static final native boolean _gdk_event_get_button(long /*int*/ event, int[] button); 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 7673768e94..660d1853a2 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 @@ -3475,10 +3475,29 @@ long /*int*/ gtk_enter_notify_event (long /*int*/ widget, long /*int*/ event) { if (display.currentControl == this) return 0; GdkEventCrossing gdkEvent = new GdkEventCrossing (); - OS.memmove (gdkEvent, event, GdkEventCrossing.sizeof); - lastInput.x = (int) gdkEvent.x; - lastInput.y = (int) gdkEvent.y; + long /*int*/ childGdkResource = 0; + int [] crossingMode = new int[1]; + int [] state = new int [1]; + GDK.gdk_event_get_state(event, state); + int time = GDK.gdk_event_get_time(event); + double [] eventRX = new double [1]; + double [] eventRY = new double [1]; + GDK.gdk_event_get_root_coords(event, eventRX, eventRY); + double [] eventX = new double [1]; + double [] eventY = new double [1]; + GDK.gdk_event_get_coords(event, eventX, eventY); + lastInput.x = (int) eventX[0]; + lastInput.y = (int) eventY[0]; if (containedInRegion(lastInput.x, lastInput.y)) return 0; + if (GTK.GTK4) { + GDK.gdk_event_get_crossing_mode(event, crossingMode); + // TODO_GTK4: GTK devs are still deciding whether or not + // to provide API for GdkEventCrossing->child_surface. + } else { + OS.memmove(gdkEvent, event, GdkEventCrossing.sizeof); + crossingMode[0] = gdkEvent.mode; + childGdkResource = gdkEvent.subwindow; + } /* * It is possible to send out too many enter/exit events if entering a @@ -3486,16 +3505,16 @@ long /*int*/ gtk_enter_notify_event (long /*int*/ widget, long /*int*/ event) { * events if the GdkEventCrossing subwindow field is set and the control * requests to check the field. */ - if (gdkEvent.subwindow != 0 && checkSubwindow ()) return 0; - if (gdkEvent.mode != GDK.GDK_CROSSING_NORMAL && gdkEvent.mode != GDK.GDK_CROSSING_UNGRAB) return 0; - if ((gdkEvent.state & (GDK.GDK_BUTTON1_MASK | GDK.GDK_BUTTON2_MASK | GDK.GDK_BUTTON3_MASK)) != 0) return 0; + if (childGdkResource != 0 && checkSubwindow ()) return 0; + if (crossingMode [0] != GDK.GDK_CROSSING_NORMAL && crossingMode[0] != GDK.GDK_CROSSING_UNGRAB) return 0; + if ((state[0] & (GDK.GDK_BUTTON1_MASK | GDK.GDK_BUTTON2_MASK | GDK.GDK_BUTTON3_MASK)) != 0) return 0; if (display.currentControl != null && !display.currentControl.isDisposed ()) { display.removeMouseHoverTimeout (display.currentControl.handle); - display.currentControl.sendMouseEvent (SWT.MouseExit, 0, gdkEvent.time, gdkEvent.x_root, gdkEvent.y_root, false, gdkEvent.state); + display.currentControl.sendMouseEvent (SWT.MouseExit, 0, time, eventRX[0], eventRY[0], false, state[0]); } if (!isDisposed ()) { display.currentControl = this; - return sendMouseEvent (SWT.MouseEnter, 0, gdkEvent.time, gdkEvent.x_root, gdkEvent.y_root, false, gdkEvent.state) ? 0 : 1; + return sendMouseEvent (SWT.MouseEnter, 0, time, eventRX[0], eventRY[0], false, state[0]) ? 0 : 1; } return 0; } @@ -3748,16 +3767,31 @@ long /*int*/ gtk_key_release_event (long /*int*/ widget, long /*int*/ event) { long /*int*/ gtk_leave_notify_event (long /*int*/ widget, long /*int*/ event) { if (display.currentControl != this) return 0; GdkEventCrossing gdkEvent = new GdkEventCrossing (); - OS.memmove (gdkEvent, event, GdkEventCrossing.sizeof); - lastInput.x = (int) gdkEvent.x; - lastInput.y = (int) gdkEvent.y; + int [] crossingMode = new int[1]; + int [] state = new int [1]; + GDK.gdk_event_get_state(event, state); + int time = GDK.gdk_event_get_time(event); + double [] eventRX = new double [1]; + double [] eventRY = new double [1]; + GDK.gdk_event_get_root_coords(event, eventRX, eventRY); + double [] eventX = new double [1]; + double [] eventY = new double [1]; + GDK.gdk_event_get_coords(event, eventX, eventY); + lastInput.x = (int) eventX[0]; + lastInput.y = (int) eventY[0]; if (containedInRegion(lastInput.x, lastInput.y)) return 0; + if (GTK.GTK4) { + GDK.gdk_event_get_crossing_mode(event, crossingMode); + } else { + OS.memmove(gdkEvent, event, GdkEventCrossing.sizeof); + crossingMode[0] = gdkEvent.mode; + } display.removeMouseHoverTimeout (handle); int result = 0; if (sendLeaveNotify () || display.getCursorControl () == null) { - if (gdkEvent.mode != GDK.GDK_CROSSING_NORMAL && gdkEvent.mode != GDK.GDK_CROSSING_UNGRAB) return 0; - if ((gdkEvent.state & (GDK.GDK_BUTTON1_MASK | GDK.GDK_BUTTON2_MASK | GDK.GDK_BUTTON3_MASK)) != 0) return 0; - result = sendMouseEvent (SWT.MouseExit, 0, gdkEvent.time, gdkEvent.x_root, gdkEvent.y_root, false, gdkEvent.state) ? 0 : 1; + if (crossingMode[0] != GDK.GDK_CROSSING_NORMAL && crossingMode[0] != GDK.GDK_CROSSING_UNGRAB) return 0; + if ((state[0] & (GDK.GDK_BUTTON1_MASK | GDK.GDK_BUTTON2_MASK | GDK.GDK_BUTTON3_MASK)) != 0) return 0; + result = sendMouseEvent (SWT.MouseExit, 0, time, eventRX[0], eventRY[0], false, state[0]) ? 0 : 1; display.currentControl = null; } return result; 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 9d72b13237..0226498a1f 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 @@ -1519,11 +1519,16 @@ long /*int*/ gtk_focus_out_event (long /*int*/ widget, long /*int*/ event) { long /*int*/ gtk_leave_notify_event (long /*int*/ widget, long /*int*/ event) { if (widget == shellHandle) { if (isCustomResize ()) { - GdkEventCrossing gdkEvent = new GdkEventCrossing (); - OS.memmove (gdkEvent, event, GdkEventCrossing.sizeof); - if ((gdkEvent.state & GDK.GDK_BUTTON1_MASK) == 0) { - long /*int*/ window = gtk_widget_get_window (shellHandle); - GDK.gdk_window_set_cursor (window, 0); + int [] state = new int [1]; + GDK.gdk_event_get_state(event, state); + if ((state[0] & GDK.GDK_BUTTON1_MASK) == 0) { + if (GTK.GTK4) { + long /*int*/ surface = gtk_widget_get_surface (shellHandle); + GDK.gdk_surface_set_cursor(surface, 0); + } else { + long /*int*/ window = gtk_widget_get_window (shellHandle); + GDK.gdk_window_set_cursor (window, 0); + } display.resizeMode = 0; } } |