diff --git a/src/compositor.c b/src/compositor.c index d0d9075b..44faa947 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -1570,10 +1570,6 @@ notify_key(struct wl_input_device *device, weston_compositor_idle_release(compositor); } - if (device->keyboard_grab == &device->default_keyboard_grab) - weston_compositor_run_binding(compositor, wd, - time, key, 0, state); - update_modifier_state(wd, key, state); end = device->keys.data + device->keys.size; for (k = device->keys.data; k < end; k++) { @@ -1586,6 +1582,10 @@ notify_key(struct wl_input_device *device, *k = key; } + if (device->keyboard_grab == &device->default_keyboard_grab) + weston_compositor_run_binding(compositor, wd, + time, key, 0, state); + device->keyboard_grab->interface->key(device->keyboard_grab, time, key, state); } diff --git a/src/shell.c b/src/shell.c index ac7301a1..c40fc6b5 100644 --- a/src/shell.c +++ b/src/shell.c @@ -134,10 +134,6 @@ struct weston_move_grab { int32_t dx, dy; }; -struct weston_zoom_grab { - struct wl_keyboard_grab grab; -}; - struct rotate_grab { struct wl_pointer_grab grab; struct shell_surface *surface; @@ -1164,21 +1160,12 @@ resize_binding(struct wl_input_device *device, uint32_t time, } static void -zoom_grab_key(struct wl_keyboard_grab *grab, - uint32_t time, uint32_t key, int32_t state) +zoom_binding(struct wl_input_device *device, uint32_t time, + uint32_t key, uint32_t button, uint32_t state, void *data) { - struct wl_input_device *device = grab->input_device; struct weston_input_device *wd = (struct weston_input_device *) device; struct weston_compositor *compositor = wd->compositor; struct weston_output *output; - struct weston_zoom_grab *zoom; - - if (!(wd->modifier_state & MODIFIER_SUPER)) { - zoom = container_of(grab, struct weston_zoom_grab, grab); - wl_input_device_end_keyboard_grab(device, time); - free(zoom); - return; - } wl_list_for_each(output, &compositor->output_list, link) { if (pixman_region32_contains_point(&output->region, @@ -1203,26 +1190,6 @@ zoom_grab_key(struct wl_keyboard_grab *grab, } } -static const struct wl_keyboard_grab_interface zoom_grab = { - zoom_grab_key, -}; - -static void -zoom_binding(struct wl_input_device *device, uint32_t time, - uint32_t key, uint32_t button, uint32_t state, void *data) -{ - struct weston_input_device *wd = (struct weston_input_device *) device; - struct weston_zoom_grab *zoom; - - zoom = malloc(sizeof *zoom); - if (!zoom) - return; - - zoom->grab.interface = &zoom_grab; - - wl_input_device_start_keyboard_grab(&wd->input_device, &zoom->grab, time); -} - static void terminate_binding(struct wl_input_device *device, uint32_t time, uint32_t key, uint32_t button, uint32_t state, void *data) @@ -1934,6 +1901,8 @@ switcher_binding(struct wl_input_device *device, uint32_t time, switcher->grab.interface = &switcher_grab; wl_input_device_start_keyboard_grab(device, &switcher->grab, time); + wl_input_device_set_keyboard_focus(device, NULL, + weston_compositor_get_time()); switcher_next(switcher); } diff --git a/src/util.c b/src/util.c index 3ca940f9..d254d12d 100644 --- a/src/util.c +++ b/src/util.c @@ -229,6 +229,46 @@ weston_binding_list_destroy_all(struct wl_list *list) weston_binding_destroy(binding); } +struct binding_keyboard_grab { + uint32_t key; + struct wl_keyboard_grab grab; +}; + +static void +binding_key(struct wl_keyboard_grab *grab, + uint32_t time, uint32_t key, int32_t state) +{ + struct binding_keyboard_grab *b = + container_of(grab, struct binding_keyboard_grab, grab); + struct wl_resource *resource; + + resource = grab->input_device->keyboard_focus_resource; + if (key == b->key) { + if (!state) { + wl_input_device_end_keyboard_grab(grab->input_device, + time); + free(b); + } + } else if (resource) + wl_input_device_send_key(resource, time, key, state); +} + +static const struct wl_keyboard_grab_interface binding_grab = { + binding_key +}; + +static void +install_binding_grab(struct wl_input_device *device, + uint32_t time, uint32_t key) +{ + struct binding_keyboard_grab *grab; + + grab = malloc(sizeof *grab); + grab->key = key; + grab->grab.interface = &binding_grab; + wl_input_device_start_keyboard_grab(device, &grab->grab, time); +} + WL_EXPORT void weston_compositor_run_binding(struct weston_compositor *compositor, struct weston_input_device *device, @@ -242,7 +282,15 @@ weston_compositor_run_binding(struct weston_compositor *compositor, b->modifier == device->modifier_state && state) { b->handler(&device->input_device, time, key, button, state, b->data); - break; + + /* If this was a key binding and it didn't + * install a keyboard grab, install one now to + * swallow the key release. */ + if (b->key && + device->input_device.keyboard_grab == + &device->input_device.default_keyboard_grab) + install_binding_grab(&device->input_device, + time, key); } } }