mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 15:40:41 -05:00
wayland: Send clipboard offers to all data devices from the same client
Make the data device track the keyboard focus, and use that list to
forward the clipboard selection to all data devices from the same
client.
This is however not the case of DnD data offers, as the semantics
of multiple in-flight offers is unclear.
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1250
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1253
(cherry picked from commit 7e4e371466
)
This commit is contained in:
parent
5c7b5ef0d9
commit
1ec91cc8ee
@ -53,6 +53,30 @@ drag_grab_data_source_destroyed (gpointer data, GObject *where_the_object_was);
|
|||||||
static struct wl_resource * create_and_send_clipboard_offer (MetaWaylandDataDevice *data_device,
|
static struct wl_resource * create_and_send_clipboard_offer (MetaWaylandDataDevice *data_device,
|
||||||
struct wl_resource *target);
|
struct wl_resource *target);
|
||||||
|
|
||||||
|
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
|
||||||
unbind_resource (struct wl_resource *resource)
|
unbind_resource (struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
@ -251,6 +275,12 @@ meta_wayland_drag_grab_set_focus (MetaWaylandDragGrab *drag_grab,
|
|||||||
client = wl_resource_get_client (surface->resource);
|
client = wl_resource_get_client (surface->resource);
|
||||||
|
|
||||||
data_device_resource = wl_resource_find_for_client (&seat->data_device.resource_list, client);
|
data_device_resource = wl_resource_find_for_client (&seat->data_device.resource_list, client);
|
||||||
|
if (!data_device_resource)
|
||||||
|
{
|
||||||
|
data_device_resource =
|
||||||
|
wl_resource_find_for_client (&seat->data_device.focus_resource_list,
|
||||||
|
client);
|
||||||
|
}
|
||||||
|
|
||||||
if (source && data_device_resource)
|
if (source && data_device_resource)
|
||||||
offer = create_and_send_dnd_offer (source, data_device_resource);
|
offer = create_and_send_dnd_offer (source, data_device_resource);
|
||||||
@ -948,10 +978,7 @@ owner_changed_cb (MetaSelection *selection,
|
|||||||
|
|
||||||
if (selection_type == META_SELECTION_CLIPBOARD)
|
if (selection_type == META_SELECTION_CLIPBOARD)
|
||||||
{
|
{
|
||||||
data_device_resource =
|
wl_resource_for_each (data_device_resource, &data_device->focus_resource_list)
|
||||||
wl_resource_find_for_client (&data_device->resource_list, focus_client);
|
|
||||||
|
|
||||||
if (data_device_resource)
|
|
||||||
{
|
{
|
||||||
struct wl_resource *offer = NULL;
|
struct wl_resource *offer = NULL;
|
||||||
|
|
||||||
@ -1021,6 +1048,7 @@ void
|
|||||||
meta_wayland_data_device_init (MetaWaylandDataDevice *data_device)
|
meta_wayland_data_device_init (MetaWaylandDataDevice *data_device)
|
||||||
{
|
{
|
||||||
wl_list_init (&data_device->resource_list);
|
wl_list_init (&data_device->resource_list);
|
||||||
|
wl_list_init (&data_device->focus_resource_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wl_resource *
|
static struct wl_resource *
|
||||||
@ -1063,14 +1091,20 @@ meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
data_device->focus_client = focus_client;
|
data_device->focus_client = focus_client;
|
||||||
|
move_resources (&data_device->resource_list,
|
||||||
|
&data_device->focus_resource_list);
|
||||||
|
|
||||||
if (!focus_client)
|
if (!focus_client)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client);
|
move_resources_for_client (&data_device->focus_resource_list,
|
||||||
if (data_device_resource)
|
&data_device->resource_list,
|
||||||
|
focus_client);
|
||||||
|
|
||||||
|
wl_resource_for_each (data_device_resource, &data_device->focus_resource_list)
|
||||||
{
|
{
|
||||||
struct wl_resource *offer;
|
struct wl_resource *offer;
|
||||||
|
|
||||||
offer = create_and_send_clipboard_offer (data_device, data_device_resource);
|
offer = create_and_send_clipboard_offer (data_device, data_device_resource);
|
||||||
wl_data_device_send_selection (data_device_resource, offer);
|
wl_data_device_send_selection (data_device_resource, offer);
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ struct _MetaWaylandDataDevice
|
|||||||
MetaWaylandDataSource *selection_data_source;
|
MetaWaylandDataSource *selection_data_source;
|
||||||
MetaWaylandDataSource *dnd_data_source;
|
MetaWaylandDataSource *dnd_data_source;
|
||||||
struct wl_list resource_list;
|
struct wl_list resource_list;
|
||||||
|
struct wl_list focus_resource_list;
|
||||||
MetaWaylandDragGrab *current_grab;
|
MetaWaylandDragGrab *current_grab;
|
||||||
struct wl_client *focus_client;
|
struct wl_client *focus_client;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user