dnd: implement option for not offering data to other clients

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.
dev
Ander Conselvan de Oliveira 13 years ago committed by Kristian Høgsberg
parent a6128d6183
commit 08bcf14903
  1. 76
      clients/dnd.c
  2. 33
      clients/window.c

@ -37,12 +37,16 @@
#include "window.h" #include "window.h"
#include "../shared/cairo-util.h" #include "../shared/cairo-util.h"
struct dnd_drag;
struct dnd { struct dnd {
struct window *window; struct window *window;
struct widget *widget; struct widget *widget;
struct display *display; struct display *display;
uint32_t key; uint32_t key;
struct item *items[16]; struct item *items[16];
int self_only;
struct dnd_drag *current_drag;
}; };
struct dnd_drag { struct dnd_drag {
@ -366,6 +370,7 @@ dnd_button_handler(struct widget *widget,
struct wl_buffer *buffer; struct wl_buffer *buffer;
unsigned int i; unsigned int i;
uint32_t serial; uint32_t serial;
cairo_surface_t *icon;
widget_get_allocation(dnd->widget, &allocation); widget_get_allocation(dnd->widget, &allocation);
input_get_position(input, &x, &y); input_get_position(input, &x, &y);
@ -397,15 +402,20 @@ dnd_button_handler(struct widget *widget,
input_ungrab(input); input_ungrab(input);
dnd_drag->data_source = if (dnd->self_only) {
display_create_data_source(dnd->display); dnd_drag->data_source = NULL;
wl_data_source_add_listener(dnd_drag->data_source, } else {
&data_source_listener, dnd_drag->data_source =
dnd_drag); display_create_data_source(dnd->display);
wl_data_source_offer(dnd_drag->data_source, wl_data_source_add_listener(dnd_drag->data_source,
"application/x-wayland-dnd-flower"); &data_source_listener,
wl_data_source_offer(dnd_drag->data_source, dnd_drag);
"text/plain; charset=utf-8"); 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), wl_data_device_start_drag(input_get_data_device(input),
dnd_drag->data_source, dnd_drag->data_source,
window_get_wl_surface(dnd->window), window_get_wl_surface(dnd->window),
@ -419,12 +429,18 @@ dnd_button_handler(struct widget *widget,
dnd_drag->translucent = dnd_drag->translucent =
create_drag_cursor(dnd_drag, item, x, y, 0.2); 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, wl_surface_attach(dnd_drag->drag_surface, buffer,
-dnd_drag->hotspot_x, -dnd_drag->hotspot_y); -dnd_drag->hotspot_x, -dnd_drag->hotspot_y);
wl_surface_damage(dnd_drag->drag_surface, 0, 0, wl_surface_damage(dnd_drag->drag_surface, 0, 0,
dnd_drag->width, dnd_drag->height); dnd_drag->width, dnd_drag->height);
dnd->current_drag = dnd_drag;
window_schedule_redraw(dnd->window); window_schedule_redraw(dnd->window);
} }
} }
@ -445,7 +461,11 @@ static int
dnd_enter_handler(struct widget *widget, dnd_enter_handler(struct widget *widget,
struct input *input, float x, float y, void *data) 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 static int
@ -463,10 +483,13 @@ dnd_data_handler(struct window *window,
{ {
struct dnd *dnd = data; struct dnd *dnd = data;
if (!dnd_get_item(dnd, x, y)) { if (!types)
input_accept(input, types[0]); return;
} else {
if (dnd_get_item(dnd, x, y) || dnd->self_only) {
input_accept(input, NULL); 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) int32_t x, int32_t y, void *data)
{ {
struct dnd *dnd = data; struct dnd *dnd = data;
struct dnd_flower_message message;
if (dnd_get_item(dnd, x, y)) { if (dnd_get_item(dnd, x, y)) {
fprintf(stderr, "got 'drop', but no target\n"); fprintf(stderr, "got 'drop', but no target\n");
return; return;
} }
input_receive_drag_data(input, if (!dnd->self_only) {
"application/x-wayland-dnd-flower", input_receive_drag_data(input,
dnd_receive_func, dnd); "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 * static struct dnd *
@ -564,6 +598,8 @@ int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
struct display *d; struct display *d;
struct dnd *dnd;
int i;
d = display_create(argc, argv); d = display_create(argc, argv);
if (d == NULL) { if (d == NULL) {
@ -571,7 +607,11 @@ main(int argc, char *argv[])
return -1; 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); display_run(d);

@ -2099,22 +2099,30 @@ data_device_enter(void *data, struct wl_data_device *data_device,
{ {
struct input *input = data; struct input *input = data;
struct window *window; struct window *window;
void *types_data;
float x = wl_fixed_to_double(x_w); float x = wl_fixed_to_double(x_w);
float y = wl_fixed_to_double(y_w); float y = wl_fixed_to_double(y_w);
char **p; char **p;
input->pointer_enter_serial = serial; input->pointer_enter_serial = serial;
input->drag_offer = wl_data_offer_get_user_data(offer);
window = wl_surface_get_user_data(surface); window = wl_surface_get_user_data(surface);
input->pointer_focus = window; input->pointer_focus = window;
p = wl_array_add(&input->drag_offer->types, sizeof *p); if (offer) {
*p = NULL; 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; window = input->pointer_focus;
if (window->data_handler) if (window->data_handler)
window->data_handler(window, input, x, y, window->data_handler(window, input, x, y, types_data,
input->drag_offer->types.data,
window->user_data); window->user_data);
} }
@ -2123,8 +2131,10 @@ data_device_leave(void *data, struct wl_data_device *data_device)
{ {
struct input *input = data; struct input *input = data;
data_offer_destroy(input->drag_offer); if (input->drag_offer) {
input->drag_offer = NULL; data_offer_destroy(input->drag_offer);
input->drag_offer = NULL;
}
} }
static void static void
@ -2135,13 +2145,18 @@ data_device_motion(void *data, struct wl_data_device *data_device,
struct window *window = input->pointer_focus; struct window *window = input->pointer_focus;
float x = wl_fixed_to_double(x_w); float x = wl_fixed_to_double(x_w);
float y = wl_fixed_to_double(y_w); float y = wl_fixed_to_double(y_w);
void *types_data;
input->sx = x; input->sx = x;
input->sy = y; input->sy = y;
if (input->drag_offer)
types_data = input->drag_offer->types.data;
else
types_data = NULL;
if (window->data_handler) if (window->data_handler)
window->data_handler(window, input, x, y, window->data_handler(window, input, x, y, types_data,
input->drag_offer->types.data,
window->user_data); window->user_data);
} }

Loading…
Cancel
Save