mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 11:32:04 +00:00
MetaWaylandPointer: Put client resources in its own struct
Instead of moving around all the bound pointer resources for a client when changing focus, keep all the resources bound by a client in a per client struct, and track the focus by having a pointer to the current active pointer client struct instance. This will simplify having wl_pointer extensinos sharing the pointer focus of the wl_pointer by only having to add them to the pointer client. https://bugzilla.gnome.org/show_bug.cgi?id=744104
This commit is contained in:
parent
cba2ab445e
commit
1ee387bb31
@ -58,10 +58,107 @@
|
|||||||
|
|
||||||
#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10)
|
#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10)
|
||||||
|
|
||||||
static void
|
static MetaWaylandPointerClient *
|
||||||
unbind_resource (struct wl_resource *resource)
|
meta_wayland_pointer_client_new (void)
|
||||||
{
|
{
|
||||||
|
MetaWaylandPointerClient *pointer_client;
|
||||||
|
|
||||||
|
pointer_client = g_slice_new0 (MetaWaylandPointerClient);
|
||||||
|
wl_list_init (&pointer_client->pointer_resources);
|
||||||
|
|
||||||
|
return pointer_client;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_pointer_client_free (MetaWaylandPointerClient *pointer_client)
|
||||||
|
{
|
||||||
|
struct wl_resource *resource;
|
||||||
|
|
||||||
|
/* Since we make every wl_pointer resource defunct when we stop advertising
|
||||||
|
* the pointer capability on the wl_seat, we need to make sure all the
|
||||||
|
* resources in the pointer client instance gets removed.
|
||||||
|
*/
|
||||||
|
wl_resource_for_each (resource, &pointer_client->pointer_resources)
|
||||||
|
{
|
||||||
|
wl_list_remove (wl_resource_get_link (resource));
|
||||||
|
wl_list_init (wl_resource_get_link (resource));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_slice_free (MetaWaylandPointerClient, pointer_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_wayland_pointer_client_is_empty (MetaWaylandPointerClient *pointer_client)
|
||||||
|
{
|
||||||
|
return wl_list_empty (&pointer_client->pointer_resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWaylandPointerClient *
|
||||||
|
meta_wayland_pointer_get_pointer_client (MetaWaylandPointer *pointer,
|
||||||
|
struct wl_client *client)
|
||||||
|
{
|
||||||
|
return g_hash_table_lookup (pointer->pointer_clients, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MetaWaylandPointerClient *
|
||||||
|
meta_wayland_pointer_ensure_pointer_client (MetaWaylandPointer *pointer,
|
||||||
|
struct wl_client *client)
|
||||||
|
{
|
||||||
|
MetaWaylandPointerClient *pointer_client;
|
||||||
|
|
||||||
|
pointer_client = meta_wayland_pointer_get_pointer_client (pointer, client);
|
||||||
|
if (pointer_client)
|
||||||
|
return pointer_client;
|
||||||
|
|
||||||
|
pointer_client = meta_wayland_pointer_client_new ();
|
||||||
|
g_hash_table_insert (pointer->pointer_clients, client, pointer_client);
|
||||||
|
|
||||||
|
if (!pointer->focus_client &&
|
||||||
|
pointer->focus_surface &&
|
||||||
|
wl_resource_get_client (pointer->focus_surface->resource) == client)
|
||||||
|
pointer->focus_client = pointer_client;
|
||||||
|
|
||||||
|
return pointer_client;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_pointer_cleanup_pointer_client (MetaWaylandPointer *pointer,
|
||||||
|
MetaWaylandPointerClient *pointer_client,
|
||||||
|
struct wl_client *client)
|
||||||
|
{
|
||||||
|
if (meta_wayland_pointer_client_is_empty (pointer_client))
|
||||||
|
{
|
||||||
|
if (pointer->focus_client == pointer_client)
|
||||||
|
pointer->focus_client = NULL;
|
||||||
|
g_hash_table_remove (pointer->pointer_clients, client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_pointer_unbind_pointer_client_resource (struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandPointer *pointer = wl_resource_get_user_data (resource);
|
||||||
|
MetaWaylandPointerClient *pointer_client;
|
||||||
|
struct wl_client *client = wl_resource_get_client (resource);
|
||||||
|
|
||||||
wl_list_remove (wl_resource_get_link (resource));
|
wl_list_remove (wl_resource_get_link (resource));
|
||||||
|
|
||||||
|
pointer_client = meta_wayland_pointer_get_pointer_client (pointer, client);
|
||||||
|
if (!pointer_client)
|
||||||
|
{
|
||||||
|
/* This happens if all pointer devices were unplugged and no new resources
|
||||||
|
* were created by the client.
|
||||||
|
*
|
||||||
|
* If this is a resource that was previously made defunct, pointer_client
|
||||||
|
* be non-NULL but it is harmless since the below cleanup call will be
|
||||||
|
* prevented from removing the pointer client because of valid resources.
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_wayland_pointer_cleanup_pointer_client (pointer,
|
||||||
|
pointer_client,
|
||||||
|
client);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -131,17 +228,20 @@ meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer,
|
|||||||
const ClutterEvent *event)
|
const ClutterEvent *event)
|
||||||
{
|
{
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
struct wl_list *l;
|
uint32_t time;
|
||||||
|
wl_fixed_t sx, sy;
|
||||||
|
|
||||||
l = &pointer->focus_resource_list;
|
if (!pointer->focus_client)
|
||||||
wl_resource_for_each(resource, l)
|
return;
|
||||||
|
|
||||||
|
time = clutter_event_get_time (event);
|
||||||
|
meta_wayland_pointer_get_relative_coordinates (pointer,
|
||||||
|
pointer->focus_surface,
|
||||||
|
&sx, &sy);
|
||||||
|
|
||||||
|
wl_resource_for_each (resource, &pointer->focus_client->pointer_resources)
|
||||||
{
|
{
|
||||||
wl_fixed_t sx, sy;
|
wl_pointer_send_motion (resource, time, sx, sy);
|
||||||
|
|
||||||
meta_wayland_pointer_get_relative_coordinates (pointer,
|
|
||||||
pointer->focus_surface,
|
|
||||||
&sx, &sy);
|
|
||||||
wl_pointer_send_motion (resource, clutter_event_get_time (event), sx, sy);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,19 +250,21 @@ meta_wayland_pointer_send_button (MetaWaylandPointer *pointer,
|
|||||||
const ClutterEvent *event)
|
const ClutterEvent *event)
|
||||||
{
|
{
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
struct wl_list *l;
|
|
||||||
ClutterEventType event_type;
|
ClutterEventType event_type;
|
||||||
|
|
||||||
event_type = clutter_event_type (event);
|
event_type = clutter_event_type (event);
|
||||||
|
|
||||||
l = &pointer->focus_resource_list;
|
if (pointer->focus_client &&
|
||||||
if (!wl_list_empty (l))
|
!wl_list_empty (&pointer->focus_client->pointer_resources))
|
||||||
{
|
{
|
||||||
struct wl_client *client = wl_resource_get_client (pointer->focus_surface->resource);
|
struct wl_client *client = wl_resource_get_client (pointer->focus_surface->resource);
|
||||||
struct wl_display *display = wl_client_get_display (client);
|
struct wl_display *display = wl_client_get_display (client);
|
||||||
|
uint32_t time;
|
||||||
uint32_t button;
|
uint32_t button;
|
||||||
uint32_t serial;
|
uint32_t serial;
|
||||||
|
|
||||||
|
time = clutter_event_get_time (event);
|
||||||
|
|
||||||
button = clutter_event_get_button (event);
|
button = clutter_event_get_button (event);
|
||||||
switch (button)
|
switch (button)
|
||||||
{
|
{
|
||||||
@ -183,10 +285,10 @@ meta_wayland_pointer_send_button (MetaWaylandPointer *pointer,
|
|||||||
|
|
||||||
serial = wl_display_next_serial (display);
|
serial = wl_display_next_serial (display);
|
||||||
|
|
||||||
wl_resource_for_each(resource, l)
|
wl_resource_for_each (resource, &pointer->focus_client->pointer_resources)
|
||||||
{
|
{
|
||||||
wl_pointer_send_button (resource, serial,
|
wl_pointer_send_button (resource, serial,
|
||||||
clutter_event_get_time (event), button,
|
time, button,
|
||||||
event_type == CLUTTER_BUTTON_PRESS ? 1 : 0);
|
event_type == CLUTTER_BUTTON_PRESS ? 1 : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -241,8 +343,9 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer,
|
|||||||
|
|
||||||
pointer->display = display;
|
pointer->display = display;
|
||||||
|
|
||||||
wl_list_init (&pointer->resource_list);
|
pointer->pointer_clients =
|
||||||
wl_list_init (&pointer->focus_resource_list);
|
g_hash_table_new_full (NULL, NULL, NULL,
|
||||||
|
(GDestroyNotify) meta_wayland_pointer_client_free);
|
||||||
|
|
||||||
pointer->focus_surface_listener.notify = pointer_handle_focus_surface_destroy;
|
pointer->focus_surface_listener.notify = pointer_handle_focus_surface_destroy;
|
||||||
|
|
||||||
@ -265,6 +368,7 @@ meta_wayland_pointer_release (MetaWaylandPointer *pointer)
|
|||||||
meta_wayland_pointer_set_focus (pointer, NULL);
|
meta_wayland_pointer_set_focus (pointer, NULL);
|
||||||
set_cursor_surface (pointer, NULL);
|
set_cursor_surface (pointer, NULL);
|
||||||
|
|
||||||
|
g_clear_pointer (&pointer->pointer_clients, g_hash_table_unref);
|
||||||
pointer->display = NULL;
|
pointer->display = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,7 +462,6 @@ handle_scroll_event (MetaWaylandPointer *pointer,
|
|||||||
const ClutterEvent *event)
|
const ClutterEvent *event)
|
||||||
{
|
{
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
struct wl_list *l;
|
|
||||||
wl_fixed_t x_value = 0, y_value = 0;
|
wl_fixed_t x_value = 0, y_value = 0;
|
||||||
|
|
||||||
if (clutter_event_is_pointer_emulated (event))
|
if (clutter_event_is_pointer_emulated (event))
|
||||||
@ -399,15 +502,17 @@ handle_scroll_event (MetaWaylandPointer *pointer,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
l = &pointer->focus_resource_list;
|
if (pointer->focus_client)
|
||||||
wl_resource_for_each (resource, l)
|
|
||||||
{
|
{
|
||||||
if (x_value)
|
wl_resource_for_each (resource, &pointer->focus_client->pointer_resources)
|
||||||
wl_pointer_send_axis (resource, clutter_event_get_time (event),
|
{
|
||||||
WL_POINTER_AXIS_HORIZONTAL_SCROLL, x_value);
|
if (x_value)
|
||||||
if (y_value)
|
wl_pointer_send_axis (resource, clutter_event_get_time (event),
|
||||||
wl_pointer_send_axis (resource, clutter_event_get_time (event),
|
WL_POINTER_AXIS_HORIZONTAL_SCROLL, x_value);
|
||||||
WL_POINTER_AXIS_VERTICAL_SCROLL, y_value);
|
if (y_value)
|
||||||
|
wl_pointer_send_axis (resource, clutter_event_get_time (event),
|
||||||
|
WL_POINTER_AXIS_VERTICAL_SCROLL, y_value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,29 +542,6 @@ meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
move_resources (struct wl_list *destination, struct wl_list *source)
|
|
||||||
{
|
|
||||||
wl_list_insert_list (destination, source);
|
|
||||||
wl_list_init (source);
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
static void
|
||||||
broadcast_focus (MetaWaylandPointer *pointer,
|
broadcast_focus (MetaWaylandPointer *pointer,
|
||||||
struct wl_resource *resource)
|
struct wl_resource *resource)
|
||||||
@ -482,22 +564,23 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
|||||||
|
|
||||||
if (pointer->focus_surface != NULL)
|
if (pointer->focus_surface != NULL)
|
||||||
{
|
{
|
||||||
|
struct wl_client *client =
|
||||||
|
wl_resource_get_client (pointer->focus_surface->resource);
|
||||||
|
struct wl_display *display = wl_client_get_display (client);
|
||||||
|
uint32_t serial;
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
struct wl_list *l;
|
|
||||||
|
|
||||||
l = &pointer->focus_resource_list;
|
serial = wl_display_next_serial (display);
|
||||||
if (!wl_list_empty (l))
|
|
||||||
|
if (pointer->focus_client)
|
||||||
{
|
{
|
||||||
struct wl_client *client = wl_resource_get_client (pointer->focus_surface->resource);
|
wl_resource_for_each (resource,
|
||||||
struct wl_display *display = wl_client_get_display (client);
|
&pointer->focus_client->pointer_resources)
|
||||||
uint32_t serial = wl_display_next_serial (display);
|
|
||||||
|
|
||||||
wl_resource_for_each (resource, l)
|
|
||||||
{
|
{
|
||||||
wl_pointer_send_leave (resource, serial, pointer->focus_surface->resource);
|
wl_pointer_send_leave (resource, serial, pointer->focus_surface->resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
move_resources (&pointer->resource_list, &pointer->focus_resource_list);
|
pointer->focus_client = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_list_remove (&pointer->focus_surface_listener.link);
|
wl_list_remove (&pointer->focus_surface_listener.link);
|
||||||
@ -506,8 +589,9 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
|||||||
|
|
||||||
if (surface != NULL)
|
if (surface != NULL)
|
||||||
{
|
{
|
||||||
|
struct wl_client *client = wl_resource_get_client (surface->resource);
|
||||||
|
struct wl_display *display = wl_client_get_display (client);
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
struct wl_list *l;
|
|
||||||
ClutterPoint pos;
|
ClutterPoint pos;
|
||||||
|
|
||||||
pointer->focus_surface = surface;
|
pointer->focus_surface = surface;
|
||||||
@ -521,18 +605,14 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
|||||||
clutter_get_current_event_time (),
|
clutter_get_current_event_time (),
|
||||||
pos.x, pos.y);
|
pos.x, pos.y);
|
||||||
|
|
||||||
move_resources_for_client (&pointer->focus_resource_list,
|
pointer->focus_client =
|
||||||
&pointer->resource_list,
|
meta_wayland_pointer_get_pointer_client (pointer, client);
|
||||||
wl_resource_get_client (pointer->focus_surface->resource));
|
if (pointer->focus_client)
|
||||||
|
|
||||||
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);
|
|
||||||
pointer->focus_serial = wl_display_next_serial (display);
|
pointer->focus_serial = wl_display_next_serial (display);
|
||||||
|
|
||||||
wl_resource_for_each (resource, l)
|
wl_resource_for_each (resource,
|
||||||
|
&pointer->focus_client->pointer_resources)
|
||||||
{
|
{
|
||||||
broadcast_focus (pointer, resource);
|
broadcast_focus (pointer, resource);
|
||||||
}
|
}
|
||||||
@ -707,19 +787,19 @@ meta_wayland_pointer_create_new_resource (MetaWaylandPointer *pointer,
|
|||||||
uint32_t id)
|
uint32_t id)
|
||||||
{
|
{
|
||||||
struct wl_resource *cr;
|
struct wl_resource *cr;
|
||||||
|
MetaWaylandPointerClient *pointer_client;
|
||||||
|
|
||||||
cr = wl_resource_create (client, &wl_pointer_interface, wl_resource_get_version (seat_resource), id);
|
cr = wl_resource_create (client, &wl_pointer_interface, wl_resource_get_version (seat_resource), id);
|
||||||
wl_resource_set_implementation (cr, &pointer_interface, pointer, unbind_resource);
|
wl_resource_set_implementation (cr, &pointer_interface, pointer,
|
||||||
|
meta_wayland_pointer_unbind_pointer_client_resource);
|
||||||
|
|
||||||
if (pointer->focus_surface && wl_resource_get_client (pointer->focus_surface->resource) == client)
|
pointer_client = meta_wayland_pointer_ensure_pointer_client (pointer, client);
|
||||||
{
|
|
||||||
wl_list_insert (&pointer->focus_resource_list, wl_resource_get_link (cr));
|
wl_list_insert (&pointer_client->pointer_resources,
|
||||||
broadcast_focus (pointer, cr);
|
wl_resource_get_link (cr));
|
||||||
}
|
|
||||||
else
|
if (pointer->focus_client == pointer_client)
|
||||||
{
|
broadcast_focus (pointer, cr);
|
||||||
wl_list_insert (&pointer->resource_list, wl_resource_get_link (cr));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -44,12 +44,17 @@ struct _MetaWaylandPointerGrab
|
|||||||
MetaWaylandPointer *pointer;
|
MetaWaylandPointer *pointer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _MetaWaylandPointerClient
|
||||||
|
{
|
||||||
|
struct wl_list pointer_resources;
|
||||||
|
};
|
||||||
|
|
||||||
struct _MetaWaylandPointer
|
struct _MetaWaylandPointer
|
||||||
{
|
{
|
||||||
struct wl_display *display;
|
struct wl_display *display;
|
||||||
|
|
||||||
struct wl_list resource_list;
|
MetaWaylandPointerClient *focus_client;
|
||||||
struct wl_list focus_resource_list;
|
GHashTable *pointer_clients;
|
||||||
|
|
||||||
MetaWaylandSurface *focus_surface;
|
MetaWaylandSurface *focus_surface;
|
||||||
struct wl_listener focus_surface_listener;
|
struct wl_listener focus_surface_listener;
|
||||||
@ -127,4 +132,8 @@ gboolean meta_wayland_pointer_can_popup (MetaWaylandPointer *pointer,
|
|||||||
|
|
||||||
MetaWaylandSurface *meta_wayland_pointer_get_top_popup (MetaWaylandPointer *pointer);
|
MetaWaylandSurface *meta_wayland_pointer_get_top_popup (MetaWaylandPointer *pointer);
|
||||||
|
|
||||||
|
MetaWaylandPointerClient * meta_wayland_pointer_get_pointer_client (MetaWaylandPointer *pointer,
|
||||||
|
struct wl_client *client);
|
||||||
|
void meta_wayland_pointer_unbind_pointer_client_resource (struct wl_resource *resource);
|
||||||
|
|
||||||
#endif /* META_WAYLAND_POINTER_H */
|
#endif /* META_WAYLAND_POINTER_H */
|
||||||
|
@ -43,4 +43,6 @@ typedef struct _MetaWaylandOutput MetaWaylandOutput;
|
|||||||
|
|
||||||
typedef struct _MetaWaylandSerial MetaWaylandSerial;
|
typedef struct _MetaWaylandSerial MetaWaylandSerial;
|
||||||
|
|
||||||
|
typedef struct _MetaWaylandPointerClient MetaWaylandPointerClient;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user