diff options
Diffstat (limited to 'clients')
-rw-r--r-- | clients/dnd.c | 36 | ||||
-rw-r--r-- | clients/window.c | 34 | ||||
-rw-r--r-- | clients/window.h | 3 |
3 files changed, 68 insertions, 5 deletions
diff --git a/clients/dnd.c b/clients/dnd.c index 974429b0..d32655de 100644 --- a/clients/dnd.c +++ b/clients/dnd.c @@ -72,6 +72,7 @@ struct dnd_drag { struct item *item; int x_offset, y_offset; int width, height; + uint32_t dnd_action; const char *mime_type; struct wl_surface *drag_surface; @@ -266,16 +267,13 @@ dnd_get_item(struct dnd *dnd, int32_t x, int32_t y) } static void -data_source_target(void *data, - struct wl_data_source *source, const char *mime_type) +dnd_drag_update_surface(struct dnd_drag *dnd_drag) { - struct dnd_drag *dnd_drag = data; struct dnd *dnd = dnd_drag->dnd; cairo_surface_t *surface; struct wl_buffer *buffer; - dnd_drag->mime_type = mime_type; - if (mime_type) + if (dnd_drag->mime_type && dnd_drag->dnd_action) surface = dnd_drag->opaque; else surface = dnd_drag->translucent; @@ -288,6 +286,16 @@ data_source_target(void *data, } static void +data_source_target(void *data, + struct wl_data_source *source, const char *mime_type) +{ + struct dnd_drag *dnd_drag = data; + + dnd_drag->mime_type = mime_type; + dnd_drag_update_surface(dnd_drag); +} + +static void data_source_send(void *data, struct wl_data_source *source, const char *mime_type, int32_t fd) { @@ -360,12 +368,22 @@ data_source_dnd_finished(void *data, struct wl_data_source *source) dnd_drag_destroy(dnd_drag); } +static void +data_source_action(void *data, struct wl_data_source *source, uint32_t dnd_action) +{ + struct dnd_drag *dnd_drag = data; + + dnd_drag->dnd_action = dnd_action; + dnd_drag_update_surface(dnd_drag); +} + static const struct wl_data_source_listener data_source_listener = { data_source_target, data_source_send, data_source_cancelled, data_source_dnd_drop_performed, data_source_dnd_finished, + data_source_action, }; static cairo_surface_t * @@ -428,6 +446,8 @@ create_drag_source(struct dnd *dnd, dnd_drag->item = item; dnd_drag->x_offset = x - item->x; dnd_drag->y_offset = y - item->y; + dnd_drag->dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; + dnd_drag->mime_type = NULL; for (i = 0; i < ARRAY_LENGTH(dnd->items); i++) { if (item == dnd->items[i]){ @@ -456,6 +476,12 @@ create_drag_source(struct dnd *dnd, text_mime_type); } + if (display_get_data_device_manager_version(display) >= + WL_DATA_SOURCE_SET_ACTIONS_SINCE_VERSION) { + wl_data_source_set_actions(dnd_drag->data_source, + WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE); + } + wl_data_device_start_drag(input_get_data_device(input), dnd_drag->data_source, window_get_wl_surface(dnd->window), diff --git a/clients/window.c b/clients/window.c index 1b3cbb1e..5cd33dd9 100644 --- a/clients/window.c +++ b/clients/window.c @@ -3418,6 +3418,8 @@ struct data_offer { int fd; data_func_t func; int32_t x, y; + uint32_t dnd_action; + uint32_t source_actions; void *user_data; }; @@ -3431,8 +3433,26 @@ data_offer_offer(void *data, struct wl_data_offer *wl_data_offer, const char *ty *p = strdup(type); } +static void +data_offer_source_actions(void *data, struct wl_data_offer *wl_data_offer, uint32_t source_actions) +{ + struct data_offer *offer = data; + + offer->source_actions = source_actions; +} + +static void +data_offer_action(void *data, struct wl_data_offer *wl_data_offer, uint32_t dnd_action) +{ + struct data_offer *offer = data; + + offer->dnd_action = dnd_action; +} + static const struct wl_data_offer_listener data_offer_listener = { data_offer_offer, + data_offer_source_actions, + data_offer_action }; static void @@ -3496,6 +3516,14 @@ data_device_enter(void *data, struct wl_data_device *data_device, *p = NULL; types_data = input->drag_offer->types.data; + + if (input->display->data_device_manager_version >= + WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION) { + wl_data_offer_set_actions(offer, + WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | + WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE, + WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE); + } } else { input->drag_offer = NULL; types_data = NULL; @@ -5932,6 +5960,12 @@ display_exit(struct display *display) display->running = 0; } +int +display_get_data_device_manager_version(struct display *display) +{ + return display->data_device_manager_version; +} + void keysym_modifiers_add(struct wl_array *modifiers_map, const char *name) diff --git a/clients/window.h b/clients/window.h index ba843cc1..1128d71b 100644 --- a/clients/window.h +++ b/clients/window.h @@ -175,6 +175,9 @@ display_run(struct display *d); void display_exit(struct display *d); +int +display_get_data_device_manager_version(struct display *d); + enum cursor_type { CURSOR_BOTTOM_LEFT, CURSOR_BOTTOM_RIGHT, |