From af6134aa6c3b5d1076fb32856a734dcc8c9a91ab Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Tue, 31 May 2022 21:15:03 +0200 Subject: [PATCH] ecore_evas: add API to offset drag position relative to cursor The values are stored in the ee itself. And it is the responsibility of the engine to use that value correctly. --- src/lib/ecore_evas/Ecore_Evas.h | 13 +++++++++++++ src/lib/ecore_evas/ecore_evas.c | 18 ++++++++++++++++++ src/lib/ecore_evas/ecore_evas_private.h | 1 + src/lib/elementary/efl_ui_dnd.c | 6 ++++++ src/lib/elementary/efl_ui_dnd.eo | 11 +++++++++++ src/lib/elementary/elm_dnd.c | 6 +++++- 6 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/lib/ecore_evas/Ecore_Evas.h b/src/lib/ecore_evas/Ecore_Evas.h index dfbd7a749f..341ca0052f 100644 --- a/src/lib/ecore_evas/Ecore_Evas.h +++ b/src/lib/ecore_evas/Ecore_Evas.h @@ -3816,6 +3816,19 @@ typedef void (*Ecore_Evas_Drag_Finished_Cb)(Ecore_Evas *ee, unsigned int seat, v */ EAPI Eina_Bool ecore_evas_drag_start(Ecore_Evas *ee, unsigned int seat, Eina_Content *content, Ecore_Evas *drag_rep, const char* action, Ecore_Evas_Drag_Finished_Cb terminate_cb, void *data); +/** + * @brief Set the offset of the dragged symbol. Only valid during a drag + * + * @param[in] ee The Ecore Evas the drag operation started on. + * @param[in] seat The seat to use + * @param[in] offset The offset to apply to the upper left corner ofthe dragged window + * + * This must be called on the ee where ecore_evas_drag_start is called on, NOT on the drag representation + * + * @since 1.24 + */ +EAPI void ecore_evas_drag_offset_set(Ecore_Evas *ee, unsigned int seat, Eina_Size2D offset); + /** * @brief Cancels an ongoing drag operation. diff --git a/src/lib/ecore_evas/ecore_evas.c b/src/lib/ecore_evas/ecore_evas.c index 080a2f3894..e54479a45e 100644 --- a/src/lib/ecore_evas/ecore_evas.c +++ b/src/lib/ecore_evas/ecore_evas.c @@ -5645,10 +5645,28 @@ ecore_evas_drag_start(Ecore_Evas *ee, unsigned int seat, Eina_Content *content, ee->drag.free = terminate_cb; ee->drag.data = data; ee->drag.accepted = EINA_FALSE; + ee->drag.offset = EINA_SIZE2D(INT_MAX, INT_MAX); return success; } +EAPI void +ecore_evas_drag_offset_set(Ecore_Evas *ee, unsigned int seat, Eina_Size2D offset) { + Ecore_Evas_Selection_Seat_Buffers *buffers; + + EINA_SAFETY_ON_NULL_RETURN(ee); + buffers = _fetch_selection_buffers_of_seat(ee, seat, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN(buffers); + EINA_SAFETY_ON_TRUE_RETURN(buffers->selection_buffer[ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER] == NULL); + if (offset.w == INT_MAX || offset.h == INT_MAX) + { + ERR("Offset is INT_MAX, this is a reserved value! Executing Fallback!"); + } + + INF("Set offset to %d %d", offset.w, offset.h); + ee->drag.offset = offset; +} + EAPI Eina_Bool ecore_evas_drag_cancel(Ecore_Evas *ee, unsigned int seat) { diff --git a/src/lib/ecore_evas/ecore_evas_private.h b/src/lib/ecore_evas/ecore_evas_private.h index 20c176f050..95901b6809 100644 --- a/src/lib/ecore_evas/ecore_evas_private.h +++ b/src/lib/ecore_evas/ecore_evas_private.h @@ -404,6 +404,7 @@ struct _Ecore_Evas struct { Ecore_Evas *rep; + Eina_Size2D offset; void *data; Ecore_Evas_Drag_Finished_Cb free; Eina_Bool accepted; diff --git a/src/lib/elementary/efl_ui_dnd.c b/src/lib/elementary/efl_ui_dnd.c index efa0669d99..d4a66f996a 100644 --- a/src/lib/elementary/efl_ui_dnd.c +++ b/src/lib/elementary/efl_ui_dnd.c @@ -64,6 +64,12 @@ _efl_ui_dnd_drag_start(Eo *obj, Efl_Ui_Dnd_Data *pd, Eina_Content *content, cons return drag_win; } +EOLIAN static void +_efl_ui_dnd_drag_offset_set(Eo *obj EINA_UNUSED, Efl_Ui_Dnd_Data *pd, unsigned int seat, Eina_Size2D size) +{ + ecore_evas_drag_offset_set(pd->ee, seat, size); +} + EOLIAN static void _efl_ui_dnd_drag_cancel(Eo *obj EINA_UNUSED, Efl_Ui_Dnd_Data *pd, unsigned int seat) { diff --git a/src/lib/elementary/efl_ui_dnd.eo b/src/lib/elementary/efl_ui_dnd.eo index 49ef148723..21c1767f8c 100644 --- a/src/lib/elementary/efl_ui_dnd.eo +++ b/src/lib/elementary/efl_ui_dnd.eo @@ -53,6 +53,17 @@ mixin @beta Efl.Ui.Dnd requires Efl.Object { of the content being dragged (like a thumbnail, for example). Use @Efl.Content.content.set on it to do so.]] } + @property drag_offset { + [[Set the offset during a drag that was initiated through drag_start]] + keys { + seat: uint; [[Seat setting the offset on.]] + } + values { + offset : Eina.Size2D; [[The offset for which the window will be shifted. The upper left of the window is + calculated by adding this offset to the cursor position]] + } + set {} + } drag_cancel { [[Cancels an on-going drag operation.]] params { diff --git a/src/lib/elementary/elm_dnd.c b/src/lib/elementary/elm_dnd.c index ad18fef161..65c328166c 100644 --- a/src/lib/elementary/elm_dnd.c +++ b/src/lib/elementary/elm_dnd.c @@ -776,10 +776,11 @@ elm_drag_start(Evas_Object *obj, Elm_Sel_Format format, Eina_Array *mime_types; Eina_Content *content; Efl_Content *ui; - int x, y, w, h; + int x = 0, y = 0, w, h; Efl_Ui_Widget *widget; Elm_Drag_Data *dd; const char *str_action; + Eina_Position2D pointer; EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); @@ -803,6 +804,9 @@ elm_drag_start(Evas_Object *obj, Elm_Sel_Format format, content = eina_content_new((Eina_Slice) EINA_SLICE_STR_FULL(data), eina_array_data_get(mime_types, 0)); ui = efl_ui_dnd_drag_start(obj, content, str_action, _default_seat(obj)); widget = createicon(createdata, ui, &x, &y); + + evas_pointer_canvas_xy_get(evas_object_evas_get(obj), &pointer.x, &pointer.y); + efl_ui_dnd_drag_offset_set(obj, _default_seat(obj), EINA_SIZE2D(x - pointer.x, y - pointer.y)); evas_object_geometry_get(widget, NULL, NULL, &w, &h); evas_object_show(widget); efl_content_set(ui, widget);