TEST(WebKit2, InputMethodFilterContextEventsWithoutKeyEvents) { TestInputMethodFilter inputMethodFilter; // This is a bit of a hack to avoid mocking out the entire InputMethodContext, by // simply replacing the get_preedit_string virtual method for the length of this test. GtkIMContext* context = inputMethodFilter.context(); GtkIMContextClass* contextClass = GTK_IM_CONTEXT_GET_CLASS(context); GetPreeditStringCallback previousCallback = contextClass->get_preedit_string; contextClass->get_preedit_string = temporaryGetPreeditStringOverride; g_signal_emit_by_name(context, "preedit-changed"); g_signal_emit_by_name(context, "commit", "commit text"); contextClass->get_preedit_string = previousCallback; const Vector<String>& events = inputMethodFilter.events(); ASSERT_EQ(6, events.size()); ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=16777215 (faked)"), events[0]); ASSERT_EQ(String("setPreedit text='preedit of doom, bringer of cheese' cursorOffset=3"), events[1]); ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=ffffff (faked)"), events[2]); ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=16777215 (faked)"), events[3]); ASSERT_EQ(String("confirmComposition 'commit text'"), events[4]); ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=ffffff (faked)"), events[5]); }
void gtk_im_context_set_client_window (GtkIMContext *context, GdkWindow *window) { GtkIMContextClass *klass; g_return_if_fail (GTK_IS_IM_CONTEXT (context)); klass = GTK_IM_CONTEXT_GET_CLASS (context); if (klass->set_client_window) klass->set_client_window (context, window); //below is our interposed codes to save the context to local_context. if(!GDK_IS_WINDOW (window)) return; g_object_set_data(G_OBJECT(context),"window",window); int width = gdk_window_get_width(window); int height = gdk_window_get_height(window); if(width != 0 && height !=0) { gtk_im_context_focus_in(context); local_context = context; } //only add this event_filter when using 'fcitx' immodule. //for xim immodule, this function is as same as original from gtk2. const gchar * immodule = g_getenv("GTK_IM_MODULE"); if(immodule && !strcmp(immodule, "fcitx")) { gdk_window_add_filter (window, event_filter, context); } }
/** * gtk_im_context_reset: * @context: a #GtkIMContext * * Notify the input method that a change such as a change in cursor * position has been made. This will typically cause the input * method to clear the preedit state. **/ void gtk_im_context_reset (GtkIMContext *context) { GtkIMContextClass *klass; g_return_if_fail (GTK_IS_IM_CONTEXT (context)); klass = GTK_IM_CONTEXT_GET_CLASS (context); if (klass->reset) klass->reset (context); }
/** * gtk_im_context_set_use_preedit: * @context: a #GtkIMContext * @use_preedit: whether the IM context should use the preedit string. * * Sets whether the IM context should use the preedit string * to display feedback. If @use_preedit is FALSE (default * is TRUE), then the IM context may use some other method to display * feedback, such as displaying it in a child of the root window. **/ void gtk_im_context_set_use_preedit (GtkIMContext *context, gboolean use_preedit) { GtkIMContextClass *klass; g_return_if_fail (GTK_IS_IM_CONTEXT (context)); klass = GTK_IM_CONTEXT_GET_CLASS (context); if (klass->set_use_preedit) klass->set_use_preedit (context, use_preedit); }
/** * gtk_im_context_set_cursor_location: * @context: a #GtkIMContext * @area: new location * * Notify the input method that a change in cursor * position has been made. The location is relative to the client * window. **/ void gtk_im_context_set_cursor_location (GtkIMContext *context, const GdkRectangle *area) { GtkIMContextClass *klass; g_return_if_fail (GTK_IS_IM_CONTEXT (context)); klass = GTK_IM_CONTEXT_GET_CLASS (context); if (klass->set_cursor_location) klass->set_cursor_location (context, (GdkRectangle *) area); }
/** * gtk_im_context_filter_keypress: * @context: a #GtkIMContext * @event: the key event * * Allow an input method to internally handle key press and release * events. If this function returns %TRUE, then no further processing * should be done for this key event. * * Return value: %TRUE if the input method handled the key event. * **/ gboolean gtk_im_context_filter_keypress (GtkIMContext *context, GdkEventKey *key) { GtkIMContextClass *klass; g_return_val_if_fail (GTK_IS_IM_CONTEXT (context), FALSE); g_return_val_if_fail (key != NULL, FALSE); klass = GTK_IM_CONTEXT_GET_CLASS (context); return klass->filter_keypress (context, key); }
/** * gtk_im_context_set_client_window: * @context: a #GtkIMContext * @window: (allow-none): the client window. This may be %NULL to indicate * that the previous client window no longer exists. * * Set the client window for the input context; this is the * #GdkWindow in which the input appears. This window is * used in order to correctly position status windows, and may * also be used for purposes internal to the input method. **/ void gtk_im_context_set_client_window (GtkIMContext *context, GdkWindow *window) { GtkIMContextClass *klass; g_return_if_fail (GTK_IS_IM_CONTEXT (context)); klass = GTK_IM_CONTEXT_GET_CLASS (context); if (klass->set_client_window) klass->set_client_window (context, window); }
/** * gtk_im_context_get_preedit_string: * @context: a #GtkIMContext * @str: (out) (transfer full): location to store the retrieved * string. The string retrieved must be freed with g_free(). * @attrs: (out) (transfer full): location to store the retrieved * attribute list. When you are done with this list, you * must unreference it with pango_attr_list_unref(). * @cursor_pos: (out): location to store position of cursor (in characters) * within the preedit string. * * Retrieve the current preedit string for the input context, * and a list of attributes to apply to the string. * This string should be displayed inserted at the insertion * point. **/ void gtk_im_context_get_preedit_string (GtkIMContext *context, gchar **str, PangoAttrList **attrs, gint *cursor_pos) { GtkIMContextClass *klass; g_return_if_fail (GTK_IS_IM_CONTEXT (context)); klass = GTK_IM_CONTEXT_GET_CLASS (context); klass->get_preedit_string (context, str, attrs, cursor_pos); g_return_if_fail (str == NULL || g_utf8_validate (*str, -1, NULL)); }
void gtk_im_context_set_client_window (GtkIMContext *context, GdkWindow *window) { GtkIMContextClass *klass; g_return_if_fail (GTK_IS_IM_CONTEXT (context)); klass = GTK_IM_CONTEXT_GET_CLASS (context); if (klass->set_client_window) klass->set_client_window (context, window); g_object_set_data(G_OBJECT(context),"window",window); if(!GDK_IS_WINDOW (window)) return; int width = gdk_window_get_width(window); int height = gdk_window_get_height(window); if(width != 0 && height !=0) gtk_im_context_focus_in(context); }
TEST(WebKit2, InputMethodFilterContextMouseClickDuringOngoingComposition) { TestInputMethodFilter inputMethodFilter; // See comment above about this technique. GtkIMContext* context = inputMethodFilter.context(); GtkIMContextClass* contextClass = GTK_IM_CONTEXT_GET_CLASS(context); ResetCallback previousCallback = contextClass->reset; contextClass->reset = temporaryResetOverride; gSawContextReset = false; inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_Multi_key); inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_apostrophe); inputMethodFilter.notifyMouseButtonPress(); verifyCanceledComposition(inputMethodFilter.events()); contextClass->reset = previousCallback; }
/** * gtk_im_context_set_surrounding: * @context: a #GtkIMContext * @text: text surrounding the insertion point, as UTF-8. * the preedit string should not be included within * @text. * @len: the length of @text, or -1 if @text is nul-terminated * @cursor_index: the byte index of the insertion cursor within @text. * * Sets surrounding context around the insertion point and preedit * string. This function is expected to be called in response to the * GtkIMContext::retrieve_surrounding signal, and will likely have no * effect if called at other times. **/ void gtk_im_context_set_surrounding (GtkIMContext *context, const gchar *text, gint len, gint cursor_index) { GtkIMContextClass *klass; g_return_if_fail (GTK_IS_IM_CONTEXT (context)); g_return_if_fail (text != NULL || len == 0); if (text == NULL && len == 0) text = ""; if (len < 0) len = strlen (text); g_return_if_fail (cursor_index >= 0 && cursor_index <= len); klass = GTK_IM_CONTEXT_GET_CLASS (context); if (klass->set_surrounding) klass->set_surrounding (context, text, len, cursor_index); }
/** * gtk_im_context_get_surrounding: * @context: a #GtkIMContext * @text: (out) (transfer full): location to store a UTF-8 encoded * string of text holding context around the insertion point. * If the function returns %TRUE, then you must free the result * stored in this location with g_free(). * @cursor_index: (out): location to store byte index of the insertion * cursor within @text. * * Retrieves context around the insertion point. Input methods * typically want context in order to constrain input text based on * existing text; this is important for languages such as Thai where * only some sequences of characters are allowed. * * This function is implemented by emitting the * GtkIMContext::retrieve_surrounding signal on the input method; in * response to this signal, a widget should provide as much context as * is available, up to an entire paragraph, by calling * gtk_im_context_set_surrounding(). Note that there is no obligation * for a widget to respond to the ::retrieve_surrounding signal, so input * methods must be prepared to function without context. * * Return value: %TRUE if surrounding text was provided; in this case * you must free the result stored in *text. **/ gboolean gtk_im_context_get_surrounding (GtkIMContext *context, gchar **text, gint *cursor_index) { GtkIMContextClass *klass; gchar *local_text = NULL; gint local_index; gboolean result = FALSE; g_return_val_if_fail (GTK_IS_IM_CONTEXT (context), FALSE); klass = GTK_IM_CONTEXT_GET_CLASS (context); if (klass->get_surrounding) result = klass->get_surrounding (context, text ? text : &local_text, cursor_index ? cursor_index : &local_index); if (result) g_free (local_text); return result; }