xkb_mod_mask_t shift_mask;
} keysym;
uint32_t serial;
+ uint32_t reset_serial;
uint32_t content_purpose;
uint32_t click_to_show;
char *preferred_language;
{
struct text_entry *entry = data;
+ if ((entry->serial - serial) > (entry->serial - entry->reset_serial)) {
+ fprintf(stderr, "Ignore commit. Serial: %u, Current: %u, Reset: %u\n",
+ serial, entry->serial, entry->reset_serial);
+ return;
+ }
+
text_entry_reset_preedit(entry);
text_entry_delete_selected_text(entry);
static void
text_input_delete_surrounding_text(void *data,
struct text_input *text_input,
- uint32_t serial,
int32_t index,
uint32_t length)
{
static void
text_input_cursor_position(void *data,
struct text_input *text_input,
- uint32_t serial,
int32_t index,
int32_t anchor)
{
static void
text_input_preedit_styling(void *data,
struct text_input *text_input,
- uint32_t serial,
uint32_t index,
uint32_t length,
uint32_t style)
static void
text_input_preedit_cursor(void *data,
struct text_input *text_input,
- uint32_t serial,
int32_t index)
{
struct text_entry *entry = data;
entry->active = 1;
+ text_entry_update(entry);
+ entry->reset_serial = entry->serial;
+
widget_schedule_redraw(entry->widget);
}
if (!entry->click_to_show)
text_input_show_input_panel(entry->text_input);
- entry->serial++;
-
text_input_activate(entry->text_input,
- entry->serial,
seat,
surface);
}
text_input_set_cursor_rectangle(entry->text_input, cursor_rectangle.x, cursor_rectangle.y,
cursor_rectangle.width, cursor_rectangle.height);
- text_input_commit_state(entry->text_input);
+ text_input_commit_state(entry->text_input, ++entry->serial);
}
static void
free(commit);
}
- entry->serial++;
- text_input_reset(entry->text_input, entry->serial);
+ text_input_reset(entry->text_input);
+ text_entry_update(entry);
+ entry->reset_serial = entry->serial;
}
static void
"",
"");
input_method_context_cursor_position(keyboard->context,
- keyboard->serial,
0, 0);
input_method_context_commit_string(keyboard->context,
keyboard->serial,
if (keyboard->preedit_style)
input_method_context_preedit_styling(keyboard->context,
- keyboard->serial,
0,
strlen(keyboard->preedit_string),
keyboard->preedit_style);
if (cursor > 0)
index = cursor;
input_method_context_preedit_cursor(keyboard->context,
- keyboard->serial,
index);
input_method_context_preedit_string(keyboard->context,
keyboard->serial,
if (strlen(keyboard->keyboard->preedit_string) == 0) {
input_method_context_delete_surrounding_text(keyboard->keyboard->context,
- keyboard->keyboard->serial,
-1, 1);
} else {
keyboard->keyboard->preedit_string[strlen(keyboard->keyboard->preedit_string) - 1] = '\0';
static void
handle_reset(void *data,
- struct input_method_context *context,
- uint32_t serial)
+ struct input_method_context *context)
{
struct virtual_keyboard *keyboard = data;
free(keyboard->preedit_string);
keyboard->preedit_string = strdup("");
}
-
- keyboard->serial = serial;
}
static void
}
static void
-handle_commit(void *data,
- struct input_method_context *context)
+handle_commit_state(void *data,
+ struct input_method_context *context,
+ uint32_t serial)
{
struct virtual_keyboard *keyboard = data;
const struct layout *layout;
+ keyboard->serial = serial;
+
layout = get_current_layout(keyboard);
if (keyboard->surrounding_text)
handle_reset,
handle_content_type,
handle_invoke_action,
- handle_commit,
+ handle_commit_state,
handle_preferred_language
};
static void
input_method_activate(void *data,
struct input_method *input_method,
- struct input_method_context *context,
- uint32_t serial)
+ struct input_method_context *context)
{
struct virtual_keyboard *keyboard = data;
struct wl_array modifiers_map;
free(keyboard->surrounding_text);
keyboard->surrounding_text = NULL;
- keyboard->serial = serial;
+ keyboard->serial = 0;
keyboard->context = context;
input_method_context_add_listener(context,
static void
handle_reset(void *data,
- struct input_method_context *context,
- uint32_t serial)
+ struct input_method_context *context)
{
struct simple_im *keyboard = data;
fprintf(stderr, "Reset pre-edit buffer\n");
keyboard->compose_state = state_normal;
-
- keyboard->serial = serial;
}
static void
}
static void
-handle_commit(void *data,
- struct input_method_context *context)
+handle_commit_state(void *data,
+ struct input_method_context *context,
+ uint32_t serial)
{
+ struct simple_im *keyboard = data;
+
+ keyboard->serial = serial;
}
static void
handle_reset,
handle_content_type,
handle_invoke_action,
- handle_commit,
+ handle_commit_state,
handle_preferred_language
};
static void
input_method_activate(void *data,
struct input_method *input_method,
- struct input_method_context *context,
- uint32_t serial)
+ struct input_method_context *context)
{
struct simple_im *keyboard = data;
keyboard->compose_state = state_normal;
- keyboard->serial = serial;
+ keyboard->serial = 0;
keyboard->context = context;
input_method_context_add_listener(context,
for (i = 0; i < sizeof(ignore_keys_on_compose) / sizeof(ignore_keys_on_compose[0]); i++) {
if (sym == ignore_keys_on_compose[i]) {
- input_method_context_key(context, serial, time, key, state);
+ input_method_context_key(context, keyboard->serial, time, key, state);
return;
}
}
if (cs) {
if (cs->keys[i + 1] == 0) {
input_method_context_preedit_cursor(keyboard->context,
- keyboard->serial,
0);
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,
}
input_method_context_preedit_cursor(keyboard->context,
- keyboard->serial,
strlen(text));
input_method_context_preedit_string(keyboard->context,
keyboard->serial,
idx += xkb_keysym_to_utf8(keyboard->compose_seq.keys[j], text + idx, sizeof(text) - idx);
}
input_method_context_preedit_cursor(keyboard->context,
- keyboard->serial,
0);
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,
return;
input_method_context_cursor_position(keyboard->context,
- keyboard->serial,
0, 0);
input_method_context_commit_string(keyboard->context,
keyboard->serial,
receive information about the text model from the application via events.
Input method contexts do not keep state after deactivation and should be
destroyed after deactivation is handled.
+
+ Serials are used to synchronize the state between the text input and
+ an input method. New serials are sent by the text input in the
+ commit_state request and are used by the input method to indicate
+ the known text input state in events like preedit_string, commit_string,
+ and keysym. The text input can then ignore events from the input method
+ which are based on an outdated state (for example after a reset).
</description>
<request name="destroy" type="destructor"/>
<request name="commit_string">
This request should be sent before sending preedit_string request.
</description>
- <arg name="serial" type="uint"/>
<arg name="index" type="uint"/>
<arg name="length" type="uint"/>
<arg name="style" type="uint"/>
This request should be sent before sending preedit_string request.
</description>
- <arg name="serial" type="uint"/>
<arg name="index" type="int"/>
</request>
<request name="delete_surrounding_text">
- <arg name="serial" type="uint"/>
<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>
<arg name="anchor" type="uint"/>
</event>
<event name="reset">
- <arg name="serial" type="uint"/>
</event>
<event name="content_type">
<arg name="hint" type="uint"/>
<arg name="button" type="uint"/>
<arg name="index" type="uint"/>
</event>
- <event name="commit"/>
+ <event name="commit_state">
+ <arg name="serial" type="uint"/>
+ </event>
<event name="preferred_language">
<arg name="language" type="string"/>
</event>
which allows communication with the text model.
</description>
<arg name="id" type="new_id" interface="input_method_context"/>
- <arg name="serial" type="uint"/>
</event>
<event name="deactivate">
<description summary="activate event">
<protocol name="text">
<copyright>
- Copyright © 2012 Intel Corporation
+ Copyright © 2012, 2013 Intel Corporation
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
the pre-edit and commit events. Using this interface removes the need
for applications to directly process hardware key events and compose text
out of them.
+
+ Serials are used to synchronize the state between the text input and
+ an input method. New serials are sent by the text input in the
+ commit_state request and are used by the input method to indicate
+ the known text input state in events like preedit_string, commit_string,
+ and keysym. The text input can then ignore events from the input method
+ which are based on an outdated state (for example after a reset).
</description>
<request name="activate">
<description summary="request activation">
text-input object and tracked for focus lost. The enter event
is emitted on successful activation.
</description>
- <arg name="serial" type="uint"/>
<arg name="seat" type="object" interface="wl_seat"/>
<arg name="surface" type="object" interface="wl_surface"/>
</request>
reset, for example after the text was changed outside of the normal
input method flow.
</description>
- <arg name="serial" type="uint"/>
</request>
<request name="set_surrounding_text">
<description summary="sets the surrounding text">
<arg name="language" type="string"/>
</request>
<request name="commit_state">
+ <arg name="serial" type="uint" summary="used to identify the known state"/>
</request>
<request name="invoke_action">
<arg name="button" type="uint"/>
The commit text can be used to replace the preedit text on reset
(for example on unfocus).
</description>
- <arg name="serial" type="uint"/>
+ <arg name="serial" type="uint" summary="serial of the latest known text input state"/>
<arg name="text" type="string"/>
<arg name="commit" type="string"/>
</event>
This event should be handled as part of a following preedit_string
event.
</description>
- <arg name="serial" type="uint"/>
<arg name="index" type="uint"/>
<arg name="length" type="uint"/>
<arg name="style" type="uint"/>
This event should be handled as part of a following preedit_string
event.
</description>
- <arg name="serial" type="uint"/>
<arg name="index" type="int"/>
</event>
<event name="commit_string">
Any previously set composing text should be removed.
</description>
- <arg name="serial" type="uint"/>
+ <arg name="serial" type="uint" summary="serial of the latest known text input state"/>
<arg name="text" type="string"/>
</event>
<event name="cursor_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>
deleted. Index is relative to the current cursor (as byte index).
Length is the length of deleted text (in bytes).
</description>
- <arg name="serial" type="uint"/>
<arg name="index" type="int"/>
<arg name="length" type="uint"/>
</event>
wl_keyboard key_state. Modifiers are a mask for effective modifiers
(where the modifier indices are set by the modifiers_map event)
</description>
- <arg name="serial" type="uint"/>
+ <arg name="serial" type="uint" summary="serial of the latest known text input state"/>
<arg name="time" type="uint"/>
<arg name="sym" type="uint"/>
<arg name="state" type="uint"/>
Sets the language of the input text. The "language" argument is a RFC-3066
format language tag.
</description>
- <arg name="serial" type="uint"/>
+ <arg name="serial" type="uint" summary="serial of the latest known text input state"/>
<arg name="language" type="string"/>
</event>
<enum name="text_direction">
editor when there is no input yet done and making sure neutral
direction text is laid out properly.
</description>
- <arg name="serial" type="uint"/>
+ <arg name="serial" type="uint" summary="serial of the latest known text input state"/>
<arg name="direction" type="uint"/>
</event>
</interface>
};
static void input_method_context_create(struct text_input *model,
- struct input_method *input_method,
- uint32_t serial);
+ struct input_method *input_method);
static void input_method_context_end_keyboard_grab(struct input_method_context *context);
static void input_method_init_seat(struct weston_seat *seat);
static void
text_input_activate(struct wl_client *client,
struct wl_resource *resource,
- uint32_t serial,
struct wl_resource *seat,
struct wl_resource *surface)
{
text_input->surface = surface->data;
- input_method_context_create(text_input, input_method, serial);
+ input_method_context_create(text_input, input_method);
if (text_input->input_panel_visible) {
wl_signal_emit(&ec->show_input_panel_signal, text_input->surface);
static void
text_input_reset(struct wl_client *client,
- struct wl_resource *resource,
- uint32_t serial)
+ struct wl_resource *resource)
{
struct text_input *text_input = resource->data;
struct input_method *input_method, *next;
wl_list_for_each_safe(input_method, next, &text_input->input_methods, link) {
if (!input_method->context)
continue;
- input_method_context_send_reset(&input_method->context->resource, serial);
+ input_method_context_send_reset(&input_method->context->resource);
}
}
static void
text_input_commit_state(struct wl_client *client,
- struct wl_resource *resource)
+ struct wl_resource *resource,
+ uint32_t serial)
{
struct text_input *text_input = resource->data;
struct input_method *input_method, *next;
wl_list_for_each_safe(input_method, next, &text_input->input_methods, link) {
if (!input_method->context)
continue;
- input_method_context_send_commit(&input_method->context->resource);
+ input_method_context_send_commit_state(&input_method->context->resource, serial);
}
}
static void
input_method_context_preedit_styling(struct wl_client *client,
struct wl_resource *resource,
- uint32_t serial,
uint32_t index,
uint32_t length,
uint32_t style)
{
struct input_method_context *context = resource->data;
- text_input_send_preedit_styling(&context->model->resource, serial, index, length, style);
+ text_input_send_preedit_styling(&context->model->resource, index, length, style);
}
static void
input_method_context_preedit_cursor(struct wl_client *client,
struct wl_resource *resource,
- uint32_t serial,
int32_t cursor)
{
struct input_method_context *context = resource->data;
- text_input_send_preedit_cursor(&context->model->resource, serial, cursor);
+ text_input_send_preedit_cursor(&context->model->resource, cursor);
}
static void
input_method_context_delete_surrounding_text(struct wl_client *client,
struct wl_resource *resource,
- uint32_t serial,
int32_t index,
uint32_t length)
{
struct input_method_context *context = resource->data;
- text_input_send_delete_surrounding_text(&context->model->resource, serial, index, length);
+ text_input_send_delete_surrounding_text(&context->model->resource, 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_input_send_cursor_position(&context->model->resource, serial, index, anchor);
+ text_input_send_cursor_position(&context->model->resource, index, anchor);
}
static void
static void
input_method_context_create(struct text_input *model,
- struct input_method *input_method,
- uint32_t serial)
+ struct input_method *input_method)
{
struct input_method_context *context;
wl_client_add_resource(input_method->input_method_binding->client, &context->resource);
- input_method_send_activate(input_method->input_method_binding, &context->resource, serial);
+ input_method_send_activate(input_method->input_method_binding, &context->resource);
}
static void
static void
text_input_delete_surrounding_text(void *data,
struct text_input *text_input,
- uint32_t serial,
int32_t index,
uint32_t length)
{
static void
text_input_cursor_position(void *data,
struct text_input *text_input,
- uint32_t serial,
int32_t index,
int32_t anchor)
{
static void
text_input_preedit_styling(void *data,
struct text_input *text_input,
- uint32_t serial,
uint32_t index,
uint32_t length,
uint32_t style)
static void
text_input_preedit_cursor(void *data,
struct text_input *text_input,
- uint32_t serial,
int32_t index)
{
}
assert(client->input->keyboard->focus == client->surface);
/* Activate test model and make sure we get enter event. */
- text_input_activate(text_input, 0, client->input->wl_seat,
+ text_input_activate(text_input, client->input->wl_seat,
client->surface->wl_surface);
client_roundtrip(client);
assert(state.activated == 1 && state.deactivated == 0);
assert(state.activated == 1 && state.deactivated == 1);
/* Activate test model again. */
- text_input_activate(text_input, 0, client->input->wl_seat,
+ text_input_activate(text_input, client->input->wl_seat,
client->surface->wl_surface);
client_roundtrip(client);
assert(state.activated == 2 && state.deactivated == 1);