[PATCH weston 5/6] input: Emit events on all resources for a client
Daniel Stone
daniel at fooishbar.org
Wed Jul 24 10:15:31 PDT 2013
Hi,
On 22 July 2013 17:31, Rob Bradford <robert.bradford at intel.com> wrote:
> The Wayland protocol permits a client to request the pointer, keyboard
> and touch multiple times from the seat global. This is very useful in a
> component like Clutter-GTK where we are combining two libraries that use
> Wayland together.
>
> This change migrates the weston input handling code to emit the
> events for all the resources for the client by using the newly added
> wl_resource_for_each macro to iterate over the resources that are
> associated with the focussed surface's client. A pointer to the list of
> resources is stored as a member on the device structures. In order to
> handle the loss of focus or the non-availability of a list of resources
> an empty list sentinel is used.
At first I wasn't too wild about this, given that it kind of allows
for split focus: two independent components could well get a button
event and both act on it. But really, that's not much of a difference
from the X11 status quo where everyone just dredged through events and
picked out what they felt like. So I guess clients already have to be
careful about how they use it.
Implementation-wise, it mostly looks good, but - do we leak
focus_resource_list and friends when releasing? I can't find where
they're freed, but if you're freeing empty_list unconditionally,
you're going to have a bad time ...
Cheers,
Daniel
> diff --git a/src/bindings.c b/src/bindings.c
> index a871c26..e51c5ed 100644
> --- a/src/bindings.c
> +++ b/src/bindings.c
> @@ -160,7 +160,6 @@ binding_key(struct weston_keyboard_grab *grab,
> struct weston_keyboard *keyboard = grab->keyboard;
> struct wl_display *display = keyboard->seat->compositor->wl_display;
>
> - resource = grab->keyboard->focus_resource;
> if (key == b->key) {
> if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
> weston_keyboard_end_grab(grab->keyboard);
> @@ -168,9 +167,11 @@ binding_key(struct weston_keyboard_grab *grab,
> keyboard->grab = &keyboard->input_method_grab;
> free(b);
> }
> - } else if (resource) {
> + } else {
> serial = wl_display_next_serial(display);
> - wl_keyboard_send_key(resource, serial, time, key, state);
> + wl_resource_for_each(resource, keyboard->focus_resource_list) {
> + wl_keyboard_send_key(resource, serial, time, key, state);
> + }
> }
> }
>
> @@ -181,12 +182,10 @@ binding_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
> {
> 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);
> + wl_resource_for_each(resource, grab->keyboard->focus_resource_list) {
> + wl_keyboard_send_modifiers(resource, serial, mods_depressed,
> + mods_latched, mods_locked, group);
> + }
> }
>
> static const struct weston_keyboard_grab_interface binding_grab = {
> diff --git a/src/compositor.h b/src/compositor.h
> index 8429b9b..fc6354c 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -297,8 +297,8 @@ struct weston_pointer {
> struct weston_seat *seat;
>
> struct wl_array resources;
> + struct wl_list *focus_resource_list;
> struct weston_surface *focus;
> - struct wl_resource *focus_resource;
> struct wl_listener focus_listener;
> uint32_t focus_serial;
> struct wl_signal focus_signal;
> @@ -323,8 +323,8 @@ struct weston_touch {
> struct weston_seat *seat;
>
> struct wl_array resources;
> + struct wl_list *focus_resource_list;
> struct weston_surface *focus;
> - struct wl_resource *focus_resource;
> struct wl_listener focus_listener;
> uint32_t focus_serial;
> struct wl_signal focus_signal;
> @@ -409,8 +409,8 @@ struct weston_keyboard {
> struct weston_seat *seat;
>
> struct wl_array resources;
> + struct wl_list *focus_resource_list;
> struct weston_surface *focus;
> - struct wl_resource *focus_resource;
> struct wl_listener focus_listener;
> uint32_t focus_serial;
> struct wl_signal focus_signal;
> diff --git a/src/input.c b/src/input.c
> index 3cf3f3f..25f2a3e 100644
> --- a/src/input.c
> +++ b/src/input.c
> @@ -31,6 +31,8 @@
> #include "../shared/os-compatibility.h"
> #include "compositor.h"
>
> +static struct wl_list empty_list = {&empty_list, &empty_list};
> +
> static void
> empty_region(pixman_region32_t *region)
> {
> @@ -74,7 +76,7 @@ lose_pointer_focus(struct wl_listener *listener, void *data)
> struct weston_pointer *pointer =
> container_of(listener, struct weston_pointer, focus_listener);
>
> - pointer->focus_resource = NULL;
> + pointer->focus_resource_list = &empty_list;
> }
>
> static void
> @@ -83,7 +85,7 @@ lose_keyboard_focus(struct wl_listener *listener, void *data)
> struct weston_keyboard *keyboard =
> container_of(listener, struct weston_keyboard, focus_listener);
>
> - keyboard->focus_resource = NULL;
> + keyboard->focus_resource_list = &empty_list;
> }
>
> static void
> @@ -92,7 +94,7 @@ lose_touch_focus(struct wl_listener *listener, void *data)
> struct weston_touch *touch =
> container_of(listener, struct weston_touch, focus_listener);
>
> - touch->focus_resource = NULL;
> + touch->focus_resource_list = &empty_list;
> }
>
> static void
> @@ -118,12 +120,15 @@ default_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
> {
> struct weston_pointer *pointer = grab->pointer;
> wl_fixed_t sx, sy;
> + struct wl_list *resource_list;
> + struct wl_resource *resource;
>
> - if (pointer->focus_resource) {
> + resource_list = pointer->focus_resource_list;
> + wl_resource_for_each(resource, resource_list) {
> weston_surface_from_global_fixed(pointer->focus,
> pointer->x, pointer->y,
> &sx, &sy);
> - wl_pointer_send_motion(pointer->focus_resource, time, sx, sy);
> + wl_pointer_send_motion(resource, time, sx, sy);
> }
> }
>
> @@ -139,11 +144,13 @@ default_grab_button(struct weston_pointer_grab *grab,
> enum wl_pointer_button_state state = state_w;
> struct wl_display *display = compositor->wl_display;
> wl_fixed_t sx, sy;
> + struct wl_list *resource_list;
>
> - resource = pointer->focus_resource;
> - if (resource) {
> + resource_list = pointer->focus_resource_list;
> + if (!wl_list_empty(resource_list)) {
> serial = wl_display_next_serial(display);
> - wl_pointer_send_button(resource, serial, time, button, state_w);
> + wl_resource_for_each(resource, resource_list)
> + wl_pointer_send_button(resource, serial, time, button, state_w);
> }
>
> if (pointer->button_count == 0 &&
> @@ -171,12 +178,17 @@ default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time,
> struct weston_touch *touch = grab->touch;
> struct wl_display *display = touch->seat->compositor->wl_display;
> uint32_t serial;
> + struct wl_resource *resource;
> + struct wl_list *resource_list;
>
> - if (touch->focus_resource && touch->focus) {
> + resource_list = touch->focus_resource_list;
> +
> + if (!wl_list_empty(resource_list) && touch->focus) {
> serial = wl_display_next_serial(display);
> - wl_touch_send_down(touch->focus_resource, serial, time,
> - touch->focus->resource,
> - touch_id, sx, sy);
> + wl_resource_for_each(resource, resource_list)
> + wl_touch_send_down(resource, serial, time,
> + touch->focus->resource,
> + touch_id, sx, sy);
> }
> }
>
> @@ -187,10 +199,15 @@ default_grab_touch_up(struct weston_touch_grab *grab,
> struct weston_touch *touch = grab->touch;
> struct wl_display *display = touch->seat->compositor->wl_display;
> uint32_t serial;
> + struct wl_resource *resource;
> + struct wl_list *resource_list;
> +
> + resource_list = touch->focus_resource_list;
>
> - if (touch->focus_resource) {
> + if (!wl_list_empty(resource_list)) {
> serial = wl_display_next_serial(display);
> - wl_touch_send_up(touch->focus_resource, serial, time, touch_id);
> + wl_resource_for_each(resource, resource_list)
> + wl_touch_send_up(resource, serial, time, touch_id);
> }
> }
>
> @@ -199,9 +216,13 @@ default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time,
> int touch_id, wl_fixed_t sx, wl_fixed_t sy)
> {
> struct weston_touch *touch = grab->touch;
> + struct wl_resource *resource;
> + struct wl_list *resource_list;
> +
> + resource_list = touch->focus_resource_list;
>
> - if (touch->focus_resource) {
> - wl_touch_send_motion(touch->focus_resource, time,
> + wl_resource_for_each(resource, resource_list) {
> + wl_touch_send_motion(resource, time,
> touch_id, sx, sy);
> }
> }
> @@ -220,39 +241,40 @@ default_grab_key(struct weston_keyboard_grab *grab,
> struct wl_resource *resource;
> struct wl_display *display = keyboard->seat->compositor->wl_display;
> uint32_t serial;
> + struct wl_list *resource_list;
> +
> + resource_list = keyboard->focus_resource_list;
>
> - resource = keyboard->focus_resource;
> - if (resource) {
> + if (!wl_list_empty(resource_list)) {
> serial = wl_display_next_serial(display);
> - wl_keyboard_send_key(resource, serial, time, key, state);
> + wl_resource_for_each(resource, resource_list) {
> + wl_keyboard_send_key(resource, serial, time, key, state);
> + }
> }
> }
>
> -static struct wl_resource *
> -find_resource_for_surface(struct wl_array *array, struct weston_surface *surface)
> +static struct wl_list *
> +find_resources_for_surface(struct wl_array *array, struct weston_surface *surface)
> {
> struct wl_client *client;
> struct wl_list *list;
> uint32_t id;
>
> if (!surface)
> - return NULL;
> + return &empty_list;
>
> if (!surface->resource)
> - return NULL;
> + return &empty_list;
>
> client = wl_resource_get_client(surface->resource);
> id = wl_client_get_id(client);
>
> if (array->size < (id + 1) * sizeof(struct wl_list *))
> - return NULL;
> + return &empty_list;
>
> list = ((struct wl_list **)array->data)[id];
>
> - if (wl_list_empty(list))
> - return NULL;
> - else
> - return wl_resource_from_link(list->next);
> + return list;
> }
>
> static void
> @@ -262,20 +284,21 @@ default_grab_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
> {
> struct weston_keyboard *keyboard = grab->keyboard;
> struct weston_pointer *pointer = keyboard->seat->pointer;
> - struct wl_resource *resource, *pr;
> + struct wl_resource *resource;
> + struct wl_list *resource_list;
>
> - resource = keyboard->focus_resource;
> - if (!resource)
> - return;
> + resource_list = keyboard->focus_resource_list;
>
> - wl_keyboard_send_modifiers(resource, serial, mods_depressed,
> - mods_latched, mods_locked, group);
> + wl_resource_for_each(resource, resource_list) {
> + wl_keyboard_send_modifiers(resource, serial, mods_depressed,
> + mods_latched, mods_locked, group);
> + }
>
> if (pointer && pointer->focus && pointer->focus != keyboard->focus) {
> - pr = find_resource_for_surface(&keyboard->resources,
> - pointer->focus);
> - if (pr) {
> - wl_keyboard_send_modifiers(pr,
> + resource_list = find_resources_for_surface(&keyboard->resources,
> + pointer->focus);
> + wl_resource_for_each(resource, resource_list) {
> + wl_keyboard_send_modifiers(resource,
> serial,
> keyboard->modifiers.mods_depressed,
> keyboard->modifiers.mods_latched,
> @@ -324,6 +347,7 @@ weston_pointer_create(void)
>
> memset(pointer, 0, sizeof *pointer);
> wl_array_init(&pointer->resources);
> + pointer->focus_resource_list = &empty_list;
> pointer->focus_listener.notify = lose_pointer_focus;
> pointer->default_grab.interface = &default_pointer_grab_interface;
> pointer->default_grab.pointer = pointer;
> @@ -346,7 +370,7 @@ weston_pointer_destroy(struct weston_pointer *pointer)
> pointer_unmap_sprite(pointer);
>
> /* XXX: What about pointer->resource_list? */
> - if (pointer->focus_resource)
> + if (!wl_list_empty(pointer->focus_resource_list))
> wl_list_remove(&pointer->focus_listener.link);
> free(pointer);
> }
> @@ -362,6 +386,7 @@ weston_keyboard_create(void)
>
> memset(keyboard, 0, sizeof *keyboard);
> wl_array_init(&keyboard->resources);
> + keyboard->focus_resource_list = &empty_list;
> wl_array_init(&keyboard->keys);
> keyboard->focus_listener.notify = lose_keyboard_focus;
> keyboard->default_grab.interface = &default_keyboard_grab_interface;
> @@ -376,7 +401,7 @@ WL_EXPORT void
> weston_keyboard_destroy(struct weston_keyboard *keyboard)
> {
> /* XXX: What about keyboard->resource_list? */
> - if (keyboard->focus_resource)
> + if (!wl_list_empty(keyboard->focus_resource_list))
> wl_list_remove(&keyboard->focus_listener.link);
> wl_array_release(&keyboard->keys);
> free(keyboard);
> @@ -393,6 +418,7 @@ weston_touch_create(void)
>
> memset(touch, 0, sizeof *touch);
> wl_array_init(&touch->resources);
> + touch->focus_resource_list = &empty_list;
> touch->focus_listener.notify = lose_touch_focus;
> touch->default_grab.interface = &default_touch_grab_interface;
> touch->default_grab.touch = touch;
> @@ -406,7 +432,7 @@ WL_EXPORT void
> weston_touch_destroy(struct weston_touch *touch)
> {
> /* XXX: What about touch->resource_list? */
> - if (touch->focus_resource)
> + if (!wl_list_empty(touch->focus_resource_list))
> wl_list_remove(&touch->focus_listener.link);
> free(touch);
> }
> @@ -439,25 +465,34 @@ weston_pointer_set_focus(struct weston_pointer *pointer,
> struct wl_resource *resource, *kr;
> struct wl_display *display = pointer->seat->compositor->wl_display;
> uint32_t serial;
> + struct wl_list *resource_list, *kbd_resource_list;
>
> - resource = pointer->focus_resource;
> - if (resource && pointer->focus != surface) {
> + resource_list = pointer->focus_resource_list;
> + if (!wl_list_empty(resource_list) &&
> + pointer->focus != surface) {
> serial = wl_display_next_serial(display);
> - wl_pointer_send_leave(resource, serial,
> - pointer->focus->resource);
> + wl_resource_for_each(resource, resource_list) {
> + wl_pointer_send_leave(resource, serial,
> + pointer->focus->resource);
> + }
> +
> + pointer->focus_resource_list = &empty_list;
> +
> wl_list_remove(&pointer->focus_listener.link);
> }
>
> - resource = find_resource_for_surface(&pointer->resources,
> - surface);
> - if (resource &&
> + resource_list = find_resources_for_surface(&pointer->resources,
> + surface);
> +
> + if (!wl_list_empty(resource_list) &&
> (pointer->focus != surface ||
> - pointer->focus_resource != resource)) {
> + resource_list != pointer->focus_resource_list)) {
> serial = wl_display_next_serial(display);
> if (kbd) {
> - kr = find_resource_for_surface(&kbd->resources,
> - surface);
> - if (kr) {
> + kbd_resource_list =
> + find_resources_for_surface(&kbd->resources,
> + surface);
> + wl_resource_for_each(kr, kbd_resource_list) {
> wl_keyboard_send_modifiers(kr,
> serial,
> kbd->modifiers.mods_depressed,
> @@ -466,14 +501,17 @@ weston_pointer_set_focus(struct weston_pointer *pointer,
> kbd->modifiers.group);
> }
> }
> - wl_pointer_send_enter(resource, serial, surface->resource,
> - sx, sy);
> +
> + wl_resource_for_each(resource, resource_list) {
> + wl_pointer_send_enter(resource, serial, surface->resource,
> + sx, sy);
> + }
> wl_client_add_destroy_listener(wl_resource_get_client(surface->resource),
> &pointer->focus_listener);
> pointer->focus_serial = serial;
> }
>
> - pointer->focus_resource = resource;
> + pointer->focus_resource_list = resource_list;
> pointer->focus = surface;
> wl_signal_emit(&pointer->focus_signal, pointer);
> }
> @@ -485,34 +523,43 @@ weston_keyboard_set_focus(struct weston_keyboard *keyboard,
> struct wl_resource *resource;
> struct wl_display *display = keyboard->seat->compositor->wl_display;
> uint32_t serial;
> + struct wl_list *resource_list;
>
> - if (keyboard->focus_resource && keyboard->focus != surface) {
> - resource = keyboard->focus_resource;
> + resource_list = keyboard->focus_resource_list;
> + if (!wl_list_empty(resource_list) &&
> + keyboard->focus != surface) {
> serial = wl_display_next_serial(display);
> - wl_keyboard_send_leave(resource, serial,
> - keyboard->focus->resource);
> + wl_resource_for_each(resource, resource_list) {
> + wl_keyboard_send_leave(resource, serial,
> + keyboard->focus->resource);
> + }
> +
> + keyboard->focus_resource_list = &empty_list;
> wl_list_remove(&keyboard->focus_listener.link);
> }
>
> - resource = find_resource_for_surface(&keyboard->resources,
> - surface);
> - if (resource &&
> + resource_list = find_resources_for_surface(&keyboard->resources,
> + surface);
> +
> + if (!wl_list_empty(resource_list) &&
> (keyboard->focus != surface ||
> - keyboard->focus_resource != resource)) {
> + resource_list != keyboard->focus_resource_list)) {
> serial = wl_display_next_serial(display);
> - wl_keyboard_send_modifiers(resource, serial,
> - keyboard->modifiers.mods_depressed,
> - keyboard->modifiers.mods_latched,
> - keyboard->modifiers.mods_locked,
> - keyboard->modifiers.group);
> - wl_keyboard_send_enter(resource, serial, surface->resource,
> - &keyboard->keys);
> + wl_resource_for_each(resource, resource_list) {
> + wl_keyboard_send_modifiers(resource, serial,
> + keyboard->modifiers.mods_depressed,
> + keyboard->modifiers.mods_latched,
> + keyboard->modifiers.mods_locked,
> + keyboard->modifiers.group);
> + wl_keyboard_send_enter(resource, serial, surface->resource,
> + &keyboard->keys);
> + }
> wl_client_add_destroy_listener(wl_resource_get_client(surface->resource),
> &keyboard->focus_listener);
> keyboard->focus_serial = serial;
> }
>
> - keyboard->focus_resource = resource;
> + keyboard->focus_resource_list = resource_list;
> keyboard->focus = surface;
> wl_signal_emit(&keyboard->focus_signal, keyboard);
> }
> @@ -722,6 +769,8 @@ notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
> struct weston_surface *focus =
> (struct weston_surface *) pointer->focus;
> uint32_t serial = wl_display_next_serial(compositor->wl_display);
> + struct wl_resource *resource;
> + struct wl_list *resource_list;
>
> if (compositor->ping_handler && focus)
> compositor->ping_handler(focus, serial);
> @@ -735,8 +784,9 @@ notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
> time, axis, value))
> return;
>
> - if (pointer->focus_resource)
> - wl_pointer_send_axis(pointer->focus_resource, time, axis,
> + resource_list = pointer->focus_resource_list;
> + wl_resource_for_each(resource, resource_list)
> + wl_pointer_send_axis(resource, time, axis,
> value);
> }
>
> @@ -993,29 +1043,29 @@ notify_keyboard_focus_out(struct weston_seat *seat)
> static void
> touch_set_focus(struct weston_seat *seat, struct weston_surface *surface)
> {
> - struct wl_resource *resource;
> + struct weston_touch *touch = seat->touch;
> + struct wl_list *resource_list;
>
> - if (seat->touch->focus == surface)
> + if (touch->focus == surface)
> return;
>
> - if (seat->touch->focus_resource)
> - wl_list_remove(&seat->touch->focus_listener.link);
> - seat->touch->focus = NULL;
> - seat->touch->focus_resource = NULL;
> + resource_list = touch->focus_resource_list;
> + if (!wl_list_empty(resource_list)) {
> + touch->focus_resource_list = &empty_list;
> + wl_list_remove(&touch->focus_listener.link);
> + }
> + touch->focus = NULL;
>
> if (surface) {
> - resource =
> - find_resource_for_surface(&seat->touch->resources,
> - surface);
> - if (!resource) {
> - weston_log("couldn't find resource\n");
> - return;
> - }
> + resource_list =
> + find_resources_for_surface(&seat->touch->resources,
> + surface);
> +
> + touch->focus_resource_list = resource_list;
>
> - seat->touch->focus = surface;
> - seat->touch->focus_resource = resource;
> + touch->focus = surface;
> wl_client_add_destroy_listener(wl_resource_get_client(surface->resource),
> - &seat->touch->focus_listener);
> + &touch->focus_listener);
> }
> }
>
> diff --git a/src/shell.c b/src/shell.c
> index e4d5a5e..a08ebf1 100644
> --- a/src/shell.c
> +++ b/src/shell.c
> @@ -2043,13 +2043,14 @@ static void
> popup_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
> {
> struct weston_pointer *pointer = grab->pointer;
> + struct wl_resource *resource;
> wl_fixed_t sx, sy;
>
> - if (pointer->focus_resource) {
> + wl_resource_for_each(resource, pointer->focus_resource_list) {
> weston_surface_from_global_fixed(pointer->focus,
> pointer->x, pointer->y,
> &sx, &sy);
> - wl_pointer_send_motion(pointer->focus_resource, time, sx, sy);
> + wl_pointer_send_motion(resource, time, sx, sy);
> }
> }
>
> @@ -2063,11 +2064,14 @@ popup_grab_button(struct weston_pointer_grab *grab,
> struct wl_display *display = shseat->seat->compositor->wl_display;
> enum wl_pointer_button_state state = state_w;
> uint32_t serial;
> + struct wl_list *resource_list;
>
> - resource = grab->pointer->focus_resource;
> - if (resource) {
> + resource_list = grab->pointer->focus_resource_list;
> + if (!wl_list_empty(resource_list)) {
> serial = wl_display_get_serial(display);
> - wl_pointer_send_button(resource, serial, time, button, state);
> + wl_resource_for_each (resource, resource_list) {
> + wl_pointer_send_button(resource, serial, time, button, state);
> + }
> } else if (state == WL_POINTER_BUTTON_STATE_RELEASED &&
> (shseat->popup_grab.initial_up ||
> time - shseat->seat->pointer->grab_time > 500)) {
> @@ -4135,6 +4139,7 @@ debug_binding_key(struct weston_keyboard_grab *grab, uint32_t time,
> int send = 0, terminate = 0;
> int check_binding = 1;
> int i;
> + struct wl_list *resource_list;
>
> if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
> /* Do not run bindings on key releases */
> @@ -4181,10 +4186,9 @@ debug_binding_key(struct weston_keyboard_grab *grab, uint32_t time,
> }
>
> if (send) {
> - resource = grab->keyboard->focus_resource;
> -
> - if (resource) {
> - serial = wl_display_next_serial(display);
> + serial = wl_display_next_serial(display);
> + resource_list = grab->keyboard->focus_resource_list;
> + wl_resource_for_each(resource, resource_list) {
> wl_keyboard_send_key(resource, serial, time, key, state);
> }
> }
> @@ -4203,13 +4207,14 @@ debug_binding_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
> uint32_t mods_locked, uint32_t group)
> {
> struct wl_resource *resource;
> + struct wl_list *resource_list;
>
> - resource = grab->keyboard->focus_resource;
> - if (!resource)
> - return;
> + resource_list = grab->keyboard->focus_resource_list;
>
> - wl_keyboard_send_modifiers(resource, serial, mods_depressed,
> - mods_latched, mods_locked, group);
> + wl_resource_for_each(resource, resource_list) {
> + wl_keyboard_send_modifiers(resource, serial, mods_depressed,
> + mods_latched, mods_locked, group);
> + }
> }
>
> struct weston_keyboard_grab_interface debug_binding_keyboard_grab = {
> --
> 1.8.3.1
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list