[PATCH 5/5] text: Split out cursor_position

Yichao Yu yyc1992 at gmail.com
Fri Feb 1 10:27:07 PST 2013


On Thu, Jan 31, 2013 at 9:52 AM, Jan Arne Petersen
<jpetersen at openismus.com> wrote:
> From: Jan Arne Petersen <jpetersen at openismus.com>
>
> Add an extra cursor_position, which also allows to change the anchor
> (for slections). Change the index type to int to allow setting it before
> the beginning of a commited string.
>
> The cursor should not be moved as a direct repsonse to this event but
> atomically on the next commit_string event.
>
> Signed-off-by: Jan Arne Petersen <jpetersen at openismus.com>
> ---
>  clients/editor.c           | 50 +++++++++++++++++++++++++++++++++++-----------
>  clients/keyboard.c         |  6 ++++--
>  clients/weston-simple-im.c | 18 +++++++++++------
>  protocol/input-method.xml  |  6 +++++-
>  protocol/text.xml          | 10 +++++++++-
>  src/text-backend.c         | 18 ++++++++++++++---
>  6 files changed, 83 insertions(+), 25 deletions(-)
>
> diff --git a/clients/editor.c b/clients/editor.c
> index a830ead..32c3f9b 100644
> --- a/clients/editor.c
> +++ b/clients/editor.c
> @@ -53,6 +53,10 @@ struct text_entry {
>                 PangoAttrList *attr_list;
>                 int32_t cursor;
>         } preedit_info;
> +       struct {
> +               int32_t cursor;
> +               int32_t anchor;
> +       } pending_commit;
>         struct text_model *model;
>         PangoLayout *layout;
>         struct {
> @@ -112,7 +116,8 @@ static void text_entry_button_handler(struct widget *widget,
>                                       struct input *input, uint32_t time,
>                                       uint32_t button,
>                                       enum wl_pointer_button_state state, void *data);
> -static void text_entry_insert_at_cursor(struct text_entry *entry, const char *text);
> +static void text_entry_insert_at_cursor(struct text_entry *entry, const char *text,
> +                                       int32_t cursor, int32_t anchor);
>  static void text_entry_set_preedit(struct text_entry *entry,
>                                    const char *preedit_text,
>                                    int preedit_cursor);
> @@ -126,18 +131,18 @@ static void
>  text_model_commit_string(void *data,
>                          struct text_model *text_model,
>                          uint32_t serial,
> -                        const char *text,
> -                        uint32_t index)
> +                        const char *text)
>  {
>         struct text_entry *entry = data;
>
> -       if (index > strlen(text))
> -               fprintf(stderr, "Invalid cursor index %d\n", index);
> -
>         text_entry_reset_preedit(entry);
>
>         text_entry_delete_selected_text(entry);
> -       text_entry_insert_at_cursor(entry, text);
> +       text_entry_insert_at_cursor(entry, text,
> +                                   entry->pending_commit.cursor,
> +                                   entry->pending_commit.anchor);
> +
> +       memset(&entry->pending_commit, 0, sizeof entry->pending_commit);
>
>         widget_schedule_redraw(entry->widget);
>  }
> @@ -195,6 +200,19 @@ text_model_delete_surrounding_text(void *data,
>  }
>
>  static void
> +text_model_cursor_position(void *data,
> +                          struct text_model *text_model,
> +                          uint32_t serial,
> +                          int32_t index,
> +                          int32_t anchor)
> +{
> +       struct text_entry *entry = data;
> +
> +       entry->pending_commit.cursor = index;
> +       entry->pending_commit.anchor = anchor;
> +}
> +
> +static void
>  text_model_preedit_styling(void *data,
>                            struct text_model *text_model,
>                            uint32_t serial,
> @@ -377,6 +395,7 @@ static const struct text_model_listener text_model_listener = {
>         text_model_commit_string,
>         text_model_preedit_string,
>         text_model_delete_surrounding_text,
> +       text_model_cursor_position,
>         text_model_preedit_styling,
>         text_model_preedit_cursor,
>         text_model_modifiers_map,
> @@ -583,7 +602,8 @@ text_entry_update(struct text_entry *entry)
>  }
>
>  static void
> -text_entry_insert_at_cursor(struct text_entry *entry, const char *text)
> +text_entry_insert_at_cursor(struct text_entry *entry, const char *text,
> +                           int32_t cursor, int32_t anchor)
>  {
>         char *new_text = malloc(strlen(entry->text) + strlen(text) + 1);
>
> @@ -594,8 +614,14 @@ text_entry_insert_at_cursor(struct text_entry *entry, const char *text)
>
>         free(entry->text);
>         entry->text = new_text;
> -       entry->cursor += strlen(text);
> -       entry->anchor += strlen(text);
> +       if (anchor >= 0)
> +               entry->anchor = entry->cursor + strlen(text) + anchor;
> +       else
> +               entry->anchor = entry->cursor + 1 + anchor;
> +       if (cursor >= 0)
> +               entry->cursor += strlen(text) + cursor;
> +       else
> +               entry->cursor += 1 + cursor;
>
>         text_entry_update_layout(entry);
>
> @@ -629,7 +655,7 @@ text_entry_commit_and_reset(struct text_entry *entry)
>
>         text_entry_reset_preedit(entry);
>         if (commit) {
> -               text_entry_insert_at_cursor(entry, commit);
> +               text_entry_insert_at_cursor(entry, commit, 0, 0);
>                 free(commit);
>         }
>  }
> @@ -993,7 +1019,7 @@ key_handler(struct window *window,
>
>                         text_entry_commit_and_reset(entry);
>
> -                       text_entry_insert_at_cursor(entry, text);
> +                       text_entry_insert_at_cursor(entry, text, 0, 0);
>                         break;
>         }
>
> diff --git a/clients/keyboard.c b/clients/keyboard.c
> index 8d94870..3760ff7 100644
> --- a/clients/keyboard.c
> +++ b/clients/keyboard.c
> @@ -321,10 +321,12 @@ virtual_keyboard_commit_preedit(struct virtual_keyboard *keyboard)
>                                             keyboard->serial,
>                                             "",
>                                             "");
> +       input_method_context_cursor_position(keyboard->context,
> +                                            keyboard->serial,
> +                                            0, 0);
>         input_method_context_commit_string(keyboard->context,
>                                            keyboard->serial,
> -                                          keyboard->preedit_string,
> -                                          strlen(keyboard->preedit_string));
> +                                          keyboard->preedit_string);
>         free(keyboard->preedit_string);
>         keyboard->preedit_string = strdup("");
>  }
> diff --git a/clients/weston-simple-im.c b/clients/weston-simple-im.c
> index fab7fc5..e955d3c 100644
> --- a/clients/weston-simple-im.c
> +++ b/clients/weston-simple-im.c
> @@ -409,10 +409,12 @@ simple_im_key_handler(struct simple_im *keyboard,
>                                 input_method_context_preedit_string(keyboard->context,
>                                                                     keyboard->serial,
>                                                                     "", "");
> +                               input_method_context_cursor_position(keyboard->context,
> +                                                                    keyboard->serial,
> +                                                                    0, 0);
>                                 input_method_context_commit_string(keyboard->context,
>                                                                    keyboard->serial,
> -                                                                  cs->text,
> -                                                                  strlen(cs->text));
> +                                                                  cs->text);
>                                 keyboard->compose_state = state_normal;
>                         } else {
>                                 uint32_t j = 0, idx = 0;
> @@ -441,10 +443,12 @@ simple_im_key_handler(struct simple_im *keyboard,
>                         input_method_context_preedit_string(keyboard->context,
>                                                             keyboard->serial,
>                                                             "", "");
> +                       input_method_context_cursor_position(keyboard->context,
> +                                                            keyboard->serial,
> +                                                            0, 0);
>                         input_method_context_commit_string(keyboard->context,
>                                                            keyboard->serial,
> -                                                          text,
> -                                                          strlen(text));
> +                                                          text);
>                         keyboard->compose_state = state_normal;
>                 }
>                 return;
> @@ -458,10 +462,12 @@ simple_im_key_handler(struct simple_im *keyboard,
>         if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
>                 return;
>
> +       input_method_context_cursor_position(keyboard->context,
> +                                            keyboard->serial,
> +                                            0, 0);
>         input_method_context_commit_string(keyboard->context,
>                                            keyboard->serial,
> -                                          text,
> -                                          strlen(text));
> +                                          text);
>  }
>
>  int
> diff --git a/protocol/input-method.xml b/protocol/input-method.xml
> index 690aee1..a59201b 100644
> --- a/protocol/input-method.xml
> +++ b/protocol/input-method.xml
> @@ -41,7 +41,6 @@
>        </description>
>        <arg name="serial" type="uint"/>
>        <arg name="text" type="string"/>
> -      <arg name="index" type="uint"/>
>      </request>
>      <request name="preedit_string">
>        <description summary="pre-edit string">
> @@ -70,6 +69,11 @@
>        <arg name="index" type="int"/>
>        <arg name="length" type="uint"/>
>      </request>
> +    <request name="cursor_position">
> +      <arg name="serial" type="uint"/>
> +      <arg name="index" type="int"/>
> +      <arg name="anchor" type="int"/>
> +    </request>

Just a off-topic question, there seems to be lots of "serial" arg's in
wayland protocol including the input method one. However, I cannot
find a detail explanation of them (or maybe I have missed sth). Since
the time stamp in xim can already cause problems (which probably
caused by the roundtrip in xim) isn't it better to explain how these
serial's should be used, in particular how the im-client, input
method, compositor should handle them? THX

>      <request name="modifiers_map">
>        <arg name="map" type="array"/>
>      </request>
> diff --git a/protocol/text.xml b/protocol/text.xml
> index 749c8c2..28d12ed 100644
> --- a/protocol/text.xml
> +++ b/protocol/text.xml
> @@ -161,7 +161,6 @@
>        </description>
>        <arg name="serial" type="uint"/>
>        <arg name="text" type="string"/>
> -      <arg name="index" type="uint"/>
>      </event>
>      <event name="preedit_string">
>        <description summary="pre-edit">
> @@ -186,6 +185,15 @@
>        <arg name="index" type="int"/>
>        <arg name="length" type="uint"/>
>      </event>
> +    <event name="cursor_position">
> +      <description summary="set cursor to new position">
> +        Notify when the cursor or anchor position should be modified. It
> +        should take effect after the next commit_string event.
> +      </description>
> +      <arg name="serial" type="uint"/>
> +      <arg name="index" type="int"/>
> +      <arg name="anchor" type="int"/>
> +    </event>
>      <enum name="preedit_style">
>        <entry name="default" value="1"/>
>        <entry name="active" value="2"/>
> diff --git a/src/text-backend.c b/src/text-backend.c
> index 00ca46e..a92aebe 100644
> --- a/src/text-backend.c
> +++ b/src/text-backend.c
> @@ -397,12 +397,11 @@ static void
>  input_method_context_commit_string(struct wl_client *client,
>                                    struct wl_resource *resource,
>                                    uint32_t serial,
> -                                  const char *text,
> -                                  uint32_t index)
> +                                  const char *text)
>  {
>         struct input_method_context *context = resource->data;
>
> -       text_model_send_commit_string(&context->model->resource, serial, text, index);
> +       text_model_send_commit_string(&context->model->resource, serial, text);
>  }
>
>  static void
> @@ -454,6 +453,18 @@ input_method_context_delete_surrounding_text(struct wl_client *client,
>  }
>
>  static void
> +input_method_context_cursor_position(struct wl_client *client,
> +                                    struct wl_resource *resource,
> +                                    uint32_t serial,
> +                                    int32_t index,
> +                                    int32_t anchor)
> +{
> +       struct input_method_context *context = resource->data;
> +
> +       text_model_send_cursor_position(&context->model->resource, serial, index, anchor);
> +}
> +
> +static void
>  input_method_context_modifiers_map(struct wl_client *client,
>                                    struct wl_resource *resource,
>                                    struct wl_array *map)
> @@ -597,6 +608,7 @@ static const struct input_method_context_interface input_method_context_implemen
>         input_method_context_preedit_styling,
>         input_method_context_preedit_cursor,
>         input_method_context_delete_surrounding_text,
> +       input_method_context_cursor_position,
>         input_method_context_modifiers_map,
>         input_method_context_keysym,
>         input_method_context_grab_keyboard,
> --
> 1.8.1
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list