Support wl_keyboard::modifiers event
authorDaniel Stone <daniel@fooishbar.org>
Thu, 31 May 2012 19:27:47 +0000 (15:27 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Thu, 31 May 2012 19:27:47 +0000 (15:27 -0400)
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@fooishbar.org>
clients/window.c
src/compositor-wayland.c
src/compositor-x11.c
src/compositor.c
src/compositor.h
src/shell.c
src/util.c

index ae8792e..012260d 100644 (file)
@@ -1831,11 +1831,9 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
                window->send_cursor_position = 1;
 
        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)
@@ -1862,6 +1860,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;
@@ -1977,6 +1992,7 @@ static const struct wl_keyboard_listener keyboard_listener = {
        keyboard_handle_enter,
        keyboard_handle_leave,
        keyboard_handle_key,
+       keyboard_handle_modifiers,
 };
 
 static void
index bbacea4..332e1c2 100644 (file)
@@ -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
index 7452c1c..98baa8a 100644 (file)
@@ -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);
index c562546..bfca256 100644 (file)
@@ -1654,6 +1654,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);
 }
 
@@ -1822,6 +1831,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
@@ -1878,6 +1894,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 {
index 09cd215..40301ae 100644 (file)
@@ -292,6 +292,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;
 };
 
index dc4fa47..4d11ba4 100644 (file)
@@ -2451,7 +2451,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;
@@ -2475,17 +2475,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
index 33dd7db..01e5991 100644 (file)
@@ -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