gtktext: Make sure input method sees focus in
authorGuido Günther <agx@sigxcpu.org>
Wed, 19 Jan 2022 13:40:43 +0000 (14:40 +0100)
committerGuido Günther <agx@sigxcpu.org>
Tue, 25 Jan 2022 10:15:29 +0000 (11:15 +0100)
Currently when the widget is realized after the focus in event the input
method isn't activated as enable is never sent. The call trace is

  gtk_text_focus_changed ->
    gtk_im_context_focus_in ->
      gtk_im_context_wayland_focus_in

which returns early as self->widget is NULL since it's set up in
gtk_text_realize() via gtk_im_context_set_client_widget(). Handle that
case by invoking gtk_im_context_focus_in() from gtk_text_realize() too.

A case where the above happens is a GtkSearchEntry in a GtkSearchBar.
E.g. in gtk4-demo when starting the demo and then hitting the search
button right away.

gtk/gtktext.c

index b4767f7c1325927b8c93fe1e1e9572c4e82e0883..a9aab3405fcd87cf5bec49280543fa1a708d3457 100644 (file)
@@ -2211,6 +2211,18 @@ gtk_text_unmap (GtkWidget *widget)
   GTK_WIDGET_CLASS (gtk_text_parent_class)->unmap (widget);
 }
 
+static void
+gtk_text_im_set_focus_in (GtkText *self)
+{
+  GtkTextPrivate *priv = gtk_text_get_instance_private (self);
+
+  if (!priv->editable)
+    return;
+
+  gtk_text_schedule_im_reset (self);
+  gtk_im_context_focus_in (priv->im_context);
+}
+
 static void
 gtk_text_realize (GtkWidget *widget)
 {
@@ -2220,6 +2232,8 @@ gtk_text_realize (GtkWidget *widget)
   GTK_WIDGET_CLASS (gtk_text_parent_class)->realize (widget);
 
   gtk_im_context_set_client_widget (priv->im_context, widget);
+  if (gtk_widget_is_focus (GTK_WIDGET (self)))
+    gtk_text_im_set_focus_in (self);
 
   gtk_text_adjust_scroll (self);
   gtk_text_update_primary_selection (self);
@@ -3245,12 +3259,7 @@ gtk_text_focus_changed (GtkEventControllerFocus *controller,
         g_signal_connect (keyboard, "notify::direction",
                           G_CALLBACK (direction_changed), self);
 
-      if (priv->editable)
-        {
-          gtk_text_schedule_im_reset (self);
-          gtk_im_context_focus_in (priv->im_context);
-        }
-
+      gtk_text_im_set_focus_in (self);
       gtk_text_reset_blink_time (self);
     }
   else /* Focus out */