evas_events: implement POINTER_CANCEL event

it looks like this was left out during initial writing of eo-based eventing,
but based on the description, the intent was to have a separate cancel event
which was emitted just prior to the 'up' event using the existing state

Reviewed-by: Marcel Hollerbach <mail@marcel-hollerbach.de>
Differential Revision: https://phab.enlightenment.org/D9184
This commit is contained in:
Mike Blumenkrantz 2019-06-26 10:30:35 -04:00 committed by Marcel Hollerbach
parent 3edf75c319
commit e399bdd6ec
1 changed files with 63 additions and 31 deletions

View File

@ -814,7 +814,7 @@ static void
_evas_event_source_mouse_up_events(Evas_Object *eo_obj, Evas *eo_e,
Efl_Input_Pointer *parent_ev,
Evas_Pointer_Data *pdata,
int event_id)
int event_id, Eina_Bool cancel)
{
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
Evas_Object *eo_src = _evas_object_image_source_get(eo_obj);
@ -853,7 +853,7 @@ _evas_event_source_mouse_up_events(Evas_Object *eo_obj, Evas *eo_e,
ev->device);
continue;
}
if (((obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_AUTOGRAB) ||
if ((!cancel) && ((obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_AUTOGRAB) ||
(obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)) &&
(obj_pdata->mouse_grabbed > 0))
{
@ -864,12 +864,15 @@ _evas_event_source_mouse_up_events(Evas_Object *eo_obj, Evas *eo_e,
ev->cur = point;
pointer_mode = obj_pdata->pointer_mode;
_evas_event_havemap_adjust_f(eo_child, child, &ev->cur, obj_pdata->mouse_grabbed);
evas_object_event_callback_call(eo_child, child, EVAS_CALLBACK_MOUSE_UP, evt,
event_id, EFL_EVENT_POINTER_UP);
if (cancel)
efl_event_callback_call(eo_child, EFL_EVENT_POINTER_CANCEL, evt);
else
evas_object_event_callback_call(eo_child, child, EVAS_CALLBACK_MOUSE_UP, evt,
event_id, EFL_EVENT_POINTER_UP);
if (e->delete_me) break;
if (pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)
{
if (pdata->seat->nogrep > 0) pdata->seat->nogrep--;
if ((!cancel) && (pdata->seat->nogrep > 0)) pdata->seat->nogrep--;
break;
}
}
@ -1755,9 +1758,10 @@ _canvas_event_feed_mouse_up_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data
Efl_Input_Pointer *evt;
Eina_List *l, *copy;
Evas_Object *eo_obj;
int event_id, b;
int event_id = 0, b;
Evas *eo_e;
Evas_Pointer_Data *pdata;
Eina_Bool cancel;
static const int value_flags =
_efl_input_value_mask(EFL_INPUT_VALUE_TIMESTAMP) |
@ -1773,20 +1777,29 @@ _canvas_event_feed_mouse_up_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data
if (!pdata) return;
b = ev->button;
DBG("ButtonEvent:up time=%u x=%d y=%d button=%d downs=%d",
ev->timestamp, pdata->seat->x, pdata->seat->y, b, pdata->seat->downs);
cancel = ev->action == EFL_POINTER_ACTION_CANCEL;
if (cancel)
DBG("ButtonEvent:cancel time=%u x=%d y=%d button=%d downs=%d",
ev->timestamp, pdata->seat->x, pdata->seat->y, b, pdata->seat->downs);
else
DBG("ButtonEvent:up time=%u x=%d y=%d button=%d downs=%d",
ev->timestamp, pdata->seat->x, pdata->seat->y, b, pdata->seat->downs);
if ((b < 1) || (b > 32)) return;
if (pdata->seat->downs <= 0) return;
pdata->button &= ~(1u << (b - 1));
pdata->seat->downs--;
if (!cancel)
{
pdata->button &= ~(1u << (b - 1));
pdata->seat->downs--;
}
if (e->is_frozen) return;
e->last_timestamp = ev->timestamp;
eo_e = e->evas;
evt = ev->eo;
event_id = _evas_object_event_new();
if (!cancel)
event_id = _evas_object_event_new();
ev->cur.x = pdata->seat->x;
ev->cur.y = pdata->seat->y;
@ -1798,8 +1811,9 @@ _canvas_event_feed_mouse_up_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data
if (ev->device) efl_ref(ev->device);
_evas_walk(e);
/* update released touch point */
_evas_touch_point_update(eo_e, 0, pdata->seat->x, pdata->seat->y, EVAS_TOUCH_POINT_UP);
if (!cancel)
/* update released touch point */
_evas_touch_point_update(eo_e, 0, pdata->seat->x, pdata->seat->y, EVAS_TOUCH_POINT_UP);
copy = evas_event_list_copy(pdata->seat->object.in);
EINA_LIST_FOREACH(copy, l, eo_obj)
{
@ -1815,7 +1829,7 @@ _canvas_event_feed_mouse_up_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data
ev->device);
continue;
}
if (((obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_AUTOGRAB) ||
if ((!cancel) && ((obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_AUTOGRAB) ||
(obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)) &&
(obj_pdata->mouse_grabbed > 0))
{
@ -1829,29 +1843,35 @@ _canvas_event_feed_mouse_up_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data
ev->cur.x = pdata->seat->x;
ev->cur.y = pdata->seat->y;
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_UP, evt,
event_id, EFL_EVENT_POINTER_UP);
if (cancel)
efl_event_callback_call(eo_obj, EFL_EVENT_POINTER_CANCEL, evt);
else
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_UP, evt,
event_id, EFL_EVENT_POINTER_UP);
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
_evas_event_source_mouse_up_events(eo_obj, eo_e, evt, pdata, event_id);
_evas_event_source_mouse_up_events(eo_obj, eo_e, evt, pdata, event_id, cancel);
if (e->delete_me) break;
}
if (pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)
{
if (pdata->seat->nogrep > 0) pdata->seat->nogrep--;
if ((!cancel) && (pdata->seat->nogrep > 0)) pdata->seat->nogrep--;
break;
}
}
eina_list_free(copy);
e->last_mouse_up_counter++;
_evas_post_event_callback_call(eo_e, e, event_id);
if (pdata->seat->mouse_grabbed == 0)
_post_up_handle(e, evt, pdata);
if (pdata->seat->mouse_grabbed < 0)
if (!cancel)
{
ERR("BUG? pdata->seat->mouse_grabbed (=%d) < 0!",
pdata->seat->mouse_grabbed);
e->last_mouse_up_counter++;
_evas_post_event_callback_call(eo_e, e, event_id);
if (pdata->seat->mouse_grabbed == 0)
_post_up_handle(e, evt, pdata);
if (pdata->seat->mouse_grabbed < 0)
{
ERR("BUG? pdata->seat->mouse_grabbed (=%d) < 0!",
pdata->seat->mouse_grabbed);
}
}
/* remove released touch point from the touch point list */
_evas_touch_point_remove(eo_e, 0);
@ -1863,7 +1883,7 @@ _canvas_event_feed_mouse_up_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data
static void
_canvas_event_feed_mouse_updown(Eo *eo_e, int b, Evas_Button_Flags flags,
unsigned int timestamp, const void *data,
Eina_Bool down, Efl_Input_Device *device)
Eina_Bool down, Efl_Input_Device *device, Eina_Bool cancel)
{
Efl_Input_Pointer_Data *ev = NULL;
Efl_Input_Pointer *evt;
@ -1879,7 +1899,10 @@ _canvas_event_feed_mouse_updown(Eo *eo_e, int b, Evas_Button_Flags flags,
ev->data = (void *) data;
ev->timestamp = timestamp;
ev->device = efl_ref(device ? device : _evas_event_legacy_device_get(eo_e, EINA_TRUE));
ev->action = down ? EFL_POINTER_ACTION_DOWN : EFL_POINTER_ACTION_UP;
if (cancel)
ev->action = EFL_POINTER_ACTION_CANCEL;
else
ev->action = down ? EFL_POINTER_ACTION_DOWN : EFL_POINTER_ACTION_UP;
ev->button = b;
ev->button_flags = flags;
ev->radius = 1;
@ -1890,12 +1913,21 @@ _canvas_event_feed_mouse_updown(Eo *eo_e, int b, Evas_Button_Flags flags,
//ev->window_pos = ?;
//ev->fake = 1;
/* first, send the cancel action through to trigger POINTER_CANCEL on all
* relevant objects.
* this does not change canvas state in any way.
* note that the 'down' branch can only occur if 'cancel' is not true
*/
if (down)
_canvas_event_feed_mouse_down_internal(e, ev);
else
_canvas_event_feed_mouse_up_internal(e, ev);
efl_unref(evt);
/* next, emit actual up event and perform state changes */
if (cancel)
_canvas_event_feed_mouse_updown(eo_e, b, flags, timestamp, data, down, device, EINA_FALSE);
}
static void
@ -1903,7 +1935,7 @@ _canvas_event_feed_mouse_updown_legacy(Eo *eo_e, int b, Evas_Button_Flags flags,
unsigned int timestamp, const void *data,
Eina_Bool down)
{
_canvas_event_feed_mouse_updown(eo_e, b, flags, timestamp, data, down, NULL);
_canvas_event_feed_mouse_updown(eo_e, b, flags, timestamp, data, down, NULL, EINA_FALSE);
}
EAPI void
@ -1954,7 +1986,7 @@ _canvas_event_feed_mouse_cancel_internal(Evas_Public_Data *e, Efl_Input_Pointer_
for (i = 0; i < 32; i++)
{
if ((pdata->button & (1u << i)))
_canvas_event_feed_mouse_updown(eo_e, i + 1, 0, ev->timestamp, ev->data, 0, ev->device);
_canvas_event_feed_mouse_updown(eo_e, i + 1, 0, ev->timestamp, ev->data, 0, ev->device, EINA_TRUE);
}
ev->action = EFL_POINTER_ACTION_CANCEL;