From: Jan Arne Petersen <jpeter...@openismus.com>

Signed-off-by: Jan Arne Petersen <jpeter...@openismus.com>
---
 clients/editor.c | 76 ++++++++++++++++++++++++++++++++------------------------
 1 file changed, 44 insertions(+), 32 deletions(-)

diff --git a/clients/editor.c b/clients/editor.c
index 7c90ed9..03cdc12 100644
--- a/clients/editor.c
+++ b/clients/editor.c
@@ -27,6 +27,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdbool.h>
 
 #include <linux/input.h>
 #include <cairo.h>
@@ -69,6 +70,7 @@ struct text_entry {
        uint32_t content_purpose;
        uint32_t click_to_show;
        char *preferred_language;
+       bool button_pressed;
 };
 
 struct editor {
@@ -112,6 +114,9 @@ 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 int text_entry_motion_handler(struct widget *widget,
+                                    struct input *input, uint32_t time,
+                                    float x, float y, void *data);
 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,
@@ -472,6 +477,7 @@ text_entry_create(struct editor *editor, const char *text)
 
        widget_set_redraw_handler(entry->widget, text_entry_redraw_handler);
        widget_set_button_handler(entry->widget, text_entry_button_handler);
+       widget_set_motion_handler(entry->widget, text_entry_motion_handler);
 
        return entry;
 }
@@ -772,42 +778,42 @@ text_entry_try_invoke_preedit_action(struct text_entry 
*entry,
        return 1;
 }
 
+static bool
+text_entry_has_preedit(struct text_entry *entry)
+{
+       return entry->preedit.text && (strlen(entry->preedit.text) > 0);
+}
+
 static void
 text_entry_set_cursor_position(struct text_entry *entry,
-                              int32_t x, int32_t y)
+                              int32_t x, int32_t y,
+                              bool move_anchor)
 {
        int index, trailing;
        const char *text;
-
-       text_entry_commit_and_reset(entry);
+       uint32_t cursor;
 
        pango_layout_xy_to_index(entry->layout,
                                 x * PANGO_SCALE, y * PANGO_SCALE,
                                 &index, &trailing);
 
        text = pango_layout_get_text(entry->layout);
-       entry->cursor = g_utf8_offset_to_pointer(text + index, trailing) - text;
 
-       text_entry_update_layout(entry);
+       cursor = g_utf8_offset_to_pointer(text + index, trailing) - text;
 
-       widget_schedule_redraw(entry->widget);
+       if (move_anchor)
+               entry->anchor = cursor;
 
-       text_entry_update(entry);
-}
+       if (text_entry_has_preedit(entry)) {
+               text_entry_commit_and_reset(entry);
 
-static void
-text_entry_set_anchor_position(struct text_entry *entry,
-                              int32_t x, int32_t y)
-{
-       int index, trailing;
-       const char *text;
+               assert(!text_entry_has_preedit(entry));
+       }
 
-       pango_layout_xy_to_index(entry->layout,
-                                x * PANGO_SCALE, y * PANGO_SCALE,
-                                &index, &trailing);
+       if (entry->cursor == cursor)
+               return;
 
-       text = pango_layout_get_text(entry->layout);
-       entry->anchor = g_utf8_offset_to_pointer(text + index, trailing) - text;
+       entry->cursor = cursor;
 
        text_entry_update_layout(entry);
 
@@ -967,11 +973,16 @@ text_entry_motion_handler(struct widget *widget,
        struct text_entry *entry = data;
        struct rectangle allocation;
 
+       if (!entry->button_pressed) {
+               return CURSOR_IBEAM;
+       }
+
        widget_get_allocation(entry->widget, &allocation);
 
        text_entry_set_cursor_position(entry,
                                       x - allocation.x - text_offset_left,
-                                      y - allocation.y - text_offset_left);
+                                      y - allocation.y - text_offset_left,
+                                      false);
 
        return CURSOR_IBEAM;
 }
@@ -996,16 +1007,21 @@ text_entry_button_handler(struct widget *widget,
 
        editor = window_get_user_data(entry->window);
 
-       result = text_entry_try_invoke_preedit_action(entry, x, y, button, 
state);
-
-       if (result)
-               return;
+       if (button == BTN_LEFT) {
+               entry->button_pressed = (state == 
WL_POINTER_BUTTON_STATE_PRESSED);
 
-       if (button != BTN_LEFT) {
-               return;
+               if (state == WL_POINTER_BUTTON_STATE_PRESSED)
+                       input_grab(input, entry->widget, button);
+               else
+                       input_ungrab(input);
        }
 
-       text_entry_set_cursor_position(entry, x, y);
+       if (text_entry_has_preedit(entry)) {
+               result = text_entry_try_invoke_preedit_action(entry, x, y, 
button, state);
+
+               if (result)
+                       return;
+       }
 
        if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
                struct wl_seat *seat = input_get_seat(input);
@@ -1013,11 +1029,7 @@ text_entry_button_handler(struct widget *widget,
                text_entry_activate(entry, seat);
                editor->active_entry = entry;
 
-               text_entry_set_anchor_position(entry, x, y);
-
-               widget_set_motion_handler(entry->widget, 
text_entry_motion_handler);
-       } else {
-               widget_set_motion_handler(entry->widget, NULL);
+               text_entry_set_cursor_position(entry, x, y, true);
        }
 }
 
-- 
1.8.1.4

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to