From a75a789fc1a00bf7625e27993746853cc8634a2e Mon Sep 17 00:00:00 2001 From: Jan Arne Petersen Date: Wed, 16 Jan 2013 21:26:50 +0100 Subject: [PATCH] text: fix weston key bindings with input methods Add a struct weston_keyboard, to handle the input method grab. Signed-off-by: Jan Arne Petersen --- src/compositor.c | 29 +++++++++++++++-------------- src/compositor.h | 9 ++++++++- src/shell.c | 10 ++++++++-- src/text-backend.c | 48 +++++++++++++++++++++++++++--------------------- src/util.c | 3 +++ tests/weston-test.c | 2 +- 6 files changed, 62 insertions(+), 39 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 764d622..63fe793 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -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; } diff --git a/src/compositor.h b/src/compositor.h index 004f931..c0694e8 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -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; diff --git a/src/shell.c b/src/shell.c index 9fcce9f..598f286 100644 --- a/src/shell.c +++ b/src/shell.c @@ -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); } } diff --git a/src/text-backend.c b/src/text-backend.c index e0b8b7d..c0cddfe 100644 --- a/src/text-backend.c +++ b/src/text-backend.c @@ -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; diff --git a/src/util.c b/src/util.c index 5f8e9c8..1cd2b8f 100644 --- a/src/util.c +++ b/src/util.c @@ -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) { diff --git a/tests/weston-test.c b/tests/weston-test.c index be635fa..a9def4b 100644 --- a/tests/weston-test.c +++ b/tests/weston-test.c @@ -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 { -- 2.7.4