diff options
author | emersion <contact@emersion.fr> | 2018-03-29 12:11:30 -0400 |
---|---|---|
committer | emersion <contact@emersion.fr> | 2018-03-29 12:11:30 -0400 |
commit | 79dd4a0ff98f6467c414903fc14112ab73345389 (patch) | |
tree | e8c6b63950d1f9944ecb4fa58e03a0853c70a17a /xwayland | |
parent | ca2a73b90d98a70d1a175cedf00c40bf7fcdf204 (diff) |
xwayland: receive DND_FINISHED
Diffstat (limited to 'xwayland')
-rw-r--r-- | xwayland/selection.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/xwayland/selection.c b/xwayland/selection.c index f56b39b5..d4a8b597 100644 --- a/xwayland/selection.c +++ b/xwayland/selection.c @@ -1015,6 +1015,41 @@ int xwm_handle_selection_client_message(struct wlr_xwm *xwm, wlr_log(L_DEBUG, "DND_STATUS window=%d accepted=%d action=%d", target_window, accepted, action); return 1; + } else if (ev->type == xwm->atoms[DND_FINISHED]) { + // This should only happen after the drag has ended, but before the drag + // source is destroyed + if (xwm->seat == NULL || xwm->seat->drag_source == NULL || + xwm->drag != NULL) { + wlr_log(L_DEBUG, "ignoring XdndFinished client message because " + "there's no finished drag"); + return 1; + } + + xcb_client_message_data_t *data = &ev->data; + xcb_window_t target_window = data->data32[0]; + bool performed = data->data32[1] & 1; + xcb_atom_t action_atom = data->data32[2]; + + if (xwm->drag_focus == NULL || + target_window != xwm->drag_focus->window_id) { + wlr_log(L_DEBUG, "ignoring XdndFinished client message because " + "it doesn't match the finished drag focus window ID"); + return 1; + } + + enum wl_data_device_manager_dnd_action action = + data_device_manager_dnd_action_from_atom(xwm, action_atom); + + if (performed) { + struct wlr_data_source *source = xwm->seat->drag_source; + if (source->dnd_finish) { + source->dnd_finish(source); + } + } + + wlr_log(L_DEBUG, "DND_FINISH window=%d performed=%d action=%d", + target_window, performed, action); + return 1; } else { return 0; } @@ -1204,7 +1239,8 @@ static void seat_handle_drag_destroy(struct wl_listener *listener, void *data) { // Don't reset drag focus yet because the target will read the drag source // right after - if (xwm->drag_focus != NULL) { + if (xwm->drag_focus != NULL && !xwm->drag->source->accepted) { + wlr_log(L_DEBUG, "Wayland drag cancelled over an Xwayland window"); xwm_dnd_send_leave(xwm); } |