static void _connect_cb(FcitxClient *client, void *user_data) { FCITX_UNUSED(user_data); GCancellable *cancellable = g_cancellable_new(); fcitx_client_process_key(client, FcitxKey_a, 0, 0, 0, 0, -1, cancellable, _process_cb, NULL); g_cancellable_cancel(cancellable); g_object_unref(cancellable); fcitx_client_process_key(client, FcitxKey_a, 0, 0, 0, 0, -1, NULL, _process_cb, NULL); }
static gboolean fcitx_im_context_filter_keypress(GtkIMContext *context, GdkEventKey *event) { FcitxLog(LOG_LEVEL, "fcitx_im_context_filter_keypress"); FcitxIMContext *fcitxcontext = FCITX_IM_CONTEXT(context); /* check this first, since we use key snooper, most key will be handled. */ if (fcitx_client_is_valid(fcitxcontext->client) ) { /* XXX it is a workaround for some applications do not set client window. */ if (fcitxcontext->client_window == NULL && event->window != NULL) { gtk_im_context_set_client_window((GtkIMContext *)fcitxcontext, event->window); /* set_cursor_location_internal() will get origin from X server, * it blocks UI. So delay it to idle callback. */ g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, (GSourceFunc) _set_cursor_location_internal, g_object_ref(fcitxcontext), (GDestroyNotify) g_object_unref); } } if (G_UNLIKELY(event->state & FcitxKeyState_HandledMask)) return TRUE; if (G_UNLIKELY(event->state & FcitxKeyState_IgnoredMask)) return gtk_im_context_filter_keypress(fcitxcontext->slave, event); if (fcitx_client_is_valid(fcitxcontext->client) && fcitxcontext->has_focus) { _request_surrounding_text (fcitxcontext); fcitxcontext->time = event->time; if (_use_sync_mode) { int ret = fcitx_client_process_key_sync(fcitxcontext->client, event->keyval, event->hardware_keycode, event->state, (event->type == GDK_KEY_PRESS) ? (FCITX_PRESS_KEY) : (FCITX_RELEASE_KEY), event->time); if (ret <= 0) { event->state |= FcitxKeyState_IgnoredMask; return gtk_im_context_filter_keypress(fcitxcontext->slave, event); } else { event->state |= FcitxKeyState_HandledMask; return TRUE; } } else { ProcessKeyStruct* pks = g_malloc0(sizeof(ProcessKeyStruct)); pks->context = fcitxcontext; pks->event = (GdkEventKey *) gdk_event_copy((GdkEvent *) event); fcitx_client_process_key(fcitxcontext->client, _fcitx_im_context_process_key_cb, pks, event->keyval, event->hardware_keycode, event->state, (event->type == GDK_KEY_PRESS) ? (FCITX_PRESS_KEY) : (FCITX_RELEASE_KEY), event->time); event->state |= FcitxKeyState_HandledMask; return TRUE; } } else { return gtk_im_context_filter_keypress(fcitxcontext->slave, event); } return FALSE; }
static gint _key_snooper_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data) { gboolean retval = FALSE; FcitxIMContext *fcitxcontext = (FcitxIMContext *) _focus_im_context; if (fcitxcontext == NULL || !fcitxcontext->has_focus) return FALSE; if (G_UNLIKELY (event->state & FcitxKeyState_HandledMask)) return TRUE; if (G_UNLIKELY (event->state & FcitxKeyState_IgnoredMask)) return FALSE; do { if (!fcitx_client_is_valid(fcitxcontext->client)) { break; } _request_surrounding_text (fcitxcontext); fcitxcontext->time = event->time; if (_use_sync_mode) { int ret = fcitx_client_process_key_sync(fcitxcontext->client, event->keyval, event->hardware_keycode, event->state, (event->type == GDK_KEY_PRESS) ? (FCITX_PRESS_KEY) : (FCITX_RELEASE_KEY), event->time); if (ret <= 0) retval = FALSE; else retval = TRUE; } else { ProcessKeyStruct* pks = g_malloc0(sizeof(ProcessKeyStruct)); pks->context = fcitxcontext; pks->event = (GdkEventKey *) gdk_event_copy((GdkEvent *) event); fcitx_client_process_key(fcitxcontext->client, _fcitx_im_context_process_key_cb, pks, event->keyval, event->hardware_keycode, event->state, (event->type == GDK_KEY_PRESS) ? (FCITX_PRESS_KEY) : (FCITX_RELEASE_KEY), event->time); retval = TRUE; } } while(0); if (!retval) { event->state |= FcitxKeyState_IgnoredMask; return FALSE; } else { event->state |= FcitxKeyState_HandledMask; return TRUE; } return retval; }