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 "../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);

@ -2099,22 +2099,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);
}
@ -2123,8 +2131,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
@ -2135,13 +2145,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);
}

Loading…
Cancel
Save