---
 clients/dnd.c    | 20 ++++++++++++++++++--
 clients/window.c | 13 ++++++++++++-
 clients/window.h |  3 +++
 3 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/clients/dnd.c b/clients/dnd.c
index 140f3f4..2b99ab1 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 *
@@ -499,6 +511,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 +535,9 @@ dnd_receive_func(void *data, size_t len, int32_t x, int32_t 
y, void *user_data)
                        len, sizeof *message);
                return;
        }
-               
+
+       input_finish_drag(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..b7ec019 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -2806,6 +2806,7 @@ struct data_offer {
        struct input *input;
        struct wl_array types;
        int refcount;
+       int dropping;
 
        struct task io_task;
        int fd;
@@ -2900,7 +2901,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 +3192,16 @@ input_receive_selection_data_to_fd(struct input *input,
 }
 
 void
+input_finish_drag(struct input *input, uint32_t action)
+{
+       if (input->drag_offer) {
+               wl_data_offer_finish(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..f1686dd 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_finish_drag(struct input *input, uint32_t action);
+
+void
 output_set_user_data(struct output *output, void *data);
 
 void *
-- 
1.8.1.5

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to