mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 08:00:42 -05:00
wayland: Unset DnD selection on wl_data_offer destruction
On a successful DnD operation we may expect the wl_data_source and wl_data_offer to live long enough to finish the data transfer, despite the grab operation (and other supporting data) being gone. When that happens, the compositor expects a wl_data_offer.finish request to notify that it finished. However the client may still chose not to send that and destroy the wl_data_offer instead, resulting in the MetaSelectionSource owner for the DnD selection not being unset. When that happens, the DnD MetaSelectionSource still exists but it's detached from any grab operation, so will not be unset if eg. the drag source client destroys the wl_data_source. This may result in crashes when the next drag operation tries to replace the owner DnD MetaSelectionSource. Check explicitly for this case, in order to ensure the DnD owner is unset after such operations. Closes: https://gitlab.gnome.org/GNOME/mutter/issues/591
This commit is contained in:
parent
75e2bfb062
commit
b3e19ee669
@ -95,6 +95,9 @@ G_DEFINE_TYPE (MetaWaylandDataSourceWayland, meta_wayland_data_source_wayland,
|
|||||||
G_DEFINE_TYPE (MetaWaylandDataSourcePrimary, meta_wayland_data_source_primary,
|
G_DEFINE_TYPE (MetaWaylandDataSourcePrimary, meta_wayland_data_source_primary,
|
||||||
META_TYPE_WAYLAND_DATA_SOURCE_WAYLAND);
|
META_TYPE_WAYLAND_DATA_SOURCE_WAYLAND);
|
||||||
|
|
||||||
|
static void unset_selection_source (MetaWaylandDataDevice *data_device,
|
||||||
|
MetaSelectionType selection_type);
|
||||||
|
|
||||||
static MetaWaylandDataSource *
|
static MetaWaylandDataSource *
|
||||||
meta_wayland_data_source_wayland_new (struct wl_resource *resource);
|
meta_wayland_data_source_wayland_new (struct wl_resource *resource);
|
||||||
static MetaWaylandDataSource *
|
static MetaWaylandDataSource *
|
||||||
@ -567,12 +570,14 @@ destroy_data_offer (struct wl_resource *resource)
|
|||||||
|
|
||||||
if (offer == meta_wayland_data_source_get_current_offer (offer->source))
|
if (offer == meta_wayland_data_source_get_current_offer (offer->source))
|
||||||
{
|
{
|
||||||
if (seat && seat->data_device.dnd_data_source == offer->source &&
|
if (seat->data_device.dnd_data_source == offer->source &&
|
||||||
wl_resource_get_version (offer->resource) <
|
wl_resource_get_version (offer->resource) <
|
||||||
WL_DATA_OFFER_ACTION_SINCE_VERSION)
|
WL_DATA_OFFER_ACTION_SINCE_VERSION)
|
||||||
meta_wayland_data_source_notify_finish (offer->source);
|
meta_wayland_data_source_notify_finish (offer->source);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (seat->data_device.dnd_data_source == offer->source)
|
||||||
|
unset_selection_source (&seat->data_device, META_SELECTION_DND);
|
||||||
meta_wayland_data_source_cancel (offer->source);
|
meta_wayland_data_source_cancel (offer->source);
|
||||||
meta_wayland_data_source_set_current_offer (offer->source, NULL);
|
meta_wayland_data_source_set_current_offer (offer->source, NULL);
|
||||||
}
|
}
|
||||||
@ -1038,7 +1043,6 @@ drag_grab_button (MetaWaylandPointerGrab *grab,
|
|||||||
{
|
{
|
||||||
/* Detach the data source from the grab, it's meant to live longer */
|
/* Detach the data source from the grab, it's meant to live longer */
|
||||||
meta_wayland_drag_grab_set_source (drag_grab, NULL);
|
meta_wayland_drag_grab_set_source (drag_grab, NULL);
|
||||||
meta_wayland_data_source_set_seat (source, NULL);
|
|
||||||
|
|
||||||
meta_wayland_surface_drag_dest_drop (drag_grab->drag_focus);
|
meta_wayland_surface_drag_dest_drop (drag_grab->drag_focus);
|
||||||
meta_wayland_data_source_notify_drop_performed (source);
|
meta_wayland_data_source_notify_drop_performed (source);
|
||||||
|
Loading…
Reference in New Issue
Block a user