Bug 574544 - [GTK4] Focus in & focus out event not emitting
- Added gtk_widget_set_focusable
- Removed setting of propagation phase of the GtkEventControllerFocus
- Changed the focusProc callback return value from long to void
- Cleaned up drawCaret class in Canvas
- Caret snippets (74, 43) now work properly (aside from
color/cairo-related issues)
Change-Id: I2ac56fd4449f5fd05d868ea3b0ddbfbb167cb5b3
Signed-off-by: Paul D'Pong <sdamrong@redhat.com>
Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/182610
Tested-by: Platform Bot <platform-bot@eclipse.org>
Reviewed-by: Alexander Kurtakov <akurtako@redhat.com>
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c
index 31023d8..24bdf0c 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c
@@ -1126,6 +1126,16 @@
}
#endif
+#ifndef NO_gtk_1widget_1set_1focusable
+JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1widget_1set_1focusable)
+ (JNIEnv *env, jclass that, jlong arg0, jboolean arg1)
+{
+ GTK4_NATIVE_ENTER(env, that, gtk_1widget_1set_1focusable_FUNC);
+ gtk_widget_set_focusable((GtkWidget *)arg0, arg1);
+ GTK4_NATIVE_EXIT(env, that, gtk_1widget_1set_1focusable_FUNC);
+}
+#endif
+
#ifndef NO_gtk_1widget_1snapshot_1child
JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1widget_1snapshot_1child)
(JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.c
index f6e046d..73ff88e 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.c
@@ -114,6 +114,7 @@
"gtk_1widget_1get_1root",
"gtk_1widget_1measure",
"gtk_1widget_1set_1cursor",
+ "gtk_1widget_1set_1focusable",
"gtk_1widget_1snapshot_1child",
"gtk_1widget_1translate_1coordinates",
"gtk_1window_1destroy",
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h
index 4ab86b6..7001202 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h
@@ -124,6 +124,7 @@
gtk_1widget_1get_1root_FUNC,
gtk_1widget_1measure_FUNC,
gtk_1widget_1set_1cursor_FUNC,
+ gtk_1widget_1set_1focusable_FUNC,
gtk_1widget_1snapshot_1child_FUNC,
gtk_1widget_1translate_1coordinates_FUNC,
gtk_1window_1destroy_FUNC,
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java
index 421e4cc..a893af2 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java
@@ -412,6 +412,11 @@
public static final native void gtk_widget_class_add_binding_signal(long widget_class, int keyval, int mods, byte[] signal, byte[] format_string, boolean arg1, boolean arg2, boolean arg3);
/** @param widget cast=(GtkWidget *) */
public static final native boolean gtk_widget_get_receives_default(long widget);
+ /**
+ * @param widget cast=(GtkWidget *)
+ * @param focusable cast(gboolean)
+ */
+ public static final native void gtk_widget_set_focusable(long widget, boolean focusable);
/* GtkComboBox */
/** @param combo_box cast=(GtkComboBox *) */
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java
index b33ac01..24fb37f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java
@@ -194,11 +194,13 @@
return result;
}
-private void drawCaret (long widget, long cairo) {
+private void drawCaret(long widget, long cairo) {
if(this.isDisposed()) return;
if (cairo == 0) error(SWT.ERROR_NO_HANDLES);
+
if (drawFlag) {
Cairo.cairo_save(cairo);
+
if (caret.image != null && !caret.image.isDisposed() && caret.image.mask == 0) {
Cairo.cairo_set_source_rgb(cairo, 1, 1, 1);
Cairo.cairo_set_operator(cairo, Cairo.CAIRO_OPERATOR_DIFFERENCE);
@@ -225,14 +227,14 @@
int nX = caret.x;
if ((style & SWT.MIRRORED) != 0) nX = getClientWidth () - nWidth - nX;
Cairo.cairo_rectangle(cairo, nX, caret.y, nWidth, nHeight);
- }
+ }
+
Cairo.cairo_fill(cairo);
Cairo.cairo_restore(cairo);
drawFlag = false;
} else {
drawFlag = true;
- }
- return;
+ }
}
@Override
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java
index 2404889..215c8b5 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java
@@ -340,8 +340,13 @@
handle = OS.g_object_new(display.gtk_fixed_get_type(), 0);
if (handle == 0) error(SWT.ERROR_NO_HANDLES);
- if (!GTK.GTK4) GTK3.gtk_widget_set_has_window(handle, true);
- GTK.gtk_widget_set_can_focus (handle, true);
+
+ if (GTK.GTK4) {
+ GTK4.gtk_widget_set_focusable(handle, true);
+ } else {
+ GTK3.gtk_widget_set_has_window(handle, true);
+ }
+ GTK.gtk_widget_set_can_focus(handle, true);
if ((style & SWT.EMBEDDED) == 0) {
if ((state & CANVAS) != 0) {
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 c41aeb2..3bc074f 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
@@ -457,7 +457,6 @@
OS.g_signal_connect(keyController, OS.key_released, display.keyPressReleaseProc, KEY_RELEASED);
long focusController = GTK4.gtk_event_controller_focus_new();
- GTK.gtk_event_controller_set_propagation_phase(focusController, GTK.GTK_PHASE_TARGET);
GTK4.gtk_widget_add_controller(focusHandle, focusController);
OS.g_signal_connect(focusController, OS.enter, display.focusProc, FOCUS_IN);
OS.g_signal_connect(focusController, OS.leave, display.focusProc, FOCUS_OUT);
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 7a778be..6a085f6 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
@@ -3577,9 +3577,8 @@
closuresProc [Widget.KEY_PRESSED] = keyPressReleaseProc;
closuresProc [Widget.KEY_RELEASED] = keyPressReleaseProc;
- focusCallback = new Callback (this, "focusProc", long.class, new Type[] {
- long.class, long.class}); //$NON-NLS-1$
- focusProc = focusCallback.getAddress ();
+ focusCallback = new Callback (this, "focusProc", void.class, new Type[] {long.class, long.class}); //$NON-NLS-1$
+ focusProc = focusCallback.getAddress();
closuresProc [Widget.FOCUS_IN] = focusProc;
closuresProc [Widget.FOCUS_OUT] = focusProc;
@@ -6072,11 +6071,11 @@
return widget.enterMotionScrollProc(controller, handle, x, y, user_data);
}
-long focusProc (long controller, long user_data) {
+void focusProc(long controller, long user_data) {
long handle = GTK.gtk_event_controller_get_widget(controller);
- Widget widget = getWidget (handle);
- if (widget == null) return 0;
- return widget.focusProc(controller, handle, user_data);
+ Widget widget = getWidget(handle);
+
+ if (widget != null) widget.focusProc(controller, handle, user_data);
}
long keyPressReleaseProc (long controller, int keyval, int keycode, int state, long user_data) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Sash.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Sash.java
index f9b5a23..fce51ca 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Sash.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Sash.java
@@ -20,6 +20,7 @@
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.gtk.*;
import org.eclipse.swt.internal.gtk3.*;
+import org.eclipse.swt.internal.gtk4.*;
/**
* Instances of the receiver represent a selectable user interface object
@@ -145,22 +146,24 @@
handle = OS.g_object_new(display.gtk_fixed_get_type(), 0);
if (handle == 0) error(SWT.ERROR_NO_HANDLES);
- if (!GTK.GTK4) GTK3.gtk_widget_set_has_window(handle, true);
- GTK.gtk_widget_set_can_focus(handle, true);
- if ((style & SWT.VERTICAL) != 0) {
- if (GTK.GTK4) {
+ if (GTK.GTK4) {
+ GTK4.gtk_widget_set_focusable(handle, true);
+ if ((style & SWT.VERTICAL) != 0) {
defaultCursor = GDK.gdk_cursor_new_from_name("sb_h_double_arrow", 0);
} else {
- defaultCursor = GDK.gdk_cursor_new_from_name (GDK.gdk_display_get_default(), "sb_h_double_arrow");
+ defaultCursor = GDK.gdk_cursor_new_from_name("sb_v_double_arrow", 0);
}
} else {
- if (GTK.GTK4) {
- defaultCursor = GDK.gdk_cursor_new_from_name("sb_v_double_arrow", 0);
+ GTK3.gtk_widget_set_has_window(handle, true);
+ if ((style & SWT.VERTICAL) != 0) {
+ defaultCursor = GDK.gdk_cursor_new_from_name(GDK.gdk_display_get_default(), "sb_h_double_arrow");
} else {
- defaultCursor = GDK.gdk_cursor_new_from_name (GDK.gdk_display_get_default(), "sb_v_double_arrow");
+ defaultCursor = GDK.gdk_cursor_new_from_name(GDK.gdk_display_get_default(), "sb_v_double_arrow");
}
}
+
+ GTK.gtk_widget_set_can_focus(handle, true);
}
void drawBand (int x, int y, int width, int height) {
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 0755dd0..ce72b82 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
@@ -950,8 +950,8 @@
long focusController = GTK4.gtk_event_controller_focus_new();
GTK4.gtk_widget_add_controller(shellHandle, focusController);
- OS.g_signal_connect (focusController, OS.enter, display.focusProc, FOCUS_IN);
- OS.g_signal_connect (focusController, OS.leave, display.focusProc, FOCUS_OUT);
+ OS.g_signal_connect(focusController, OS.enter, display.focusProc, FOCUS_IN);
+ OS.g_signal_connect(focusController, OS.leave, display.focusProc, FOCUS_OUT);
long enterLeaveController = GTK4.gtk_event_controller_motion_new();
GTK4.gtk_widget_add_controller(shellHandle, enterLeaveController);
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 800114f..df474fb 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
@@ -2196,20 +2196,17 @@
return result;
}
-long focusProc(long controller, long handle, long user_data) {
- long result = 0;
+void focusProc(long controller, long handle, long user_data) {
long event = GTK4.gtk_event_controller_get_current_event(controller);
switch ((int)user_data) {
case FOCUS_IN:
- result = gtk_focus_in_event(handle, event);
+ gtk_focus_in_event(handle, event);
break;
case FOCUS_OUT:
- result = gtk_focus_out_event(handle, event);
+ gtk_focus_out_event(handle, event);
break;
}
-
- return result;
}
long keyPressReleaseProc(long controller, long handle, int keyval, int keycode, int state, long user_data) {