[PATCH 1/5] editor: Fix text selection
Jan Arne Petersen
jpetersen at openismus.com
Thu May 30 04:57:01 PDT 2013
From: Jan Arne Petersen <jpetersen at openismus.com>
Signed-off-by: Jan Arne Petersen <jpetersen at 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
More information about the wayland-devel
mailing list