ecore_evas: add API for finding out if event is used

Summary:
ecore_x_dnd_send_status can be used to indicate if a item can be dropped
on a client or not. However, we should only indicate that this can be
dropped, if there is a object we signaled that a drop is in.

Long story short: there is no assertion that after indicating that
things can be dropped, that a notify for the data is sent. A drag
implementation should always listen to a mouse up event, and abort the
drag if no further operations are sent.
Depends on D11698

Reviewers: zmike, stefan_schmidt, raster

Reviewed By: zmike

Subscribers: cedric, #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D11699
This commit is contained in:
Marcel Hollerbach 2020-04-14 11:29:43 -04:00 committed by Mike Blumenkrantz
parent f2ed538d41
commit 0a2db329c8
4 changed files with 29 additions and 8 deletions

View File

@ -5699,6 +5699,7 @@ ecore_evas_callback_drop_drop_set(Ecore_Evas *ee, Ecore_Evas_Drop_Cb cb)
typedef struct {
Eina_Array *available_mime_types;
Eina_Position2D pos;
Eina_Bool last_motion_was_used;
} Ecore_Evas_Active_Dnd;
static void
@ -5734,18 +5735,34 @@ ecore_evas_dnd_enter(Ecore_Evas *ee, unsigned int seat, Eina_Iterator *available
ee->func.fn_dnd_state_change(ee, seat, pos, EINA_TRUE);
}
EAPI void
EAPI Eina_Bool
ecore_evas_dnd_position_set(Ecore_Evas *ee, unsigned int seat, Eina_Position2D pos)
{
Ecore_Evas_Active_Dnd *dnd;
ECORE_EVAS_CHECK_GOTO(ee, err);
EINA_SAFETY_ON_NULL_GOTO(ee->active_drags, err);
dnd = eina_hash_find(ee->active_drags, &seat);
EINA_SAFETY_ON_NULL_GOTO(dnd, err);
dnd->pos = pos;
dnd->last_motion_was_used = EINA_FALSE;
if (ee->func.fn_dnd_motion)
ee->func.fn_dnd_motion(ee, seat, pos);
return dnd->last_motion_was_used;
err:
return EINA_FALSE;
}
EAPI void
ecore_evas_dnd_mark_motion_used(Ecore_Evas *ee, unsigned int seat)
{
Ecore_Evas_Active_Dnd *dnd;
ECORE_EVAS_CHECK(ee);
EINA_SAFETY_ON_NULL_RETURN(ee->active_drags);
dnd = eina_hash_find(ee->active_drags, &seat);
EINA_SAFETY_ON_NULL_RETURN(dnd);
dnd->pos = pos;
if (ee->func.fn_dnd_motion)
ee->func.fn_dnd_motion(ee, seat, pos);
dnd->last_motion_was_used = EINA_TRUE;
}
EAPI void

View File

@ -522,8 +522,8 @@ EAPI Eina_Bool ecore_evas_render(Ecore_Evas *ee);
EAPI Evas *ecore_evas_evas_new(Ecore_Evas *ee, int w, int h);
EAPI void ecore_evas_done(Ecore_Evas *ee, Eina_Bool single_window);
EAPI void ecore_evas_dnd_position_set(Ecore_Evas *ee, unsigned int seat, Eina_Position2D pos);
EAPI void ecore_evas_dnd_mark_motion_used(Ecore_Evas *ee, unsigned int seat);
EAPI Eina_Bool ecore_evas_dnd_position_set(Ecore_Evas *ee, unsigned int seat, Eina_Position2D pos);
EAPI void ecore_evas_dnd_leave(Ecore_Evas *ee, unsigned int seat, Eina_Position2D pos);
EAPI void ecore_evas_dnd_enter(Ecore_Evas *ee, unsigned int seat, Eina_Iterator *available_types, Eina_Position2D pos);
EAPI Eina_Position2D ecore_evas_dnd_pos_get(Ecore_Evas *ee, unsigned int seat);

View File

@ -9268,15 +9268,18 @@ _motion_cb(Ecore_Evas *ee, unsigned int seat, Eina_Position2D p)
{
target->currently_inside = EINA_FALSE;
efl_event_callback_call(target->obj, EFL_UI_DND_EVENT_DROP_LEFT, &ev);
ecore_evas_dnd_mark_motion_used(ee, seat);
}
else if (!target->currently_inside && inside)
{
target->currently_inside = EINA_TRUE;
efl_event_callback_call(target->obj, EFL_UI_DND_EVENT_DROP_ENTERED, &ev);
ecore_evas_dnd_mark_motion_used(ee, seat);
}
else if (target->currently_inside && inside)
{
efl_event_callback_call(target->obj, EFL_UI_DND_EVENT_DROP_POSITION_CHANGED, &ev);
ecore_evas_dnd_mark_motion_used(ee, seat);
}
eina_accessor_free(ev.available_types);
}

View File

@ -4185,8 +4185,9 @@ _ecore_evas_x_dnd_position(void *udata EINA_UNUSED, int type EINA_UNUSED, void *
ee = ecore_event_window_match(pos->win);
EINA_SAFETY_ON_NULL_GOTO(ee, end);
ecore_evas_geometry_get(ee, &x, &y, &w, &h);
ecore_evas_dnd_position_set(ee, 1, EINA_POSITION2D(pos->position.x - x, pos->position.y - y));
ecore_x_dnd_send_status(EINA_TRUE, EINA_FALSE, (Ecore_X_Rectangle){x,y,w,h}, pos->action);
Eina_Bool used = ecore_evas_dnd_position_set(ee, 1, EINA_POSITION2D(pos->position.x - x, pos->position.y - y));
if (used)
ecore_x_dnd_send_status(EINA_TRUE, EINA_FALSE, (Ecore_X_Rectangle){x,y,w,h}, pos->action);
end:
return ECORE_CALLBACK_PASS_ON;
}