text: fix weston key bindings with input methods
authorJan Arne Petersen <jpetersen@openismus.com>
Wed, 16 Jan 2013 20:26:50 +0000 (21:26 +0100)
committerKristian Høgsberg <krh@bitplanet.net>
Fri, 15 Feb 2013 22:02:26 +0000 (17:02 -0500)
Add a struct weston_keyboard, to handle the input method grab.

Signed-off-by: Jan Arne Petersen <jpetersen@openismus.com>
src/compositor.c
src/compositor.h
src/shell.c
src/text-backend.c
src/util.c
tests/weston-test.c

index 764d622..63fe793 100644 (file)
@@ -1792,7 +1792,7 @@ notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
 WL_EXPORT void
 notify_modifiers(struct weston_seat *seat, uint32_t serial)
 {
-       struct wl_keyboard *keyboard = &seat->keyboard;
+       struct wl_keyboard *keyboard = &seat->keyboard.keyboard;
        struct wl_keyboard_grab *grab = keyboard->grab;
        uint32_t mods_depressed, mods_latched, mods_locked, group;
        uint32_t mods_lookup;
@@ -1881,10 +1881,10 @@ notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
           enum weston_key_state_update update_state)
 {
        struct weston_compositor *compositor = seat->compositor;
-       struct wl_keyboard *keyboard = seat->seat.keyboard;
+       struct weston_keyboard *keyboard = &seat->keyboard;
        struct weston_surface *focus =
-               (struct weston_surface *) keyboard->focus;
-       struct wl_keyboard_grab *grab = keyboard->grab;
+               (struct weston_surface *) keyboard->keyboard.focus;
+       struct wl_keyboard_grab *grab = keyboard->keyboard.grab;
        uint32_t serial = wl_display_next_serial(compositor->wl_display);
        uint32_t *k, *end;
 
@@ -1893,14 +1893,14 @@ notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
                        compositor->ping_handler(focus, serial);
 
                weston_compositor_idle_inhibit(compositor);
-               keyboard->grab_key = key;
-               keyboard->grab_time = time;
+               keyboard->keyboard.grab_key = key;
+               keyboard->keyboard.grab_time = time;
        } else {
                weston_compositor_idle_release(compositor);
        }
 
-       end = keyboard->keys.data + keyboard->keys.size;
-       for (k = keyboard->keys.data; k < end; k++) {
+       end = keyboard->keyboard.keys.data + keyboard->keyboard.keys.size;
+       for (k = keyboard->keyboard.keys.data; k < end; k++) {
                if (*k == key) {
                        /* Ignore server-generated repeats. */
                        if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
@@ -1908,16 +1908,17 @@ notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
                        *k = *--end;
                }
        }
-       keyboard->keys.size = (void *) end - keyboard->keys.data;
+       keyboard->keyboard.keys.size = (void *) end - keyboard->keyboard.keys.data;
        if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
-               k = wl_array_add(&keyboard->keys, sizeof *k);
+               k = wl_array_add(&keyboard->keyboard.keys, sizeof *k);
                *k = key;
        }
 
-       if (grab == &keyboard->default_grab) {
+       if (grab == &keyboard->keyboard.default_grab ||
+           grab == &keyboard->input_method_grab) {
                weston_compositor_run_key_binding(compositor, seat, time, key,
                                                  state);
-               grab = keyboard->grab;
+               grab = keyboard->keyboard.grab;
        }
 
        grab->interface->key(grab, time, key, state);
@@ -2507,8 +2508,8 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
 
        seat->xkb_state.leds = 0;
 
-       wl_keyboard_init(&seat->keyboard);
-       wl_seat_set_keyboard(&seat->seat, &seat->keyboard);
+       wl_keyboard_init(&seat->keyboard.keyboard);
+       wl_seat_set_keyboard(&seat->seat, &seat->keyboard.keyboard);
 
        seat->has_keyboard = 1;
 }
index 004f931..c0694e8 100644 (file)
@@ -211,11 +211,18 @@ struct weston_xkb_info {
        xkb_led_index_t scroll_led;
 };
 
+struct weston_keyboard {
+       struct wl_keyboard keyboard;
+
+       struct wl_keyboard_grab input_method_grab;
+       struct wl_resource *input_method_resource;
+};
+
 struct weston_seat {
        struct wl_seat seat;
        struct wl_pointer pointer;
        int has_pointer;
-       struct wl_keyboard keyboard;
+       struct weston_keyboard keyboard;
        int has_keyboard;
        struct wl_touch touch;
        int has_touch;
index 9fcce9f..598f286 100644 (file)
@@ -868,8 +868,8 @@ move_surface_to_workspace(struct desktop_shell *shell,
        drop_focus_state(shell, from, surface);
        wl_list_for_each(seat, &shell->compositor->seat_list, link)
                if (seat->has_keyboard &&
-                   seat->keyboard.focus == &surface->surface)
-                       wl_keyboard_set_focus(&seat->keyboard, NULL);
+                   seat->keyboard.keyboard.focus == &surface->surface)
+                       wl_keyboard_set_focus(&seat->keyboard.keyboard, NULL);
 
        weston_surface_damage_below(surface);
 }
@@ -3426,6 +3426,7 @@ switcher_destroy(struct switcher *switcher)
 {
        struct weston_surface *surface;
        struct wl_keyboard *keyboard = switcher->grab.keyboard;
+       struct weston_keyboard *weston_keyboard = (struct weston_keyboard *)keyboard;
        struct workspace *ws = get_current_workspace(switcher->shell);
 
        wl_list_for_each(surface, &ws->layer.surface_list, layer_link) {
@@ -3438,6 +3439,8 @@ switcher_destroy(struct switcher *switcher)
                         (struct weston_seat *) keyboard->seat);
        wl_list_remove(&switcher->listener.link);
        wl_keyboard_end_grab(keyboard);
+       if (weston_keyboard->input_method_resource)
+               keyboard->grab = &weston_keyboard->input_method_grab;
        free(switcher);
 }
 
@@ -3608,7 +3611,10 @@ debug_binding_key(struct wl_keyboard_grab *grab, uint32_t time,
        }
 
        if (terminate) {
+               struct weston_keyboard *weston_keyboard = (struct weston_keyboard *) grab->keyboard;
                wl_keyboard_end_grab(grab->keyboard);
+               if (weston_keyboard->input_method_resource)
+                       grab->keyboard->grab = &weston_keyboard->input_method_grab;
                free(db);
        }
 }
index e0b8b7d..c0cddfe 100644 (file)
@@ -77,7 +77,6 @@ struct input_method_context {
        struct wl_list link;
 
        struct wl_resource *keyboard;
-       struct wl_keyboard_grab grab;
 };
 
 struct text_backend {
@@ -455,14 +454,17 @@ static void
 input_method_context_grab_key(struct wl_keyboard_grab *grab,
                              uint32_t time, uint32_t key, uint32_t state_w)
 {
-       struct input_method_context *input_method_context = container_of(grab, struct input_method_context, grab);
+       struct weston_keyboard *keyboard = (struct weston_keyboard *)grab->keyboard;
+       struct wl_display *display;
        uint32_t serial;
-       
-       if (input_method_context->keyboard) {
-               serial = wl_display_next_serial(input_method_context->model->ec->wl_display);
-               wl_keyboard_send_key(input_method_context->keyboard,
-                                    serial, time, key, state_w);
-       }
+
+       if (!keyboard->input_method_resource)
+               return;
+
+       display = wl_client_get_display(keyboard->input_method_resource->client);
+       serial = wl_display_next_serial(display);
+       wl_keyboard_send_key(keyboard->input_method_resource,
+                            serial, time, key, state_w);
 }
 
 static void
@@ -470,12 +472,12 @@ input_method_context_grab_modifier(struct wl_keyboard_grab *grab, uint32_t seria
                                   uint32_t mods_depressed, uint32_t mods_latched,
                                   uint32_t mods_locked, uint32_t group)
 {
-       struct input_method_context *input_method_context = container_of(grab, struct input_method_context, grab);
+       struct weston_keyboard *keyboard = (struct weston_keyboard *)grab->keyboard;
 
-       if (!input_method_context->keyboard)
+       if (!keyboard->input_method_resource)
                return;
 
-       wl_keyboard_send_modifiers(input_method_context->keyboard,
+       wl_keyboard_send_modifiers(keyboard->input_method_resource,
                                   serial, mods_depressed, mods_latched,
                                   mods_locked, group);
 }
@@ -493,7 +495,7 @@ input_method_context_grab_keyboard(struct wl_client *client,
        struct input_method_context *context = resource->data;
        struct wl_resource *cr;
        struct weston_seat *seat = context->input_method->seat;
-       struct wl_keyboard *keyboard = seat->seat.keyboard;
+       struct weston_keyboard *keyboard = &seat->keyboard;
 
        cr = wl_client_add_object(client, &wl_keyboard_interface,
                                  NULL, id, context);
@@ -505,10 +507,11 @@ input_method_context_grab_keyboard(struct wl_client *client,
                                seat->xkb_info.keymap_fd,
                                seat->xkb_info.keymap_size);
 
-       if (keyboard->grab != &keyboard->default_grab) {
-               wl_keyboard_end_grab(keyboard);
+       if (keyboard->keyboard.grab != &keyboard->keyboard.default_grab) {
+               wl_keyboard_end_grab(&keyboard->keyboard);
        }
-       wl_keyboard_start_grab(keyboard, &context->grab);
+       wl_keyboard_start_grab(&keyboard->keyboard, &keyboard->input_method_grab);
+       keyboard->input_method_resource = cr;
 }
 
 static void
@@ -600,8 +603,6 @@ input_method_context_create(struct text_model *model,
        context->input_method = input_method;
        input_method->context = context;
 
-       context->grab.interface = &input_method_context_grab;
-
        wl_client_add_resource(input_method->input_method_binding->client, &context->resource);
 
        input_method_send_activate(input_method->input_method_binding, &context->resource, serial);
@@ -610,13 +611,17 @@ input_method_context_create(struct text_model *model,
 static void
 input_method_context_end_keyboard_grab(struct input_method_context *context)
 {
-       struct wl_keyboard_grab *grab = &context->grab;
+       struct wl_keyboard_grab *grab = &context->input_method->seat->keyboard.input_method_grab;
+       struct weston_keyboard *keyboard = (struct weston_keyboard *)grab->keyboard;
 
-       if (grab->keyboard && (grab->keyboard->grab == grab)) {
+       if (!grab->keyboard)
+               return;
+
+       if (grab->keyboard->grab == grab)
                wl_keyboard_end_grab(grab->keyboard);
-       }
-}
 
+       keyboard->input_method_resource = NULL;
+}
 
 static void
 unbind_input_method(struct wl_resource *resource)
@@ -699,6 +704,7 @@ input_method_init_seat(struct weston_seat *seat)
        if (seat->has_keyboard) {
                seat->input_method->keyboard_focus_listener.notify = handle_keyboard_focus;
                wl_signal_add(&seat->seat.keyboard->focus_signal, &seat->input_method->keyboard_focus_listener);
+               seat->keyboard.input_method_grab.interface = &input_method_context_grab;
        }
 
        seat->input_method->focus_listener_initialized = 1;
index 5f8e9c8..1cd2b8f 100644 (file)
@@ -406,11 +406,14 @@ binding_key(struct wl_keyboard_grab *grab,
        struct wl_display *display;
        enum wl_keyboard_key_state state = state_w;
        uint32_t serial;
+       struct weston_keyboard *keyboard = (struct weston_keyboard *)grab->keyboard;
 
        resource = grab->keyboard->focus_resource;
        if (key == b->key) {
                if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
                        wl_keyboard_end_grab(grab->keyboard);
+                       if (keyboard->input_method_resource)
+                               keyboard->keyboard.grab = &keyboard->input_method_grab;
                        free(b);
                }
        } else if (resource) {
index be635fa..a9def4b 100644 (file)
@@ -155,7 +155,7 @@ activate_surface(struct wl_client *client, struct wl_resource *resource,
 
        if (surface) {
                weston_surface_activate(surface, seat);
-               notify_keyboard_focus_in(seat, &seat->keyboard.keys,
+               notify_keyboard_focus_in(seat, &seat->keyboard.keyboard.keys,
                                         STATE_UPDATE_AUTOMATIC);
        }
        else {