summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2021-07-30 16:40:17 +0200
committerMarge Bot <marge-bot@gnome.org>2021-09-03 22:05:46 +0000
commit765f41de803e9d14f31e3659015a6da3802535dc (patch)
treeeb8cd808671f95fff990e352a535f028bf7e5da0
parent9c20b4144ac2230724979b17d26362ec06e232b5 (diff)
downloadmutter-765f41de803e9d14f31e3659015a6da3802535dc.tar.gz
clutter: Add ClutterPreeditResetMode hint to preedit text
This mode is passed along by the ClutterInputMethod, the ClutterInputFocus will preserve it and ensure it is honored whenever the IM is being reset. This mode is immediate. The ClutterInputFocus commits the text directly without queueing a CLUTTER_IM_COMMIT event. This is important so events are serialized in the right order in the wayland implementations (i.e. commit before wl_pointer.press). Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1940>
-rw-r--r--clutter/clutter/clutter-enums.h6
-rw-r--r--clutter/clutter/clutter-event.h1
-rw-r--r--clutter/clutter/clutter-input-focus.c33
-rw-r--r--clutter/clutter/clutter-input-method.c28
-rw-r--r--clutter/clutter/clutter-input-method.h7
5 files changed, 59 insertions, 16 deletions
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)
@@ -54,8 +56,24 @@ clutter_input_focus_real_focus_out (ClutterInputFocus *focus)
}
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,