[mutter/wip/carlosg/im-update-preedit-with-mode: 14/16] clutter: Add ClutterPreeditResetMode hint to preedit text




commit 765f41de803e9d14f31e3659015a6da3802535dc
Author: Carlos Garnacho <carlosg gnome org>
Date:   Fri Jul 30 16:40:17 2021 +0200

    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>

 clutter/clutter/clutter-enums.h        |  6 ++++++
 clutter/clutter/clutter-event.h        |  1 +
 clutter/clutter/clutter-input-focus.c  | 33 +++++++++++++++++++++++++++++++--
 clutter/clutter/clutter-input-method.c | 28 +++++++++++++++++-----------
 clutter/clutter/clutter-input-method.h |  7 ++++---
 5 files changed, 59 insertions(+), 16 deletions(-)
---
diff --git a/clutter/clutter/clutter-enums.h b/clutter/clutter/clutter-enums.h
index 458d0fd2cc..54344248f4 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 b77e64d15c..a14b2eca38 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 b54e64aa30..c22e3a32c0 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 ff62925a51..be1a3c99c0 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 b7f9a474e1..cc11545c8c 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,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]