904 lines
31 KiB
Diff
904 lines
31 KiB
Diff
From babad7839ba6d72609c717d647bb2928724b4cc3 Mon Sep 17 00:00:00 2001
|
|
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
|
|
Date: Tue, 6 Sep 2022 17:08:43 +0900
|
|
Subject: [PATCH] tools: Check libdl for dlclose() properly in configure
|
|
|
|
BUG=https://github.com/ibus/ibus/pull/2442
|
|
---
|
|
configure.ac | 4 ++++
|
|
tools/Makefile.am | 2 +-
|
|
2 files changed, 5 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 0868d6c9..2344523a 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -147,6 +147,10 @@ AC_CHECK_HEADERS([sys/prctl.h])
|
|
# Check functions.
|
|
AC_CHECK_FUNCS(daemon)
|
|
|
|
+# Check dlclose() in libc.so.
|
|
+AC_CHECK_LIB(c, dlclose, LIBDL="", [AC_CHECK_LIB(dl, dlclose, LIBDL="-ldl")])
|
|
+AC_SUBST(LIBDL)
|
|
+
|
|
# Check packages.
|
|
# Check glib2.
|
|
AM_PATH_GLIB_2_0
|
|
diff --git a/tools/Makefile.am b/tools/Makefile.am
|
|
index b82395da..e300f9f3 100644
|
|
--- a/tools/Makefile.am
|
|
+++ b/tools/Makefile.am
|
|
@@ -63,7 +63,7 @@ AM_LDADD = \
|
|
@GTHREAD2_LIBS@ \
|
|
$(libibus) \
|
|
$(libibusimmodule) \
|
|
- -ldl \
|
|
+ $(LIBDL) \
|
|
$(NULL)
|
|
|
|
AM_VALAFLAGS = \
|
|
--
|
|
2.37.3
|
|
|
|
From 39b69073ad34ab89a3e5aa012ff740c84f69eb8f Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Fri, 16 Sep 2022 14:30:35 +0900
|
|
Subject: [PATCH] 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(-)
|
|
|
|
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
|
|
index bc14df00..3fc9c0f2 100644
|
|
--- a/client/gtk2/ibusimcontext.c
|
|
+++ b/client/gtk2/ibusimcontext.c
|
|
@@ -567,6 +567,7 @@ _process_key_event (IBusInputContext *context,
|
|
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 @@ _request_surrounding_text (IBusIMContext *context)
|
|
* 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;
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
--
|
|
2.37.3
|
|
|
|
From 50f8d8b79bc8eac1bae80116fe669d7314a44663 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Fri, 16 Sep 2022 14:34:54 +0900
|
|
Subject: [PATCH] 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(-)
|
|
|
|
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
|
|
index 3fc9c0f2..eaf7eb90 100644
|
|
--- a/client/gtk2/ibusimcontext.c
|
|
+++ b/client/gtk2/ibusimcontext.c
|
|
@@ -577,10 +577,14 @@ _request_surrounding_text (IBusIMContext *context)
|
|
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 ());
|
|
--
|
|
2.37.3
|
|
|
|
From 7bbcce66e1ca694b7a62553327161290bf4ee283 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Mon, 19 Sep 2022 11:52:14 +0900
|
|
Subject: [PATCH] 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(-)
|
|
|
|
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
|
|
index eaf7eb90..6e338157 100644
|
|
--- a/client/gtk2/ibusimcontext.c
|
|
+++ b/client/gtk2/ibusimcontext.c
|
|
@@ -70,6 +70,7 @@ struct _IBusIMContext {
|
|
#endif
|
|
|
|
IBusInputContext *ibuscontext;
|
|
+ IBusInputContext *ibuscontext_needs_surrounding;
|
|
|
|
/* preedit status */
|
|
gchar *preedit_string;
|
|
@@ -985,6 +986,7 @@ ibus_im_context_init (GObject *obj)
|
|
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
|
|
@@ -2183,6 +2185,18 @@ _ibus_context_hide_preedit_text_cb (IBusInputContext *ibuscontext,
|
|
g_signal_emit (ibusimcontext, _signal_preedit_end_id, 0);
|
|
}
|
|
|
|
+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 @@ _create_input_context_done (IBusBus *bus,
|
|
"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 @@ _create_input_context_done (IBusBus *bus,
|
|
|
|
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)) {
|
|
diff --git a/src/ibusinputcontext.c b/src/ibusinputcontext.c
|
|
index 7981de38..28ae04ad 100644
|
|
--- 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 @@ enum {
|
|
CURSOR_DOWN_LOOKUP_TABLE,
|
|
REGISTER_PROPERTIES,
|
|
UPDATE_PROPERTY,
|
|
+ REQUIRE_SURROUNDING_TEXT,
|
|
LAST_SIGNAL,
|
|
};
|
|
|
|
@@ -488,6 +489,21 @@ ibus_input_context_class_init (IBusInputContextClass *class)
|
|
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 @@ ibus_input_context_g_signal (GDBusProxy *proxy,
|
|
|
|
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 @@ ibus_input_context_set_surrounding_text (IBusInputContext *context,
|
|
|
|
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);
|
|
--
|
|
2.37.3
|
|
|
|
From cd621f8b82c80a174cd880cb27f27d7ccb9cb4d4 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Thu, 3 Nov 2022 08:36:17 +0900
|
|
Subject: [PATCH] ui/gtk3/switcher: Avoid to unref m_engines with double run
|
|
|
|
m_engines could be a buffer overflow if switcher.run() is called
|
|
again and m_engines is unrefed durling showing the swicher popup.
|
|
|
|
BUG=rhbz#2081055
|
|
---
|
|
ui/gtk3/switcher.vala | 2 ++
|
|
1 file changed, 2 insertions(+)
|
|
|
|
diff --git a/ui/gtk3/switcher.vala b/ui/gtk3/switcher.vala
|
|
index a4529c88..9400e9ba 100644
|
|
--- a/ui/gtk3/switcher.vala
|
|
+++ b/ui/gtk3/switcher.vala
|
|
@@ -143,6 +143,8 @@ class Switcher : Gtk.Window {
|
|
assert (m_loop == null);
|
|
assert (index < engines.length);
|
|
|
|
+ if (m_is_running)
|
|
+ return index;
|
|
m_is_running = true;
|
|
m_keyval = keyval;
|
|
m_modifiers = state;
|
|
--
|
|
2.37.3
|
|
|
|
From 506ac9993d5166196b7c4e9bfa9fb0f9d3792ffa Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Thu, 10 Nov 2022 18:38:05 +0900
|
|
Subject: [PATCH] client/x11: Implement new process_key_event for ibus-x11
|
|
|
|
The new process_key_event is ported from GTK4 to X11 because
|
|
hangul maintainers wish to delete forward_key_event as much as possible
|
|
and currently we could apply forward_key_event to the sync mode only
|
|
and the new process_key_event is a new async key event process in X11
|
|
and hangul might disable forward_key_event by default.
|
|
|
|
Now the definition of IBUS_CAP_SYNC_PROCESS_KEY_V2 capability is changed
|
|
to set only if the sync mode.
|
|
|
|
Also switch a heavy GMainLoop to the light GSource.
|
|
|
|
Fixes: https://github.com/ibus/ibus/commit/c957c5f
|
|
---
|
|
client/gtk2/ibusimcontext.c | 61 ++++++++++----
|
|
client/x11/main.c | 157 +++++++++++++++++++++++++++++++-----
|
|
src/ibustypes.h | 1 +
|
|
3 files changed, 184 insertions(+), 35 deletions(-)
|
|
|
|
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
|
|
index 6e338157..1f3723e6 100644
|
|
--- a/client/gtk2/ibusimcontext.c
|
|
+++ b/client/gtk2/ibusimcontext.c
|
|
@@ -382,8 +382,9 @@ typedef struct {
|
|
} ProcessKeyEventData;
|
|
|
|
typedef struct {
|
|
- GMainLoop *loop;
|
|
- gboolean retval;
|
|
+ int count;
|
|
+ guint count_cb_id;
|
|
+ gboolean retval;
|
|
} ProcessKeyEventReplyData;
|
|
|
|
static void
|
|
@@ -453,7 +454,23 @@ _process_key_event_reply_done (GObject *object,
|
|
}
|
|
g_return_if_fail (data);
|
|
data->retval = retval;
|
|
- g_main_loop_quit (data->loop);
|
|
+ data->count = 0;
|
|
+ g_source_remove (data->count_cb_id);
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+_process_key_event_count_cb (gpointer user_data)
|
|
+{
|
|
+ ProcessKeyEventReplyData *data = (ProcessKeyEventReplyData *)user_data;
|
|
+ g_return_val_if_fail (data, G_SOURCE_REMOVE);
|
|
+ if (!data->count)
|
|
+ return G_SOURCE_REMOVE;
|
|
+ /* Wait for about 10 secs. */
|
|
+ if (data->count++ == 10000) {
|
|
+ data->count = 0;
|
|
+ return G_SOURCE_REMOVE;
|
|
+ }
|
|
+ return G_SOURCE_CONTINUE;
|
|
}
|
|
|
|
static gboolean
|
|
@@ -496,10 +513,10 @@ _process_key_event (IBusInputContext *context,
|
|
break;
|
|
}
|
|
case 2: {
|
|
- GMainLoop *loop = g_main_loop_new (NULL, TRUE);
|
|
+ GSource *source = g_timeout_source_new (1);
|
|
ProcessKeyEventReplyData *data = NULL;
|
|
|
|
- if (loop)
|
|
+ if (source)
|
|
data = g_slice_new0 (ProcessKeyEventReplyData);
|
|
if (!data) {
|
|
g_warning ("Cannot wait for the reply of the process key event.");
|
|
@@ -507,11 +524,14 @@ _process_key_event (IBusInputContext *context,
|
|
keyval,
|
|
keycode - 8,
|
|
state);
|
|
- if (loop)
|
|
- g_main_loop_quit (loop);
|
|
+ if (source)
|
|
+ g_source_destroy (source);
|
|
break;
|
|
}
|
|
- data->loop = loop;
|
|
+ data->count = 1;
|
|
+ g_source_attach (source, NULL);
|
|
+ g_source_unref (source);
|
|
+ data->count_cb_id = g_source_get_id (source);
|
|
ibus_input_context_process_key_event_async (context,
|
|
keyval,
|
|
keycode - 8,
|
|
@@ -520,7 +540,14 @@ _process_key_event (IBusInputContext *context,
|
|
NULL,
|
|
_process_key_event_reply_done,
|
|
data);
|
|
- g_main_loop_run (loop);
|
|
+ g_source_set_callback (source, _process_key_event_count_cb, data, NULL);
|
|
+ while (data->count)
|
|
+ g_main_context_iteration (NULL, TRUE);
|
|
+ if (source->ref_count > 0) {
|
|
+ /* g_source_get_id() could causes a SEGV */
|
|
+ g_info ("Broken GSource.ref_count and maybe a timing issue in %p.",
|
|
+ source);
|
|
+ }
|
|
retval = data->retval;
|
|
g_slice_free (ProcessKeyEventReplyData, data);
|
|
break;
|
|
@@ -994,8 +1021,8 @@ ibus_im_context_init (GObject *obj)
|
|
#else
|
|
ibusimcontext->caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS;
|
|
#endif
|
|
- if (_use_sync_mode != 1)
|
|
- ibusimcontext->caps |= IBUS_CAP_SYNC_PROCESS_KEY;
|
|
+ if (_use_sync_mode == 1)
|
|
+ ibusimcontext->caps |= IBUS_CAP_SYNC_PROCESS_KEY_V2;
|
|
|
|
ibusimcontext->events_queue = g_queue_new ();
|
|
|
|
@@ -1338,7 +1365,7 @@ ibus_im_context_reset (GtkIMContext *context)
|
|
* IBus uses button-press-event instead until GTK is fixed.
|
|
* https://gitlab.gnome.org/GNOME/gtk/issues/1534
|
|
*/
|
|
- if (_use_sync_mode == 1)
|
|
+ if (_use_sync_mode != 0)
|
|
ibus_im_context_clear_preedit_text (ibusimcontext);
|
|
ibus_input_context_reset (ibusimcontext->ibuscontext);
|
|
}
|
|
@@ -1453,7 +1480,7 @@ ibus_im_context_set_client_window (GtkIMContext *context,
|
|
|
|
if (ibusimcontext->client_window) {
|
|
#if !GTK_CHECK_VERSION (3, 98, 4)
|
|
- if (ibusimcontext->use_button_press_event && _use_sync_mode != 1)
|
|
+ if (ibusimcontext->use_button_press_event && _use_sync_mode == 0)
|
|
_connect_button_press_event (ibusimcontext, FALSE);
|
|
#endif
|
|
g_object_unref (ibusimcontext->client_window);
|
|
@@ -1463,7 +1490,7 @@ ibus_im_context_set_client_window (GtkIMContext *context,
|
|
if (client != NULL) {
|
|
ibusimcontext->client_window = g_object_ref (client);
|
|
#if !GTK_CHECK_VERSION (3, 98, 4)
|
|
- if (!ibusimcontext->use_button_press_event && _use_sync_mode != 1)
|
|
+ if (!ibusimcontext->use_button_press_event && _use_sync_mode == 0)
|
|
_connect_button_press_event (ibusimcontext, TRUE);
|
|
#endif
|
|
}
|
|
@@ -2085,7 +2112,7 @@ _ibus_context_update_preedit_text_cb (IBusInputContext *ibuscontext,
|
|
#if !GTK_CHECK_VERSION (3, 98, 4)
|
|
if (!ibusimcontext->use_button_press_event &&
|
|
mode == IBUS_ENGINE_PREEDIT_COMMIT &&
|
|
- _use_sync_mode != 1) {
|
|
+ _use_sync_mode == 0) {
|
|
if (ibusimcontext->client_window) {
|
|
_connect_button_press_event (ibusimcontext, TRUE);
|
|
}
|
|
@@ -2459,8 +2486,8 @@ _create_fake_input_context_done (IBusBus *bus,
|
|
NULL);
|
|
|
|
guint32 caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS | IBUS_CAP_SURROUNDING_TEXT;
|
|
- if (_use_sync_mode != 1)
|
|
- caps |= IBUS_CAP_SYNC_PROCESS_KEY;
|
|
+ if (_use_sync_mode == 1)
|
|
+ caps |= IBUS_CAP_SYNC_PROCESS_KEY_V2;
|
|
ibus_input_context_set_capabilities (_fake_context, caps);
|
|
|
|
/* focus in/out the fake context */
|
|
diff --git a/client/x11/main.c b/client/x11/main.c
|
|
index 6057cc03..905fd251 100644
|
|
--- a/client/x11/main.c
|
|
+++ b/client/x11/main.c
|
|
@@ -124,7 +124,7 @@ static gint g_debug_level = 0;
|
|
|
|
static IBusBus *_bus = NULL;
|
|
|
|
-static gboolean _use_sync_mode = TRUE;
|
|
+static char _use_sync_mode = 2;
|
|
|
|
static void
|
|
_xim_preedit_start (XIMS xims, const X11IC *x11ic)
|
|
@@ -331,6 +331,7 @@ xim_create_ic (XIMS xims, IMChangeICStruct *call_data)
|
|
{
|
|
static int base_icid = 1;
|
|
X11IC *x11ic;
|
|
+ guint32 capabilities = IBUS_CAP_FOCUS;
|
|
|
|
call_data->icid = base_icid ++;
|
|
|
|
@@ -375,12 +376,11 @@ xim_create_ic (XIMS xims, IMChangeICStruct *call_data)
|
|
G_CALLBACK (_context_disabled_cb), x11ic);
|
|
|
|
|
|
- if (x11ic->input_style & XIMPreeditCallbacks) {
|
|
- ibus_input_context_set_capabilities (x11ic->context, IBUS_CAP_FOCUS | IBUS_CAP_PREEDIT_TEXT);
|
|
- }
|
|
- else {
|
|
- ibus_input_context_set_capabilities (x11ic->context, IBUS_CAP_FOCUS);
|
|
- }
|
|
+ if (x11ic->input_style & XIMPreeditCallbacks)
|
|
+ capabilities |= IBUS_CAP_PREEDIT_TEXT;
|
|
+ if (_use_sync_mode == 1)
|
|
+ capabilities |= IBUS_CAP_SYNC_PROCESS_KEY_V2;
|
|
+ ibus_input_context_set_capabilities (x11ic->context, capabilities);
|
|
|
|
g_hash_table_insert (_x11_ic_table,
|
|
GINT_TO_POINTER (x11ic->icid), (gpointer)x11ic);
|
|
@@ -461,6 +461,13 @@ xim_unset_ic_focus (XIMS xims, IMChangeFocusStruct *call_data)
|
|
|
|
}
|
|
|
|
+typedef struct {
|
|
+ IMForwardEventStruct *pfe;
|
|
+ int count;
|
|
+ guint count_cb_id;
|
|
+ gboolean retval;
|
|
+} ProcessKeyEventReplyData;
|
|
+
|
|
static void
|
|
_process_key_event_done (GObject *object,
|
|
GAsyncResult *res,
|
|
@@ -493,6 +500,43 @@ _process_key_event_done (GObject *object,
|
|
g_slice_free (IMForwardEventStruct, pfe);
|
|
}
|
|
|
|
+static void
|
|
+_process_key_event_reply_done (GObject *object,
|
|
+ GAsyncResult *res,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ IBusInputContext *context = (IBusInputContext *)object;
|
|
+ ProcessKeyEventReplyData *data = (ProcessKeyEventReplyData *)user_data;
|
|
+ GError *error = NULL;
|
|
+ gboolean retval = ibus_input_context_process_key_event_async_finish (
|
|
+ context,
|
|
+ res,
|
|
+ &error);
|
|
+ if (error != NULL) {
|
|
+ g_warning ("Process Key Event failed: %s.", error->message);
|
|
+ g_error_free (error);
|
|
+ }
|
|
+ g_return_if_fail (data);
|
|
+ data->retval = retval;
|
|
+ data->count = 0;
|
|
+ g_source_remove (data->count_cb_id);
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+_process_key_event_count_cb (gpointer user_data)
|
|
+{
|
|
+ ProcessKeyEventReplyData *data = (ProcessKeyEventReplyData *)user_data;
|
|
+ g_return_val_if_fail (data, G_SOURCE_REMOVE);
|
|
+ if (!data->count)
|
|
+ return G_SOURCE_REMOVE;
|
|
+ /* Wait for about 10 secs. */
|
|
+ if (data->count++ == 10000) {
|
|
+ data->count = 0;
|
|
+ return G_SOURCE_REMOVE;
|
|
+ }
|
|
+ return G_SOURCE_CONTINUE;
|
|
+}
|
|
+
|
|
static int
|
|
xim_forward_event (XIMS xims, IMForwardEventStruct *call_data)
|
|
{
|
|
@@ -520,14 +564,15 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data)
|
|
event.state |= IBUS_RELEASE_MASK;
|
|
}
|
|
|
|
- if (_use_sync_mode) {
|
|
+ switch (_use_sync_mode) {
|
|
+ case 1: {
|
|
retval = ibus_input_context_process_key_event (
|
|
x11ic->context,
|
|
event.keyval,
|
|
event.hardware_keycode - 8,
|
|
event.state);
|
|
if (retval) {
|
|
- if (! x11ic->has_preedit_area) {
|
|
+ if (!x11ic->has_preedit_area) {
|
|
_xim_set_cursor_location (x11ic);
|
|
}
|
|
return 1;
|
|
@@ -546,8 +591,80 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data)
|
|
IMForwardEvent (_xims, (XPointer) &fe);
|
|
|
|
retval = 1;
|
|
+ break;
|
|
}
|
|
- else {
|
|
+ case 2: {
|
|
+ GSource *source = g_timeout_source_new (1);
|
|
+ ProcessKeyEventReplyData *data = NULL;
|
|
+ IMForwardEventStruct fe;
|
|
+
|
|
+ if (source)
|
|
+ data = g_slice_new0 (ProcessKeyEventReplyData);
|
|
+ if (!data) {
|
|
+ g_warning ("Cannot wait for the reply of the process key event.");
|
|
+ retval = ibus_input_context_process_key_event (
|
|
+ x11ic->context,
|
|
+ event.keyval,
|
|
+ event.hardware_keycode - 8,
|
|
+ event.state);
|
|
+ if (source)
|
|
+ g_source_destroy (source);
|
|
+ } else {
|
|
+ CARD16 connect_id = x11ic->connect_id;
|
|
+ data->count = 1;
|
|
+ g_source_attach (source, NULL);
|
|
+ g_source_unref (source);
|
|
+ data->count_cb_id = g_source_get_id (source);
|
|
+ ibus_input_context_process_key_event_async (
|
|
+ x11ic->context,
|
|
+ event.keyval,
|
|
+ event.hardware_keycode - 8,
|
|
+ event.state,
|
|
+ -1,
|
|
+ NULL,
|
|
+ _process_key_event_reply_done,
|
|
+ data);
|
|
+ g_source_set_callback (source, _process_key_event_count_cb,
|
|
+ data, NULL);
|
|
+ while (data->count)
|
|
+ g_main_context_iteration (NULL, TRUE);
|
|
+ if (source->ref_count > 0) {
|
|
+ /* g_source_get_id() could causes a SEGV */
|
|
+ g_info ("Broken GSource.ref_count and maybe a timing "
|
|
+ "issue in %p.", source);
|
|
+ }
|
|
+ retval = data->retval;
|
|
+ g_slice_free (ProcessKeyEventReplyData, data);
|
|
+
|
|
+ if (g_hash_table_lookup (_connections,
|
|
+ GINT_TO_POINTER ((gint)connect_id))
|
|
+ == NULL) {
|
|
+ return 1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (retval) {
|
|
+ if (! x11ic->has_preedit_area) {
|
|
+ _xim_set_cursor_location (x11ic);
|
|
+ }
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ memset (&fe, 0, sizeof (fe));
|
|
+
|
|
+ fe.major_code = XIM_FORWARD_EVENT;
|
|
+ fe.icid = x11ic->icid;
|
|
+ fe.connect_id = x11ic->connect_id;
|
|
+ fe.sync_bit = 0;
|
|
+ fe.serial_number = 0L;
|
|
+ fe.event = call_data->event;
|
|
+
|
|
+ IMForwardEvent (_xims, (XPointer) &fe);
|
|
+
|
|
+ retval = 1;
|
|
+ break;
|
|
+ }
|
|
+ default: {
|
|
IMForwardEventStruct *pfe;
|
|
|
|
pfe = g_slice_new0 (IMForwardEventStruct);
|
|
@@ -569,6 +686,7 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data)
|
|
pfe);
|
|
retval = 1;
|
|
}
|
|
+ }
|
|
return retval;
|
|
}
|
|
|
|
@@ -1026,23 +1144,26 @@ _context_disabled_cb (IBusInputContext *context,
|
|
_xim_preedit_end (_xims, x11ic);
|
|
}
|
|
|
|
-static gboolean
|
|
-_get_boolean_env(const gchar *name,
|
|
- gboolean defval)
|
|
+static char
|
|
+_get_char_env (const gchar *name,
|
|
+ char defval)
|
|
{
|
|
const gchar *value = g_getenv (name);
|
|
|
|
if (value == NULL)
|
|
- return defval;
|
|
+ return defval;
|
|
|
|
if (g_strcmp0 (value, "") == 0 ||
|
|
g_strcmp0 (value, "0") == 0 ||
|
|
g_strcmp0 (value, "false") == 0 ||
|
|
g_strcmp0 (value, "False") == 0 ||
|
|
- g_strcmp0 (value, "FALSE") == 0)
|
|
- return FALSE;
|
|
+ g_strcmp0 (value, "FALSE") == 0) {
|
|
+ return 0;
|
|
+ } else if (!g_strcmp0 (value, "2")) {
|
|
+ return 2;
|
|
+ }
|
|
|
|
- return TRUE;
|
|
+ return 1;
|
|
}
|
|
|
|
static void
|
|
@@ -1059,7 +1180,7 @@ _init_ibus (void)
|
|
G_CALLBACK (_bus_disconnected_cb), NULL);
|
|
|
|
/* https://github.com/ibus/ibus/issues/1713 */
|
|
- _use_sync_mode = _get_boolean_env ("IBUS_ENABLE_SYNC_MODE", TRUE);
|
|
+ _use_sync_mode = _get_char_env ("IBUS_ENABLE_SYNC_MODE", 2);
|
|
}
|
|
|
|
static void
|
|
diff --git a/src/ibustypes.h b/src/ibustypes.h
|
|
index a8eee319..ba2a0010 100644
|
|
--- a/src/ibustypes.h
|
|
+++ b/src/ibustypes.h
|
|
@@ -124,6 +124,7 @@ typedef enum {
|
|
IBUS_CAP_SURROUNDING_TEXT = 1 << 5,
|
|
IBUS_CAP_OSK = 1 << 6,
|
|
IBUS_CAP_SYNC_PROCESS_KEY = 1 << 7,
|
|
+ IBUS_CAP_SYNC_PROCESS_KEY_V2 = IBUS_CAP_SYNC_PROCESS_KEY,
|
|
} IBusCapabilite;
|
|
|
|
/**
|
|
--
|
|
2.37.3
|
|
|
|
From 2719e936cc1f1f26f414b339a7f4f0e48331732f Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Tue, 22 Nov 2022 21:47:01 +0900
|
|
Subject: [PATCH] src/tests: Fallback gtk-query-immodules-3.0 for Ubuntu
|
|
22.04
|
|
|
|
---
|
|
src/tests/runtest | 4 ++++
|
|
1 file changed, 4 insertions(+)
|
|
|
|
diff --git a/src/tests/runtest b/src/tests/runtest
|
|
index a229140a..036dc771 100755
|
|
--- a/src/tests/runtest
|
|
+++ b/src/tests/runtest
|
|
@@ -44,6 +44,10 @@ MACHINE=`uname -m`
|
|
if test x"$MACHINE" = xx86_64 ; then
|
|
GTK_QUERY_MODULE=gtk-query-immodules-3.0-64
|
|
fi
|
|
+which $GTK_QUERY_MODULE
|
|
+if [ $? -ne 0 ] ; then
|
|
+ GTK_QUERY_MODULE=gtk-query-immodules-3.0
|
|
+fi
|
|
|
|
retval=0
|
|
|
|
--
|
|
2.37.3
|
|
|
|
From 2555fa9781ccb40445d8a344ec180ff654e0c5f1 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Fri, 2 Dec 2022 13:41:39 +0900
|
|
Subject: [PATCH] src/tests: Fix Connection refused in ibus-bus
|
|
|
|
ibus-bus is failed in Ubuntu 22.04 under GitHub action + Docer
|
|
with the warning of:
|
|
"Unable to connect to ibus: Could not connect: Connection refused"
|
|
during ibus_bus_new_async()'s callback if IBus socket file is
|
|
deleted after ibus_bus_exit_async()'s callback is called.
|
|
---
|
|
src/tests/ibus-bus.c | 70 +++++++++++++++++++++++++++++++++++++++++---
|
|
1 file changed, 66 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/src/tests/ibus-bus.c b/src/tests/ibus-bus.c
|
|
index a2af0bb2..d6b105cf 100644
|
|
--- a/src/tests/ibus-bus.c
|
|
+++ b/src/tests/ibus-bus.c
|
|
@@ -802,6 +802,33 @@ start_set_preload_engines_async (void)
|
|
NULL); /* user_data */
|
|
}
|
|
|
|
+static void
|
|
+_socket_changed_cb (GFileMonitor *monitor,
|
|
+ GFile *file,
|
|
+ GFile *other_file,
|
|
+ GFileMonitorEvent event_type,
|
|
+ IBusBus *bus)
|
|
+{
|
|
+ switch (event_type) {
|
|
+ case G_FILE_MONITOR_EVENT_CHANGED:
|
|
+ g_debug ("IBus socket file is changed");
|
|
+ call_next_async_function ();
|
|
+ g_signal_handlers_disconnect_by_func (monitor,
|
|
+ G_CALLBACK (_socket_changed_cb),
|
|
+ NULL);
|
|
+ g_object_unref (monitor);
|
|
+ break;
|
|
+ case G_FILE_MONITOR_EVENT_CREATED:
|
|
+ g_debug ("IBus socket file is created");
|
|
+ break;
|
|
+ case G_FILE_MONITOR_EVENT_DELETED:
|
|
+ g_debug ("IBus socket file is deleted");
|
|
+ break;
|
|
+ default:
|
|
+ g_debug ("IBus socket file's status is %d\n", event_type);
|
|
+ }
|
|
+}
|
|
+
|
|
static void
|
|
finish_exit_async (GObject *source_object,
|
|
GAsyncResult *res,
|
|
@@ -811,15 +838,25 @@ finish_exit_async (GObject *source_object,
|
|
gboolean result = ibus_bus_exit_async_finish (bus,
|
|
res,
|
|
&error);
|
|
+ gboolean has_socket_path = GPOINTER_TO_INT (user_data);
|
|
+ if (error) {
|
|
+ g_warning ("Failed to ibus_bus_exit(): %s", error->message);
|
|
+ g_error_free (error);
|
|
+ }
|
|
g_assert (result);
|
|
- g_debug ("ibus_bus_exit_finish: OK");
|
|
- g_usleep (G_USEC_PER_SEC);
|
|
- call_next_async_function ();
|
|
+ if (has_socket_path == FALSE) {
|
|
+ g_debug ("ibus_bus_exit_finish: OK socket file: none");
|
|
+ g_usleep (G_USEC_PER_SEC);
|
|
+ call_next_async_function ();
|
|
+ } else {
|
|
+ g_debug ("ibus_bus_exit_finish: OK socket file: monitored");
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
start_exit_async (void)
|
|
{
|
|
+ gboolean has_socket_path = FALSE;
|
|
/* When `./runtest ibus-bus` runs, ibus-daemon sometimes failed to
|
|
* restart because closing a file descriptor was failed in
|
|
* bus/server.c:_restart_server() with a following error:
|
|
@@ -828,12 +865,37 @@ start_exit_async (void)
|
|
* fail to restart ibus-daemon.
|
|
*/
|
|
g_usleep (G_USEC_PER_SEC);
|
|
+ /* IBus socket file can be deleted after finish_exit_async() is called
|
|
+ * so the next ibus_bus_new_async() in test_bus_new_async() could be failed
|
|
+ * if the socket file is deleted after ibus_bus_new_async() is called
|
|
+ * in case that the socket file is not monitored.
|
|
+ */
|
|
+ if (!g_getenv ("IBUS_ADDRESS")) {
|
|
+ const gchar *address_path = ibus_get_socket_path ();
|
|
+ GFile *file;
|
|
+ GError *error = NULL;
|
|
+ GFileMonitor *monitor;
|
|
+
|
|
+ g_assert (address_path);
|
|
+ file = g_file_new_for_path (address_path);
|
|
+ g_assert (file);
|
|
+ has_socket_path = TRUE;
|
|
+ monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, &error);
|
|
+ if (error) {
|
|
+ g_warning ("Failed to monitor socket file: %s", error->message);
|
|
+ g_error_free (error);
|
|
+ }
|
|
+ g_assert (monitor);
|
|
+ g_signal_connect (monitor, "changed",
|
|
+ G_CALLBACK (_socket_changed_cb), NULL);
|
|
+ g_object_unref (file);
|
|
+ }
|
|
ibus_bus_exit_async (bus,
|
|
TRUE, /* restart */
|
|
-1, /* timeout */
|
|
NULL, /* cancellable */
|
|
finish_exit_async,
|
|
- NULL); /* user_data */
|
|
+ GINT_TO_POINTER (has_socket_path)); /* user_data */
|
|
}
|
|
|
|
static gboolean
|
|
--
|
|
2.37.3
|
|
|