summaryrefslogtreecommitdiff
path: root/clients
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2016-01-18 23:52:12 +0100
committerJonas Ådahl <jadahl@gmail.com>2016-01-19 12:34:35 +0800
commit9c93179023fe894e417ccd20533d72d672d976fc (patch)
tree2fa33eef91f38225fa22e4bbfb8c820ff5cb1284 /clients
parent78d4bf9a3ec990dceee23fd53962a69891352a0e (diff)
downloadweston-9c93179023fe894e417ccd20533d72d672d976fc.tar.gz
data-device: Implement DnD actions
The policy in weston in order to determine the chosen DnD action is deliberately simple, and is probably the minimals that any compositor should be doing here. Besides honoring the set_actions requests on both wl_data_source and wl_data_offer, weston now will emit the newly added "action" events notifying both source and dest of the chosen action. The "dnd" client has been updated too (although minimally), so it notifies the compositor of a "move" action on both sides. Changes since v8: - Add back wl_data_offer.source_actions emission, gone during last code shuffling. Fix nits found in review. Changes since v7: - Fixes spotted during review. Add client-side version checks. Implement .action emission as specified in protocol patch v11. Changes since v6: - Emit errors as defined in DnD actions patch v10. Changes since v5: - Use enum types and values for not-a-bitfield stored values. handle errors when finding unexpected dnd_actions values. Changes since v4: - Added compositor-side version checks. Spaces vs tabs fixes. Fixed resource versioning. Initialized new weston_data_source/offer fields. Changes since v3: - Put data_source.action to use in the dnd client, now updates the dnd surface like data_source.target events do. Changes since v2: - Split from DnD progress notification changes. Changes since v1: - Updated to v2 of DnD actions protocol changes, implement wl_data_offer.source_actions. - Fixed coding style issues. Signed-off-by: Carlos Garnacho <carlosg@gnome.org> Reviewed-by: Michael Catanzaro <mcatanzaro@igalia.com> Reviewed-by: Jonas Ådahl <jadahl@gmail.com>
Diffstat (limited to 'clients')
-rw-r--r--clients/dnd.c36
-rw-r--r--clients/window.c34
-rw-r--r--clients/window.h3
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,