imwayland: Connect OSK activating gesture to parent widget on editables
authorCarlos Garnacho <carlosg@gnome.org>
Wed, 6 Apr 2022 09:01:01 +0000 (11:01 +0200)
committerCarlos Garnacho <carlosg@gnome.org>
Wed, 6 Apr 2022 11:52:05 +0000 (13:52 +0200)
The gesture as connected currently on the child GtkText is easily overridden
by the parent editables (and gently done so in the attempt to consume all
clicks).

Connect this gesture to the parent editable widget in these cases, so the
gesture can cohabit with the click-consuming one. It's not part of the same
group, but it won't be abruptly cancelled.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4795
gtk/gtkimcontextwayland.c

index 486435f9e0ef9b151d40f0d9e3c241d142ce43c8..7e8d0e721c6f3a2ba46745692decdd3a645da1b9 100644 (file)
@@ -71,6 +71,7 @@ struct _GtkIMContextWayland
 {
   GtkIMContextSimple parent_instance;
   GtkWidget *widget;
+  GtkWidget *controller_widget;
 
   GtkGesture *gesture;
   double press_x;
@@ -555,16 +556,21 @@ gtk_im_context_wayland_set_client_widget (GtkIMContext *context,
     return;
 
   if (context_wayland->widget)
+    gtk_im_context_wayland_focus_out (context);
+
+  if (context_wayland->controller_widget)
     {
-      gtk_im_context_wayland_focus_out (context);
-      gtk_widget_remove_controller (context_wayland->widget, GTK_EVENT_CONTROLLER (context_wayland->gesture));
+      gtk_widget_remove_controller (context_wayland->controller_widget,
+                                    GTK_EVENT_CONTROLLER (context_wayland->gesture));
       context_wayland->gesture = NULL;
+      g_clear_object (&context_wayland->controller_widget);
     }
 
   g_set_object (&context_wayland->widget, widget);
 
   if (widget)
     {
+      GtkWidget *parent;
       GtkGesture *gesture;
 
       gesture = gtk_gesture_click_new ();
@@ -575,7 +581,18 @@ gtk_im_context_wayland_set_client_widget (GtkIMContext *context,
                         G_CALLBACK (pressed_cb), context);
       g_signal_connect (gesture, "released",
                         G_CALLBACK (released_cb), context);
-      gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (gesture));
+
+      parent = gtk_widget_get_parent (widget);
+
+      if (parent &&
+          GTK_IS_EDITABLE (widget) &&
+          GTK_IS_EDITABLE (parent))
+        g_set_object (&context_wayland->controller_widget, parent);
+      else
+        g_set_object (&context_wayland->controller_widget, widget);
+
+      gtk_widget_add_controller (context_wayland->controller_widget,
+                                 GTK_EVENT_CONTROLLER (gesture));
       context_wayland->gesture = gesture;
     }
 }