[PATCH 2/5] text: add serial argument to text protocol

Jan Arne Petersen jpetersen at openismus.com
Fri Nov 30 08:01:41 PST 2012


From: Jan Arne Petersen <jpetersen at openismus.com>

The serial argument will allow to ignore outdated events from before a
reset request.

Signed-off-by: Jan Arne Petersen <jpetersen at openismus.com>
---
 clients/editor.c           | 13 ++++++++++++-
 clients/keyboard.c         | 20 ++++++++++++++++++--
 clients/weston-simple-im.c | 21 +++++++++++++++++++--
 protocol/input-method.xml  |  7 +++++++
 protocol/text.xml          |  7 +++++++
 src/text-backend.c         | 31 ++++++++++++++++++++-----------
 6 files changed, 83 insertions(+), 16 deletions(-)

diff --git a/clients/editor.c b/clients/editor.c
index 2198813..890b32c 100644
--- a/clients/editor.c
+++ b/clients/editor.c
@@ -64,6 +64,7 @@ struct text_entry {
 	struct {
 		xkb_mod_mask_t shift_mask;
 	} keysym;
+	uint32_t serial;
 };
 
 struct editor {
@@ -300,6 +301,7 @@ static void text_entry_delete_selected_text(struct text_entry *entry);
 static void
 text_model_commit_string(void *data,
 			 struct text_model *text_model,
+			 uint32_t serial,
 			 const char *text,
 			 uint32_t index)
 {
@@ -317,6 +319,7 @@ text_model_commit_string(void *data,
 static void
 text_model_preedit_string(void *data,
 			  struct text_model *text_model,
+			  uint32_t serial,
 			  const char *text,
 			  const char *commit)
 {
@@ -331,6 +334,7 @@ text_model_preedit_string(void *data,
 static void
 text_model_delete_surrounding_text(void *data,
 				   struct text_model *text_model,
+				   uint32_t serial,
 				   int32_t index,
 				   uint32_t length)
 {
@@ -362,6 +366,7 @@ text_model_delete_surrounding_text(void *data,
 static void
 text_model_preedit_styling(void *data,
 			   struct text_model *text_model,
+			   uint32_t serial,
 			   uint32_t index,
 			   uint32_t length,
 			   uint32_t style)
@@ -371,6 +376,7 @@ text_model_preedit_styling(void *data,
 static void
 text_model_preedit_cursor(void *data,
 			  struct text_model *text_model,
+			  uint32_t serial,
 			  int32_t index)
 {
 	struct text_entry *entry = data;
@@ -594,7 +600,10 @@ text_entry_activate(struct text_entry *entry,
 {
 	struct wl_surface *surface = window_get_wl_surface(entry->window);
 
+	entry->serial++;
+
 	text_model_activate(entry->model,
+			    entry->serial,
 			    seat,
 			    surface);
 }
@@ -681,7 +690,9 @@ text_entry_set_cursor_position(struct text_entry *entry,
 {
 	entry->cursor = text_layout_xy_to_index(entry->layout, x, y);
 
-	text_model_reset(entry->model);
+	entry->serial++;
+
+	text_model_reset(entry->model, entry->serial);
 
 	if (entry->preedit.cursor > 0 &&
 	    entry->cursor >= (uint32_t)entry->preedit.cursor) {
diff --git a/clients/keyboard.c b/clients/keyboard.c
index a32cf60..c1f2a7f 100644
--- a/clients/keyboard.c
+++ b/clients/keyboard.c
@@ -41,6 +41,7 @@ struct virtual_keyboard {
 	struct {
 		xkb_mod_mask_t shift_mask;
 	} keysym;
+	uint32_t serial;
 };
 
 enum key_type {
@@ -227,11 +228,14 @@ virtual_keyboard_commit_preedit(struct virtual_keyboard *keyboard)
 		return;
 
 	input_method_context_preedit_cursor(keyboard->context,
+					    keyboard->serial,
 					    0);
 	input_method_context_preedit_string(keyboard->context,
+					    keyboard->serial,
 					    "",
 					    "");
 	input_method_context_commit_string(keyboard->context,
+					   keyboard->serial,
 					   keyboard->preedit_string,
 					   strlen(keyboard->preedit_string));
 	free(keyboard->preedit_string);
@@ -253,8 +257,10 @@ keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *
 			keyboard->keyboard->preedit_string = strcat(keyboard->keyboard->preedit_string,
 								    label);
 			input_method_context_preedit_cursor(keyboard->keyboard->context,
+							    keyboard->keyboard->serial,
 							    strlen(keyboard->keyboard->preedit_string));
 			input_method_context_preedit_string(keyboard->keyboard->context,
+							    keyboard->keyboard->serial,
 							    keyboard->keyboard->preedit_string,
 							    keyboard->keyboard->preedit_string);
 			break;
@@ -264,12 +270,15 @@ keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *
 
 			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';
 				input_method_context_preedit_cursor(keyboard->keyboard->context,
+								    keyboard->keyboard->serial,
 								    strlen(keyboard->keyboard->preedit_string));
 				input_method_context_preedit_string(keyboard->keyboard->context,
+								    keyboard->keyboard->serial,
 								    keyboard->keyboard->preedit_string,
 								    keyboard->keyboard->preedit_string);
 			}
@@ -385,7 +394,8 @@ input_method_context_surrounding_text(void *data,
 
 static void
 input_method_context_reset(void *data,
-			   struct input_method_context *context)
+			   struct input_method_context *context,
+			   uint32_t serial)
 {
 	struct virtual_keyboard *keyboard = data;
 
@@ -393,13 +403,17 @@ input_method_context_reset(void *data,
 
 	if (strlen(keyboard->preedit_string)) {
 		input_method_context_preedit_cursor(context,
+						    serial,
 						    0);
 		input_method_context_preedit_string(context,
+						    serial,
 						    "",
 						    "");
 		free(keyboard->preedit_string);
 		keyboard->preedit_string = strdup("");
 	}
+
+	keyboard->serial = serial;
 }
 
 static const struct input_method_context_listener input_method_context_listener = {
@@ -410,7 +424,8 @@ static const struct input_method_context_listener input_method_context_listener
 static void
 input_method_activate(void *data,
 		      struct input_method *input_method,
-		      struct input_method_context *context)
+		      struct input_method_context *context,
+		      uint32_t serial)
 {
 	struct virtual_keyboard *keyboard = data;
 	struct wl_array modifiers_map;
@@ -422,6 +437,7 @@ input_method_activate(void *data,
 		free(keyboard->preedit_string);
 
 	keyboard->preedit_string = strdup("");
+	keyboard->serial = serial;
 
 	keyboard->context = context;
 	input_method_context_add_listener(context,
diff --git a/clients/weston-simple-im.c b/clients/weston-simple-im.c
index acc7112..bb01332 100644
--- a/clients/weston-simple-im.c
+++ b/clients/weston-simple-im.c
@@ -70,6 +70,8 @@ struct simple_im {
 	xkb_mod_mask_t shift_mask;
 
 	keyboard_input_key_handler_t key_handler;
+
+	uint32_t serial;
 };
 
 static const struct compose_seq compose_seqs[] = {
@@ -110,13 +112,16 @@ input_method_context_surrounding_text(void *data,
 
 static void
 input_method_context_reset(void *data,
-			   struct input_method_context *context)
+			   struct input_method_context *context,
+			   uint32_t serial)
 {
 	struct simple_im *keyboard = data;
 
 	fprintf(stderr, "Reset pre-edit buffer\n");
 
 	keyboard->compose_state = state_normal;
+
+	keyboard->serial = serial;
 }
 
 static const struct input_method_context_listener input_method_context_listener = {
@@ -247,7 +252,8 @@ static const struct wl_keyboard_listener input_method_keyboard_listener = {
 static void
 input_method_activate(void *data,
 		      struct input_method *input_method,
-		      struct input_method_context *context)
+		      struct input_method_context *context,
+		      uint32_t serial)
 {
 	struct simple_im *keyboard = data;
 
@@ -256,6 +262,8 @@ input_method_activate(void *data,
 
 	keyboard->compose_state = state_normal;
 
+	keyboard->serial = serial;
+
 	keyboard->context = context;
 	input_method_context_add_listener(context,
 					  &input_method_context_listener,
@@ -364,10 +372,13 @@ simple_im_key_handler(struct simple_im *keyboard,
 		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_commit_string(keyboard->context,
+								   keyboard->serial,
 								   cs->text,
 								   strlen(cs->text));
 				keyboard->compose_state = state_normal;
@@ -379,8 +390,10 @@ simple_im_key_handler(struct simple_im *keyboard,
 				}
 
 				input_method_context_preedit_cursor(keyboard->context,
+								    keyboard->serial,
 								    strlen(text));
 				input_method_context_preedit_string(keyboard->context,
+								    keyboard->serial,
 								    text,
 								    text);
 			}
@@ -391,10 +404,13 @@ simple_im_key_handler(struct simple_im *keyboard,
 				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_commit_string(keyboard->context,
+							   keyboard->serial,
 							   text,
 							   strlen(text));
 			keyboard->compose_state = state_normal;
@@ -411,6 +427,7 @@ simple_im_key_handler(struct simple_im *keyboard,
 		return;
 
 	input_method_context_commit_string(keyboard->context,
+					   keyboard->serial,
 					   text,
 					   strlen(text));
 }
diff --git a/protocol/input-method.xml b/protocol/input-method.xml
index 20d3667..03991f1 100644
--- a/protocol/input-method.xml
+++ b/protocol/input-method.xml
@@ -39,6 +39,7 @@
       <description summary="commit string">
         Send the commit string text to the applications text model.
       </description>
+      <arg name="serial" type="uint"/>
       <arg name="text" type="string"/>
       <arg name="index" type="uint"/>
     </request>
@@ -46,10 +47,12 @@
       <description summary="pre-edit string">
         Send the pre-edit string text to the applications text model.
       </description>
+      <arg name="serial" type="uint"/>
       <arg name="text" type="string"/>
       <arg name="commit" type="string"/>
     </request>
     <request name="preedit_styling">
+      <arg name="serial" type="uint"/>
       <arg name="index" type="uint"/>
       <arg name="length" type="uint"/>
       <arg name="style" type="uint"/>
@@ -59,9 +62,11 @@
         Sets the cursor position inside the composing text (as byte index)
         relative to the start of the composing text.
       </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>
@@ -116,6 +121,7 @@
       <arg name="anchor" type="uint"/>
     </event>
     <event name="reset">
+      <arg name="serial" type="uint"/>
     </event>
   </interface>
 
@@ -132,6 +138,7 @@
         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">
diff --git a/protocol/text.xml b/protocol/text.xml
index 5efeec8..bd74ee1 100644
--- a/protocol/text.xml
+++ b/protocol/text.xml
@@ -56,6 +56,7 @@
         model and tracked for focus lost. The activated 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>
@@ -73,6 +74,7 @@
         be reseted, for example after the text was changed outside of the
         normal input method flow.
       </description>
+      <arg name="serial" type="uint"/>
     </request>
     <request name="set_micro_focus">
       <arg name="x" type="int"/>
@@ -90,6 +92,7 @@
         or the result of some composing (pre-edit). It also sets the new
         cursor position (as byte index) relative to the inserted text.
       </description>
+      <arg name="serial" type="uint"/>
       <arg name="text" type="string"/>
       <arg name="index" type="uint"/>
     </event>
@@ -100,6 +103,7 @@
         be removed. It also sets the cursor position (as byte index) relative
         to the start of the composing text.
       </description>
+      <arg name="serial" type="uint"/>
       <arg name="text" type="string"/>
       <arg name="commit" type="string"/>
     </event>
@@ -109,6 +113,7 @@
         deleted. Index is relative to the current cursor (as byte index).
         Length is the length of deleted text (as bytes).
       </description>
+      <arg name="serial" type="uint"/>
       <arg name="index" type="int"/>
       <arg name="length" type="uint"/>
     </event>
@@ -122,6 +127,7 @@
       <entry name="incorrect" value="7"/>
     </enum>
     <event name="preedit_styling">
+      <arg name="serial" type="uint"/>
       <arg name="index" type="uint"/>
       <arg name="length" type="uint"/>
       <arg name="style" type="uint"/>
@@ -131,6 +137,7 @@
         Sets the cursor position inside the composing text (as byte index)
         relative to the start of the composing text.
       </description>
+      <arg name="serial" type="uint"/>
       <arg name="index" type="int"/>
     </event>
     <event name="modifiers_map">
diff --git a/src/text-backend.c b/src/text-backend.c
index 7f8c16e..cc8fa43 100644
--- a/src/text-backend.c
+++ b/src/text-backend.c
@@ -95,7 +95,8 @@ struct text_backend {
 };
 
 static void input_method_context_create(struct text_model *model,
-					struct input_method *input_method);
+					struct input_method *input_method,
+					uint32_t serial);
 static void input_method_context_end_keyboard_grab(struct input_method_context *context);
 
 static void input_method_init_seat(struct weston_seat *seat);
@@ -157,6 +158,7 @@ text_model_set_surrounding_text(struct wl_client *client,
 static void
 text_model_activate(struct wl_client *client,
 	            struct wl_resource *resource,
+		    uint32_t serial,
 		    struct wl_resource *seat,
 		    struct wl_resource *surface)
 {
@@ -180,7 +182,7 @@ text_model_activate(struct wl_client *client,
 
 	text_model->surface = surface->data;
 
-	input_method_context_create(text_model, input_method);
+	input_method_context_create(text_model, input_method, serial);
 
 	wl_signal_emit(&ec->show_input_panel_signal, ec);
 
@@ -201,7 +203,8 @@ text_model_deactivate(struct wl_client *client,
 
 static void
 text_model_reset(struct wl_client *client,
-		 struct wl_resource *resource)
+		 struct wl_resource *resource,
+		 uint32_t serial)
 {
 	struct text_model *text_model = resource->data;
 	struct input_method *input_method, *next;
@@ -209,7 +212,7 @@ text_model_reset(struct wl_client *client,
 	wl_list_for_each_safe(input_method, next, &text_model->input_methods, link) {
 		if (!input_method->context)
 			continue;
-		input_method_context_send_reset(&input_method->context->resource);
+		input_method_context_send_reset(&input_method->context->resource, serial);
 	}
 }
 
@@ -328,56 +331,61 @@ input_method_context_destroy(struct wl_client *client,
 static void
 input_method_context_commit_string(struct wl_client *client,
 				   struct wl_resource *resource,
+				   uint32_t serial,
 				   const char *text,
 				   uint32_t index)
 {
 	struct input_method_context *context = resource->data;
 
-	text_model_send_commit_string(&context->model->resource, text, index);
+	text_model_send_commit_string(&context->model->resource, serial, text, index);
 }
 
 static void
 input_method_context_preedit_string(struct wl_client *client,
 				    struct wl_resource *resource,
+				    uint32_t serial,
 				    const char *text,
 				    const char *commit)
 {
 	struct input_method_context *context = resource->data;
 
-	text_model_send_preedit_string(&context->model->resource, text, commit);
+	text_model_send_preedit_string(&context->model->resource, serial, text, commit);
 }
 
 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_model_send_preedit_styling(&context->model->resource, index, length, style);
+	text_model_send_preedit_styling(&context->model->resource, serial, 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_model_send_preedit_cursor(&context->model->resource, cursor);
+	text_model_send_preedit_cursor(&context->model->resource, serial, 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_model_send_delete_surrounding_text(&context->model->resource, index, length);
+	text_model_send_delete_surrounding_text(&context->model->resource, serial, index, length);
 }
 
 static void
@@ -541,7 +549,8 @@ destroy_input_method_context(struct wl_resource *resource)
 
 static void
 input_method_context_create(struct text_model *model,
-			    struct input_method *input_method)
+			    struct input_method *input_method,
+			    uint32_t serial)
 {
 	struct input_method_context *context;
 
@@ -568,7 +577,7 @@ input_method_context_create(struct text_model *model,
 
 	wl_client_add_resource(input_method->input_method_binding->client, &context->resource);
 
-	input_method_send_activate(input_method->input_method_binding, &context->resource);
+	input_method_send_activate(input_method->input_method_binding, &context->resource, serial);
 }
 
 static void
-- 
1.7.11.7



More information about the wayland-devel mailing list