diff options
author | Xi Yan | 2019-02-08 20:05:48 +0000 |
---|---|---|
committer | Xi Yan | 2019-02-13 15:28:19 +0000 |
commit | 7c2bb7000bca9e2c79a80b9d0a2fc149f3d2e6de (patch) | |
tree | 9bde57a4f7dc6ebaabbc854eb90a1c4dbc37d7d9 | |
parent | c0a12d643b53fe3d88c2cf1373ecd9f3e4b92a16 (diff) | |
download | eclipse.platform.swt-7c2bb7000bca9e2c79a80b9d0a2fc149f3d2e6de.tar.gz eclipse.platform.swt-7c2bb7000bca9e2c79a80b9d0a2fc149f3d2e6de.tar.xz eclipse.platform.swt-7c2bb7000bca9e2c79a80b9d0a2fc149f3d2e6de.zip |
Bug 544114 - [GTK4] Replace 2BUTTON and 3BUTTON events
- 2BUTTON used to signal double click events, this is replaced by
GtkGestureMultiPress controller for handling double click events
whenever n_press equals 2.
- 3BUTTON constants in GTK3 used for early return of button_click
handlers, this is ignored by default on GTK4.
Tested GTK3 with Mouse Listeners in ControlExample,
Bug543984_GTK4EventTypeConstants on GTK4, ButtonTab double click BG/FG
dialog in ControlExample on GTK4.
Change-Id: I63bdb1a205bb40e478dea74dd99de97ddb66716f
Signed-off-by: Xi Yan <xixiyan@redhat.com>
13 files changed, 231 insertions, 1 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 dd4b9126fe..36ff357503 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 @@ -6241,6 +6241,32 @@ JNIEXPORT jboolean JNICALL GTK_NATIVE(_1gtk_1gesture_1is_1recognized) } #endif +#ifndef NO__1gtk_1gesture_1multi_1press_1new +JNIEXPORT jintLong JNICALL GTK_NATIVE(_1gtk_1gesture_1multi_1press_1new) + (JNIEnv *env, jclass that) +{ + jintLong rc = 0; + GTK_NATIVE_ENTER(env, that, _1gtk_1gesture_1multi_1press_1new_FUNC); + rc = (jintLong)gtk_gesture_multi_press_new(); + GTK_NATIVE_EXIT(env, that, _1gtk_1gesture_1multi_1press_1new_FUNC); + return rc; +} +#endif + +#ifndef NO__1gtk_1gesture_1multi_1press_1set_1area +JNIEXPORT void JNICALL GTK_NATIVE(_1gtk_1gesture_1multi_1press_1set_1area) + (JNIEnv *env, jclass that, jintLong arg0, jobject arg1) +{ + GdkRectangle _arg1, *lparg1=NULL; + GTK_NATIVE_ENTER(env, that, _1gtk_1gesture_1multi_1press_1set_1area_FUNC); + if (arg1) if ((lparg1 = getGdkRectangleFields(env, arg1, &_arg1)) == NULL) goto fail; + gtk_gesture_multi_press_set_area(arg0, lparg1); +fail: + if (arg1 && lparg1) setGdkRectangleFields(env, arg1, lparg1); + GTK_NATIVE_EXIT(env, that, _1gtk_1gesture_1multi_1press_1set_1area_FUNC); +} +#endif + #ifndef NO__1gtk_1gesture_1pan_1get_1orientation JNIEXPORT jintLong JNICALL GTK_NATIVE(_1gtk_1gesture_1pan_1get_1orientation) (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 c379af9343..ca3b880219 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 @@ -444,6 +444,9 @@ #define NO__1gtk_1css_1provider_1load_1from_1data__I_3BI #define NO__1gtk_1css_1provider_1load_1from_1data__J_3BJ +#define NO__1gtk_1gesture_1multi_1press_1new +#define NO__1gtk_1gesture_1multi_1press_1set_1area + // GdkCursor API changes from GTK3 -> GTK4 #define NO__1gdk_1cursor_1new_1from_1name___3BI #define NO__1gdk_1cursor_1new_1from_1name___3BJ 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 ace3ab56f9..015ce38cc1 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 @@ -561,6 +561,8 @@ char * GTK_nativeFunctionNames[] = { "_1gtk_1gesture_1get_1sequences", "_1gtk_1gesture_1group", "_1gtk_1gesture_1is_1recognized", + "_1gtk_1gesture_1multi_1press_1new", + "_1gtk_1gesture_1multi_1press_1set_1area", "_1gtk_1gesture_1pan_1get_1orientation", "_1gtk_1gesture_1pan_1new", "_1gtk_1gesture_1pan_1set_1orientation", 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 593affb51e..e372239036 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 @@ -559,6 +559,8 @@ typedef enum { _1gtk_1gesture_1get_1sequences_FUNC, _1gtk_1gesture_1group_FUNC, _1gtk_1gesture_1is_1recognized_FUNC, + _1gtk_1gesture_1multi_1press_1new_FUNC, + _1gtk_1gesture_1multi_1press_1set_1area_FUNC, _1gtk_1gesture_1pan_1get_1orientation_FUNC, _1gtk_1gesture_1pan_1new_FUNC, _1gtk_1gesture_1pan_1set_1orientation_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java index 821f8f735e..eb4a565f3f 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java @@ -2466,6 +2466,26 @@ public class GTK extends OS { lock.unlock(); } } + public static final native long /*int*/ _gtk_gesture_multi_press_new(); + /** [GTK4 only, if-def'd in os.h] */ + public static final long /*int*/ gtk_gesture_multi_press_new() { + lock.lock(); + try { + return _gtk_gesture_multi_press_new(); + } finally { + lock.unlock(); + } + } + public static final native void _gtk_gesture_multi_press_set_area(long /*int*/ gesture, GdkRectangle rect); + /** [GTK4 only, if-def'd in os.h] */ + public static final void gtk_gesture_multi_press_set_area(long /*int*/ gesture, GdkRectangle rect) { + lock.lock(); + try { + _gtk_gesture_multi_press_set_area(gesture, rect); + } finally { + lock.unlock(); + } + } public static final native long /*int*/ _gtk_event_controller_key_new(); /** [GTK4 only, if-def'd in os.h] */ public static final long /*int*/ gtk_event_controller_key_new() { 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 aa03c447f3..88fb44e9b7 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 @@ -345,6 +345,8 @@ public class OS extends C { public static final byte[] move_focus = ascii("move-focus"); public static final byte[] output = ascii("output"); public static final byte[] paste_clipboard = ascii("paste-clipboard"); + public static final byte[] pressed = ascii("pressed"); + public static final byte[] released = ascii("released"); public static final byte[] popped_up = ascii("popped-up"); public static final byte[] popup_menu = ascii("popup-menu"); public static final byte[] populate_popup = ascii("populate-popup"); 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 f59e798276..4663075a91 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 @@ -424,6 +424,12 @@ void hookEvents () { OS.g_signal_connect (keyController, OS.focus_in, focusAddress, FOCUS_IN); OS.g_signal_connect (keyController, OS.focus_out, focusAddress, FOCUS_OUT); + long /*int*/ gesturePressReleaseAddress = display.gesturePressReleaseCallback.getAddress(); + long /*int*/ gestureMultiPress = GTK.gtk_gesture_multi_press_new(); + GTK.gtk_widget_add_controller(focusHandle, gestureMultiPress); + OS.g_signal_connect(gestureMultiPress, OS.pressed, gesturePressReleaseAddress, GESTURE_PRESSED); + OS.g_signal_connect(gestureMultiPress, OS.released, gesturePressReleaseAddress, GESTURE_RELEASED); + } else { GTK.gtk_widget_add_events (focusHandle, focusMask); OS.g_signal_connect_closure_by_id (focusHandle, display.signalIds [KEY_PRESS_EVENT], 0, display.getClosure (KEY_PRESS_EVENT), false); @@ -3421,6 +3427,77 @@ long /*int*/ gtk_event (long /*int*/ widget, long /*int*/ event) { return 0; } +/** + * Handling multi-press event on GTK4 + */ +@Override +long /*int*/ gtk_gesture_press_event (long /*int*/ gesture, int n_press, double x, double y, long /*int*/ event) { + if (n_press == 1) return 0; + mouseDown = true; + dragBegun = false; + + // Event fields + double [] eventX = new double [1]; + double [] eventY = new double [1]; + GDK.gdk_event_get_coords(event, eventX, eventY); + int [] eventButton = new int [1]; + GDK.gdk_event_get_button(event, eventButton); + double [] eventRX = new double [1]; + double [] eventRY = new double [1]; + GDK.gdk_event_get_root_coords(event, eventRX, eventRY); + int eventTime = GDK.gdk_event_get_time(event); + int [] eventState = new int[1]; + GDK.gdk_event_get_state(event, eventState); + + lastInput.x = (int) eventX[0]; + lastInput.y = (int) eventY[0]; + if (containedInRegion(lastInput.x, lastInput.y)) return 0; + + /* + * When a shell is created with SWT.ON_TOP and SWT.NO_FOCUS, + * do not activate the shell when the user clicks on the + * the client area or on the border or a control within the + * shell that does not take focus. + */ + Shell shell = _getShell (); + if (((shell.style & SWT.ON_TOP) != 0) && (((shell.style & SWT.NO_FOCUS) == 0) || ((style & SWT.NO_FOCUS) == 0))) { + shell.forceActive(); + } + + long /*int*/ result = 0; + // Only send DoubleClick event as regular click is handled by generic gtk_event + if (n_press == 2) { + display.clickCount = 2; + result = sendMouseEvent (SWT.MouseDoubleClick, eventButton[0], display.clickCount, 0, false, eventTime, eventRX[0], eventRY[0], false, eventState[0]) ? 0 : 1; + } + if (!shell.isDisposed ()) shell.setActiveControl (this, SWT.MouseDown); + return result; +} + +@Override +long /*int*/ gtk_gesture_release_event (long /*int*/ gesture, int n_press, double x, double y, long /*int*/ event) { + if (n_press == 1) return 0; + mouseDown = false; + + // Event fields + double [] eventX = new double [1]; + double [] eventY = new double [1]; + GDK.gdk_event_get_coords(event, eventX, eventY); + int [] eventButton = new int [1]; + GDK.gdk_event_get_button(event, eventButton); + int eventTime = 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); + int [] eventState = new int [1]; + GDK.gdk_event_get_state(event, eventState); + + lastInput.x = (int) eventX[0]; + lastInput.y = (int) eventY[0]; + if (containedInRegion(lastInput.x, lastInput.y)) return 0; + return sendMouseEvent (SWT.MouseUp, eventButton[0], display.clickCount, 0, false, eventTime, eventRX[0], eventRY[0], false, eventState[0]) ? 0 : 1; +} + @Override long /*int*/ gtk_button_press_event (long /*int*/ widget, long /*int*/ event) { return gtk_button_press_event (widget, event, true); 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 d073f2cf0a..2d9f05b41f 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 @@ -129,9 +129,11 @@ public class Display extends Device { long /*int*/ eventProc, windowProc2, windowProc3, windowProc4, windowProc5, windowProc6; long /*int*/ snapshotDrawProc; long /*int*/ keyPressReleaseProc, focusProc, enterMotionScrollProc, leaveProc; + long /*int*/ gesturePressReleaseProc; Callback windowCallback2, windowCallback3, windowCallback4, windowCallback5, windowCallback6; Callback snapshotDraw; Callback keyPressReleaseCallback, focusCallback, enterMotionScrollCallback, leaveCallback; + Callback gesturePressReleaseCallback; EventTable eventTable, filterTable; static String APP_NAME = "SWT"; //$NON-NLS-1$ static String APP_VERSION = ""; //$NON-NLS-1$ @@ -3644,6 +3646,14 @@ void initializeCallbacks () { closuresProc [Widget.MOTION] = enterMotionScrollProc; closuresProc [Widget.SCROLL] = enterMotionScrollProc; + gesturePressReleaseCallback = new Callback (this, "gesturePressReleaseProc", long.class, new Type[] { + long.class, int.class, double.class, double.class, long.class}); //$NON-NLS-1$ + gesturePressReleaseProc = gesturePressReleaseCallback.getAddress(); + if (gesturePressReleaseProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS); + + closuresProc [Widget.GESTURE_PRESSED] = gesturePressReleaseProc; + closuresProc [Widget.GESTURE_RELEASED] = gesturePressReleaseProc; + leaveCallback = new Callback (this, "leaveProc", long.class, new Type[] { long.class, long.class}); //$NON-NLS-1$ leaveProc = leaveCallback.getAddress (); @@ -4662,6 +4672,8 @@ void releaseDisplay () { enterMotionScrollProc = 0; leaveCallback.dispose(); leaveProc = 0; + gesturePressReleaseCallback.dispose(); + gesturePressReleaseProc = 0; } /* Dispose checkIfEvent callback */ @@ -5997,6 +6009,13 @@ long /*int*/ keyPressReleaseProc (long /*int*/ controller, int keyval, int keyco return widget.keyPressReleaseProc(handle, keyval, keycode, state, user_data); } +long /*int*/ gesturePressReleaseProc (long /*int*/ gesture, int n_press, double x, double y, long /*int*/ user_data) { + long /*int*/ handle = GTK.gtk_event_controller_get_widget(gesture); + Widget widget = getWidget (handle); + if (widget == null) return 0; + return widget.getsurePressReleaseProc (gesture, n_press, x, y, user_data); +} + long /*int*/ leaveProc (long /*int*/ controller, long /*int*/ user_data) { long /*int*/ handle = GTK.gtk_event_controller_get_widget(controller); Widget widget = getWidget (handle); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java index a45d3560f4..e16aaa3ae0 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java @@ -892,6 +892,20 @@ long /*int*/ gtk_button_press_event (long /*int*/ widget, long /*int*/ event) { } @Override +long /*int*/ gtk_gesture_press_event (long /*int*/ gesture, int n_press, double x, double y, long /*int*/ event) { + if (n_press == 1) return 0; + long /*int*/ widget = GTK.gtk_event_controller_get_widget(gesture); + long /*int*/ result = gtk_button_press_event (widget, event); + + if (n_press == 2 && rowActivated) { + sendTreeDefaultSelection (); + rowActivated = false; + } + + return result; +} + +@Override long /*int*/ gtk_row_activated (long /*int*/ tree, long /*int*/ path, long /*int*/ column) { rowActivated = true; return 0; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java index 20015d028d..c75fd7f313 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java @@ -2096,6 +2096,19 @@ long /*int*/ gtk_button_press_event (long /*int*/ widget, long /*int*/ event) { } @Override +long /*int*/ gtk_gesture_press_event (long /*int*/ gesture, int n_press, double x, double y, long /*int*/ event) { + if (n_press == 1) return 0; + long /*int*/ widget = GTK.gtk_event_controller_get_widget(gesture); + long /*int*/ result = gtk_button_press_event (widget, event); + + if (n_press == 2 && rowActivated) { + sendTreeDefaultSelection (); + rowActivated = false; + } + return result; +} + +@Override long /*int*/ gtk_row_activated (long /*int*/ tree, long /*int*/ path, long /*int*/ column) { rowActivated = true; return 0; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TrayItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TrayItem.java index aaf48d9ff7..8ca4c509fa 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TrayItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TrayItem.java @@ -293,6 +293,19 @@ long /*int*/ gtk_button_press_event (long /*int*/ widget, long /*int*/ event) { } @Override +long /*int*/ gtk_gesture_press_event (long /*int*/ gesture, int n_press, double x, double y, long /*int*/ event) { + if (n_press == 1) return 0; + long /*int*/ widget = GTK.gtk_event_controller_get_widget(gesture); + long /*int*/ result = gtk_button_press_event (widget, event); + + if (n_press == 2) { + sendSelectionEvent (SWT.DefaultSelection); + } + + return result; +} + +@Override long /*int*/ gtk_size_allocate (long /*int*/ widget, long /*int*/ allocation) { return 0; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java index 85de32f6f8..af9216a56c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java @@ -2162,6 +2162,20 @@ long /*int*/ gtk_button_press_event (long /*int*/ widget, long /*int*/ event) { } @Override +long /*int*/ gtk_gesture_press_event (long /*int*/ gesture, int n_press, double x, double y, long /*int*/ event) { + if (n_press == 1) return 0; + long /*int*/ widget = GTK.gtk_event_controller_get_widget(gesture); + long /*int*/ result = gtk_button_press_event (widget, event); + + if (n_press == 2 && rowActivated) { + sendTreeDefaultSelection (); + rowActivated = false; + } + return result; +} + + +@Override long /*int*/ gtk_row_activated (long /*int*/ tree, long /*int*/ path, long /*int*/ column) { rowActivated = true; return 0; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java index 1c20e79b5d..21cccef3f5 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java @@ -232,7 +232,9 @@ public abstract class Widget { static final int MOTION = 97; static final int MOTION_INVERSE = 98; static final int CLOSE_REQUEST = 99; - static final int LAST_SIGNAL = 100; + static final int GESTURE_PRESSED = 100; + static final int GESTURE_RELEASED = 101; + static final int LAST_SIGNAL = 102; static final String IS_ACTIVE = "org.eclipse.swt.internal.control.isactive"; //$NON-NLS-1$ static final String KEY_CHECK_SUBWINDOW = "org.eclipse.swt.internal.control.checksubwindow"; //$NON-NLS-1$ @@ -703,6 +705,14 @@ long /*int*/ gtk_button_release_event (long /*int*/ widget, long /*int*/ event) return 0; } +long /*int*/ gtk_gesture_press_event (long /*int*/ gesture, int n_press, double x, double y, long /*int*/ event) { + return 0; +} + +long /*int*/ gtk_gesture_release_event (long /*int*/ gesture, int n_press, double x, double y, long /*int*/ event) { + return 0; +} + long /*int*/ gtk_changed (long /*int*/ widget) { return 0; } @@ -2104,6 +2114,21 @@ long /*int*/ keyPressReleaseProc (long /*int*/ handle, int keyval, int keycode, return result; } +long /*int*/ getsurePressReleaseProc (long /*int*/ gesture, int n_press, double x, double y, long /*int*/ user_data) { + long /*int*/ event = GTK.gtk_get_current_event(); + long /*int*/ result = 0; + switch ((int)/*64*/user_data) { + case GESTURE_PRESSED: + result = gtk_gesture_press_event(gesture, n_press, x, y, event); + break; + case GESTURE_RELEASED: + result = gtk_gesture_release_event(gesture, n_press, x, y, event); + break; + } + gdk_event_free(event); + return result; +} + long /*int*/ leaveProc (long /*int*/ handle, long /*int*/ user_data) { long /*int*/ event = GTK.gtk_get_current_event(); long /*int*/ result = 0; |