[PATCH 2/2] keyboard: fix to make it work in the presence of multiple seats

Philipp Brüschweiler blei42 at gmail.com
Sat Aug 11 03:12:29 PDT 2012


If a certain seat causes a button click, send the commit_string to the
input method that is assigned to the same seat.
---
 clients/keyboard.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++------
 1 Datei geändert, 72 Zeilen hinzugefügt(+), 9 Zeilen entfernt(-)

diff --git a/clients/keyboard.c b/clients/keyboard.c
index 9fdd8cc..fc8d5ae 100644
--- a/clients/keyboard.c
+++ b/clients/keyboard.c
@@ -20,6 +20,8 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <assert.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -33,11 +35,12 @@
 
 struct virtual_keyboard {
 	struct input_panel *input_panel;
-	struct input_method *input_method;
 	struct display *display;
+
+	struct wl_list input_methods;
 };
 
-struct keyboard {
+struct keyboard_window {
 	struct virtual_keyboard *keyboard;
 	struct window *window;
 	struct widget *widget;
@@ -45,10 +48,18 @@ struct keyboard {
 	int cy;
 };
 
+struct keyboard_input_method {
+	struct virtual_keyboard *keyboard;
+	struct input_method *input_method;
+	struct wl_seat *seat;
+
+	struct wl_list link;
+};
+
 static void
 redraw_handler(struct widget *widget, void *data)
 {
-	struct keyboard *keyboard = data;
+	struct keyboard_window *keyboard = data;
 	cairo_surface_t *surface;
 	struct rectangle allocation;
 	cairo_t *cr;
@@ -107,12 +118,30 @@ resize_handler(struct widget *widget,
 }
 
 static void
+commit_to_seat(struct virtual_keyboard *keyboard,
+	       struct wl_seat *seat,
+	       char *text,
+	       int32_t index)
+{
+	struct keyboard_input_method *im;
+	wl_list_for_each(im, &keyboard->input_methods, link)
+		if (seat == im->seat) {
+			input_method_commit_string(im->input_method,
+						   text, index);
+			return;
+		}
+
+	assert(false && "no input method for seat");
+}
+
+static void
 button_handler(struct widget *widget,
 	       struct input *input, uint32_t time,
 	       uint32_t button,
 	       enum wl_pointer_button_state state, void *data)
 {
-	struct keyboard *keyboard = data;
+	struct keyboard_window *keyboard = data;
+	struct wl_seat *seat = input_get_seat(input);
 	struct rectangle allocation;
 	int32_t x, y;	
 	char text[] = { '0', '\0' };
@@ -129,28 +158,60 @@ button_handler(struct widget *widget,
 
 	text[0] = y / keyboard->cy * 10 + x / keyboard->cx + '0';
 
-	input_method_commit_string(keyboard->keyboard->input_method, text, -1);
+	commit_to_seat(keyboard->keyboard, seat, text, -1);
 
 	widget_schedule_redraw(widget);
 }
 
 static void
+input_method_assigned_seat(void *data,
+			   struct input_method *input_method,
+			   struct wl_seat *seat)
+{
+	struct keyboard_input_method *im = data;
+	im->seat = seat;
+}
+
+static const struct input_method_listener input_method_listener = {
+	input_method_assigned_seat,
+};
+
+static void
+keyboard_input_method_create(struct virtual_keyboard *keyboard,
+			     struct input_method *input_method)
+{
+	struct keyboard_input_method *im = malloc(sizeof *im);
+	im->keyboard = keyboard;
+	im->input_method = input_method;
+	im->seat = NULL;
+
+	wl_list_insert(&keyboard->input_methods, &im->link);
+
+	input_method_add_listener(im->input_method,
+				  &input_method_listener,
+				  im);
+}
+
+static void
 global_handler(struct wl_display *display, uint32_t id,
 	       const char *interface, uint32_t version, void *data)
 {
 	struct virtual_keyboard *keyboard = data;
+	struct input_method *input_method;
 
 	if (!strcmp(interface, "input_panel")) {
 		keyboard->input_panel = wl_display_bind(display, id, &input_panel_interface);
 	} else if (!strcmp(interface, "input_method")) {
-		keyboard->input_method = wl_display_bind(display, id, &input_method_interface);
+		input_method = wl_display_bind(display, id, &input_method_interface);
+		keyboard_input_method_create(keyboard, input_method);
 	}
 }
 
 static void
-keyboard_create(struct output *output, struct virtual_keyboard *virtual_keyboard)
+keyboard_window_create(struct output *output,
+		       struct virtual_keyboard *virtual_keyboard)
 {
-	struct keyboard *keyboard;
+	struct keyboard_window *keyboard;
 
 	keyboard = malloc(sizeof *keyboard);
 	memset(keyboard, 0, sizeof *keyboard);
@@ -187,7 +248,7 @@ handle_output_configure(struct output *output, void *data)
 
 	output_set_user_data(output, virtual_keyboard);
 
-	keyboard_create(output, virtual_keyboard);
+	keyboard_window_create(output, virtual_keyboard);
 }
 
 int
@@ -201,6 +262,8 @@ main(int argc, char *argv[])
 		return -1;
 	}
 
+	wl_list_init(&virtual_keyboard.input_methods);
+
 	wl_display_add_global_listener(display_get_display(virtual_keyboard.display),
 				       global_handler, &virtual_keyboard);
 
-- 
1.7.11.4



More information about the wayland-devel mailing list