Button/ImageButton: consume touch events

Androids button consumes touch events, while GTKs button lets touch
events propagate to the parent. This previously caused some glitches
with buttons inside a CoordinatorLayout.
This commit is contained in:
Julian Winkler
2024-07-19 14:06:52 +02:00
parent c7f64cd24b
commit 23e7d32924
4 changed files with 27 additions and 0 deletions

View File

@@ -224,3 +224,27 @@ void wrapper_widget_set_background(WrapperWidget *wrapper, GdkPaintable *paintab
}
gtk_picture_set_paintable(GTK_PICTURE(wrapper->background), paintable);
}
static gboolean on_touch_event_consume(GtkEventControllerLegacy *controller, GdkEvent *event) {
switch(gdk_event_get_event_type(event)) {
case GDK_BUTTON_PRESS:
case GDK_TOUCH_BEGIN:
case GDK_BUTTON_RELEASE:
case GDK_TOUCH_END:
case GDK_MOTION_NOTIFY:
case GDK_TOUCH_UPDATE:
return TRUE;
default:
return FALSE;
}
}
// Add default on touch listener, which just consumes all events to prevent bubbling to the parent
void wrapper_widget_consume_touch_events(WrapperWidget *wrapper)
{
GtkEventController *controller = GTK_EVENT_CONTROLLER(gtk_event_controller_legacy_new());
g_signal_connect(controller, "event", G_CALLBACK(on_touch_event_consume), NULL);
gtk_widget_add_controller(GTK_WIDGET(wrapper), controller);
g_object_set_data(G_OBJECT(wrapper), "on_touch_listener", controller);
}

View File

@@ -35,6 +35,7 @@ void wrapper_widget_set_jobject(WrapperWidget *wrapper, JNIEnv *env, jobject job
void wrapper_widget_queue_draw(WrapperWidget *wrapper);
void wrapper_widget_set_layout_params(WrapperWidget *wrapper, int width, int height);
void wrapper_widget_set_background(WrapperWidget *wrapper, GdkPaintable *paintable);
void wrapper_widget_consume_touch_events(WrapperWidget *wrapper);
void _setOnTouchListener(JNIEnv *env, jobject this, GtkWidget *widget, jobject on_touch_listener);

View File

@@ -14,6 +14,7 @@ JNIEXPORT jlong JNICALL Java_android_widget_Button_native_1constructor(JNIEnv *e
GtkWidget *wrapper = g_object_ref(wrapper_widget_new());
GtkWidget *label = gtk_button_new_with_label(text);
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), label);
wrapper_widget_consume_touch_events(WRAPPER_WIDGET(wrapper)); // Android button consumes touch events
return _INTPTR(label);
}

View File

@@ -14,6 +14,7 @@ JNIEXPORT jlong JNICALL Java_android_widget_ImageButton_native_1constructor(JNIE
GtkWidget *image = gtk_picture_new_for_resource("/org/gtk/libgtk/icons/16x16/status/image-missing.png"); // show "broken image" icon
gtk_button_set_child(GTK_BUTTON(button), image);
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), button);
wrapper_widget_consume_touch_events(WRAPPER_WIDGET(wrapper)); // Android button consumes touch events
wrapper_widget_set_jobject(WRAPPER_WIDGET(wrapper), env, this);
return _INTPTR(button);