Skip to content

Commit 1119bac

Browse files
ptzieglerakurtakov
authored andcommitted
[GTK4] Manage propagation for gesture events and fix popup menus
For e.g. the text widget, a default pop-up menu if provided by GTK and activated, unless a custom menu is set within SWT. To avoid both menus being shown at the same time, the event must be consumed when showing the SWT menu. In GTK3, this is done by returning TRUE in the callback method, which is no longer possible in GTK4. Instead, the event needs to be marked as "claimed" via gtk_gesture_set_sequence_state(), to prevent other, native listeners from processing it as well. To do so, the gtk_gesture_press_event() and gtk_gesture_release_event() have been adapted to now return an integer, which may be one of the following values: - GTK_EVENT_SEQUENCE_NONE - GTK_EVENT_SEQUENCE_CLAIMED - GTK_EVENT_SEQUENCE_DENIED For example, the value should be GTK_EVENT_SEQUENCE_CLAIMED after the menu is shown. Note: It is not possible to always claim an event as "claimed", as it would then prevent the default value from being shown at all, even if no SWT menu is set. Additionally, the check for whether a menu can be shown has been inverted ((state & MENU) != 0), to match the GTK3 logic. Because this bit is always set, this effectively stops all SWT menus from being shown.
1 parent e218c17 commit 1119bac

File tree

12 files changed

+113
-33
lines changed

12 files changed

+113
-33
lines changed

bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c

+24
Original file line numberDiff line numberDiff line change
@@ -1362,6 +1362,18 @@ JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1gesture_1drag_1new)
13621362
}
13631363
#endif
13641364

1365+
#ifndef NO_gtk_1gesture_1get_1last_1updated_1sequence
1366+
JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1gesture_1get_1last_1updated_1sequence)
1367+
(JNIEnv *env, jclass that, jlong arg0)
1368+
{
1369+
jlong rc = 0;
1370+
GTK4_NATIVE_ENTER(env, that, gtk_1gesture_1get_1last_1updated_1sequence_FUNC);
1371+
rc = (jlong)gtk_gesture_get_last_updated_sequence((GtkGesture *)arg0);
1372+
GTK4_NATIVE_EXIT(env, that, gtk_1gesture_1get_1last_1updated_1sequence_FUNC);
1373+
return rc;
1374+
}
1375+
#endif
1376+
13651377
#ifndef NO_gtk_1gesture_1rotate_1new
13661378
JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1gesture_1rotate_1new)
13671379
(JNIEnv *env, jclass that)
@@ -1374,6 +1386,18 @@ JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1gesture_1rotate_1new)
13741386
}
13751387
#endif
13761388

1389+
#ifndef NO_gtk_1gesture_1set_1sequence_1state
1390+
JNIEXPORT jboolean JNICALL GTK4_NATIVE(gtk_1gesture_1set_1sequence_1state)
1391+
(JNIEnv *env, jclass that, jlong arg0, jlong arg1, jint arg2)
1392+
{
1393+
jboolean rc = 0;
1394+
GTK4_NATIVE_ENTER(env, that, gtk_1gesture_1set_1sequence_1state_FUNC);
1395+
rc = (jboolean)gtk_gesture_set_sequence_state((GtkGesture *)arg0, (GdkEventSequence *)arg1, (GtkEventSequenceState)arg2);
1396+
GTK4_NATIVE_EXIT(env, that, gtk_1gesture_1set_1sequence_1state_FUNC);
1397+
return rc;
1398+
}
1399+
#endif
1400+
13771401
#ifndef NO_gtk_1gesture_1zoom_1new
13781402
JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1gesture_1zoom_1new)
13791403
(JNIEnv *env, jclass that)

bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h

+2
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ typedef enum {
115115
gtk_1frame_1set_1child_FUNC,
116116
gtk_1gesture_1click_1new_FUNC,
117117
gtk_1gesture_1drag_1new_FUNC,
118+
gtk_1gesture_1get_1last_1updated_1sequence_FUNC,
118119
gtk_1gesture_1rotate_1new_FUNC,
120+
gtk_1gesture_1set_1sequence_1state_FUNC,
119121
gtk_1gesture_1zoom_1new_FUNC,
120122
gtk_1hsv_1to_1rgb_FUNC,
121123
gtk_1icon_1paintable_1get_1file_FUNC,

bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2021, 2024 Syntevo and others.
2+
* Copyright (c) 2021, 2025 Syntevo and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -22,6 +22,10 @@ public class GTK4 {
2222

2323
public static final int GTK_POPOVER_MENU_NESTED = 1 << 0;
2424

25+
public static final int GTK_EVENT_SEQUENCE_NONE = 0;
26+
public static final int GTK_EVENT_SEQUENCE_CLAIMED = 1;
27+
public static final int GTK_EVENT_SEQUENCE_DENIED = 2;
28+
2529
/**
2630
* @param context cast=(GtkIMContext *)
2731
* @param event cast=(GdkEvent *)
@@ -830,4 +834,16 @@ public class GTK4 {
830834

831835
public static final native long gtk_gesture_drag_new();
832836

837+
/**
838+
* @param gesture cast=(GtkGesture *)
839+
* @param sequence cast=(GdkEventSequence *)
840+
* @param state cast=(GtkEventSequenceState)
841+
*/
842+
public static final native boolean gtk_gesture_set_sequence_state(long gesture, long sequence, int state);
843+
844+
/**
845+
* @param gesture cast=(GtkGesture *)
846+
*/
847+
public static final native long gtk_gesture_get_last_updated_sequence(long gesture);
848+
833849
}

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java

+23-8
Original file line numberDiff line numberDiff line change
@@ -3406,28 +3406,38 @@ void gtk_style_context_get_border (long context, int state, GtkBorder padding) {
34063406
* Handling multi-press event on GTK4
34073407
*/
34083408
@Override
3409-
void gtk_gesture_press_event (long gesture, int n_press, double x, double y, long event) {
3409+
int gtk_gesture_press_event (long gesture, int n_press, double x, double y, long event) {
34103410
mouseDown = true;
34113411

34123412
int eventButton = GDK.gdk_button_event_get_button(event);
34133413
int eventTime = GDK.gdk_event_get_time(event);
34143414
int eventState = GDK.gdk_event_get_modifier_state(event);
3415+
int result = GTK4.GTK_EVENT_SEQUENCE_NONE;
34153416

34163417
display.clickCount = n_press;
34173418
if (n_press == 1) {
3418-
sendMouseEvent(SWT.MouseDown, eventButton, n_press, 0, false, eventTime, x, y, false, eventState);
3419-
if ((state & MENU) == 0) {
3419+
boolean cancelled = sendMouseEvent(SWT.MouseDown, eventButton, n_press, 0, false, eventTime, x, y, false, eventState);
3420+
if (!cancelled) {
3421+
result = GTK4.GTK_EVENT_SEQUENCE_CLAIMED;
3422+
}
3423+
if ((state & MENU) != 0) {
34203424
if (eventButton == 3) {
3421-
showMenu ((int)x, (int)y);
3425+
if (showMenu ((int)x, (int)y)) {
3426+
result = GTK4.GTK_EVENT_SEQUENCE_CLAIMED;
3427+
}
34223428
}
34233429
}
34243430
} else if (n_press == 2) {
3425-
sendMouseEvent(SWT.MouseDoubleClick, eventButton, n_press, 0, false, eventTime, x, y, false, eventState);
3431+
boolean cancelled = sendMouseEvent(SWT.MouseDoubleClick, eventButton, n_press, 0, false, eventTime, x, y, false, eventState);
3432+
if (!cancelled) {
3433+
result = GTK4.GTK_EVENT_SEQUENCE_CLAIMED;
3434+
}
34263435
}
3436+
return result;
34273437
}
34283438

34293439
@Override
3430-
void gtk_gesture_release_event (long gesture, int n_press, double x, double y, long event) {
3440+
int gtk_gesture_release_event (long gesture, int n_press, double x, double y, long event) {
34313441
mouseDown = false;
34323442

34333443
double [] eventX = new double [1];
@@ -3440,8 +3450,13 @@ void gtk_gesture_release_event (long gesture, int n_press, double x, double y, l
34403450

34413451
lastInput.x = (int) eventX[0];
34423452
lastInput.y = (int) eventY[0];
3443-
if (containedInRegion(lastInput.x, lastInput.y)) return;
3444-
sendMouseEvent(SWT.MouseUp, eventButton, display.clickCount, 0, false, eventTime, 0, 0, false, eventState);
3453+
if (containedInRegion(lastInput.x, lastInput.y)) return GTK4.GTK_EVENT_SEQUENCE_NONE;
3454+
boolean cancelled = sendMouseEvent(SWT.MouseUp, eventButton, display.clickCount, 0, false, eventTime, 0, 0, false, eventState);
3455+
int result = GTK4.GTK_EVENT_SEQUENCE_NONE;
3456+
if (!cancelled) {
3457+
result = GTK4.GTK_EVENT_SEQUENCE_CLAIMED;
3458+
}
3459+
return result;
34453460
}
34463461

34473462
@Override

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/DateTime.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -2222,7 +2222,7 @@ long gtk_button_release_event (long widget, long event) {
22222222
}
22232223

22242224
@Override
2225-
void gtk_gesture_release_event(long gesture, int n_press, double x, double y, long event) {
2225+
int gtk_gesture_release_event(long gesture, int n_press, double x, double y, long event) {
22262226
if (isDate() || isTime()) {
22272227
int button = GTK.gtk_gesture_single_get_current_button(gesture);
22282228

@@ -2231,7 +2231,7 @@ void gtk_gesture_release_event(long gesture, int n_press, double x, double y, lo
22312231
}
22322232
}
22332233

2234-
super.gtk_gesture_release_event(gesture, n_press, x, y, event);
2234+
return super.gtk_gesture_release_event(gesture, n_press, x, y, event);
22352235
}
22362236

22372237
/**

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -905,14 +905,16 @@ long gtk_button_press_event (long widget, long event) {
905905
}
906906

907907
@Override
908-
void gtk_gesture_press_event (long gesture, int n_press, double x, double y, long event) {
909-
if (n_press == 1) return;
910-
super.gtk_gesture_press_event(gesture, n_press, x, y, event);
908+
int gtk_gesture_press_event (long gesture, int n_press, double x, double y, long event) {
909+
if (n_press == 1) return GTK4.GTK_EVENT_SEQUENCE_NONE;
910+
int result = super.gtk_gesture_press_event(gesture, n_press, x, y, event);
911911

912912
if (n_press == 2 && rowActivated) {
913913
sendTreeDefaultSelection ();
914914
rowActivated = false;
915915
}
916+
917+
return result;
916918
}
917919

918920
@Override

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Sash.java

+11-7
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,11 @@ void createHandle(int index) {
170170
}
171171

172172
@Override
173-
void gtk_gesture_press_event(long gesture, int n_press, double x, double y, long event) {
174-
super.gtk_gesture_press_event(gesture, n_press, x, y, event);
173+
int gtk_gesture_press_event(long gesture, int n_press, double x, double y, long event) {
174+
int result = super.gtk_gesture_press_event(gesture, n_press, x, y, event);
175175

176176
int eventButton = GDK.gdk_button_event_get_button(event);
177-
if (eventButton != 1 || n_press != 1) return;
177+
if (eventButton != 1 || n_press != 1) return result;
178178

179179
startX = (int)x;
180180
startY = (int)y;
@@ -197,20 +197,24 @@ void gtk_gesture_press_event(long gesture, int n_press, double x, double y, long
197197
}
198198
if ((parent.style & SWT.MIRRORED) != 0) jEvent.x = DPIUtil.autoScaleDown(parent.getClientWidth() - width) - jEvent.x;
199199
sendSelectionEvent(SWT.Selection, jEvent, true);
200-
if (isDisposed()) return;
200+
if (isDisposed()) return result;
201201

202202
if (jEvent.doit) {
203203
dragging = true;
204204
}
205+
206+
return result;
205207
}
206208

207209
@Override
208-
void gtk_gesture_release_event(long gesture, int n_press, double x, double y, long event) {
209-
super.gtk_gesture_release_event(gesture, n_press, x, y, event);
210+
int gtk_gesture_release_event(long gesture, int n_press, double x, double y, long event) {
211+
int result = super.gtk_gesture_release_event(gesture, n_press, x, y, event);
210212

211213
int eventButton = GDK.gdk_button_event_get_button(event);
212-
if (eventButton != 1 || !dragging) return;
214+
if (eventButton != 1 || !dragging) return result;
213215
dragging = false;
216+
217+
return result;
214218
}
215219

216220
@Override

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -2129,16 +2129,18 @@ long gtk_button_press_event (long widget, long event) {
21292129
}
21302130

21312131
@Override
2132-
void gtk_gesture_press_event (long gesture, int n_press, double x, double y, long event) {
2133-
if (n_press == 1) return;
2134-
super.gtk_gesture_press_event(gesture, n_press, x, y, event);
2132+
int gtk_gesture_press_event (long gesture, int n_press, double x, double y, long event) {
2133+
if (n_press == 1) return GTK4.GTK_EVENT_SEQUENCE_NONE;
2134+
int result = super.gtk_gesture_press_event(gesture, n_press, x, y, event);
21352135

21362136
// TODO: GTK4 replicate gtk_button_press_event functions
21372137

21382138
if (n_press == 2 && rowActivated) {
21392139
sendTreeDefaultSelection ();
21402140
rowActivated = false;
21412141
}
2142+
2143+
return result;
21422144
}
21432145

21442146
@Override

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TrayItem.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.eclipse.swt.internal.*;
2020
import org.eclipse.swt.internal.gtk.*;
2121
import org.eclipse.swt.internal.gtk3.*;
22+
import org.eclipse.swt.internal.gtk4.*;
2223

2324
/**
2425
* Instances of this class represent icons that can be placed on the
@@ -288,7 +289,7 @@ long gtk_button_press_event (long widget, long event) {
288289
}
289290

290291
@Override
291-
void gtk_gesture_press_event(long gesture, int n_press, double x, double y, long event) {
292+
int gtk_gesture_press_event(long gesture, int n_press, double x, double y, long event) {
292293
switch (n_press) {
293294
case 1: {
294295
int eventButton = GDK.gdk_button_event_get_button(event);
@@ -306,6 +307,7 @@ void gtk_gesture_press_event(long gesture, int n_press, double x, double y, long
306307
default:
307308
break;
308309
}
310+
return GTK4.GTK_EVENT_SEQUENCE_NONE;
309311
}
310312

311313
@Override

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -2318,13 +2318,15 @@ long gtk_button_press_event (long widget, long event) {
23182318
}
23192319

23202320
@Override
2321-
void gtk_gesture_press_event (long gesture, int n_press, double x, double y, long event) {
2322-
super.gtk_gesture_press_event(gesture, n_press, x, y, event);
2321+
int gtk_gesture_press_event (long gesture, int n_press, double x, double y, long event) {
2322+
int result = super.gtk_gesture_press_event(gesture, n_press, x, y, event);
23232323

23242324
if (n_press == 2 && rowActivated) {
23252325
sendTreeDefaultSelection ();
23262326
rowActivated = false;
23272327
}
2328+
2329+
return result;
23282330
}
23292331

23302332
@Override

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeColumn.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -365,10 +365,12 @@ long gtk_clicked (long widget) {
365365
}
366366

367367
@Override
368-
void gtk_gesture_press_event(long gesture, int n_press, double x, double y, long event) {
368+
int gtk_gesture_press_event(long gesture, int n_press, double x, double y, long event) {
369369
boolean doubleClick = n_press >= 2 ? true : false;
370370

371371
sendSelectionEvent(doubleClick ? SWT.DefaultSelection : SWT.Selection);
372+
373+
return GTK4.GTK_EVENT_SEQUENCE_NONE;
372374
}
373375

374376
@Override

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java

+14-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2024 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -806,7 +806,9 @@ long gtk_button_release_event (long widget, long event) {
806806
* @param y the y coordinate, in widget allocation coordinates
807807
* @param event the GdkEvent captured
808808
*/
809-
void gtk_gesture_press_event(long gesture, int n_press, double x, double y, long event) {}
809+
int gtk_gesture_press_event(long gesture, int n_press, double x, double y, long event) {
810+
return GTK4.GTK_EVENT_SEQUENCE_NONE;
811+
}
810812

811813
/**
812814
* @param gesture the corresponding controller responsible for capturing the event
@@ -815,7 +817,9 @@ void gtk_gesture_press_event(long gesture, int n_press, double x, double y, long
815817
* @param y the y coordinate, in widget allocation coordinates
816818
* @param event the GdkEvent captured
817819
*/
818-
void gtk_gesture_release_event(long gesture, int n_press, double x, double y, long event) {}
820+
int gtk_gesture_release_event(long gesture, int n_press, double x, double y, long event) {
821+
return GTK4.GTK_EVENT_SEQUENCE_NONE;
822+
}
819823

820824
/**
821825
* @param controller the corresponding controller responsible for capturing the event
@@ -2531,15 +2535,20 @@ boolean keyPressReleaseProc(long controller, int keyval, int keycode, int state,
25312535

25322536
void gesturePressReleaseProc(long gesture, int n_press, double x, double y, long user_data) {
25332537
long event = GTK4.gtk_event_controller_get_current_event(gesture);
2538+
long sequence = GTK4.gtk_gesture_get_last_updated_sequence(gesture);
2539+
2540+
int result = GTK4.GTK_EVENT_SEQUENCE_NONE;
25342541

25352542
switch ((int)user_data) {
25362543
case GESTURE_PRESSED:
2537-
gtk_gesture_press_event(gesture, n_press, x, y, event);
2544+
result = gtk_gesture_press_event(gesture, n_press, x, y, event);
25382545
break;
25392546
case GESTURE_RELEASED:
2540-
gtk_gesture_release_event(gesture, n_press, x, y, event);
2547+
result = gtk_gesture_release_event(gesture, n_press, x, y, event);
25412548
break;
25422549
}
2550+
2551+
GTK4.gtk_gesture_set_sequence_state(gesture, sequence, result);
25432552
}
25442553

25452554
void leaveProc(long controller, long handle, long user_data) {

0 commit comments

Comments
 (0)