diff --git a/sesman/chansrv/input_ibus.c b/sesman/chansrv/input_ibus.c index 8df7af23..f986fc6f 100644 --- a/sesman/chansrv/input_ibus.c +++ b/sesman/chansrv/input_ibus.c @@ -204,6 +204,31 @@ xrdp_input_enable(void) return TRUE; } + /* Only reclaim XrdpIme if the current engine is either unset, or is + * the original one we remembered before ever switching away from + * it (last_input_name) - that's ibus silently reverting on its + * own, which is exactly the scenario this reassertion exists to + * fix. If it's some OTHER named engine, that's a deliberate user + * action (e.g. manually switching to a native engine like + * libpinyin to compose directly in the remote session), possibly + * well before this call - forcibly reclaiming XrdpIme would yank + * that away mid-use for the sake of a single, possibly stale or + * deferred commit (e.g. macOS auto-flushing a composition that was + * left pending after the user moved on to something else). Drop + * this commit instead and leave the user's active choice alone. */ + if (last_input_name != NULL && name != NULL && + g_ascii_strcasecmp(name, last_input_name) != 0) + { + LOG(LOG_LEVEL_WARNING, + "xrdp_input_enable: global engine is \"%s\", not XrdpIme or " + "the original \"%s\" - leaving it alone rather than " + "reclaiming it, dropping this commit", + name, last_input_name); + g_object_unref(desc); + g_object_unref(local_bus); + return FALSE; + } + /* Remember the user's engine only the first time we replace it. */ if (last_input_name == NULL && name != NULL) { @@ -719,6 +744,14 @@ xrdp_input_unicode_init(void) { LOG(LOG_LEVEL_ERROR, "xrdp_input_unicode_init: timed out waiting for IBus daemon"); + /* No thread was created, so nothing will ever broadcast + * state_cond to wake a future destroy()/init() call waiting on + * ibus_thread_exited - reset it back to TRUE (set FALSE above + * in anticipation of the thread this function didn't end up + * creating), or that later wait blocks forever. */ + g_mutex_lock(&state_mutex); + ibus_thread_exited = TRUE; + g_mutex_unlock(&state_mutex); return 1; }