typedef struct _Ecore_Wl2_Keyboard Ecore_Wl2_Keyboard;
typedef struct _Ecore_Wl2_Touch Ecore_Wl2_Touch;
+/* matches protocol values */
+typedef enum
+{
+ ECORE_WL2_DRAG_ACTION_NONE = 0,
+ ECORE_WL2_DRAG_ACTION_COPY = 1,
+ ECORE_WL2_DRAG_ACTION_MOVE = 2,
+ ECORE_WL2_DRAG_ACTION_ASK = 4,
+} Ecore_Wl2_Drag_Action;
+
typedef struct _Ecore_Wl2_Global
{
Eina_Stringshare *interface;
unsigned int win, source;
} Ecore_Wl2_Event_Dnd_End;
-typedef struct _Ecore_Wl2_Event_Data_Source_Cancelled
+struct _Ecore_Wl2_Event_Data_Source_Event
{
unsigned int win, source;
-} Ecore_Wl2_Event_Data_Source_Cancelled;
+ Ecore_Wl2_Drag_Action action;
+};
+
+typedef struct _Ecore_Wl2_Event_Data_Source_Event Ecore_Wl2_Event_Data_Source_End;
+typedef struct _Ecore_Wl2_Event_Data_Source_Event Ecore_Wl2_Event_Data_Source_Drop;
+typedef struct _Ecore_Wl2_Event_Data_Source_Event Ecore_Wl2_Event_Data_Source_Action;
typedef struct _Ecore_Wl2_Event_Data_Source_Target
{
EAPI extern int ECORE_WL2_EVENT_DND_MOTION; /** @since 1.17 */
EAPI extern int ECORE_WL2_EVENT_DND_DROP; /** @since 1.17 */
EAPI extern int ECORE_WL2_EVENT_DND_END; /** @since 1.17 */
-EAPI extern int ECORE_WL2_EVENT_DATA_SOURCE_CANCELLED; /** @since 1.17 */
+EAPI extern int ECORE_WL2_EVENT_DATA_SOURCE_END; /** @since 1.18 */
+EAPI extern int ECORE_WL2_EVENT_DATA_SOURCE_DROP; /** @since 1.18 */
+EAPI extern int ECORE_WL2_EVENT_DATA_SOURCE_ACTION; /** @since 1.18 */
EAPI extern int ECORE_WL2_EVENT_DATA_SOURCE_TARGET; /** @since 1.17 */
EAPI extern int ECORE_WL2_EVENT_DATA_SOURCE_SEND; /** @since 1.17 */
EAPI extern int ECORE_WL2_EVENT_SELECTION_DATA_READY; /** @since 1.17 */
EAPI int ECORE_WL2_EVENT_DND_MOTION = 0;
EAPI int ECORE_WL2_EVENT_DND_DROP = 0;
EAPI int ECORE_WL2_EVENT_DND_END = 0;
-EAPI int ECORE_WL2_EVENT_DATA_SOURCE_CANCELLED = 0;
+EAPI int ECORE_WL2_EVENT_DATA_SOURCE_END = 0;
+EAPI int ECORE_WL2_EVENT_DATA_SOURCE_DROP = 0;
+EAPI int ECORE_WL2_EVENT_DATA_SOURCE_ACTION = 0;
EAPI int ECORE_WL2_EVENT_DATA_SOURCE_TARGET = 0;
EAPI int ECORE_WL2_EVENT_DATA_SOURCE_SEND = 0;
EAPI int ECORE_WL2_EVENT_SELECTION_DATA_READY = 0;
ECORE_WL2_EVENT_DND_MOTION = ecore_event_type_new();
ECORE_WL2_EVENT_DND_DROP = ecore_event_type_new();
ECORE_WL2_EVENT_DND_END = ecore_event_type_new();
- ECORE_WL2_EVENT_DATA_SOURCE_CANCELLED = ecore_event_type_new();
+ ECORE_WL2_EVENT_DATA_SOURCE_END = ecore_event_type_new();
+ ECORE_WL2_EVENT_DATA_SOURCE_DROP = ecore_event_type_new();
+ ECORE_WL2_EVENT_DATA_SOURCE_ACTION = ecore_event_type_new();
ECORE_WL2_EVENT_DATA_SOURCE_TARGET = ecore_event_type_new();
ECORE_WL2_EVENT_DATA_SOURCE_SEND = ecore_event_type_new();
ECORE_WL2_EVENT_SELECTION_DATA_READY = ecore_event_type_new();
ECORE_WL2_EVENT_DND_MOTION = 0;
ECORE_WL2_EVENT_DND_DROP = 0;
ECORE_WL2_EVENT_DND_END = 0;
- ECORE_WL2_EVENT_DATA_SOURCE_CANCELLED = 0;
+ ECORE_WL2_EVENT_DATA_SOURCE_END = 0;
+ ECORE_WL2_EVENT_DATA_SOURCE_DROP = 0;
+ ECORE_WL2_EVENT_DATA_SOURCE_ACTION = 0;
ECORE_WL2_EVENT_DATA_SOURCE_TARGET = 0;
ECORE_WL2_EVENT_DATA_SOURCE_SEND = 0;
ECORE_WL2_EVENT_SELECTION_DATA_READY = 0;
};
static void
-_source_cb_target_free(void *data EINA_UNUSED, void *event)
+data_source_target_free(void *data EINA_UNUSED, void *event)
{
Ecore_Wl2_Event_Data_Source_Target *ev;
}
static void
-_source_cb_target(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type)
+data_source_target(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type)
{
Ecore_Wl2_Input *input;
Ecore_Wl2_Event_Data_Source_Target *ev;
if (mime_type) ev->type = strdup(mime_type);
ecore_event_add(ECORE_WL2_EVENT_DATA_SOURCE_TARGET, ev,
- _source_cb_target_free, NULL);
+ data_source_target_free, NULL);
}
static void
-_source_cb_send_free(void *data EINA_UNUSED, void *event)
+data_source_send_free(void *data EINA_UNUSED, void *event)
{
Ecore_Wl2_Event_Data_Source_Send *ev;
}
static void
-_source_cb_send(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type, int32_t fd)
+data_source_send(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type, int32_t fd)
{
Ecore_Wl2_Input *input;
Ecore_Wl2_Event_Data_Source_Send *ev;
ev->type = strdup(mime_type);
ecore_event_add(ECORE_WL2_EVENT_DATA_SOURCE_SEND, ev,
- _source_cb_send_free, NULL);
+ data_source_send_free, NULL);
}
static void
-_source_cb_cancelled(void *data, struct wl_data_source *source)
+data_source_event_emit(Ecore_Wl2_Input *input, int event)
{
- Ecore_Wl2_Input *input;
- Ecore_Wl2_Event_Data_Source_Cancelled *ev;
-
- input = data;
- if (!input) return;
+ Ecore_Wl2_Event_Data_Source_End *ev;
- if (input->data.source == source) input->data.source = NULL;
- wl_data_source_destroy(source);
-
- ev = calloc(1, sizeof(Ecore_Wl2_Event_Data_Source_Cancelled));
+ ev = calloc(1, sizeof(Ecore_Wl2_Event_Data_Source_End));
if (!ev) return;
if (input->focus.pointer)
ev->source = input->focus.keyboard->id;
if (!ev->win) ev->win = ev->source;
+ ev->action = input->drag.source->dnd_action;
+
+ ecore_event_add(event, ev, NULL, NULL);
+}
+
+static void
+data_source_cancelled(void *data, struct wl_data_source *source)
+{
+ Ecore_Wl2_Input *input = data;
- ecore_event_add(ECORE_WL2_EVENT_DATA_SOURCE_CANCELLED, ev, NULL, NULL);
+ if (input->data.source == source) input->data.source = NULL;
+ wl_data_source_destroy(source);
+ input->drag.source->dnd_action = 0;
+ data_source_event_emit(input, ECORE_WL2_EVENT_DATA_SOURCE_END);
+}
+
+static void
+data_source_dnd_drop_performed(void *data, struct wl_data_source *source EINA_UNUSED)
+{
+ Ecore_Wl2_Input *input = data;
+ data_source_event_emit(input, ECORE_WL2_EVENT_DATA_SOURCE_DROP);
+}
+
+static void
+data_source_dnd_finished(void *data, struct wl_data_source *source)
+{
+ Ecore_Wl2_Input *input = data;
+
+ if (input->data.source == source) input->data.source = NULL;
+ wl_data_source_destroy(source);
+ data_source_event_emit(input, ECORE_WL2_EVENT_DATA_SOURCE_END);
+}
+
+static void
+data_source_action(void *data, struct wl_data_source *source EINA_UNUSED, uint32_t dnd_action)
+{
+ Ecore_Wl2_Input *input = data;
+
+ input->drag.source->dnd_action = dnd_action;
+ data_source_event_emit(input, ECORE_WL2_EVENT_DATA_SOURCE_ACTION);
}
static const struct wl_data_source_listener _source_listener =
{
- _source_cb_target,
- _source_cb_send,
- _source_cb_cancelled
+ data_source_target,
+ data_source_send,
+ data_source_cancelled,
+ data_source_dnd_drop_performed,
+ data_source_dnd_finished,
+ data_source_action,
};
static void
if (len <= 0)
{
+ if (source->input->display->wl.data_device_manager_version >=
+ WL_DATA_OFFER_FINISH_SINCE_VERSION)
+ wl_data_offer_finish(source->offer);
if (source->input->selection.source == source)
source->input->selection.source = NULL;
_ecore_wl2_dnd_del(source);
if (offer)
{
input->drag.source = wl_data_offer_get_user_data(offer);
+ input->drag.source->dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
num = (input->drag.source->types.size / sizeof(char *));
types = input->drag.source->types.data;
if (input->display->wl.data_device_manager_version >=
osurface = ecore_wl2_window_surface_get(window);
if (osurface)
{
+ if (input->display->wl.data_device_manager_version >= WL_DATA_SOURCE_SET_ACTIONS_SINCE_VERSION)
+ wl_data_source_set_actions(input->data.source,
+ WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY);
+
wl_data_device_start_drag(input->data.device, input->data.source,
osurface, dsurface, input->display->serial);