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:
committed by
Kristian Høgsberg
parent
a6128d6183
commit
08bcf14903
+58
-18
@@ -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);
|
||||||
|
|
||||||
|
|||||||
+24
-9
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user