diff options
author | fujiwarat <takao.fujiwara1@gmail.com> | 2022-07-19 22:58:24 +0900 |
---|---|---|
committer | fujiwarat <takao.fujiwara1@gmail.com> | 2022-07-19 22:58:24 +0900 |
commit | c957c5f6ba07074a8fb56c978c27873c1cfe0783 (patch) | |
tree | 1b3989865de294b585484fc638e3a4530aebe809 | |
parent | 965567d7fd26b6c045cc59adcccbe978abe1dfc4 (diff) | |
download | ibus-c957c5f6ba07074a8fb56c978c27873c1cfe0783.tar.gz |
client/gtk2: Implement new process_key_event for GTK4
-rw-r--r-- | client/gtk2/ibusimcontext.c | 147 | ||||
-rw-r--r-- | src/ibustypes.h | 4 |
2 files changed, 127 insertions, 24 deletions
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c index c7f23293..bc14df00 100644 --- a/client/gtk2/ibusimcontext.c +++ b/client/gtk2/ibusimcontext.c @@ -111,13 +111,13 @@ static guint _signal_delete_surrounding_id = 0; static guint _signal_retrieve_surrounding_id = 0; #if GTK_CHECK_VERSION (3, 98, 4) -static gboolean _use_sync_mode = TRUE; +static char _use_sync_mode = 2; #else static const gchar *_no_snooper_apps = NO_SNOOPER_APPS; static gboolean _use_key_snooper = ENABLE_SNOOPER; static guint _key_snooper_id = 0; -static gboolean _use_sync_mode = FALSE; +static char _use_sync_mode = 0; #endif static const gchar *_discard_password_apps = ""; @@ -375,12 +375,15 @@ ibus_im_context_commit_event (IBusIMContext *ibusimcontext, return FALSE; } -struct _ProcessKeyEventData { +typedef struct { GdkEvent *event; IBusIMContext *ibusimcontext; -}; +} ProcessKeyEventData; -typedef struct _ProcessKeyEventData ProcessKeyEventData; +typedef struct { + GMainLoop *loop; + gboolean retval; +} ProcessKeyEventReplyData; static void _process_key_event_done (GObject *object, @@ -395,12 +398,12 @@ _process_key_event_done (GObject *object, IBusIMContext *ibusimcontext = data->ibusimcontext; #endif GError *error = NULL; + gboolean retval; g_slice_free (ProcessKeyEventData, data); - gboolean retval = ibus_input_context_process_key_event_async_finish ( - context, - res, - &error); + retval = ibus_input_context_process_key_event_async_finish (context, + res, + &error); if (error != NULL) { g_warning ("Process Key Event failed: %s.", error->message); @@ -431,6 +434,27 @@ _process_key_event_done (GObject *object, #endif } +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; + g_main_loop_quit (data->loop); +} + static gboolean _process_key_event (IBusInputContext *context, #if GTK_CHECK_VERSION (3, 98, 4) @@ -462,13 +486,45 @@ _process_key_event (IBusInputContext *context, #endif keycode = hardware_keycode; - if (_use_sync_mode) { + switch (_use_sync_mode) { + case 1: { retval = ibus_input_context_process_key_event (context, + keyval, + keycode - 8, + state); + break; + } + case 2: { + GMainLoop *loop = g_main_loop_new (NULL, TRUE); + ProcessKeyEventReplyData *data = NULL; + + if (loop) + 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 (context, + keyval, + keycode - 8, + state); + if (loop) + g_main_loop_quit (loop); + break; + } + data->loop = loop; + ibus_input_context_process_key_event_async (context, keyval, keycode - 8, - state); + state, + -1, + NULL, + _process_key_event_reply_done, + data); + g_main_loop_run (loop); + retval = data->retval; + g_slice_free (ProcessKeyEventReplyData, data); + break; } - else { + default: { ProcessKeyEventData *data = g_slice_new0 (ProcessKeyEventData); #if GTK_CHECK_VERSION (3, 98, 4) data->event = gdk_event_ref (event); @@ -487,6 +543,7 @@ _process_key_event (IBusInputContext *context, retval = TRUE; } + } /* GTK4 does not provide gtk_key_snooper_install() and also * GtkIMContextClass->filter_keypress() cannot send the updated @@ -676,24 +733,47 @@ _key_snooper_cb (GtkWidget *widget, #endif static gboolean -_get_boolean_env(const gchar *name, - gboolean defval) +_get_boolean_env (const gchar *name, + gboolean 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 FALSE; + } return TRUE; } +static char +_get_char_env (const gchar *name, + char defval) +{ + const gchar *value = g_getenv (name); + + if (value == NULL) + 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 0; + } else if (!g_strcmp0 (value, "2")) { + return 2; + } + + return 1; +} + static void daemon_name_appeared (GDBusConnection *connection, const gchar *name, @@ -777,11 +857,11 @@ ibus_im_context_class_init (IBusIMContextClass *class) g_assert (_signal_retrieve_surrounding_id != 0); #if GTK_CHECK_VERSION (3, 98, 4) - _use_sync_mode = _get_boolean_env ("IBUS_ENABLE_SYNC_MODE", TRUE); + _use_sync_mode = _get_char_env ("IBUS_ENABLE_SYNC_MODE", 2); #else _use_key_snooper = !_get_boolean_env ("IBUS_DISABLE_SNOOPER", !(ENABLE_SNOOPER)); - _use_sync_mode = _get_boolean_env ("IBUS_ENABLE_SYNC_MODE", FALSE); + _use_sync_mode = (char)_get_char_env ("IBUS_ENABLE_SYNC_MODE", 0); #endif _use_discard_password = _get_boolean_env ("IBUS_DISCARD_PASSWORD", FALSE); @@ -904,6 +984,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; ibusimcontext->events_queue = g_queue_new (); @@ -1246,7 +1328,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) + if (_use_sync_mode == 1) ibus_im_context_clear_preedit_text (ibusimcontext); ibus_input_context_reset (ibusimcontext->ibuscontext); } @@ -1361,7 +1443,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) + if (ibusimcontext->use_button_press_event && _use_sync_mode != 1) _connect_button_press_event (ibusimcontext, FALSE); #endif g_object_unref (ibusimcontext->client_window); @@ -1371,7 +1453,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) + if (!ibusimcontext->use_button_press_event && _use_sync_mode != 1) _connect_button_press_event (ibusimcontext, TRUE); #endif } @@ -1993,7 +2075,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) { + _use_sync_mode != 1) { if (ibusimcontext->client_window) { _connect_button_press_event (ibusimcontext, TRUE); } @@ -2200,6 +2282,8 @@ _create_input_context_done (IBusBus *bus, static void _create_input_context (IBusIMContext *ibusimcontext) { + gchar *prgname = g_strdup (g_get_prgname()); + gchar *client_name; IDEBUG ("%s", __FUNCTION__); g_assert (ibusimcontext->ibuscontext == NULL); @@ -2208,11 +2292,24 @@ _create_input_context (IBusIMContext *ibusimcontext) ibusimcontext->cancellable = g_cancellable_new (); + if (!prgname) + prgname = g_strdup_printf ("(%d)", getpid ()); + client_name = g_strdup_printf ("%s:%s", +#if GTK_CHECK_VERSION (3, 98, 4) + "gtk4-im", +#elif GTK_CHECK_VERSION (2, 91, 0) + "gtk3-im", +#else + "gtk-im", +#endif + prgname); + g_free (prgname); ibus_bus_create_input_context_async (_bus, - "gtk-im", -1, + client_name, -1, ibusimcontext->cancellable, (GAsyncReadyCallback)_create_input_context_done, g_object_ref (ibusimcontext)); + g_free (client_name); } /* Callback functions for slave context */ @@ -2329,6 +2426,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; ibus_input_context_set_capabilities (_fake_context, caps); /* focus in/out the fake context */ diff --git a/src/ibustypes.h b/src/ibustypes.h index 60bcb92b..a8eee319 100644 --- a/src/ibustypes.h +++ b/src/ibustypes.h @@ -109,6 +109,9 @@ typedef enum * @IBUS_CAP_SURROUNDING_TEXT: Client can provide surround text, * or IME can handle surround text. * @IBUS_CAP_OSK: UI is owned by on-screen keyboard. + * @IBUS_CAP_SYNC_PROCESS_KEY: Asynchronous process key events are not + * supported and the ibus_engine_forward_key_event() should not be + * used for the return value of #IBusEngine::process_key_event(). * * Capability flags of UI. */ @@ -120,6 +123,7 @@ typedef enum { IBUS_CAP_PROPERTY = 1 << 4, IBUS_CAP_SURROUNDING_TEXT = 1 << 5, IBUS_CAP_OSK = 1 << 6, + IBUS_CAP_SYNC_PROCESS_KEY = 1 << 7, } IBusCapabilite; /** |