Add option --self-only to dnd client. If this options is passed, the
drag will be started with no data source so that no drag and drop
events are sent to other clients.
---
 clients/dnd.c    |   76 +++++++++++++++++++++++++++++++++++++++++-------------
 clients/window.c |   33 +++++++++++++++++------
 2 files changed, 82 insertions(+), 27 deletions(-)

diff --git a/clients/dnd.c b/clients/dnd.c
index de1ca47..c6f0f18 100644
--- a/clients/dnd.c
+++ b/clients/dnd.c
@@ -37,12 +37,16 @@
 #include "window.h"
 #include "../shared/cairo-util.h"
 
+struct dnd_drag;
+
 struct dnd {
        struct window *window;
        struct widget *widget;
        struct display *display;
        uint32_t key;
        struct item *items[16];
+       int self_only;
+       struct dnd_drag *current_drag;
 };
 
 struct dnd_drag {
@@ -366,6 +370,7 @@ dnd_button_handler(struct widget *widget,
        struct wl_buffer *buffer;
        unsigned int i;
        uint32_t serial;
+       cairo_surface_t *icon;
 
        widget_get_allocation(dnd->widget, &allocation);
        input_get_position(input, &x, &y);
@@ -397,15 +402,20 @@ dnd_button_handler(struct widget *widget,
 
                input_ungrab(input);
 
-               dnd_drag->data_source =
-                       display_create_data_source(dnd->display);
-               wl_data_source_add_listener(dnd_drag->data_source,
-                                           &data_source_listener,
-                                           dnd_drag);
-               wl_data_source_offer(dnd_drag->data_source,
-                                    "application/x-wayland-dnd-flower");
-               wl_data_source_offer(dnd_drag->data_source,
-                                    "text/plain; charset=utf-8");
+               if (dnd->self_only) {
+                       dnd_drag->data_source = NULL;
+               } else {
+                       dnd_drag->data_source =
+                               display_create_data_source(dnd->display);
+                       wl_data_source_add_listener(dnd_drag->data_source,
+                                                   &data_source_listener,
+                                                   dnd_drag);
+                       wl_data_source_offer(dnd_drag->data_source,
+                                            
"application/x-wayland-dnd-flower");
+                       wl_data_source_offer(dnd_drag->data_source,
+                                            "text/plain; charset=utf-8");
+               }
+
                wl_data_device_start_drag(input_get_data_device(input),
                                          dnd_drag->data_source,
                                          window_get_wl_surface(dnd->window),
@@ -419,12 +429,18 @@ dnd_button_handler(struct widget *widget,
                dnd_drag->translucent =
                        create_drag_cursor(dnd_drag, item, x, y, 0.2);
 
-               buffer = display_get_buffer_for_surface(dnd->display, 
dnd_drag->translucent);
+               if (dnd->self_only)
+                       icon = dnd_drag->opaque;
+               else
+                       icon = dnd_drag->translucent;
+
+               buffer = display_get_buffer_for_surface(dnd->display, icon);
                wl_surface_attach(dnd_drag->drag_surface, buffer,
                                  -dnd_drag->hotspot_x, -dnd_drag->hotspot_y);
                wl_surface_damage(dnd_drag->drag_surface, 0, 0,
                                  dnd_drag->width, dnd_drag->height);
 
+               dnd->current_drag = dnd_drag;
                window_schedule_redraw(dnd->window);
        }
 }
@@ -445,7 +461,11 @@ static int
 dnd_enter_handler(struct widget *widget,
                  struct input *input, float x, float y, void *data)
 {
-       return lookup_cursor(data, x, y);
+       struct dnd *dnd = data;
+
+       dnd->current_drag = NULL;
+
+       return lookup_cursor(dnd, x, y);
 }
 
 static int
@@ -463,10 +483,13 @@ dnd_data_handler(struct window *window,
 {
        struct dnd *dnd = data;
 
-       if (!dnd_get_item(dnd, x, y)) {
-               input_accept(input, types[0]);
-       } else {
+       if (!types)
+               return;
+
+       if (dnd_get_item(dnd, x, y) || dnd->self_only) {
                input_accept(input, NULL);
+       } else {
+               input_accept(input, types[0]);
        }
 }
 
@@ -501,15 +524,26 @@ dnd_drop_handler(struct window *window, struct input 
*input,
                 int32_t x, int32_t y, void *data)
 {
        struct dnd *dnd = data;
+       struct dnd_flower_message message;
 
        if (dnd_get_item(dnd, x, y)) {
                fprintf(stderr, "got 'drop', but no target\n");
                return;
        }
 
-       input_receive_drag_data(input, 
-                               "application/x-wayland-dnd-flower",
-                               dnd_receive_func, dnd);
+       if (!dnd->self_only) {
+               input_receive_drag_data(input,
+                                       "application/x-wayland-dnd-flower",
+                                       dnd_receive_func, dnd);
+       } else if (dnd->current_drag) {
+               message.seed = dnd->current_drag->item->seed;
+               message.x_offset = dnd->current_drag->x_offset;
+               message.y_offset = dnd->current_drag->y_offset;
+               dnd_receive_func(&message, sizeof message, x, y, dnd);
+               dnd->current_drag = NULL;
+       } else {
+               fprintf(stderr, "ignoring drop from another client\n");
+       }
 }
 
 static struct dnd *
@@ -564,6 +598,8 @@ int
 main(int argc, char *argv[])
 {
        struct display *d;
+       struct dnd *dnd;
+       int i;
 
        d = display_create(argc, argv);
        if (d == NULL) {
@@ -571,7 +607,11 @@ main(int argc, char *argv[])
                return -1;
        }
 
-       dnd_create(d);
+       dnd = dnd_create(d);
+
+       for (i = 1; i < argc; i++)
+               if (strcmp("--self-only", argv[i]) == 0)
+                       dnd->self_only = 1;
 
        display_run(d);
 
diff --git a/clients/window.c b/clients/window.c
index bab5d76..4c2dea5 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -2098,22 +2098,30 @@ data_device_enter(void *data, struct wl_data_device 
*data_device,
 {
        struct input *input = data;
        struct window *window;
+       void *types_data;
        float x = wl_fixed_to_double(x_w);
        float y = wl_fixed_to_double(y_w);
        char **p;
 
        input->pointer_enter_serial = serial;
-       input->drag_offer = wl_data_offer_get_user_data(offer);
        window = wl_surface_get_user_data(surface);
        input->pointer_focus = window;
 
-       p = wl_array_add(&input->drag_offer->types, sizeof *p);
-       *p = NULL;
+       if (offer) {
+               input->drag_offer = wl_data_offer_get_user_data(offer);
+
+               p = wl_array_add(&input->drag_offer->types, sizeof *p);
+               *p = NULL;
+
+               types_data = input->drag_offer->types.data;
+       } else {
+               input->drag_offer = NULL;
+               types_data = NULL;
+       }
 
        window = input->pointer_focus;
        if (window->data_handler)
-               window->data_handler(window, input, x, y,
-                                    input->drag_offer->types.data,
+               window->data_handler(window, input, x, y, types_data,
                                     window->user_data);
 }
 
@@ -2122,8 +2130,10 @@ data_device_leave(void *data, struct wl_data_device 
*data_device)
 {
        struct input *input = data;
 
-       data_offer_destroy(input->drag_offer);
-       input->drag_offer = NULL;
+       if (input->drag_offer) {
+               data_offer_destroy(input->drag_offer);
+               input->drag_offer = NULL;
+       }
 }
 
 static void
@@ -2134,13 +2144,18 @@ data_device_motion(void *data, struct wl_data_device 
*data_device,
        struct window *window = input->pointer_focus;
        float x = wl_fixed_to_double(x_w);
        float y = wl_fixed_to_double(y_w);
+       void *types_data;
 
        input->sx = x;
        input->sy = y;
 
+       if (input->drag_offer)
+               types_data = input->drag_offer->types.data;
+       else
+               types_data = NULL;
+
        if (window->data_handler)
-               window->data_handler(window, input, x, y,
-                                    input->drag_offer->types.data,
+               window->data_handler(window, input, x, y, types_data,
                                     window->user_data);
 }
 
-- 
1.7.4.1

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

Reply via email to