[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1019453: ibus: IBus doesn't work correctly in apps that don't support surrounding text



My fault. I created a local package with the upstream changes and fell in the ibus link trap - the upstream repo uses links for ibusimcontext.c for gtk2/gtk3/gtk4 whereas the source package uses three different files. When I imported the patches I forgot to make the changes for gtk3 and gtk4. With the correct patches that match upstream everything works as expected. 😁

Attached are patches for the three related upstream commits (I tested with all three commits, although probably only 0002 would be needed for this bug).

Gunnar Hjalmarsson wrote on 2022-09-27 15:53:
On 2022-09-27 15:16, Eberhard Beilharz wrote:
AFAICT the problem in Firefox has been fixed in Firefox 99.

In that case, did Takao Fujiwara misunderstand it when he wrote in the 781119be commit message that "the special issue should be fixed in firefox"?

I'll report back once I have an idea what would make sense regarding
patching ibus.

Great; I'll await your next step then.

From ddead515d9d53fc692af252f610b009660494e21 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Wed, 21 Sep 2022 21:08:33 +0900
Subject: [PATCH 3/3] client/gtk2: Update surrounding text properties by focus
 in

ibus_input_context_set_surrounding_text() should be succeeded
if input contexts are different so that ibus engines can
update surrounding text properties with focus in event.

When an input context is created newly, RequireSurroundingText D-Bus
signal could not be received yet and set_surrounding_text() is failed.
Now "require-surrounding-text" signal is added to IBusInputContext
and clients can call set_surrounding_text() later.

BUG=https://github.com/ibus/ibus/issues/2423
---
 client/gtk2/ibusimcontext.c | 25 +++++++++++++++++++++++++
 src/ibusinputcontext.c      | 29 ++++++++++++++++++++++++++++-
 2 files changed, 53 insertions(+), 1 deletion(-)

--- a/client/gtk2/ibusimcontext.c
+++ b/client/gtk2/ibusimcontext.c
@@ -70,6 +70,7 @@
 #endif
 
     IBusInputContext *ibuscontext;
+    IBusInputContext *ibuscontext_needs_surrounding;
 
     /* preedit status */
     gchar           *preedit_string;
@@ -985,6 +986,7 @@
     ibusimcontext->cursor_area.height = 0;
 
     ibusimcontext->ibuscontext = NULL;
+    ibusimcontext->ibuscontext_needs_surrounding = NULL;
     ibusimcontext->has_focus = FALSE;
     ibusimcontext->time = GDK_CURRENT_TIME;
 #ifdef ENABLE_SURROUNDING
@@ -2184,6 +2186,18 @@
 }
 
 static void
+_ibus_context_require_surrounding_text_cb (IBusInputContext *ibuscontext,
+                                           IBusIMContext    *ibusimcontext)
+{
+    IDEBUG ("%s", __FUNCTION__);
+    g_assert (ibusimcontext->ibuscontext == ibuscontext);
+    if (ibusimcontext->ibuscontext_needs_surrounding == ibuscontext) {
+        _request_surrounding_text (ibusimcontext);
+        ibusimcontext->ibuscontext_needs_surrounding = NULL;
+    }
+}
+
+static void
 _ibus_context_destroy_cb (IBusInputContext *ibuscontext,
                           IBusIMContext    *ibusimcontext)
 {
@@ -2249,6 +2263,11 @@
                           "hide-preedit-text",
                           G_CALLBACK (_ibus_context_hide_preedit_text_cb),
                           ibusimcontext);
+        g_signal_connect (
+                ibusimcontext->ibuscontext,
+                "require-surrounding-text",
+                G_CALLBACK (_ibus_context_require_surrounding_text_cb),
+                ibusimcontext);
         g_signal_connect (ibusimcontext->ibuscontext, "destroy",
                           G_CALLBACK (_ibus_context_destroy_cb),
                           ibusimcontext);
@@ -2265,6 +2284,12 @@
 
             ibus_input_context_focus_in (ibusimcontext->ibuscontext);
             _set_cursor_location_internal (ibusimcontext);
+            if (ibus_input_context_needs_surrounding_text (
+                        ibusimcontext->ibuscontext)) {
+                _request_surrounding_text (ibusimcontext);
+            } else {
+                ibusimcontext->ibuscontext_needs_surrounding = ibusimcontext->ibuscontext;
+            }
         }
 
         if (!g_queue_is_empty (ibusimcontext->events_queue)) {
--- a/client/gtk3/ibusimcontext.c
+++ b/client/gtk3/ibusimcontext.c
@@ -70,6 +70,7 @@
 #endif
 
     IBusInputContext *ibuscontext;
+    IBusInputContext *ibuscontext_needs_surrounding;
 
     /* preedit status */
     gchar           *preedit_string;
@@ -985,6 +986,7 @@
     ibusimcontext->cursor_area.height = 0;
 
     ibusimcontext->ibuscontext = NULL;
+    ibusimcontext->ibuscontext_needs_surrounding = NULL;
     ibusimcontext->has_focus = FALSE;
     ibusimcontext->time = GDK_CURRENT_TIME;
 #ifdef ENABLE_SURROUNDING
@@ -2184,6 +2186,18 @@
 }
 
 static void
+_ibus_context_require_surrounding_text_cb (IBusInputContext *ibuscontext,
+                                           IBusIMContext    *ibusimcontext)
+{
+    IDEBUG ("%s", __FUNCTION__);
+    g_assert (ibusimcontext->ibuscontext == ibuscontext);
+    if (ibusimcontext->ibuscontext_needs_surrounding == ibuscontext) {
+        _request_surrounding_text (ibusimcontext);
+        ibusimcontext->ibuscontext_needs_surrounding = NULL;
+    }
+}
+
+static void
 _ibus_context_destroy_cb (IBusInputContext *ibuscontext,
                           IBusIMContext    *ibusimcontext)
 {
@@ -2249,6 +2263,11 @@
                           "hide-preedit-text",
                           G_CALLBACK (_ibus_context_hide_preedit_text_cb),
                           ibusimcontext);
+        g_signal_connect (
+                ibusimcontext->ibuscontext,
+                "require-surrounding-text",
+                G_CALLBACK (_ibus_context_require_surrounding_text_cb),
+                ibusimcontext);
         g_signal_connect (ibusimcontext->ibuscontext, "destroy",
                           G_CALLBACK (_ibus_context_destroy_cb),
                           ibusimcontext);
@@ -2265,6 +2284,12 @@
 
             ibus_input_context_focus_in (ibusimcontext->ibuscontext);
             _set_cursor_location_internal (ibusimcontext);
+            if (ibus_input_context_needs_surrounding_text (
+                        ibusimcontext->ibuscontext)) {
+                _request_surrounding_text (ibusimcontext);
+            } else {
+                ibusimcontext->ibuscontext_needs_surrounding = ibusimcontext->ibuscontext;
+            }
         }
 
         if (!g_queue_is_empty (ibusimcontext->events_queue)) {
--- a/client/gtk4/ibusimcontext.c
+++ b/client/gtk4/ibusimcontext.c
@@ -70,6 +70,7 @@
 #endif
 
     IBusInputContext *ibuscontext;
+    IBusInputContext *ibuscontext_needs_surrounding;
 
     /* preedit status */
     gchar           *preedit_string;
@@ -985,6 +986,7 @@
     ibusimcontext->cursor_area.height = 0;
 
     ibusimcontext->ibuscontext = NULL;
+    ibusimcontext->ibuscontext_needs_surrounding = NULL;
     ibusimcontext->has_focus = FALSE;
     ibusimcontext->time = GDK_CURRENT_TIME;
 #ifdef ENABLE_SURROUNDING
@@ -2184,6 +2186,18 @@
 }
 
 static void
+_ibus_context_require_surrounding_text_cb (IBusInputContext *ibuscontext,
+                                           IBusIMContext    *ibusimcontext)
+{
+    IDEBUG ("%s", __FUNCTION__);
+    g_assert (ibusimcontext->ibuscontext == ibuscontext);
+    if (ibusimcontext->ibuscontext_needs_surrounding == ibuscontext) {
+        _request_surrounding_text (ibusimcontext);
+        ibusimcontext->ibuscontext_needs_surrounding = NULL;
+    }
+}
+
+static void
 _ibus_context_destroy_cb (IBusInputContext *ibuscontext,
                           IBusIMContext    *ibusimcontext)
 {
@@ -2249,6 +2263,11 @@
                           "hide-preedit-text",
                           G_CALLBACK (_ibus_context_hide_preedit_text_cb),
                           ibusimcontext);
+        g_signal_connect (
+                ibusimcontext->ibuscontext,
+                "require-surrounding-text",
+                G_CALLBACK (_ibus_context_require_surrounding_text_cb),
+                ibusimcontext);
         g_signal_connect (ibusimcontext->ibuscontext, "destroy",
                           G_CALLBACK (_ibus_context_destroy_cb),
                           ibusimcontext);
@@ -2265,6 +2284,12 @@
 
             ibus_input_context_focus_in (ibusimcontext->ibuscontext);
             _set_cursor_location_internal (ibusimcontext);
+            if (ibus_input_context_needs_surrounding_text (
+                        ibusimcontext->ibuscontext)) {
+                _request_surrounding_text (ibusimcontext);
+            } else {
+                ibusimcontext->ibuscontext_needs_surrounding = ibusimcontext->ibuscontext;
+            }
         }
 
         if (!g_queue_is_empty (ibusimcontext->events_queue)) {
--- a/src/ibusinputcontext.c
+++ b/src/ibusinputcontext.c
@@ -2,7 +2,7 @@
 /* vim:set et sts=4: */
 /* ibus - The Input Bus
  * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2018-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
+ * Copyright (C) 2018-2022 Takao Fujiwara <takao.fujiwara1@gmail.com>
  * Copyright (C) 2008-2019 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
@@ -55,6 +55,7 @@
     CURSOR_DOWN_LOOKUP_TABLE,
     REGISTER_PROPERTIES,
     UPDATE_PROPERTY,
+    REQUIRE_SURROUNDING_TEXT,
     LAST_SIGNAL,
 };
 
@@ -488,6 +489,21 @@
             1,
             IBUS_TYPE_PROPERTY);
 
+    /**
+     * IBusInputContext::require-surrounding-text:
+     * @context: An IBusInputContext.
+     *
+     * Emitted to receive the RequireSurroundingText signal from the daemon.
+     */
+    context_signals[REQUIRE_SURROUNDING_TEXT] =
+        g_signal_new (I_("require-surrounding-text"),
+            G_TYPE_FROM_CLASS (class),
+            G_SIGNAL_RUN_LAST,
+            0,
+            NULL, NULL,
+            _ibus_marshal_VOID__VOID,
+            G_TYPE_NONE, 0);
+
     text_empty = ibus_text_new_from_static_string ("");
     g_object_ref_sink (text_empty);
 }
@@ -735,6 +751,7 @@
 
     if (g_strcmp0 (signal_name, "RequireSurroundingText") == 0) {
         priv->needs_surrounding_text = TRUE;
+        g_signal_emit (context, context_signals[REQUIRE_SURROUNDING_TEXT], 0);
         return;
     }
 
@@ -1116,9 +1133,19 @@
 
     priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (context);
 
+    /* This API should send "SetSurroundingText" D-Bus method when
+     * input contexts are switched between tabs in a text application
+     * so that engines can receive the updated surrounding texts after
+     * focus-in events happen.
+     *
+     * GNOME shell uses a single input context and the address of the input
+     * contexts are always same. So check the address of texts if the input
+     * contexts on applications are switched.
+     */
     if (cursor_pos != priv->surrounding_cursor_pos ||
         anchor_pos != priv->selection_anchor_pos ||
         priv->surrounding_text == NULL ||
+        text != priv->surrounding_text ||
         g_strcmp0 (text->text, priv->surrounding_text->text) != 0) {
         if (priv->surrounding_text)
             g_object_unref (priv->surrounding_text);
From 781119be4f646f06197badb73398a41d5acca787 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Wed, 21 Sep 2022 21:08:31 +0900
Subject: [PATCH 2/3] client/gtk2: Update capabilities if
 "retrieve-surrounding" is failed

Some engine developers wish to update the capabilities if emitting
"retrieve-surrounding" signal is failed so that engines disable the
surrounding text feature but I had deleted the logic with #2054 since
the second typing could be succeeded.
Asking all applications the second typing would not be a good condition
and the special issue should be fixed in firefox.

Fixes: https://github.com/ibus/ibus/commit/7b3b8c8b0c

BUG=https://github.com/ibus/ibus/issues/2054
BUG=https://github.com/ibus/ibus/issues/2354
---
 client/gtk2/ibusimcontext.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

--- a/client/gtk2/ibusimcontext.c
+++ b/client/gtk2/ibusimcontext.c
@@ -577,10 +577,14 @@
         g_signal_emit (context, _signal_retrieve_surrounding_id, 0,
                        &return_value);
         if (!return_value) {
-            /* #2054 firefox::IMContextWrapper::GetCurrentParagraph() could
-             * fail with the first typing on firefox but it succeeds with
-             * the second typing.
+            /* Engines can disable the surrounding text feature with
+             * the updated capabilities.
              */
+            if (context->caps & IBUS_CAP_SURROUNDING_TEXT) {
+                context->caps &= ~IBUS_CAP_SURROUNDING_TEXT;
+                ibus_input_context_set_capabilities (context->ibuscontext,
+                                                     context->caps);
+            }
             if (!warned) {
                 g_warning ("%s has no capability of surrounding-text feature",
                            g_get_prgname ());
--- a/client/gtk3/ibusimcontext.c
+++ b/client/gtk3/ibusimcontext.c
@@ -577,10 +577,14 @@
         g_signal_emit (context, _signal_retrieve_surrounding_id, 0,
                        &return_value);
         if (!return_value) {
-            /* #2054 firefox::IMContextWrapper::GetCurrentParagraph() could
-             * fail with the first typing on firefox but it succeeds with
-             * the second typing.
+            /* Engines can disable the surrounding text feature with
+             * the updated capabilities.
              */
+            if (context->caps & IBUS_CAP_SURROUNDING_TEXT) {
+                context->caps &= ~IBUS_CAP_SURROUNDING_TEXT;
+                ibus_input_context_set_capabilities (context->ibuscontext,
+                                                     context->caps);
+            }
             if (!warned) {
                 g_warning ("%s has no capability of surrounding-text feature",
                            g_get_prgname ());
--- a/client/gtk4/ibusimcontext.c
+++ b/client/gtk4/ibusimcontext.c
@@ -577,10 +577,14 @@
         g_signal_emit (context, _signal_retrieve_surrounding_id, 0,
                        &return_value);
         if (!return_value) {
-            /* #2054 firefox::IMContextWrapper::GetCurrentParagraph() could
-             * fail with the first typing on firefox but it succeeds with
-             * the second typing.
+            /* Engines can disable the surrounding text feature with
+             * the updated capabilities.
              */
+            if (context->caps & IBUS_CAP_SURROUNDING_TEXT) {
+                context->caps &= ~IBUS_CAP_SURROUNDING_TEXT;
+                ibus_input_context_set_capabilities (context->ibuscontext,
+                                                     context->caps);
+            }
             if (!warned) {
                 g_warning ("%s has no capability of surrounding-text feature",
                            g_get_prgname ());
From 8d0abbcbcef9a4fda706c70f12f4f596728bf90b Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Wed, 21 Sep 2022 21:08:29 +0900
Subject: [PATCH 1/3] client/gtk2: Stop many warnings of surrounding text

Surrounding text is requested by ibus_im_context_filter_keypress()
and the no supported warning could be output many times.
Now the warning is output one time by input context but
brower applicaations do not use GtkWidget for the input context
so the warning is output by instance but not input context.

BUG=https://github.com/ibus/ibus/issues/2418
---
 client/gtk2/ibusimcontext.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

--- a/client/gtk2/ibusimcontext.c
+++ b/client/gtk2/ibusimcontext.c
@@ -567,6 +567,7 @@
 static void
 _request_surrounding_text (IBusIMContext *context)
 {
+    static gboolean warned = FALSE;
     if (context &&
         (context->caps & IBUS_CAP_SURROUNDING_TEXT) != 0 &&
         context->ibuscontext != NULL &&
@@ -580,8 +581,11 @@
              * fail with the first typing on firefox but it succeeds with
              * the second typing.
              */
-            g_warning ("%s has no capability of surrounding-text feature",
-                       g_get_prgname ());
+            if (!warned) {
+                g_warning ("%s has no capability of surrounding-text feature",
+                           g_get_prgname ());
+                warned = TRUE;
+            }
         }
     }
 }
--- a/client/gtk3/ibusimcontext.c
+++ b/client/gtk3/ibusimcontext.c
@@ -567,6 +567,7 @@
 static void
 _request_surrounding_text (IBusIMContext *context)
 {
+    static gboolean warned = FALSE;
     if (context &&
         (context->caps & IBUS_CAP_SURROUNDING_TEXT) != 0 &&
         context->ibuscontext != NULL &&
@@ -580,8 +581,11 @@
              * fail with the first typing on firefox but it succeeds with
              * the second typing.
              */
-            g_warning ("%s has no capability of surrounding-text feature",
-                       g_get_prgname ());
+            if (!warned) {
+                g_warning ("%s has no capability of surrounding-text feature",
+                           g_get_prgname ());
+                warned = TRUE;
+            }
         }
     }
 }
--- a/client/gtk4/ibusimcontext.c
+++ b/client/gtk4/ibusimcontext.c
@@ -567,6 +567,7 @@
 static void
 _request_surrounding_text (IBusIMContext *context)
 {
+    static gboolean warned = FALSE;
     if (context &&
         (context->caps & IBUS_CAP_SURROUNDING_TEXT) != 0 &&
         context->ibuscontext != NULL &&
@@ -580,8 +581,11 @@
              * fail with the first typing on firefox but it succeeds with
              * the second typing.
              */
-            g_warning ("%s has no capability of surrounding-text feature",
-                       g_get_prgname ());
+            if (!warned) {
+                g_warning ("%s has no capability of surrounding-text feature",
+                           g_get_prgname ());
+                warned = TRUE;
+            }
         }
     }
 }

Attachment: OpenPGP_0xE9140597606020D3.asc
Description: OpenPGP public key

Attachment: OpenPGP_signature
Description: OpenPGP digital signature


Reply to: