[mutter] pointer/keyboard: Support more than one focused resource
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] pointer/keyboard: Support more than one focused resource
- Date: Wed, 16 Apr 2014 19:32:57 +0000 (UTC)
commit 339a78718dad817bbdfc7ba7056fc0371c89d9aa
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Wed Apr 16 15:11:10 2014 -0400
pointer/keyboard: Support more than one focused resource
Sophisticated clients, like those using ClutterGtk, will have more
than one focused resource per client, as both Clutter and GDK will
ask for a wl_pointer / wl_keyboard. Support this naturally using
the same "hack" as Weston: multiple resource lists, where we move
elements from one to the other.
src/wayland/meta-wayland-keyboard.c | 102 +++++++++++++++++++++++------------
src/wayland/meta-wayland-keyboard.h | 2 +-
src/wayland/meta-wayland-pointer.c | 80 ++++++++++++++++++---------
src/wayland/meta-wayland-pointer.h | 2 +-
src/wayland/meta-wayland-seat.c | 21 ++++---
5 files changed, 135 insertions(+), 72 deletions(-)
---
diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c
index cb227a9..08e0934 100644
--- a/src/wayland/meta-wayland-keyboard.c
+++ b/src/wayland/meta-wayland-keyboard.c
@@ -211,7 +211,6 @@ keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, focus_surface_listener);
keyboard->focus_surface = NULL;
- keyboard->focus_resource = NULL;
}
static gboolean
@@ -220,34 +219,47 @@ default_grab_key (MetaWaylandKeyboardGrab *grab,
{
MetaWaylandKeyboard *keyboard = grab->keyboard;
struct wl_resource *resource;
- uint32_t serial;
+ struct wl_list *l;
- resource = keyboard->focus_resource;
- if (resource)
+ l = &keyboard->focus_resource_list;
+ if (!wl_list_empty (l))
{
struct wl_client *client = wl_resource_get_client (keyboard->focus_surface->resource);
struct wl_display *display = wl_client_get_display (client);
- serial = wl_display_next_serial (display);
- wl_keyboard_send_key (resource, serial, time, key, state);
+ uint32_t serial = wl_display_next_serial (display);
+
+ wl_resource_for_each (resource, l)
+ {
+ wl_keyboard_send_key (resource, serial, time, key, state);
+ }
+
+ return TRUE;
}
- return resource != NULL;
+ return FALSE;
}
-static struct wl_resource *
-find_resource_for_surface (struct wl_list *list, MetaWaylandSurface *surface)
+static void
+move_resources (struct wl_list *destination, struct wl_list *source)
{
- struct wl_client *client;
-
- if (!surface)
- return NULL;
-
- if (!surface->resource)
- return NULL;
-
- client = wl_resource_get_client (surface->resource);
+ wl_list_insert_list (destination, source);
+ wl_list_init (source);
+}
- return wl_resource_find_for_client (list, client);
+static void
+move_resources_for_client (struct wl_list *destination,
+ struct wl_list *source,
+ struct wl_client *client)
+{
+ struct wl_resource *resource, *tmp;
+ wl_resource_for_each_safe (resource, tmp, source)
+ {
+ if (wl_resource_get_client (resource) == client)
+ {
+ wl_list_remove (wl_resource_get_link (resource));
+ wl_list_insert (destination, wl_resource_get_link (resource));
+ }
+ }
}
static void
@@ -256,10 +268,13 @@ default_grab_modifiers (MetaWaylandKeyboardGrab *grab, uint32_t serial,
uint32_t mods_locked, uint32_t group)
{
MetaWaylandKeyboard *keyboard = grab->keyboard;
+ struct wl_resource *resource;
+ struct wl_list *l;
- if (keyboard->focus_resource)
+ l = &keyboard->focus_resource_list;
+ wl_resource_for_each (resource, l)
{
- wl_keyboard_send_modifiers (keyboard->focus_resource, serial, mods_depressed,
+ wl_keyboard_send_modifiers (resource, serial, mods_depressed,
mods_latched, mods_locked, group);
}
}
@@ -278,6 +293,7 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
keyboard->xkb_info.keymap_fd = -1;
wl_list_init (&keyboard->resource_list);
+ wl_list_init (&keyboard->focus_resource_list);
wl_array_init (&keyboard->keys);
keyboard->focus_surface_listener.notify = keyboard_handle_focus_surface_destroy;
@@ -418,19 +434,27 @@ void
meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard,
MetaWaylandSurface *surface)
{
- if (keyboard->focus_surface == surface && keyboard->focus_resource != NULL)
+ if (keyboard->focus_surface == surface && !wl_list_empty (&keyboard->focus_resource_list))
return;
if (keyboard->focus_surface != NULL)
{
- if (keyboard->focus_resource)
+ struct wl_resource *resource;
+ struct wl_list *l;
+
+ l = &keyboard->focus_resource_list;
+ if (!wl_list_empty (l))
{
struct wl_client *client = wl_resource_get_client (keyboard->focus_surface->resource);
struct wl_display *display = wl_client_get_display (client);
uint32_t serial = wl_display_next_serial (display);
- wl_keyboard_send_leave (keyboard->focus_resource, serial, keyboard->focus_surface->resource);
- keyboard->focus_resource = NULL;
+ wl_resource_for_each (resource, l)
+ {
+ wl_keyboard_send_leave (resource, serial, keyboard->focus_surface->resource);
+ }
+
+ move_resources (&keyboard->resource_list, &keyboard->focus_resource_list);
}
wl_list_remove (&keyboard->focus_surface_listener.link);
@@ -439,24 +463,34 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard,
if (surface != NULL)
{
+ struct wl_resource *resource;
+ struct wl_list *l;
+
keyboard->focus_surface = surface;
wl_resource_add_destroy_listener (keyboard->focus_surface->resource,
&keyboard->focus_surface_listener);
- keyboard->focus_resource = find_resource_for_surface (&keyboard->resource_list, surface);
- if (keyboard->focus_resource)
+ move_resources_for_client (&keyboard->focus_resource_list,
+ &keyboard->resource_list,
+ wl_resource_get_client (keyboard->focus_surface->resource));
+
+ l = &keyboard->focus_resource_list;
+ if (!wl_list_empty (l))
{
struct wl_client *client = wl_resource_get_client (keyboard->focus_surface->resource);
struct wl_display *display = wl_client_get_display (client);
struct xkb_state *state = keyboard->xkb_info.state;
uint32_t serial = wl_display_next_serial (display);
- wl_keyboard_send_modifiers (keyboard->focus_resource, serial,
- xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED),
- xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED),
- xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED),
- xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE));
- wl_keyboard_send_enter (keyboard->focus_resource, serial, keyboard->focus_surface->resource,
- &keyboard->keys);
+ wl_resource_for_each (resource, l)
+ {
+ wl_keyboard_send_modifiers (resource, serial,
+ xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED),
+ xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED),
+ xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED),
+ xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE));
+ wl_keyboard_send_enter (resource, serial, keyboard->focus_surface->resource,
+ &keyboard->keys);
+ }
keyboard->focus_serial = serial;
}
diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h
index f67d02f..38011c9 100644
--- a/src/wayland/meta-wayland-keyboard.h
+++ b/src/wayland/meta-wayland-keyboard.h
@@ -78,10 +78,10 @@ typedef struct
struct _MetaWaylandKeyboard
{
struct wl_list resource_list;
+ struct wl_list focus_resource_list;
MetaWaylandSurface *focus_surface;
struct wl_listener focus_surface_listener;
- struct wl_resource *focus_resource;
uint32_t focus_serial;
MetaWaylandKeyboardGrab *grab;
diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c
index 7ed2255..f5535a6 100644
--- a/src/wayland/meta-wayland-pointer.c
+++ b/src/wayland/meta-wayland-pointer.c
@@ -60,7 +60,6 @@ pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_surface_listener);
pointer->focus_surface = NULL;
- pointer->focus_resource = NULL;
}
static void
@@ -81,9 +80,10 @@ default_grab_motion (MetaWaylandPointerGrab *grab,
{
MetaWaylandPointer *pointer = grab->pointer;
struct wl_resource *resource;
+ struct wl_list *l;
- resource = pointer->focus_resource;
- if (resource)
+ l = &pointer->focus_resource_list;
+ wl_resource_for_each(resource, l)
{
wl_fixed_t sx, sy;
@@ -100,12 +100,13 @@ default_grab_button (MetaWaylandPointerGrab *grab,
{
MetaWaylandPointer *pointer = grab->pointer;
struct wl_resource *resource;
+ struct wl_list *l;
ClutterEventType event_type;
event_type = clutter_event_type (event);
- resource = pointer->focus_resource;
- if (resource)
+ l = &grab->pointer->focus_resource_list;
+ wl_resource_for_each(resource, l)
{
struct wl_client *client = wl_resource_get_client (pointer->focus_surface->resource);
struct wl_display *display = wl_client_get_display (client);
@@ -256,6 +257,7 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer)
memset (pointer, 0, sizeof *pointer);
wl_list_init (&pointer->resource_list);
+ wl_list_init (&pointer->focus_resource_list);
pointer->focus_surface_listener.notify = pointer_handle_focus_surface_destroy;
@@ -288,37 +290,54 @@ meta_wayland_pointer_release (MetaWaylandPointer *pointer)
/* Do nothing. */
}
-static struct wl_resource *
-find_resource_for_surface (struct wl_list *list, MetaWaylandSurface *surface)
+static void
+move_resources (struct wl_list *destination, struct wl_list *source)
{
- struct wl_client *client;
-
- if (!surface)
- return NULL;
-
- g_assert (surface->resource);
- client = wl_resource_get_client (surface->resource);
+ wl_list_insert_list (destination, source);
+ wl_list_init (source);
+}
- return wl_resource_find_for_client (list, client);
+static void
+move_resources_for_client (struct wl_list *destination,
+ struct wl_list *source,
+ struct wl_client *client)
+{
+ struct wl_resource *resource, *tmp;
+ wl_resource_for_each_safe (resource, tmp, source)
+ {
+ if (wl_resource_get_client (resource) == client)
+ {
+ wl_list_remove (wl_resource_get_link (resource));
+ wl_list_insert (destination, wl_resource_get_link (resource));
+ }
+ }
}
void
meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
MetaWaylandSurface *surface)
{
- if (pointer->focus_surface == surface && pointer->focus_resource != NULL)
+ if (pointer->focus_surface == surface && !wl_list_empty (&pointer->focus_resource_list))
return;
if (pointer->focus_surface)
{
- if (pointer->focus_resource)
+ struct wl_resource *resource;
+ struct wl_list *l;
+
+ l = &pointer->focus_resource_list;
+ if (!wl_list_empty (l))
{
struct wl_client *client = wl_resource_get_client (pointer->focus_surface->resource);
struct wl_display *display = wl_client_get_display (client);
uint32_t serial = wl_display_next_serial (display);
- wl_pointer_send_leave (pointer->focus_resource, serial, pointer->focus_surface->resource);
- pointer->focus_resource = NULL;
+ wl_resource_for_each (resource, l)
+ {
+ wl_pointer_send_leave (resource, serial, pointer->focus_surface->resource);
+ }
+
+ move_resources (&pointer->resource_list, &pointer->focus_resource_list);
}
wl_list_remove (&pointer->focus_surface_listener.link);
@@ -327,6 +346,9 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
if (surface != NULL)
{
+ struct wl_resource *resource;
+ struct wl_list *l;
+
pointer->focus_surface = surface;
wl_resource_add_destroy_listener (pointer->focus_surface->resource, &pointer->focus_surface_listener);
@@ -336,19 +358,24 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
wl_fixed_to_int (pointer->x),
wl_fixed_to_int (pointer->y));
- pointer->focus_resource = find_resource_for_surface (&pointer->resource_list, surface);
- if (pointer->focus_resource)
+ move_resources_for_client (&pointer->focus_resource_list,
+ &pointer->resource_list,
+ wl_resource_get_client (pointer->focus_surface->resource));
+
+ l = &pointer->focus_resource_list;
+ if (!wl_list_empty (l))
{
struct wl_client *client = wl_resource_get_client (pointer->focus_surface->resource);
struct wl_display *display = wl_client_get_display (client);
uint32_t serial = wl_display_next_serial (display);
- {
- wl_fixed_t sx, sy;
+ wl_resource_for_each (resource, l)
+ {
+ wl_fixed_t sx, sy;
- meta_wayland_pointer_get_relative_coordinates (pointer, pointer->focus_surface, &sx, &sy);
- wl_pointer_send_enter (pointer->focus_resource, serial, pointer->focus_surface->resource, sx,
sy);
- }
+ meta_wayland_pointer_get_relative_coordinates (pointer, pointer->focus_surface, &sx, &sy);
+ wl_pointer_send_enter (resource, serial, pointer->focus_surface->resource, sx, sy);
+ }
pointer->focus_serial = serial;
}
@@ -419,7 +446,6 @@ static void
popup_grab_button (MetaWaylandPointerGrab *grab,
const ClutterEvent *event)
{
- MetaWaylandPopupGrab *popup_grab = (MetaWaylandPopupGrab*)grab;
MetaWaylandPointer *pointer = grab->pointer;
if (pointer->focus_surface)
diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h
index 98b536c..43c82fb 100644
--- a/src/wayland/meta-wayland-pointer.h
+++ b/src/wayland/meta-wayland-pointer.h
@@ -45,10 +45,10 @@ struct _MetaWaylandPointerGrab
struct _MetaWaylandPointer
{
struct wl_list resource_list;
+ struct wl_list focus_resource_list;
MetaWaylandSurface *focus_surface;
struct wl_listener focus_surface_listener;
- struct wl_resource *focus_resource;
guint32 focus_serial;
guint32 click_serial;
diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c
index 24280d3..3484d08 100644
--- a/src/wayland/meta-wayland-seat.c
+++ b/src/wayland/meta-wayland-seat.c
@@ -301,13 +301,12 @@ static void
handle_scroll_event (MetaWaylandSeat *seat,
const ClutterEvent *event)
{
+ struct wl_resource *resource;
+ struct wl_list *l;
wl_fixed_t x_value = 0, y_value = 0;
notify_motion (seat, event);
- if (!seat->pointer.focus_resource)
- return;
-
if (clutter_event_is_pointer_emulated (event))
return;
@@ -342,12 +341,16 @@ handle_scroll_event (MetaWaylandSeat *seat,
return;
}
- if (x_value)
- wl_pointer_send_axis (seat->pointer.focus_resource, clutter_event_get_time (event),
- WL_POINTER_AXIS_HORIZONTAL_SCROLL, x_value);
- if (y_value)
- wl_pointer_send_axis (seat->pointer.focus_resource, clutter_event_get_time (event),
- WL_POINTER_AXIS_VERTICAL_SCROLL, y_value);
+ l = &seat->pointer.focus_resource_list;
+ wl_resource_for_each (resource, l)
+ {
+ if (x_value)
+ wl_pointer_send_axis (resource, clutter_event_get_time (event),
+ WL_POINTER_AXIS_HORIZONTAL_SCROLL, x_value);
+ if (y_value)
+ wl_pointer_send_axis (resource, clutter_event_get_time (event),
+ WL_POINTER_AXIS_VERTICAL_SCROLL, y_value);
+ }
}
static int
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]