summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2017-03-07 20:00:20 +0100
committerCarlos Garnacho <carlosg@gnome.org>2017-03-11 15:30:24 +0100
commit9bd4fd7b981d7aa435960e267969d96e6c130fba (patch)
tree3407c54b1f18f3b26e1ec5b34d7076b2df9c7949
parenta27f8debcac442bf66bca32b828f158bb7b8b5cc (diff)
downloadmutter-9bd4fd7b981d7aa435960e267969d96e6c130fba.tar.gz
xwayland: Release xdnd grabs ASAP
We currently wait for the selection being cleared by the drag source, which might not happen on not quite educated clients. This may leave a stuck XDND grab in the compositor side. We can actually do a bit better, and clear the grab if: 1) The drag source sent XdndDrop to the wayland drag destination. 2) There's no accepting drag destination and all pointer buttons are released. 3) As usual, whenever the drag source clears the selection data https://bugzilla.gnome.org/show_bug.cgi?id=763246
-rw-r--r--src/wayland/meta-xwayland-selection.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/src/wayland/meta-xwayland-selection.c b/src/wayland/meta-xwayland-selection.c
index d2a6e9421..f739eeb8b 100644
--- a/src/wayland/meta-xwayland-selection.c
+++ b/src/wayland/meta-xwayland-selection.c
@@ -388,6 +388,20 @@ meta_xwayland_shutdown_dnd (MetaXWaylandManager *manager)
dnd->dnd_window = None;
}
+static void
+meta_xwayland_end_dnd_grab (MetaWaylandDataDevice *data_device)
+{
+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+ MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
+ MetaXWaylandManager *manager = &compositor->xwayland_manager;
+ MetaDndBridge *dnd = &manager->selection_data->dnd;
+
+ meta_wayland_data_device_end_drag (data_device);
+
+ XMoveResizeWindow (xdisplay, dnd->dnd_window, -1, -1, 1, 1);
+ XUnmapWindow (xdisplay, dnd->dnd_window);
+}
+
/* X11/Wayland data bridges */
static MetaSelectionBridge *
@@ -1400,8 +1414,16 @@ drag_xgrab_button (MetaWaylandPointerGrab *grab,
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
MetaWaylandSeat *seat = compositor->seat;
+ MetaWaylandDataSource *data_source;
meta_wayland_pointer_send_button (seat->pointer, event);
+ data_source = compositor->seat->data_device.dnd_data_source;
+
+ if (seat->pointer->button_count == 0 &&
+ (!meta_wayland_drag_grab_get_focus ((MetaWaylandDragGrab *) grab) ||
+ meta_wayland_data_source_get_current_action (data_source) ==
+ WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE))
+ meta_xwayland_end_dnd_grab (&seat->data_device);
}
static const MetaWaylandPointerGrabInterface drag_xgrab_interface = {
@@ -1537,6 +1559,7 @@ meta_xwayland_selection_handle_client_message (MetaWaylandCompositor *compositor
else if (event->message_type == xdnd_atoms[ATOM_DND_DROP])
{
meta_wayland_surface_drag_dest_drop (drag_focus);
+ meta_xwayland_end_dnd_grab (&seat->data_device);
return TRUE;
}
}
@@ -1596,7 +1619,6 @@ meta_xwayland_selection_handle_xfixes_selection_notify (MetaWaylandCompositor *c
else if (selection->selection_atom == xdnd_atoms[ATOM_DND_SELECTION])
{
MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
- MetaXWaylandSelection *selection_data = compositor->xwayland_manager.selection_data;
MetaWaylandSurface *focus;
selection->owner = event->owner;
@@ -1617,8 +1639,7 @@ meta_xwayland_selection_handle_xfixes_selection_notify (MetaWaylandCompositor *c
}
else if (event->owner == None)
{
- meta_wayland_data_device_end_drag (data_device);
- XUnmapWindow (xdisplay, selection_data->dnd.dnd_window);
+ meta_xwayland_end_dnd_grab (data_device);
}
}