--- clients/dnd.c | 22 ++++++++++++++++++++-- clients/window.c | 24 +++++++++++++++++++++++- clients/window.h | 3 +++ 3 files changed, 46 insertions(+), 3 deletions(-)
diff --git a/clients/dnd.c b/clients/dnd.c index 140f3f4..5e45b54 100644 --- a/clients/dnd.c +++ b/clients/dnd.c @@ -48,6 +48,7 @@ struct dnd { struct item *items[16]; int self_only; struct dnd_drag *current_drag; + struct input *offer_input; }; struct dnd_drag { @@ -311,10 +312,21 @@ data_source_cancelled(void *data, struct wl_data_source *source) free(dnd_drag); } +static void +data_source_dropped(void *data, struct wl_data_source *source, + uint32_t action) +{ + struct dnd_drag *dnd_drag = data; + + wl_data_source_destroy(dnd_drag->data_source); + free(dnd_drag); +} + static const struct wl_data_source_listener data_source_listener = { data_source_target, data_source_send, - data_source_cancelled + data_source_cancelled, + data_source_dropped }; static cairo_surface_t * @@ -426,6 +438,8 @@ dnd_button_handler(struct widget *widget, "application/x-wayland-dnd-flower"); wl_data_source_offer(dnd_drag->data_source, "text/plain; charset=utf-8"); + wl_data_source_set_actions(dnd_drag->data_source, + WL_DATA_OFFER_DND_ACTION_MOVE); } wl_data_device_start_drag(input_get_data_device(input), @@ -499,6 +513,8 @@ dnd_data_handler(struct window *window, if (!types) return; + dnd->offer_input = input; + if (dnd_get_item(dnd, x, y) || dnd->self_only) { input_accept(input, NULL); } else { @@ -521,7 +537,9 @@ dnd_receive_func(void *data, size_t len, int32_t x, int32_t y, void *user_data) len, sizeof *message); return; } - + + input_drag_notify_received(dnd->offer_input, WL_DATA_OFFER_DND_ACTION_MOVE); + widget_get_allocation(dnd->widget, &allocation); item = item_create(dnd->display, x - message->x_offset - allocation.x, diff --git a/clients/window.c b/clients/window.c index 249ba6f..006f753 100644 --- a/clients/window.c +++ b/clients/window.c @@ -2805,7 +2805,9 @@ struct data_offer { struct wl_data_offer *offer; struct input *input; struct wl_array types; + uint32_t available_actions; int refcount; + int dropping; struct task io_task; int fd; @@ -2824,8 +2826,17 @@ data_offer_offer(void *data, struct wl_data_offer *wl_data_offer, const char *ty *p = strdup(type); } +static void +data_offer_actions(void *data, struct wl_data_offer *wl_data_offer, uint32_t actions) +{ + struct data_offer *offer = data; + + offer->available_actions = actions; +} + static const struct wl_data_offer_listener data_offer_listener = { data_offer_offer, + data_offer_actions }; static void @@ -2856,6 +2867,7 @@ data_device_data_offer(void *data, offer->refcount = 1; offer->input = data; offer->offer = _offer; + offer->available_actions = WL_DATA_OFFER_DND_ACTION_IGNORE; wl_data_offer_add_listener(offer->offer, &data_offer_listener, offer); } @@ -2900,7 +2912,7 @@ data_device_leave(void *data, struct wl_data_device *data_device) { struct input *input = data; - if (input->drag_offer) { + if (input->drag_offer && !input->drag_offer->dropping) { data_offer_destroy(input->drag_offer); input->drag_offer = NULL; } @@ -3191,6 +3203,16 @@ input_receive_selection_data_to_fd(struct input *input, } void +input_drag_notify_received(struct input *input, uint32_t action) +{ + if (input->drag_offer) { + wl_data_offer_notify_received(input->drag_offer->offer, action); + data_offer_destroy(input->drag_offer); + input->drag_offer = NULL; + } +} + +void window_move(struct window *window, struct input *input, uint32_t serial) { if (!window->shell_surface) diff --git a/clients/window.h b/clients/window.h index c2946d8..dce1875 100644 --- a/clients/window.h +++ b/clients/window.h @@ -467,6 +467,9 @@ input_receive_selection_data_to_fd(struct input *input, const char *mime_type, int fd); void +input_drag_notify_received(struct input *input, enum wl_data_offer_dnd_action action); + +void output_set_user_data(struct output *output, void *data); void * -- 1.8.1.5 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel