evas: Fix mouse event info in global events

When using the legacy API (and in fact also with the EO API) to
listen to mouse events (move, in, out...) on a window instead
of an actual evas object, some information was missing:
 - buttons (bitmask of pressed buttons)
 - prev.x/y (previous position)

This is because Evas had not handled the event yet at this
point, it was coming directly from ecore_evas with incomplete
information. This patch involves evas a little bit earlier, and
also fixes evas_events_legacy.c to have consistent values for
cur/prev canvas/ouput coordinates. See also 890a91785 and
484dae76e6. Those commits were making the pointer coord
a seat-based property (instead of canvas-based) but the event
should already have those proper values before converting to
a legacy struct. This patch restores the meaning of the DUP
macros, as I observed 4 different coordinates from the app side
(instead of just 2: prev and cur).

Thanks to Andy for reporting the original issue on the ML!
This commit is contained in:
Jean-Philippe Andre 2017-07-10 14:21:13 +09:00
parent 0d6cdd661c
commit 7f724f6c5d
4 changed files with 40 additions and 17 deletions

View File

@ -3481,6 +3481,8 @@ _ecore_evas_mouse_move_process_internal(Ecore_Evas *ee,
ev->timestamp = timestamp;
ev->cur.x = evt_x;
ev->cur.y = evt_y;
efl_input_pointer_finalize(evt);
efl_event_callback_legacy_call(ee->evas,
_event_description_get(ev->action), evt);
efl_del(evt);
@ -4640,6 +4642,7 @@ _direct_mouse_updown(Ecore_Evas *ee, const Ecore_Event_Mouse_Button *info, Efl_P
ev->angle = info->multi.angle - ee->rotation;
if (info->dev) ev->device = efl_ref(info->dev);
else ev->device = efl_ref(evas_default_device_get(e, EFL_INPUT_DEVICE_TYPE_MOUSE));
efl_input_pointer_finalize(evt);
efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
processed = ev->evas_done;
@ -4701,6 +4704,7 @@ _direct_mouse_move_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_Move *info)
ev->angle = info->multi.angle - ee->rotation;
if (info->dev) ev->device = efl_ref(info->dev);
else ev->device = efl_ref(evas_default_device_get(e, EFL_INPUT_DEVICE_TYPE_MOUSE));
efl_input_pointer_finalize(evt);
efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
processed = ev->evas_done;
@ -4735,6 +4739,7 @@ _direct_mouse_wheel_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_Wheel *info)
ev->wheel.dir = info->direction ? EFL_ORIENT_HORIZONTAL : EFL_ORIENT_VERTICAL;
if (info->dev) ev->device = efl_ref(info->dev);
else ev->device = efl_ref(evas_default_device_get(e, EFL_INPUT_DEVICE_TYPE_MOUSE));
efl_input_pointer_finalize(evt);
efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
processed = ev->evas_done;
@ -4764,6 +4769,7 @@ _direct_mouse_inout(Ecore_Evas *ee, const Ecore_Event_Mouse_IO *info, Efl_Pointe
_pointer_position_set(ev, ee, info->x, info->y, info->x, info->y);
if (info->dev) ev->device = efl_ref(info->dev);
else ev->device = efl_ref(evas_default_device_get(e, EFL_INPUT_DEVICE_TYPE_MOUSE));
efl_input_pointer_finalize(evt);
efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
processed = ev->evas_done;
@ -4893,6 +4899,7 @@ _direct_axis_update_cb(Ecore_Evas *ee, const Ecore_Event_Axis_Update *info)
_pointer_position_set(ev, ee, x, y, x, y);
if (info->dev) ev->device = efl_ref(info->dev);
else ev->device = efl_ref(evas_default_device_get(e, EFL_INPUT_DEVICE_TYPE_MOUSE));
efl_input_pointer_finalize(evt);
efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
processed = ev->evas_done;

View File

@ -46,6 +46,7 @@ EAPI Evas_Engine_Info *efl_canvas_output_engine_info_get(Efl_Canvas_Output *outp
EAPI Eina_Bool efl_canvas_output_lock(Efl_Canvas_Output *output);
EAPI Eina_Bool efl_canvas_output_unlock(Efl_Canvas_Output *output);
EAPI void efl_input_pointer_finalize(Efl_Input_Pointer *obj);
/* Internal EO APIs */
EOAPI void efl_canvas_object_legacy_ctor(Eo *obj);

View File

@ -46,13 +46,13 @@ _del_hook(Eo *evt)
}
}
EOLIAN static Efl_Input_Pointer *
/* internal eo */
static Efl_Input_Pointer *
_efl_input_pointer_efl_input_event_instance_get(Eo *klass EINA_UNUSED, void *_pd EINA_UNUSED,
Eo *owner, void **priv)
{
Efl_Input_Pointer_Data *ev;
Efl_Input_Pointer *evt;
Evas *evas;
if (s_cached_event)
{
@ -70,17 +70,36 @@ _efl_input_pointer_efl_input_event_instance_get(Eo *klass EINA_UNUSED, void *_pd
ev->fake = EINA_FALSE;
if (priv) *priv = ev;
evas = efl_provider_find(owner, EVAS_CANVAS_CLASS);
if (evas)
{
Evas_Public_Data *e = efl_data_scope_get(evas, EVAS_CANVAS_CLASS);
ev->modifiers = &e->modifiers;
ev->locks = &e->locks;
}
return evt;
}
EAPI void
efl_input_pointer_finalize(Efl_Input_Pointer *obj)
{
const Evas_Pointer_Data *pdata;
Efl_Input_Pointer_Data *ev;
Evas_Public_Data *evas;
Evas *eo_evas;
ev = efl_data_scope_safe_get(obj, MY_CLASS);
EINA_SAFETY_ON_NULL_RETURN(ev);
eo_evas = efl_provider_find(obj, EVAS_CANVAS_CLASS);
evas = efl_data_scope_get(eo_evas, EVAS_CANVAS_CLASS);
if (!evas) return;
/* FIXME: modifiers & locks should be seat-based! */
ev->modifiers = &evas->modifiers;
ev->locks = &evas->locks;
pdata = _evas_pointer_data_by_device_get(evas, ev->device);
if (!pdata) return;
ev->prev.x = pdata->seat->x;
ev->prev.y = pdata->seat->y;
ev->pressed_buttons = pdata->button;
}
EOLIAN static void
_efl_input_pointer_class_destructor(Efl_Class *klass EINA_UNUSED)
{

View File

@ -37,19 +37,15 @@ efl_input_pointer_legacy_info_fill(Evas *eo_evas, Efl_Input_Key *eo_ev, Evas_Cal
{
Efl_Input_Pointer_Data *ev = efl_data_scope_get(eo_ev, EFL_INPUT_POINTER_CLASS);
Evas_Public_Data *evas;
Evas_Pointer_Data *pdata;
if (!ev) return NULL;
if (!eo_evas) eo_evas = efl_provider_find(eo_ev, EVAS_CANVAS_CLASS);
evas = efl_data_scope_get(eo_evas, EVAS_CANVAS_CLASS);
if (!evas) return NULL;
pdata = _evas_pointer_data_by_device_get(evas, ev->device);
EINA_SAFETY_ON_NULL_RETURN_VAL(pdata, NULL);
#define COORD_DUP(e) do { (e)->output.x = pdata->seat->x; (e)->output.y = pdata->seat->y; } while (0)
#define COORD_DUP_CUR(e) do { (e)->cur.output.x = pdata->seat->x; (e)->cur.output.y = pdata->seat->y; } while (0)
#define COORD_DUP_PREV(e) do { (e)->prev.output.x = pdata->seat->prev.x; (e)->prev.output.y = pdata->seat->prev.y; } while (0)
#define COORD_DUP(e) do { (e)->output.x = (e)->canvas.x; (e)->output.y = (e)->canvas.y; } while (0)
#define COORD_DUP_CUR(e) do { (e)->cur.output.x = (e)->cur.canvas.x; (e)->cur.output.y = (e)->cur.canvas.y; } while (0)
#define COORD_DUP_PREV(e) do { (e)->prev.output.x = (e)->prev.canvas.x; (e)->prev.output.y = (e)->prev.canvas.y; } while (0)
#define TYPE_CHK(typ) do { if ((type != EVAS_CALLBACK_LAST) && (type != EVAS_CALLBACK_ ## typ)) return NULL; } while (0)
switch (ev->action)