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.
This commit is contained in:
Ander Conselvan de Oliveira 2012-05-29 10:58:27 +03:00 committed by Kristian Høgsberg
parent a6128d6183
commit 08bcf14903
2 changed files with 82 additions and 27 deletions

View file

@ -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);

View file

@ -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);
}