text: Split out cursor_position
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@openismus.com>
This commit is contained in:
parent
964b517c9b
commit
1cc9e08d2f
@ -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);
|
||||
}
|
||||
@ -194,6 +199,19 @@ text_model_delete_surrounding_text(void *data,
|
||||
end - start);
|
||||
}
|
||||
|
||||
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,
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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("");
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
<request name="modifiers_map">
|
||||
<arg name="map" type="array"/>
|
||||
</request>
|
||||
|
@ -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"/>
|
||||
|
@ -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
|
||||
@ -453,6 +452,18 @@ input_method_context_delete_surrounding_text(struct wl_client *client,
|
||||
text_model_send_delete_surrounding_text(&context->model->resource, serial, index, length);
|
||||
}
|
||||
|
||||
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,
|
||||
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user