From babad7839ba6d72609c717d647bb2928724b4cc3 Mon Sep 17 00:00:00 2001 From: Izumi Tsutsui 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 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 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 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 - * Copyright (C) 2018-2019 Takao Fujiwara + * Copyright (C) 2018-2022 Takao Fujiwara * 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 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 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 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 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