summaryrefslogtreecommitdiff
path: root/src/util.c
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2012-03-05 17:47:15 -0500
committerKristian Høgsberg <krh@bitplanet.net>2012-03-05 17:47:15 -0500
commitabcef3cf7a40a15a0e0805919c37230f5bc8143f (patch)
tree4b85271f6c6c3dc85d19666ea1c792611e6298a5 /src/util.c
parent63e5e06d82170a91c5d944221948c7a1ebe14030 (diff)
compositor: Swallow binding key for bindings that don't set up a grab
This prevents passing the key press and release to the keyboard focus client.
Diffstat (limited to 'src/util.c')
-rw-r--r--src/util.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/src/util.c b/src/util.c
index 3ca940f..d254d12 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);
}
}
}