[PATCH weston 03/31] Support wl_keyboard::modifiers event

Daniel Stone daniel at fooishbar.org
Wed May 30 08:31:41 PDT 2012


This event lets the compositor inform clients of the canonical keyboard
modifier/group state.  Make sure we send it at appropriate moments from
the compositor, and listen for it in clients as well.

Signed-off-by: Daniel Stone <daniel at fooishbar.org>
---
 clients/window.c         |   24 ++++++++++++++++++++----
 src/compositor-wayland.c |   10 ++++++++++
 src/compositor-x11.c     |    2 ++
 src/compositor.c         |   25 +++++++++++++++++++++++++
 src/compositor.h         |    4 ++++
 src/shell.c              |   23 ++++++++++++++++-------
 src/util.c               |   18 +++++++++++++++++-
 7 files changed, 94 insertions(+), 12 deletions(-)

diff --git a/clients/window.c b/clients/window.c
index 9eb62e6..3959bc6 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -1824,11 +1824,9 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
 		return;
 
 	num_syms = xkb_key_get_syms(d->xkb.state, code, &syms);
-	xkb_state_update_key(d->xkb.state, code,
-			     state ? XKB_KEY_DOWN : XKB_KEY_UP);
 
-	mask = xkb_state_serialize_mods(d->xkb.state, 
-					XKB_STATE_DEPRESSED | 
+	mask = xkb_state_serialize_mods(d->xkb.state,
+					XKB_STATE_DEPRESSED |
 					XKB_STATE_LATCHED);
 	input->modifiers = 0;
 	if (mask & input->display->xkb.control_mask)
@@ -1855,6 +1853,23 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
 }
 
 static void
+keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
+			  uint32_t serial, uint32_t mods_depressed,
+			  uint32_t mods_latched, uint32_t mods_locked,
+			  uint32_t group)
+{
+	struct input *input = data;
+
+	xkb_state_update_mask(input->display->xkb.state,
+			      mods_depressed,
+			      mods_latched,
+			      mods_locked,
+			      0,
+			      0,
+			      group);
+}
+
+static void
 input_remove_pointer_focus(struct input *input)
 {
 	struct window *window = input->pointer_focus;
@@ -1970,6 +1985,7 @@ static const struct wl_keyboard_listener keyboard_listener = {
 	keyboard_handle_enter,
 	keyboard_handle_leave,
 	keyboard_handle_key,
+	keyboard_handle_modifiers,
 };
 
 static void
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index bbacea4..332e1c2 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -608,10 +608,20 @@ input_handle_key(void *data, struct wl_keyboard *keyboard,
 	notify_key(&c->base.seat->seat, time, key, state);
 }
 
+static void
+input_handle_modifiers(void *data, struct wl_keyboard *keyboard,
+		       uint32_t serial, uint32_t mods_depressed,
+		       uint32_t mods_latched, uint32_t mods_locked,
+		       uint32_t group)
+{
+	/* XXX notify_modifiers(); */
+}
+
 static const struct wl_keyboard_listener keyboard_listener = {
 	input_handle_keyboard_enter,
 	input_handle_keyboard_leave,
 	input_handle_key,
+	input_handle_modifiers,
 };
 
 static void
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index 7452c1c..98baa8a 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -568,6 +568,7 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data)
 		case XCB_KEY_RELEASE:
 			key_release = (xcb_key_press_event_t *) prev;
 			key_press = (xcb_key_press_event_t *) event;
+			/* XXX use XkbSetDetectableAutoRepeat */
 			if ((event->response_type & ~0x80) == XCB_KEY_PRESS &&
 			    key_release->time == key_press->time &&
 			    key_release->detail == key_press->detail) {
@@ -654,6 +655,7 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data)
 			output = x11_compositor_find_output(c, enter_notify->event);
 			x = wl_fixed_from_int(output->base.x + enter_notify->event_x);
 			y = wl_fixed_from_int(output->base.y + enter_notify->event_y);
+			/* XXX notify_modifiers() */
 
 			notify_pointer_focus(&c->base.seat->seat,
 					     &output->base, x, y);
diff --git a/src/compositor.c b/src/compositor.c
index c9e6170..6baa554 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1656,6 +1656,15 @@ weston_surface_activate(struct weston_surface *surface,
 	wl_keyboard_set_focus(seat->seat.keyboard, &surface->surface);
 	wl_data_device_set_keyboard_focus(&seat->seat);
 
+	if (seat->seat.keyboard->focus_resource) {
+		wl_keyboard_send_modifiers(seat->seat.keyboard->focus_resource,
+					   wl_display_next_serial(compositor->wl_display),
+					   compositor->xkb_info.mods_depressed,
+					   compositor->xkb_info.mods_latched,
+					   compositor->xkb_info.mods_locked,
+					   compositor->xkb_info.group);
+	}
+
 	wl_signal_emit(&compositor->activate_signal, surface);
 }
 
@@ -1824,6 +1833,13 @@ notify_key(struct wl_seat *seat, uint32_t time, uint32_t key, uint32_t state)
 					      time, key, 0, 0, state);
 
 	grab->interface->key(grab, time, key, state);
+	if (mods)
+		grab->interface->modifiers(grab,
+					   wl_display_get_serial(compositor->wl_display),
+					   compositor->xkb_info.mods_depressed,
+					   compositor->xkb_info.mods_latched,
+					   compositor->xkb_info.mods_locked,
+					   compositor->xkb_info.group);
 }
 
 WL_EXPORT void
@@ -1880,6 +1896,15 @@ notify_keyboard_focus(struct wl_seat *seat, struct wl_array *keys)
 		if (surface) {
 			wl_list_remove(&ws->saved_kbd_focus_listener.link);
 			wl_keyboard_set_focus(ws->seat.keyboard, surface);
+
+			if (seat->keyboard->focus_resource) {
+				wl_keyboard_send_modifiers(seat->keyboard->focus_resource,
+							   wl_display_next_serial(compositor->wl_display),
+							   compositor->xkb_info.mods_depressed,
+							   compositor->xkb_info.mods_latched,
+							   compositor->xkb_info.mods_locked,
+							   compositor->xkb_info.group);
+			}
 			ws->saved_kbd_focus = NULL;
 		}
 	} else {
diff --git a/src/compositor.h b/src/compositor.h
index 5752e81..c9fe510 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -287,6 +287,10 @@ struct weston_compositor {
 		struct xkb_context *context;
 		struct xkb_keymap *keymap;
 		struct xkb_state *state;
+		uint32_t mods_depressed;
+		uint32_t mods_latched;
+		uint32_t mods_locked;
+		uint32_t group;
 	} xkb_info;
 };
 
diff --git a/src/shell.c b/src/shell.c
index e1f3a04..f818b4c 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -2450,7 +2450,7 @@ switcher_handle_surface_destroy(struct wl_listener *listener, void *data)
 }
 
 static void
-switcher_destroy(struct switcher *switcher, uint32_t time)
+switcher_destroy(struct switcher *switcher)
 {
 	struct weston_compositor *compositor = switcher->shell->compositor;
 	struct weston_surface *surface;
@@ -2474,17 +2474,26 @@ switcher_key(struct wl_keyboard_grab *grab,
 	     uint32_t time, uint32_t key, uint32_t state)
 {
 	struct switcher *switcher = container_of(grab, struct switcher, grab);
-	struct weston_seat *seat = (struct weston_seat *) grab->keyboard->seat;
 
-	if ((seat->modifier_state & switcher->shell->binding_modifier) == 0) {
-		switcher_destroy(switcher, time);
-	} else if (key == KEY_TAB && state) {
+	if (key == KEY_TAB && state)
 		switcher_next(switcher);
-	}
+}
+
+static void
+switcher_modifier(struct wl_keyboard_grab *grab, uint32_t serial,
+		  uint32_t mods_depressed, uint32_t mods_latched,
+		  uint32_t mods_locked, uint32_t group)
+{
+	struct switcher *switcher = container_of(grab, struct switcher, grab);
+	struct weston_seat *seat = (struct weston_seat *) grab->keyboard->seat;
+
+	if ((seat->modifier_state & switcher->shell->binding_modifier) == 0)
+		switcher_destroy(switcher);
 }
 
 static const struct wl_keyboard_grab_interface switcher_grab = {
-	switcher_key
+	switcher_key,
+	switcher_modifier,
 };
 
 static void
diff --git a/src/util.c b/src/util.c
index 33dd7db..01e5991 100644
--- a/src/util.c
+++ b/src/util.c
@@ -270,8 +270,24 @@ binding_key(struct wl_keyboard_grab *grab,
 	}
 }
 
+static void
+binding_modifiers(struct wl_keyboard_grab *grab, uint32_t serial,
+		  uint32_t mods_depressed, uint32_t mods_latched,
+		  uint32_t mods_locked, uint32_t group)
+{
+	struct wl_resource *resource;
+
+	resource = grab->keyboard->focus_resource;
+	if (!resource)
+		return;
+
+	wl_keyboard_send_modifiers(resource, serial, mods_depressed,
+				   mods_latched, mods_locked, group);
+}
+
 static const struct wl_keyboard_grab_interface binding_grab = {
-	binding_key
+	binding_key,
+	binding_modifiers,
 };
 
 static void
-- 
1.7.10



More information about the wayland-devel mailing list