From ca2a73b90d98a70d1a175cedf00c40bf7fcdf204 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 29 Mar 2018 11:40:19 -0400 Subject: [PATCH] xwayland: allow drag data source transfer after drag ends --- include/xwayland/xwm.h | 1 + xwayland/selection.c | 51 ++++++++++++++++++++++++++---------------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/include/xwayland/xwm.h b/include/xwayland/xwm.h index b85b5bae..d36f9ac0 100644 --- a/include/xwayland/xwm.h +++ b/include/xwayland/xwm.h @@ -139,6 +139,7 @@ struct wlr_xwm { struct wl_listener seat_drag_motion; struct wl_listener seat_drag_drop; struct wl_listener seat_drag_destroy; + struct wl_listener seat_drag_source_destroy; }; struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland); diff --git a/xwayland/selection.c b/xwayland/selection.c index fa7e478b..f56b39b5 100644 --- a/xwayland/selection.c +++ b/xwayland/selection.c @@ -186,7 +186,7 @@ static void xwm_selection_source_send(struct wlr_xwm_selection *selection, const char *mime_type, int32_t fd) { if (selection == &selection->xwm->clipboard_selection) { struct wlr_data_source *source = - selection->xwm->seat->selection_data_source; + selection->xwm->seat->selection_source; if (source != NULL) { source->send(source, mime_type, fd); return; @@ -199,13 +199,11 @@ static void xwm_selection_source_send(struct wlr_xwm_selection *selection, return; } } else if (selection == &selection->xwm->dnd_selection) { - if (selection->xwm->seat->drag != NULL) { - struct wlr_data_source *source = - selection->xwm->seat->drag->source; - if (source != NULL) { - source->send(source, mime_type, fd); - return; - } + struct wlr_data_source *source = + selection->xwm->seat->drag_source; + if (source != NULL) { + source->send(source, mime_type, fd); + return; } } @@ -216,7 +214,7 @@ static struct wl_array *xwm_selection_source_get_mime_types( struct wlr_xwm_selection *selection) { if (selection == &selection->xwm->clipboard_selection) { struct wlr_data_source *source = - selection->xwm->seat->selection_data_source; + selection->xwm->seat->selection_source; if (source != NULL) { return &source->mime_types; } @@ -227,9 +225,10 @@ static struct wl_array *xwm_selection_source_get_mime_types( return &source->mime_types; } } else if (selection == &selection->xwm->dnd_selection) { - if (selection->xwm->seat->drag != NULL && - selection->xwm->seat->drag->source != NULL) { - return &selection->xwm->seat->drag->source->mime_types; + struct wlr_data_source *source = + selection->xwm->seat->drag_source; + if (source != NULL) { + return &source->mime_types; } } return NULL; @@ -815,8 +814,7 @@ static void xwm_selection_get_targets(struct wlr_xwm_selection *selection) { // set the wayland selection to the X11 selection struct wlr_xwm *xwm = selection->xwm; - if (selection == &xwm->clipboard_selection || - selection == &xwm->dnd_selection) { + if (selection == &xwm->clipboard_selection) { struct x11_data_source *source = calloc(1, sizeof(struct x11_data_source)); if (source == NULL) { @@ -827,8 +825,6 @@ static void xwm_selection_get_targets(struct wlr_xwm_selection *selection) { source->base.send = data_source_send; source->base.cancel = data_source_cancel; - // TODO: DND - source->selection = selection; wl_array_init(&source->mime_types_atoms); @@ -861,6 +857,8 @@ static void xwm_selection_get_targets(struct wlr_xwm_selection *selection) { } else { source->base.cancel(&source->base); } + } else if (selection == &xwm->dnd_selection) { + // TODO } } @@ -1082,8 +1080,8 @@ void xwm_selection_finish(struct wlr_xwm *xwm) { xcb_destroy_window(xwm->xcb_conn, xwm->selection_window); } if (xwm->seat) { - if (xwm->seat->selection_data_source && - xwm->seat->selection_data_source->cancel == data_source_cancel) { + if (xwm->seat->selection_source && + xwm->seat->selection_source->cancel == data_source_cancel) { wlr_seat_set_selection(xwm->seat, NULL, wl_display_next_serial(xwm->xwayland->wl_display)); } @@ -1118,7 +1116,7 @@ static void seat_handle_selection(struct wl_listener *listener, struct wlr_seat *seat = data; struct wlr_xwm *xwm = wl_container_of(listener, xwm, seat_selection); - struct wlr_data_source *source = seat->selection_data_source; + struct wlr_data_source *source = seat->selection_source; if (source != NULL && source->send == data_source_send) { return; @@ -1211,10 +1209,21 @@ static void seat_handle_drag_destroy(struct wl_listener *listener, void *data) { } wl_list_remove(&xwm->seat_drag_focus.link); + wl_list_remove(&xwm->seat_drag_motion.link); + wl_list_remove(&xwm->seat_drag_drop.link); wl_list_remove(&xwm->seat_drag_destroy.link); xwm->drag = NULL; } +static void seat_handle_drag_source_destroy(struct wl_listener *listener, + void *data) { + struct wlr_xwm *xwm = + wl_container_of(listener, xwm, seat_drag_source_destroy); + + wl_list_remove(&xwm->seat_drag_source_destroy.link); + xwm->drag_focus = NULL; +} + static void seat_handle_start_drag(struct wl_listener *listener, void *data) { struct wlr_drag *drag = data; struct wlr_xwm *xwm = wl_container_of(listener, xwm, seat_start_drag); @@ -1232,6 +1241,10 @@ static void seat_handle_start_drag(struct wl_listener *listener, void *data) { xwm->seat_drag_drop.notify = seat_handle_drag_drop; wl_signal_add(&drag->events.destroy, &xwm->seat_drag_destroy); xwm->seat_drag_destroy.notify = seat_handle_drag_destroy; + + wl_signal_add(&drag->source->events.destroy, + &xwm->seat_drag_source_destroy); + xwm->seat_drag_source_destroy.notify = seat_handle_drag_source_destroy; } }