diff --git a/clutter/clutter/clutter-enums.h b/clutter/clutter/clutter-enums.h index 458d0fd2c..54344248f 100644 --- a/clutter/clutter/clutter-enums.h +++ b/clutter/clutter/clutter-enums.h @@ -1638,6 +1638,12 @@ typedef enum CLUTTER_INPUT_PANEL_STATE_TOGGLE, } ClutterInputPanelState; +typedef enum +{ + CLUTTER_PREEDIT_RESET_CLEAR, + CLUTTER_PREEDIT_RESET_COMMIT, +} ClutterPreeditResetMode; + G_END_DECLS #endif /* __CLUTTER_ENUMS_H__ */ diff --git a/clutter/clutter/clutter-event.h b/clutter/clutter/clutter-event.h index b77e64d15..a14b2eca3 100644 --- a/clutter/clutter/clutter-event.h +++ b/clutter/clutter/clutter-event.h @@ -561,6 +561,7 @@ struct _ClutterIMEvent char *text; int32_t offset; uint32_t len; + ClutterPreeditResetMode mode; }; /** diff --git a/clutter/clutter/clutter-input-focus.c b/clutter/clutter/clutter-input-focus.c index b54e64aa3..c22e3a32c 100644 --- a/clutter/clutter/clutter-input-focus.c +++ b/clutter/clutter/clutter-input-focus.c @@ -30,6 +30,8 @@ typedef struct _ClutterInputFocusPrivate ClutterInputFocusPrivate; struct _ClutterInputFocusPrivate { ClutterInputMethod *im; + char *preedit; + ClutterPreeditResetMode mode; }; G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterInputFocus, clutter_input_focus, G_TYPE_OBJECT) @@ -53,9 +55,25 @@ clutter_input_focus_real_focus_out (ClutterInputFocus *focus) priv->im = NULL; } +static void +clutter_input_focus_finalize (GObject *object) +{ + ClutterInputFocus *focus = CLUTTER_INPUT_FOCUS (object); + ClutterInputFocusPrivate *priv = + clutter_input_focus_get_instance_private (focus); + + g_clear_pointer (&priv->preedit, g_free); + + G_OBJECT_CLASS (clutter_input_focus_parent_class)->finalize (object); +} + static void clutter_input_focus_class_init (ClutterInputFocusClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = clutter_input_focus_finalize; + klass->focus_in = clutter_input_focus_real_focus_in; klass->focus_out = clutter_input_focus_real_focus_out; } @@ -85,6 +103,14 @@ clutter_input_focus_reset (ClutterInputFocus *focus) priv = clutter_input_focus_get_instance_private (focus); + if (priv->preedit && + priv->mode == CLUTTER_PREEDIT_RESET_COMMIT) + clutter_input_focus_commit (focus, priv->preedit); + + clutter_input_focus_set_preedit_text (focus, NULL, 0); + g_clear_pointer (&priv->preedit, g_free); + priv->mode = CLUTTER_PREEDIT_RESET_CLEAR; + clutter_input_method_reset (priv->im); } @@ -175,13 +201,16 @@ clutter_input_focus_filter_event (ClutterInputFocus *focus, } else if (event->type == CLUTTER_IM_PREEDIT) { + g_clear_pointer (&priv->preedit, g_free); + priv->preedit = g_strdup (event->im.text); + priv->mode = event->im.mode; clutter_input_focus_set_preedit_text (focus, event->im.text, event->im.offset); return TRUE; } else if (event->type == CLUTTER_TOUCH_BEGIN || - (event->type == CLUTTER_BUTTON_PRESS && - event->button.button == CLUTTER_BUTTON_PRIMARY)) + (event->type == CLUTTER_BUTTON_PRESS && + event->button.button == CLUTTER_BUTTON_PRIMARY)) { clutter_input_focus_reset (focus); /* pointing events are not consumed by IMs */ diff --git a/clutter/clutter/clutter-input-method.c b/clutter/clutter/clutter-input-method.c index ff62925a5..be1a3c99c 100644 --- a/clutter/clutter/clutter-input-method.c +++ b/clutter/clutter/clutter-input-method.c @@ -278,11 +278,12 @@ clutter_input_method_get_focus (ClutterInputMethod *im) } static void -clutter_input_method_put_im_event (ClutterInputMethod *im, - ClutterEventType event_type, - const char *text, - int32_t offset, - uint32_t len) +clutter_input_method_put_im_event (ClutterInputMethod *im, + ClutterEventType event_type, + const char *text, + int32_t offset, + uint32_t len, + ClutterPreeditResetMode mode) { ClutterInputDevice *keyboard; ClutterSeat *seat; @@ -299,6 +300,7 @@ clutter_input_method_put_im_event (ClutterInputMethod *im, event->im.text = g_strdup (text); event->im.offset = offset; event->im.len = len; + event->im.mode = mode; clutter_event_set_device (event, keyboard); clutter_event_set_source_device (event, keyboard); clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_INPUT_METHOD); @@ -315,7 +317,8 @@ clutter_input_method_commit (ClutterInputMethod *im, { g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - clutter_input_method_put_im_event (im, CLUTTER_IM_COMMIT, text, 0, 0); + clutter_input_method_put_im_event (im, CLUTTER_IM_COMMIT, text, 0, 0, + CLUTTER_PREEDIT_RESET_CLEAR); } void @@ -325,7 +328,8 @@ clutter_input_method_delete_surrounding (ClutterInputMethod *im, { g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - clutter_input_method_put_im_event (im, CLUTTER_IM_DELETE, NULL, offset, len); + clutter_input_method_put_im_event (im, CLUTTER_IM_DELETE, NULL, offset, len, + CLUTTER_PREEDIT_RESET_CLEAR); } void @@ -349,13 +353,15 @@ clutter_input_method_request_surrounding (ClutterInputMethod *im) * Sets the preedit text on the current input focus. **/ void -clutter_input_method_set_preedit_text (ClutterInputMethod *im, - const gchar *preedit, - guint cursor) +clutter_input_method_set_preedit_text (ClutterInputMethod *im, + const gchar *preedit, + unsigned int cursor, + ClutterPreeditResetMode mode) { g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - clutter_input_method_put_im_event (im, CLUTTER_IM_PREEDIT, preedit, cursor, 0); + clutter_input_method_put_im_event (im, CLUTTER_IM_PREEDIT, preedit, + cursor, 0, mode); } void diff --git a/clutter/clutter/clutter-input-method.h b/clutter/clutter/clutter-input-method.h index b7f9a474e..cc11545c8 100644 --- a/clutter/clutter/clutter-input-method.h +++ b/clutter/clutter/clutter-input-method.h @@ -74,9 +74,10 @@ CLUTTER_EXPORT void clutter_input_method_request_surrounding (ClutterInputMethod *im); CLUTTER_EXPORT -void clutter_input_method_set_preedit_text (ClutterInputMethod *im, - const gchar *preedit, - guint cursor); +void clutter_input_method_set_preedit_text (ClutterInputMethod *im, + const gchar *preedit, + unsigned int cursor, + ClutterPreeditResetMode mode); CLUTTER_EXPORT void clutter_input_method_notify_key_event (ClutterInputMethod *im,