[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