2016-08-25 03:20:10 -07:00
|
|
|
#define EFL_INPUT_EVENT_PROTECTED
|
2016-06-01 22:36:55 -07:00
|
|
|
|
2013-06-20 03:53:29 -07:00
|
|
|
#include "evas_common_private.h"
|
2002-11-08 00:02:15 -08:00
|
|
|
#include "evas_private.h"
|
|
|
|
|
2016-04-28 02:43:18 -07:00
|
|
|
#define EFL_INTERNAL_UNSTABLE
|
|
|
|
#include "interfaces/efl_common_internal.h"
|
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
int _evas_event_counter = 0;
|
|
|
|
|
2012-01-17 00:35:32 -08:00
|
|
|
static Eina_List *
|
2012-10-08 18:58:41 -07:00
|
|
|
_evas_event_object_list_in_get(Evas *eo_e, Eina_List *in,
|
2017-06-14 12:42:25 -07:00
|
|
|
const Eina_Inlist *ilist,
|
2017-06-14 12:20:36 -07:00
|
|
|
const Eina_List *list,
|
|
|
|
Evas_Object *stop,
|
2012-10-23 01:44:11 -07:00
|
|
|
int x, int y, int *no_rep, Eina_Bool source);
|
2012-01-17 00:35:32 -08:00
|
|
|
|
2016-08-18 00:28:55 -07:00
|
|
|
/* FIXME: use eina_list_clone */
|
2012-10-26 05:44:52 -07:00
|
|
|
static Eina_List *
|
|
|
|
evas_event_list_copy(Eina_List *list);
|
|
|
|
|
2016-05-29 22:26:48 -07:00
|
|
|
static void
|
2016-08-25 03:20:10 -07:00
|
|
|
_canvas_event_feed_mouse_move_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data *ev);
|
2016-05-27 00:21:13 -07:00
|
|
|
|
|
|
|
static void
|
2016-08-25 03:20:10 -07:00
|
|
|
_canvas_event_feed_multi_up_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data *ev);
|
2016-05-27 00:21:13 -07:00
|
|
|
|
2016-08-17 23:33:36 -07:00
|
|
|
static void
|
2016-08-25 03:20:10 -07:00
|
|
|
_canvas_event_feed_multi_move_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data *ev);
|
2016-08-17 23:33:36 -07:00
|
|
|
|
2016-08-18 00:28:55 -07:00
|
|
|
static void
|
|
|
|
_canvas_event_feed_mouse_move_legacy(Evas *eo_e, Evas_Public_Data *e, int x, int y,
|
|
|
|
unsigned int timestamp, const void *data);
|
|
|
|
|
2017-02-16 02:34:08 -08:00
|
|
|
static inline void
|
|
|
|
_evas_event_feed_check(Evas_Public_Data *e)
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
{
|
2017-02-16 02:34:08 -08:00
|
|
|
if (EINA_LIKELY(!e->running_post_events)) return;
|
2017-03-07 23:54:45 -08:00
|
|
|
CRI("Feeding new input events from a post-event callback is risky!");
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:03:09 -07:00
|
|
|
static inline Eina_Bool
|
|
|
|
_evas_event_object_pointer_allow(Eo *eo_obj, Evas_Object_Protected_Data *obj, Evas_Object_Pointer_Data *obj_pdata)
|
|
|
|
{
|
|
|
|
return (obj->is_event_parent || evas_object_clippers_is_visible(eo_obj, obj) || obj_pdata->mouse_grabbed) &&
|
|
|
|
(!evas_event_passes_through(eo_obj, obj)) &&
|
|
|
|
(!evas_event_freezes_through(eo_obj, obj)) &&
|
|
|
|
(!obj->clip.clipees);
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:03:09 -07:00
|
|
|
static inline Eina_Bool
|
|
|
|
_evas_event_object_pointer_allow_precise(Eo *eo_obj, Evas_Object_Protected_Data *obj, int x, int y, const Eina_List *ins)
|
|
|
|
{
|
|
|
|
return eina_list_data_find(ins, eo_obj) &&
|
|
|
|
((!obj->precise_is_inside) || evas_object_is_inside(eo_obj, obj, x, y));
|
|
|
|
}
|
|
|
|
|
2017-02-16 02:34:08 -08:00
|
|
|
#define EVAS_EVENT_FEED_SAFETY_CHECK(evas) _evas_event_feed_check(evas)
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
|
2016-08-10 19:58:42 -07:00
|
|
|
static void
|
|
|
|
_evas_event_havemap_adjust_f(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, Eina_Vector2 *point, Eina_Bool mouse_grabbed)
|
|
|
|
{
|
|
|
|
if (obj->smart.parent)
|
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *smart_parent_obj = efl_data_scope_get(obj->smart.parent, EFL_CANVAS_OBJECT_CLASS);
|
|
|
|
_evas_event_havemap_adjust_f(obj->smart.parent, smart_parent_obj, point, mouse_grabbed);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((!obj->map->cur.usemap) || (!obj->map->cur.map) ||
|
|
|
|
(obj->map->cur.map->count != 4))
|
|
|
|
return;
|
|
|
|
|
|
|
|
//FIXME: Unless map_coords_get() supports grab mode and extrapolate coords
|
|
|
|
//outside map, this should check the return value for outside case.
|
|
|
|
if (evas_map_coords_get(obj->map->cur.map, point->x, point->y, &point->x, &point->y, mouse_grabbed))
|
|
|
|
{
|
|
|
|
point->x += obj->cur->geometry.x;
|
|
|
|
point->y += obj->cur->geometry.y;
|
2012-11-10 04:52:00 -08:00
|
|
|
}
|
2009-11-05 07:24:48 -08:00
|
|
|
}
|
|
|
|
|
2016-07-05 06:38:02 -07:00
|
|
|
#if 0
|
|
|
|
# define DDD_DO 1
|
2017-06-15 03:49:44 -07:00
|
|
|
# define DDD(...) do { for (int _i = 0; _i < spaces; _i++) printf(" "); printf(__VA_ARGS__); } while (0)
|
2016-07-05 06:38:02 -07:00
|
|
|
# define D(...) do { printf(__VA_ARGS__); } while (0)
|
2017-06-15 03:49:44 -07:00
|
|
|
# define DDD_STATIC static
|
2016-07-05 06:38:02 -07:00
|
|
|
#else
|
|
|
|
# define DDD(...) do { } while (0)
|
|
|
|
# define D(...) do { } while (0)
|
2017-06-15 03:49:44 -07:00
|
|
|
# define DDD_STATIC
|
2016-07-05 06:38:02 -07:00
|
|
|
#endif
|
|
|
|
|
2016-07-06 22:10:24 -07:00
|
|
|
#ifdef DDD_DO
|
|
|
|
static void
|
|
|
|
walk_clippers_print(int spaces, Evas_Object_Protected_Data *obj)
|
|
|
|
{
|
|
|
|
DDD("<<< CLIP %p c[%6i %6i %6ix%6i] c[%6i %6i %6ix%6i]\n",
|
|
|
|
obj->object,
|
|
|
|
obj->cur->geometry.x, obj->cur->geometry.y,
|
|
|
|
obj->cur->geometry.w, obj->cur->geometry.h,
|
|
|
|
obj->cur->cache.clip.x, obj->cur->cache.clip.y,
|
|
|
|
obj->cur->cache.clip.w, obj->cur->cache.clip.h
|
|
|
|
);
|
2017-06-15 03:49:44 -07:00
|
|
|
if (obj->cur->clipper) walk_clippers_print(spaces + 1, obj->cur->clipper);
|
2016-07-06 22:10:24 -07:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static void
|
2017-09-13 00:38:33 -07:00
|
|
|
clip_calc(Evas_Object_Protected_Data *obj, Eina_Rectangle *c)
|
2016-07-06 22:10:24 -07:00
|
|
|
{
|
|
|
|
if (!obj) return;
|
|
|
|
RECTS_CLIP_TO_RECT(c->x, c->y, c->w, c->h,
|
|
|
|
obj->cur->geometry.x, obj->cur->geometry.y,
|
|
|
|
obj->cur->geometry.w, obj->cur->geometry.h);
|
|
|
|
clip_calc(obj->cur->clipper, c);
|
|
|
|
}
|
|
|
|
|
2008-10-21 09:31:05 -07:00
|
|
|
static Eina_List *
|
2017-06-09 17:16:08 -07:00
|
|
|
_evas_event_object_list_raw_in_get_single(Evas *eo_e, Evas_Object_Protected_Data *obj, Eina_List *in, Evas_Object *stop,
|
2017-06-15 03:49:44 -07:00
|
|
|
int x, int y, int *no_rep, Eina_Bool source, int spaces EINA_UNUSED)
|
2005-10-26 19:44:36 -07:00
|
|
|
{
|
2017-09-13 00:38:33 -07:00
|
|
|
Eina_Rectangle c;
|
2011-12-19 23:06:53 -08:00
|
|
|
int inside;
|
2017-06-09 17:16:08 -07:00
|
|
|
Evas_Object *eo_obj = obj->object;
|
|
|
|
if (eo_obj == stop)
|
|
|
|
{
|
|
|
|
*no_rep = 1;
|
|
|
|
DDD("***** NO REP - STOP *****\n");
|
|
|
|
return in;
|
|
|
|
}
|
evas: add new event_grabber smart-ish object
adding an "event rect" is a common use case for rectangles, but I needed
a smarter event rect so I sent one off to school and it came back like this.
an event_grabber is a smart object which functions like a normal event rect
which has color(0,0,0,0), but with an important difference: it can have smart
members. event propagation works differently for an event_grabber:
normal:
event -> layer -> smart(obj1,obj2,obj3) ->(?) other objects
in this case, obj1,obj2,obj3 are all "inside" the smart object and their stacking
will always be considered as being inside the smart object. rendering is also
tied to the smart object in this case, as is clipping.
an event which reaches a smart object will be sent to the objects inside,
and then may continue through the smart object if there are no objects which
block repeating.
event_grabber:
event -> layer -> event_grabber -> obj1,obj2,obj3 -> STOP
in this case, obj1,obj2,obj3 are unmodified after being added to the event_grabber
and can be stacked, rendered, and clipped completely independently of the
event_grabber.
the event_grabber is considered an "event_parent" for this case. member objects
are not "inside" the event_grabber, and they are unable to receive events on
their own. instead, the event_grabber, which must be stacked above all its
members, receives events and propagates them top->down through its member objects.
if none of the member objects block the repeat of an event then the event will
still be blocked from further propagation past the event_grabber.
object lifetimes are independent of the event_grabber; deleting the event_grabber
has no effect on its members.
@feature
2017-06-09 17:16:08 -07:00
|
|
|
if ((!obj->cur->visible) && (!obj->is_event_parent)) return in;
|
2017-06-09 17:16:08 -07:00
|
|
|
// XXX: this below DYNAMICALLY calculates the current clip rect
|
|
|
|
// by walking clippers to each parent clipper until there are
|
|
|
|
// no more of them. this is a necessary hack because cache.clip
|
|
|
|
// cooreds are broken. somewhere along the way in the past few years
|
|
|
|
// someone has forgotten to flag them as dirty and update them
|
|
|
|
// so a clicp recalce caqn work... somewhere. maybe a prexy or map fix
|
|
|
|
// or an optimization. finding this is really hard, so i'm going
|
|
|
|
// for plan b and doing this on the fly. it's only for event or
|
|
|
|
// callback handling so its a small percentage of the time, but
|
|
|
|
// it's better that we get this right
|
|
|
|
|
|
|
|
if (EINA_UNLIKELY((!!obj->map) && (obj->map->cur.map)
|
|
|
|
&& (obj->map->cur.usemap)))
|
|
|
|
c = obj->map->cur.map->normal_geometry;
|
|
|
|
else
|
2005-10-26 19:44:36 -07:00
|
|
|
{
|
2017-06-09 17:16:08 -07:00
|
|
|
if (obj->is_smart)
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2017-09-13 00:38:33 -07:00
|
|
|
Eina_Rectangle bounding_box = { 0, };
|
2017-06-09 17:16:08 -07:00
|
|
|
|
|
|
|
evas_object_smart_bounding_box_update(obj);
|
|
|
|
evas_object_smart_bounding_box_get(obj, &bounding_box, NULL);
|
|
|
|
c = bounding_box;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (obj->clip.clipees) return in;
|
|
|
|
c = obj->cur->geometry;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
clip_calc(obj->cur->clipper, &c);
|
|
|
|
// only worry about objects that intersect INCLUDING clippint
|
2017-09-19 00:59:16 -07:00
|
|
|
if ((!RECTS_INTERSECT(x, y, 1, 1, c.x, c.y, c.w, c.h)) && (!obj->child_has_map))
|
2017-06-09 17:16:08 -07:00
|
|
|
{
|
2016-07-05 06:38:02 -07:00
|
|
|
#ifdef DDD_DO
|
2017-06-09 17:16:08 -07:00
|
|
|
if (obj->is_smart)
|
|
|
|
{
|
2017-09-13 00:38:33 -07:00
|
|
|
Eina_Rectangle bounding_box = { 0, 0, 0, 0 };
|
2017-06-09 17:16:08 -07:00
|
|
|
|
|
|
|
evas_object_smart_bounding_box_get(obj, &bounding_box, NULL);
|
|
|
|
DDD("___ %p g[%6i %6i %6ix%6i] c[%6i %6i %6ix%6i] b[%6i %6i %6ix%6i] %s\n",
|
|
|
|
obj->object,
|
|
|
|
obj->cur->geometry.x, obj->cur->geometry.y,
|
|
|
|
obj->cur->geometry.w, obj->cur->geometry.h,
|
|
|
|
obj->cur->cache.clip.x, obj->cur->cache.clip.y,
|
|
|
|
obj->cur->cache.clip.w, obj->cur->cache.clip.h,
|
|
|
|
bounding_box.x, bounding_box.y,
|
|
|
|
bounding_box.w, bounding_box.h,
|
|
|
|
obj->type);
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2016-07-06 22:10:24 -07:00
|
|
|
else
|
|
|
|
{
|
2017-06-09 17:16:08 -07:00
|
|
|
DDD("___ %p g[%6i %6i %6ix%6i] c[%6i %6i %6ix%6i] %s\n",
|
|
|
|
obj->object,
|
|
|
|
obj->cur->geometry.x, obj->cur->geometry.y,
|
|
|
|
obj->cur->geometry.w, obj->cur->geometry.h,
|
|
|
|
obj->cur->cache.clip.x, obj->cur->cache.clip.y,
|
|
|
|
obj->cur->cache.clip.w, obj->cur->cache.clip.h,
|
|
|
|
obj->type);
|
2016-07-06 22:10:24 -07:00
|
|
|
}
|
2017-06-09 17:16:08 -07:00
|
|
|
if (!strcmp(obj->type, "e_layout"))
|
2016-07-05 06:38:02 -07:00
|
|
|
{
|
2017-06-09 17:16:08 -07:00
|
|
|
if (obj->cur->clipper)
|
2017-06-15 03:49:44 -07:00
|
|
|
walk_clippers_print(spaces + 1, obj->cur->clipper);
|
2016-07-05 06:38:02 -07:00
|
|
|
}
|
2017-06-09 17:16:08 -07:00
|
|
|
#endif
|
|
|
|
return in;
|
|
|
|
}
|
2016-07-06 22:10:24 -07:00
|
|
|
#ifdef DDD_DO
|
2017-06-09 17:16:08 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (obj->is_smart)
|
|
|
|
{
|
2017-09-13 00:38:33 -07:00
|
|
|
Eina_Rectangle bounding_box = { 0, 0, 0, 0 };
|
2017-06-09 17:16:08 -07:00
|
|
|
|
|
|
|
evas_object_smart_bounding_box_get(obj, &bounding_box, NULL);
|
|
|
|
DDD("OBJ %p g[%6i %6i %6ix%6i] c[%6i %6i %6ix%6i] b[%6i %6i %6ix%6i] %s\n",
|
|
|
|
obj->object,
|
|
|
|
obj->cur->geometry.x, obj->cur->geometry.y,
|
|
|
|
obj->cur->geometry.w, obj->cur->geometry.h,
|
|
|
|
obj->cur->cache.clip.x, obj->cur->cache.clip.y,
|
|
|
|
obj->cur->cache.clip.w, obj->cur->cache.clip.h,
|
|
|
|
bounding_box.x, bounding_box.y,
|
|
|
|
bounding_box.w, bounding_box.h,
|
|
|
|
obj->type);
|
|
|
|
}
|
2016-07-05 06:38:02 -07:00
|
|
|
else
|
|
|
|
{
|
2017-06-09 17:16:08 -07:00
|
|
|
DDD("OBJ %p g[%6i %6i %6ix%6i] c[%6i %6i %6ix%6i] %s\n",
|
|
|
|
obj->object,
|
|
|
|
obj->cur->geometry.x, obj->cur->geometry.y,
|
|
|
|
obj->cur->geometry.w, obj->cur->geometry.h,
|
|
|
|
obj->cur->cache.clip.x, obj->cur->cache.clip.y,
|
|
|
|
obj->cur->cache.clip.w, obj->cur->cache.clip.h,
|
|
|
|
obj->type);
|
|
|
|
}
|
2016-07-06 22:10:24 -07:00
|
|
|
// if (!strcmp(obj->type, "e_layout"))
|
2017-06-09 17:16:08 -07:00
|
|
|
{
|
|
|
|
if (obj->cur->clipper)
|
2017-06-15 03:49:44 -07:00
|
|
|
walk_clippers_print(spaces + 1, obj->cur->clipper);
|
2016-07-05 06:38:02 -07:00
|
|
|
}
|
2017-06-09 17:16:08 -07:00
|
|
|
}
|
2016-07-06 22:10:24 -07:00
|
|
|
#endif
|
2016-07-04 23:40:12 -07:00
|
|
|
|
2017-06-09 17:16:08 -07:00
|
|
|
if (!source)
|
|
|
|
{
|
|
|
|
if (evas_event_passes_through(eo_obj, obj)) return in;
|
|
|
|
if (evas_object_is_source_invisible(eo_obj, obj)) return in;
|
|
|
|
}
|
|
|
|
if ((obj->delete_me == 0) &&
|
evas: add new event_grabber smart-ish object
adding an "event rect" is a common use case for rectangles, but I needed
a smarter event rect so I sent one off to school and it came back like this.
an event_grabber is a smart object which functions like a normal event rect
which has color(0,0,0,0), but with an important difference: it can have smart
members. event propagation works differently for an event_grabber:
normal:
event -> layer -> smart(obj1,obj2,obj3) ->(?) other objects
in this case, obj1,obj2,obj3 are all "inside" the smart object and their stacking
will always be considered as being inside the smart object. rendering is also
tied to the smart object in this case, as is clipping.
an event which reaches a smart object will be sent to the objects inside,
and then may continue through the smart object if there are no objects which
block repeating.
event_grabber:
event -> layer -> event_grabber -> obj1,obj2,obj3 -> STOP
in this case, obj1,obj2,obj3 are unmodified after being added to the event_grabber
and can be stacked, rendered, and clipped completely independently of the
event_grabber.
the event_grabber is considered an "event_parent" for this case. member objects
are not "inside" the event_grabber, and they are unable to receive events on
their own. instead, the event_grabber, which must be stacked above all its
members, receives events and propagates them top->down through its member objects.
if none of the member objects block the repeat of an event then the event will
still be blocked from further propagation past the event_grabber.
object lifetimes are independent of the event_grabber; deleting the event_grabber
has no effect on its members.
@feature
2017-06-09 17:16:08 -07:00
|
|
|
((source) || ((obj->cur->visible || obj->is_event_parent) && (!obj->clip.clipees) &&
|
|
|
|
(obj->is_event_parent || evas_object_clippers_is_visible(eo_obj, obj)))))
|
2017-06-09 17:16:08 -07:00
|
|
|
{
|
|
|
|
if (obj->is_smart)
|
2009-11-05 07:24:48 -08:00
|
|
|
{
|
2017-06-09 17:16:08 -07:00
|
|
|
DDD("CHILDREN ->\n");
|
|
|
|
Evas_Object_Protected_Data *clip = obj->cur->clipper;
|
|
|
|
int norep = 0;
|
2012-06-13 10:37:19 -07:00
|
|
|
|
2017-06-09 17:16:08 -07:00
|
|
|
if (clip && clip->mask->is_mask && clip->precise_is_inside)
|
|
|
|
if (!evas_object_is_inside(clip->object, clip, x, y))
|
|
|
|
return in;
|
2015-01-15 18:45:28 -08:00
|
|
|
|
2018-10-26 04:33:44 -07:00
|
|
|
if ((obj->map->cur.usemap) && (obj->map->cur.map))
|
2017-06-09 17:16:08 -07:00
|
|
|
{
|
|
|
|
inside = evas_object_is_in_output_rect(eo_obj, obj, x, y, 1, 1);
|
|
|
|
if (inside)
|
2009-11-05 07:24:48 -08:00
|
|
|
{
|
2017-06-09 17:16:08 -07:00
|
|
|
if (!evas_map_coords_get(obj->map->cur.map, x, y,
|
|
|
|
&(obj->map->cur.map->mx),
|
|
|
|
&(obj->map->cur.map->my), 0))
|
2009-11-05 07:24:48 -08:00
|
|
|
{
|
2017-06-09 17:16:08 -07:00
|
|
|
inside = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
in = _evas_event_object_list_in_get
|
|
|
|
(eo_e, in,
|
|
|
|
evas_object_smart_members_get_direct(eo_obj),
|
evas: add new event_grabber smart-ish object
adding an "event rect" is a common use case for rectangles, but I needed
a smarter event rect so I sent one off to school and it came back like this.
an event_grabber is a smart object which functions like a normal event rect
which has color(0,0,0,0), but with an important difference: it can have smart
members. event propagation works differently for an event_grabber:
normal:
event -> layer -> smart(obj1,obj2,obj3) ->(?) other objects
in this case, obj1,obj2,obj3 are all "inside" the smart object and their stacking
will always be considered as being inside the smart object. rendering is also
tied to the smart object in this case, as is clipping.
an event which reaches a smart object will be sent to the objects inside,
and then may continue through the smart object if there are no objects which
block repeating.
event_grabber:
event -> layer -> event_grabber -> obj1,obj2,obj3 -> STOP
in this case, obj1,obj2,obj3 are unmodified after being added to the event_grabber
and can be stacked, rendered, and clipped completely independently of the
event_grabber.
the event_grabber is considered an "event_parent" for this case. member objects
are not "inside" the event_grabber, and they are unable to receive events on
their own. instead, the event_grabber, which must be stacked above all its
members, receives events and propagates them top->down through its member objects.
if none of the member objects block the repeat of an event then the event will
still be blocked from further propagation past the event_grabber.
object lifetimes are independent of the event_grabber; deleting the event_grabber
has no effect on its members.
@feature
2017-06-09 17:16:08 -07:00
|
|
|
NULL,
|
2017-06-09 17:16:08 -07:00
|
|
|
stop,
|
|
|
|
obj->cur->geometry.x + obj->map->cur.map->mx,
|
|
|
|
obj->cur->geometry.y + obj->map->cur.map->my,
|
|
|
|
&norep, source);
|
2009-11-05 07:24:48 -08:00
|
|
|
}
|
|
|
|
}
|
2017-06-09 17:16:08 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-09-13 00:38:33 -07:00
|
|
|
Eina_Rectangle bounding_box = { 0, };
|
2017-06-09 17:16:08 -07:00
|
|
|
|
|
|
|
if (!obj->child_has_map)
|
|
|
|
evas_object_smart_bounding_box_update(obj);
|
|
|
|
|
|
|
|
evas_object_smart_bounding_box_get(obj, &bounding_box, NULL);
|
|
|
|
|
|
|
|
if (obj->child_has_map ||
|
|
|
|
(bounding_box.x <= x &&
|
|
|
|
bounding_box.x + bounding_box.w >= x &&
|
|
|
|
bounding_box.y <= y &&
|
|
|
|
bounding_box.y + bounding_box.h >= y) ||
|
|
|
|
(obj->cur->geometry.x <= x &&
|
|
|
|
obj->cur->geometry.x + obj->cur->geometry.w >= x &&
|
|
|
|
obj->cur->geometry.y <= y &&
|
|
|
|
obj->cur->geometry.y + obj->cur->geometry.h >= y))
|
|
|
|
in = _evas_event_object_list_in_get
|
2017-06-14 12:42:25 -07:00
|
|
|
(eo_e, in, evas_object_smart_members_get_direct(eo_obj), NULL,
|
2017-06-09 17:16:08 -07:00
|
|
|
stop, x, y, &norep, source);
|
|
|
|
}
|
|
|
|
if (norep)
|
|
|
|
{
|
|
|
|
if (!obj->repeat_events)
|
2012-06-13 10:37:19 -07:00
|
|
|
{
|
2017-06-09 17:16:08 -07:00
|
|
|
*no_rep = 1;
|
|
|
|
DDD("***** NO REP1 *****\n");
|
evas: add new event_grabber smart-ish object
adding an "event rect" is a common use case for rectangles, but I needed
a smarter event rect so I sent one off to school and it came back like this.
an event_grabber is a smart object which functions like a normal event rect
which has color(0,0,0,0), but with an important difference: it can have smart
members. event propagation works differently for an event_grabber:
normal:
event -> layer -> smart(obj1,obj2,obj3) ->(?) other objects
in this case, obj1,obj2,obj3 are all "inside" the smart object and their stacking
will always be considered as being inside the smart object. rendering is also
tied to the smart object in this case, as is clipping.
an event which reaches a smart object will be sent to the objects inside,
and then may continue through the smart object if there are no objects which
block repeating.
event_grabber:
event -> layer -> event_grabber -> obj1,obj2,obj3 -> STOP
in this case, obj1,obj2,obj3 are unmodified after being added to the event_grabber
and can be stacked, rendered, and clipped completely independently of the
event_grabber.
the event_grabber is considered an "event_parent" for this case. member objects
are not "inside" the event_grabber, and they are unable to receive events on
their own. instead, the event_grabber, which must be stacked above all its
members, receives events and propagates them top->down through its member objects.
if none of the member objects block the repeat of an event then the event will
still be blocked from further propagation past the event_grabber.
object lifetimes are independent of the event_grabber; deleting the event_grabber
has no effect on its members.
@feature
2017-06-09 17:16:08 -07:00
|
|
|
return in;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (obj->is_event_parent)
|
|
|
|
{
|
|
|
|
int norep = 0;
|
|
|
|
in = _evas_event_object_list_in_get(eo_e, in,
|
2017-06-14 12:42:25 -07:00
|
|
|
NULL, evas_object_event_grabber_members_list(eo_obj),
|
evas: add new event_grabber smart-ish object
adding an "event rect" is a common use case for rectangles, but I needed
a smarter event rect so I sent one off to school and it came back like this.
an event_grabber is a smart object which functions like a normal event rect
which has color(0,0,0,0), but with an important difference: it can have smart
members. event propagation works differently for an event_grabber:
normal:
event -> layer -> smart(obj1,obj2,obj3) ->(?) other objects
in this case, obj1,obj2,obj3 are all "inside" the smart object and their stacking
will always be considered as being inside the smart object. rendering is also
tied to the smart object in this case, as is clipping.
an event which reaches a smart object will be sent to the objects inside,
and then may continue through the smart object if there are no objects which
block repeating.
event_grabber:
event -> layer -> event_grabber -> obj1,obj2,obj3 -> STOP
in this case, obj1,obj2,obj3 are unmodified after being added to the event_grabber
and can be stacked, rendered, and clipped completely independently of the
event_grabber.
the event_grabber is considered an "event_parent" for this case. member objects
are not "inside" the event_grabber, and they are unable to receive events on
their own. instead, the event_grabber, which must be stacked above all its
members, receives events and propagates them top->down through its member objects.
if none of the member objects block the repeat of an event then the event will
still be blocked from further propagation past the event_grabber.
object lifetimes are independent of the event_grabber; deleting the event_grabber
has no effect on its members.
@feature
2017-06-09 17:16:08 -07:00
|
|
|
stop, x, y, &norep, source);
|
|
|
|
if (norep)
|
|
|
|
{
|
|
|
|
if (!obj->repeat_events)
|
|
|
|
{
|
|
|
|
*no_rep = 1;
|
|
|
|
DDD("***** NO REP1 *****\n");
|
2017-06-09 17:16:08 -07:00
|
|
|
return in;
|
2009-11-05 07:24:48 -08:00
|
|
|
}
|
|
|
|
}
|
2017-06-09 17:16:08 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *clip = obj->cur->clipper;
|
|
|
|
if (clip && clip->mask->is_mask && clip->precise_is_inside)
|
|
|
|
inside = evas_object_is_inside(clip->object, clip, x, y);
|
2009-11-05 07:24:48 -08:00
|
|
|
else
|
2017-06-09 17:16:08 -07:00
|
|
|
inside = evas_object_is_in_output_rect(eo_obj, obj, x, y, 1, 1);
|
2012-06-13 10:37:19 -07:00
|
|
|
|
2017-06-09 17:16:08 -07:00
|
|
|
if (inside)
|
|
|
|
{
|
2018-10-26 04:33:44 -07:00
|
|
|
if ((obj->map->cur.usemap) && (obj->map->cur.map))
|
2009-11-05 07:24:48 -08:00
|
|
|
{
|
2017-06-09 17:16:08 -07:00
|
|
|
if (!evas_map_coords_get(obj->map->cur.map, x, y,
|
|
|
|
&(obj->map->cur.map->mx),
|
|
|
|
&(obj->map->cur.map->my), 0))
|
2009-11-05 07:24:48 -08:00
|
|
|
{
|
2017-06-09 17:16:08 -07:00
|
|
|
inside = 0;
|
2009-11-05 07:24:48 -08:00
|
|
|
}
|
|
|
|
}
|
2017-06-09 17:16:08 -07:00
|
|
|
}
|
|
|
|
if (inside && ((!obj->precise_is_inside) ||
|
|
|
|
(evas_object_is_inside(eo_obj, obj, x, y))))
|
|
|
|
{
|
|
|
|
if (!evas_event_freezes_through(eo_obj, obj))
|
2009-11-05 07:24:48 -08:00
|
|
|
{
|
2017-06-09 17:16:08 -07:00
|
|
|
DDD("----------------> ADD obj %p\n", obj->object);
|
|
|
|
in = eina_list_append(in, eo_obj);
|
|
|
|
}
|
|
|
|
if (!obj->repeat_events)
|
|
|
|
{
|
|
|
|
*no_rep = 1;
|
|
|
|
DDD("***** NO REP2 *****\n");
|
|
|
|
return in;
|
2009-11-05 07:24:48 -08:00
|
|
|
}
|
|
|
|
}
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2005-10-26 19:44:36 -07:00
|
|
|
}
|
2017-06-09 17:16:08 -07:00
|
|
|
return in;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_List *
|
|
|
|
_evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
|
2017-06-14 12:20:36 -07:00
|
|
|
const Eina_Inlist *ilist,
|
|
|
|
const Eina_List *list,
|
|
|
|
Evas_Object *stop,
|
2019-06-15 01:38:06 -07:00
|
|
|
int x, int y, int *no_rep, Eina_Bool source,
|
|
|
|
Eina_Bool must_walk_last)
|
2017-06-09 17:16:08 -07:00
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *obj = NULL;
|
2017-06-15 03:49:44 -07:00
|
|
|
DDD_STATIC int spaces = 0;
|
2017-06-09 17:16:08 -07:00
|
|
|
|
2017-06-14 12:42:25 -07:00
|
|
|
if ((!ilist) && (!list)) return in;
|
2017-06-15 03:49:44 -07:00
|
|
|
|
2017-06-09 17:16:08 -07:00
|
|
|
spaces++;
|
2017-06-14 12:20:36 -07:00
|
|
|
if (ilist)
|
evas: add new event_grabber smart-ish object
adding an "event rect" is a common use case for rectangles, but I needed
a smarter event rect so I sent one off to school and it came back like this.
an event_grabber is a smart object which functions like a normal event rect
which has color(0,0,0,0), but with an important difference: it can have smart
members. event propagation works differently for an event_grabber:
normal:
event -> layer -> smart(obj1,obj2,obj3) ->(?) other objects
in this case, obj1,obj2,obj3 are all "inside" the smart object and their stacking
will always be considered as being inside the smart object. rendering is also
tied to the smart object in this case, as is clipping.
an event which reaches a smart object will be sent to the objects inside,
and then may continue through the smart object if there are no objects which
block repeating.
event_grabber:
event -> layer -> event_grabber -> obj1,obj2,obj3 -> STOP
in this case, obj1,obj2,obj3 are unmodified after being added to the event_grabber
and can be stacked, rendered, and clipped completely independently of the
event_grabber.
the event_grabber is considered an "event_parent" for this case. member objects
are not "inside" the event_grabber, and they are unable to receive events on
their own. instead, the event_grabber, which must be stacked above all its
members, receives events and propagates them top->down through its member objects.
if none of the member objects block the repeat of an event then the event will
still be blocked from further propagation past the event_grabber.
object lifetimes are independent of the event_grabber; deleting the event_grabber
has no effect on its members.
@feature
2017-06-09 17:16:08 -07:00
|
|
|
{
|
2019-06-15 01:38:06 -07:00
|
|
|
Eina_Inlist *last;
|
|
|
|
|
|
|
|
if (must_walk_last) last = eina_inlist_last(ilist);
|
|
|
|
else last = ilist->last;
|
|
|
|
for (obj = _EINA_INLIST_CONTAINER(obj, last);
|
2017-06-09 17:16:08 -07:00
|
|
|
obj;
|
|
|
|
obj = _EINA_INLIST_CONTAINER(obj, EINA_INLIST_GET(obj)->prev))
|
|
|
|
{
|
2017-06-14 12:42:25 -07:00
|
|
|
if (obj->events->parent) continue;
|
2017-06-15 03:49:44 -07:00
|
|
|
in = _evas_event_object_list_raw_in_get_single(eo_e, obj, in, stop, x, y, no_rep, source, spaces);
|
|
|
|
if (*no_rep) goto end;
|
evas: add new event_grabber smart-ish object
adding an "event rect" is a common use case for rectangles, but I needed
a smarter event rect so I sent one off to school and it came back like this.
an event_grabber is a smart object which functions like a normal event rect
which has color(0,0,0,0), but with an important difference: it can have smart
members. event propagation works differently for an event_grabber:
normal:
event -> layer -> smart(obj1,obj2,obj3) ->(?) other objects
in this case, obj1,obj2,obj3 are all "inside" the smart object and their stacking
will always be considered as being inside the smart object. rendering is also
tied to the smart object in this case, as is clipping.
an event which reaches a smart object will be sent to the objects inside,
and then may continue through the smart object if there are no objects which
block repeating.
event_grabber:
event -> layer -> event_grabber -> obj1,obj2,obj3 -> STOP
in this case, obj1,obj2,obj3 are unmodified after being added to the event_grabber
and can be stacked, rendered, and clipped completely independently of the
event_grabber.
the event_grabber is considered an "event_parent" for this case. member objects
are not "inside" the event_grabber, and they are unable to receive events on
their own. instead, the event_grabber, which must be stacked above all its
members, receives events and propagates them top->down through its member objects.
if none of the member objects block the repeat of an event then the event will
still be blocked from further propagation past the event_grabber.
object lifetimes are independent of the event_grabber; deleting the event_grabber
has no effect on its members.
@feature
2017-06-09 17:16:08 -07:00
|
|
|
}
|
|
|
|
}
|
2017-06-14 12:20:36 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
EINA_LIST_REVERSE_FOREACH(list, l, obj)
|
|
|
|
{
|
2017-06-15 03:49:44 -07:00
|
|
|
in = _evas_event_object_list_raw_in_get_single(eo_e, obj, in, stop, x, y, no_rep, source, spaces);
|
|
|
|
if (*no_rep) goto end;
|
2017-06-14 12:20:36 -07:00
|
|
|
}
|
|
|
|
}
|
2005-10-26 19:44:36 -07:00
|
|
|
*no_rep = 0;
|
2017-06-15 03:49:44 -07:00
|
|
|
|
|
|
|
end:
|
2016-07-05 06:38:02 -07:00
|
|
|
spaces--;
|
2005-10-26 19:44:36 -07:00
|
|
|
return in;
|
|
|
|
}
|
|
|
|
|
2016-08-10 19:58:42 -07:00
|
|
|
static void
|
|
|
|
_transform_to_src_space_f(Evas_Object_Protected_Data *obj, Evas_Object_Protected_Data *src, Eina_Vector2 *point)
|
|
|
|
{
|
|
|
|
double obj_w = obj->cur->geometry.w, obj_h = obj->cur->geometry.h;
|
|
|
|
double src_w = src->cur->geometry.w, src_h = src->cur->geometry.h;
|
|
|
|
double tmp_x = point->x;
|
|
|
|
double tmp_y = point->y;
|
|
|
|
|
|
|
|
tmp_x -= obj->cur->geometry.x;
|
|
|
|
tmp_y -= obj->cur->geometry.y;
|
|
|
|
|
2017-01-06 09:57:46 -08:00
|
|
|
if (!EINA_DBL_EQ(obj_w, src_w))
|
2016-08-10 19:58:42 -07:00
|
|
|
tmp_x = (tmp_x * (src_w / obj_w));
|
2017-01-06 09:57:46 -08:00
|
|
|
if (!EINA_DBL_EQ(obj_h, src_h))
|
2016-08-10 19:58:42 -07:00
|
|
|
tmp_y = (tmp_y * (src_h / obj_h));
|
|
|
|
|
|
|
|
tmp_x += src->cur->geometry.x;
|
|
|
|
tmp_y += src->cur->geometry.y;
|
|
|
|
point->x = tmp_x;
|
|
|
|
point->y = tmp_y;
|
|
|
|
}
|
|
|
|
|
2016-10-26 05:37:29 -07:00
|
|
|
static Efl_Input_Device *
|
|
|
|
_evas_event_legacy_device_get(Eo *evas, Eina_Bool mouse)
|
|
|
|
{
|
|
|
|
Efl_Input_Device *dev = _evas_device_top_get(evas);
|
|
|
|
//The user did not push a device, use the default mouse/keyboard instead.
|
|
|
|
if (!dev)
|
|
|
|
{
|
|
|
|
Evas_Public_Data *e = efl_data_scope_get(evas, EVAS_CANVAS_CLASS);
|
|
|
|
if (mouse)
|
|
|
|
return e->default_mouse;
|
|
|
|
return e->default_keyboard;
|
|
|
|
}
|
|
|
|
return dev;
|
|
|
|
}
|
|
|
|
|
2012-10-25 08:12:54 -07:00
|
|
|
static void
|
2016-05-27 04:06:06 -07:00
|
|
|
_evas_event_source_mouse_down_events(Evas_Object *eo_obj, Evas *eo_e,
|
2016-10-21 05:25:41 -07:00
|
|
|
Efl_Input_Pointer *parent_ev,
|
|
|
|
Evas_Pointer_Data *pdata,
|
|
|
|
int event_id)
|
2012-10-23 01:44:11 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-25 08:12:54 -07:00
|
|
|
Evas_Object *eo_src = _evas_object_image_source_get(eo_obj);
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *src = efl_data_scope_get(eo_src, EFL_CANVAS_OBJECT_CLASS);
|
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2013-01-16 23:21:06 -08:00
|
|
|
Evas_Object_Protected_Data *child;
|
|
|
|
Evas_Object *eo_child;
|
2016-08-17 04:29:39 -07:00
|
|
|
Eina_List *copy, *l;
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev;
|
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-17 04:29:39 -07:00
|
|
|
Eina_Vector2 point;
|
2013-01-16 23:21:06 -08:00
|
|
|
int addgrab = 0;
|
2016-08-17 04:29:39 -07:00
|
|
|
int no_rep = 0;
|
2019-04-25 21:24:01 -07:00
|
|
|
int srcgrab = 0;
|
2012-10-24 00:10:17 -07:00
|
|
|
|
2012-10-25 08:12:54 -07:00
|
|
|
if (obj->delete_me || src->delete_me || e->is_frozen) return;
|
2012-10-24 21:03:06 -07:00
|
|
|
|
2017-12-10 21:50:22 -08:00
|
|
|
evt = efl_duplicate(parent_ev);
|
2016-08-25 03:20:10 -07:00
|
|
|
ev = efl_data_scope_get(evt, EFL_INPUT_POINTER_CLASS);
|
2016-08-17 04:29:39 -07:00
|
|
|
if (!ev) return;
|
2012-10-24 00:10:17 -07:00
|
|
|
|
2016-08-17 04:29:39 -07:00
|
|
|
_transform_to_src_space_f(obj, src, &ev->cur);
|
|
|
|
point = ev->cur;
|
|
|
|
ev->source = eo_obj;
|
2019-06-20 03:13:37 -07:00
|
|
|
ev->touch_id = 0;
|
2013-01-03 17:55:07 -08:00
|
|
|
|
2019-04-25 21:24:01 -07:00
|
|
|
EINA_LIST_FOREACH(src->proxy->src_event_in, l, eo_child)
|
2012-10-23 01:44:11 -07:00
|
|
|
{
|
2019-04-25 21:24:01 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
2014-08-26 20:15:33 -07:00
|
|
|
|
2019-04-25 21:24:01 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, child);
|
|
|
|
if (!obj_pdata)
|
2014-08-26 20:15:33 -07:00
|
|
|
{
|
2019-04-25 21:24:01 -07:00
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
srcgrab += obj_pdata->mouse_grabbed;
|
2012-10-23 01:44:11 -07:00
|
|
|
}
|
2012-10-26 05:44:52 -07:00
|
|
|
|
2019-04-25 21:24:01 -07:00
|
|
|
if (srcgrab == 0)
|
|
|
|
{
|
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, src->proxy, Evas_Object_Proxy_Data, proxy_write)
|
|
|
|
{
|
|
|
|
if (proxy_write->src_event_in)
|
|
|
|
proxy_write->src_event_in = eina_list_free(proxy_write->src_event_in);
|
|
|
|
|
|
|
|
if (src->is_smart)
|
|
|
|
{
|
|
|
|
proxy_write->src_event_in = _evas_event_object_list_raw_in_get
|
|
|
|
(eo_e, proxy_write->src_event_in,
|
|
|
|
evas_object_smart_members_get_direct(eo_src), NULL,
|
2019-06-15 01:38:06 -07:00
|
|
|
NULL, ev->cur.x, ev->cur.y, &no_rep, EINA_TRUE, EINA_FALSE);
|
2019-04-25 21:24:01 -07:00
|
|
|
}
|
|
|
|
else if (src->is_event_parent)
|
|
|
|
{
|
|
|
|
proxy_write->src_event_in = _evas_event_object_list_raw_in_get
|
|
|
|
(eo_e, proxy_write->src_event_in,
|
|
|
|
NULL, evas_object_event_grabber_members_list(eo_src),
|
2019-06-15 01:38:06 -07:00
|
|
|
NULL, ev->cur.x, ev->cur.y, &no_rep, EINA_TRUE, EINA_FALSE);
|
2019-04-25 21:24:01 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
proxy_write->src_event_in = eina_list_append(proxy_write->src_event_in, eo_src);
|
|
|
|
}
|
|
|
|
EINA_COW_WRITE_END(evas_object_proxy_cow, src->proxy, proxy_write);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pdata->seat->mouse_grabbed == 0)
|
|
|
|
{
|
|
|
|
if (pdata->seat->downs > 1) addgrab = pdata->seat->downs - 1;
|
|
|
|
}
|
2012-10-26 05:44:52 -07:00
|
|
|
|
2013-01-16 23:21:06 -08:00
|
|
|
EINA_LIST_FOREACH(src->proxy->src_event_in, l, eo_child)
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, child);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ((obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_AUTOGRAB) ||
|
|
|
|
(obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN))
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
obj_pdata->mouse_grabbed += (addgrab + 1);
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->mouse_grabbed += (addgrab + 1);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (obj_pdata->pointer_mode ==
|
2012-10-26 05:44:52 -07:00
|
|
|
EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)
|
|
|
|
{
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->nogrep++;
|
2012-10-26 05:44:52 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-16 23:21:06 -08:00
|
|
|
copy = evas_event_list_copy(src->proxy->src_event_in);
|
2012-10-26 05:44:52 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_child)
|
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
|
|
|
Evas_Object_Pointer_Mode pointer_mode;
|
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
2016-08-17 04:29:39 -07:00
|
|
|
ev->cur = point;
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, child);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
pointer_mode = obj_pdata->pointer_mode;
|
|
|
|
_evas_event_havemap_adjust_f(eo_child, child, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_child, child, EVAS_CALLBACK_MOUSE_DOWN, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_DOWN);
|
2012-10-26 05:44:52 -07:00
|
|
|
if (e->delete_me) break;
|
2016-10-21 05:25:41 -07:00
|
|
|
if (pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)
|
2012-10-26 05:44:52 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
eina_list_free(copy);
|
2016-08-17 04:29:39 -07:00
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2012-10-23 01:44:11 -07:00
|
|
|
}
|
|
|
|
|
evas_events: Fix to set mouse_in state to all pointers in the seat.
Summary:
mouse coordinate is set by seat.
Therefore, mouse_in state should be set based on seat.
As a result, mouse_in state of all pointers in the seat should be
updated at the same time.
Reviewers: eagleeye, devilhorns, zmike
Reviewed By: eagleeye, devilhorns, zmike
Subscribers: devilhorns, Hermet, kimcinoo, cedric, iscaro, zmike, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6699
2018-08-02 02:16:46 -07:00
|
|
|
static void
|
|
|
|
_evas_event_mouse_in_set(Evas_Pointer_Seat *pseat,
|
|
|
|
Evas_Object_Protected_Data *obj, Eina_Bool mouse_in)
|
|
|
|
{
|
|
|
|
Evas_Pointer_Data *pdata;
|
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
|
|
|
|
|
|
|
if ((!pseat) || (!obj)) return;
|
|
|
|
|
|
|
|
EINA_INLIST_FOREACH(pseat->pointers, pdata)
|
|
|
|
{
|
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
|
|
|
if (obj_pdata)
|
|
|
|
obj_pdata->mouse_in = mouse_in;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-25 08:12:54 -07:00
|
|
|
static void
|
2016-05-27 04:06:06 -07:00
|
|
|
_evas_event_source_mouse_move_events(Evas_Object *eo_obj, Evas *eo_e,
|
2016-10-21 05:25:41 -07:00
|
|
|
Efl_Input_Pointer *parent_ev,
|
|
|
|
Evas_Pointer_Data *pdata,
|
|
|
|
int event_id)
|
2012-10-25 08:12:54 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-25 08:12:54 -07:00
|
|
|
Evas_Object *eo_src = _evas_object_image_source_get(eo_obj);
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *src = efl_data_scope_get(eo_src, EFL_CANVAS_OBJECT_CLASS);
|
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-17 06:00:37 -07:00
|
|
|
Evas_Object_Protected_Data *child;
|
|
|
|
Evas_Object *eo_child;
|
|
|
|
Eina_List *l;
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev;
|
|
|
|
Efl_Input_Pointer *evt;
|
2016-09-07 05:21:09 -07:00
|
|
|
Eina_Vector2 curpt, curpt_real, prevpt;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2012-10-26 05:44:52 -07:00
|
|
|
if (obj->delete_me || src->delete_me || e->is_frozen) return;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2017-12-10 21:50:22 -08:00
|
|
|
evt = efl_duplicate(parent_ev);
|
2016-08-25 03:20:10 -07:00
|
|
|
ev = efl_data_scope_get(evt, EFL_INPUT_POINTER_CLASS);
|
2016-08-17 06:00:37 -07:00
|
|
|
if (!ev) return;
|
2013-01-03 17:55:07 -08:00
|
|
|
|
2016-08-17 06:00:37 -07:00
|
|
|
curpt_real = ev->cur;
|
|
|
|
_transform_to_src_space_f(obj, src, &ev->cur);
|
|
|
|
_transform_to_src_space_f(obj, src, &ev->prev);
|
|
|
|
curpt = ev->cur;
|
|
|
|
prevpt = ev->prev;
|
|
|
|
ev->source = eo_obj;
|
2019-06-20 03:13:37 -07:00
|
|
|
ev->touch_id = 0;
|
2012-10-26 05:44:52 -07:00
|
|
|
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->mouse_grabbed)
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
|
|
|
Eina_List *outs = NULL;
|
2013-01-16 23:21:06 -08:00
|
|
|
Eina_List *copy = evas_event_list_copy(src->proxy->src_event_in);
|
2016-08-17 06:00:37 -07:00
|
|
|
|
2012-10-26 05:44:52 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_child)
|
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
2017-01-01 22:17:40 -08:00
|
|
|
//FIXME: When object is deleted in the src_event_in list,
|
|
|
|
//the src_event_in list should be updated. But now there is no way.
|
|
|
|
//So add checking NULL logic, please delete it if you make a better way.
|
|
|
|
if (!child) continue;
|
|
|
|
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, child);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2012-10-26 05:44:52 -07:00
|
|
|
|
2017-06-16 12:03:09 -07:00
|
|
|
if (_evas_event_object_pointer_allow(eo_child, child, obj_pdata))
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2016-08-17 06:00:37 -07:00
|
|
|
ev->cur = curpt;
|
|
|
|
ev->prev = prevpt;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_child, child, &ev->cur, obj_pdata->mouse_grabbed);
|
|
|
|
_evas_event_havemap_adjust_f(eo_child, child, &ev->prev, obj_pdata->mouse_grabbed);
|
2016-08-17 06:00:37 -07:00
|
|
|
|
|
|
|
ev->action = EFL_POINTER_ACTION_MOVE;
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_child, child, EVAS_CALLBACK_MOUSE_MOVE, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_MOVE);
|
2012-10-26 05:44:52 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
outs = eina_list_append(outs, eo_child);
|
|
|
|
if (e->delete_me || e->is_frozen) break;
|
2019-06-20 03:13:37 -07:00
|
|
|
//FIXME: take care nograb object
|
2012-10-26 05:44:52 -07:00
|
|
|
}
|
|
|
|
eina_list_free(copy);
|
|
|
|
|
2016-08-17 06:00:37 -07:00
|
|
|
EINA_LIST_FREE(outs, eo_child)
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (child->delete_me) continue;
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, child);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ((obj_pdata->mouse_grabbed == 0) && (!e->delete_me))
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
if (obj_pdata->mouse_in) continue; /* FIXME: dubious logic! */
|
evas_events: Fix to set mouse_in state to all pointers in the seat.
Summary:
mouse coordinate is set by seat.
Therefore, mouse_in state should be set based on seat.
As a result, mouse_in state of all pointers in the seat should be
updated at the same time.
Reviewers: eagleeye, devilhorns, zmike
Reviewed By: eagleeye, devilhorns, zmike
Subscribers: devilhorns, Hermet, kimcinoo, cedric, iscaro, zmike, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6699
2018-08-02 02:16:46 -07:00
|
|
|
_evas_event_mouse_in_set(pdata->seat, child, 0);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (e->is_frozen) continue;
|
2016-08-17 06:00:37 -07:00
|
|
|
ev->cur = curpt_real;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_child, child, &ev->cur, obj_pdata->mouse_grabbed);
|
2014-08-26 20:15:33 -07:00
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, src->proxy, Evas_Object_Proxy_Data, proxy_write)
|
|
|
|
proxy_write->src_event_in = eina_list_remove(proxy_write->src_event_in, eo_child);
|
|
|
|
EINA_COW_WRITE_END(evas_object_proxy_cow, src->proxy, proxy_write);
|
2013-01-16 23:21:06 -08:00
|
|
|
|
2016-08-17 06:00:37 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_OUT;
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_child, child, EVAS_CALLBACK_MOUSE_OUT, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_OUT);
|
2012-10-26 05:44:52 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Eina_List *ins = NULL;
|
2013-01-16 23:21:06 -08:00
|
|
|
Eina_List *copy = evas_event_list_copy(src->proxy->src_event_in);
|
2016-05-27 04:06:06 -07:00
|
|
|
|
2012-10-26 05:44:52 -07:00
|
|
|
if (src->is_smart)
|
|
|
|
{
|
|
|
|
int no_rep = 0;
|
2016-08-17 06:00:37 -07:00
|
|
|
ins = _evas_event_object_list_raw_in_get(eo_e, ins, evas_object_smart_members_get_direct(eo_src),
|
2019-06-15 01:38:06 -07:00
|
|
|
NULL, NULL, ev->cur.x, ev->cur.y, &no_rep, EINA_TRUE, EINA_FALSE);
|
evas: add new event_grabber smart-ish object
adding an "event rect" is a common use case for rectangles, but I needed
a smarter event rect so I sent one off to school and it came back like this.
an event_grabber is a smart object which functions like a normal event rect
which has color(0,0,0,0), but with an important difference: it can have smart
members. event propagation works differently for an event_grabber:
normal:
event -> layer -> smart(obj1,obj2,obj3) ->(?) other objects
in this case, obj1,obj2,obj3 are all "inside" the smart object and their stacking
will always be considered as being inside the smart object. rendering is also
tied to the smart object in this case, as is clipping.
an event which reaches a smart object will be sent to the objects inside,
and then may continue through the smart object if there are no objects which
block repeating.
event_grabber:
event -> layer -> event_grabber -> obj1,obj2,obj3 -> STOP
in this case, obj1,obj2,obj3 are unmodified after being added to the event_grabber
and can be stacked, rendered, and clipped completely independently of the
event_grabber.
the event_grabber is considered an "event_parent" for this case. member objects
are not "inside" the event_grabber, and they are unable to receive events on
their own. instead, the event_grabber, which must be stacked above all its
members, receives events and propagates them top->down through its member objects.
if none of the member objects block the repeat of an event then the event will
still be blocked from further propagation past the event_grabber.
object lifetimes are independent of the event_grabber; deleting the event_grabber
has no effect on its members.
@feature
2017-06-09 17:16:08 -07:00
|
|
|
}
|
|
|
|
else if (src->is_event_parent)
|
|
|
|
{
|
|
|
|
int no_rep = 0;
|
2017-06-14 12:42:25 -07:00
|
|
|
ins = _evas_event_object_list_raw_in_get(eo_e, ins, NULL,
|
|
|
|
evas_object_event_grabber_members_list(eo_src),
|
2019-06-15 01:38:06 -07:00
|
|
|
NULL, ev->cur.x, ev->cur.y, &no_rep, EINA_TRUE, EINA_FALSE);
|
2012-10-26 05:44:52 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
ins = eina_list_append(ins, eo_src);
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2012-10-26 05:44:52 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_child)
|
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
2017-01-01 22:17:40 -08:00
|
|
|
//FIXME: When object is deleted in the src_event_in list,
|
|
|
|
//the src_event_in list should be updated. But now there is no way.
|
|
|
|
//So add checking NULL logic, please delete it if you make a better way.
|
|
|
|
if (!child) continue;
|
2012-10-26 05:44:52 -07:00
|
|
|
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, child);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2016-08-17 06:00:37 -07:00
|
|
|
ev->cur = curpt;
|
2012-10-26 05:44:52 -07:00
|
|
|
if (evas_object_is_in_output_rect(eo_child, child,
|
2016-08-17 06:00:37 -07:00
|
|
|
ev->cur.x, ev->cur.y, 1, 1) &&
|
2017-06-16 12:03:09 -07:00
|
|
|
_evas_event_object_pointer_allow(eo_child, child, obj_pdata) &&
|
2017-06-16 12:03:09 -07:00
|
|
|
_evas_event_object_pointer_allow_precise(eo_child, child, ev->cur.x, ev->cur.y, ins))
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2016-08-17 06:00:37 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_MOVE;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_child, child, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_child, child, EVAS_CALLBACK_MOUSE_MOVE, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_MOVE);
|
2012-10-26 05:44:52 -07:00
|
|
|
}
|
2016-10-21 05:25:41 -07:00
|
|
|
else if (obj_pdata->mouse_in)
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
evas_events: Fix to set mouse_in state to all pointers in the seat.
Summary:
mouse coordinate is set by seat.
Therefore, mouse_in state should be set based on seat.
As a result, mouse_in state of all pointers in the seat should be
updated at the same time.
Reviewers: eagleeye, devilhorns, zmike
Reviewed By: eagleeye, devilhorns, zmike
Subscribers: devilhorns, Hermet, kimcinoo, cedric, iscaro, zmike, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6699
2018-08-02 02:16:46 -07:00
|
|
|
_evas_event_mouse_in_set(pdata->seat, child, 0);
|
2012-10-26 05:44:52 -07:00
|
|
|
if (e->is_frozen) continue;
|
2016-08-17 06:00:37 -07:00
|
|
|
ev->cur = curpt;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_child, child, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-17 06:00:37 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_OUT;
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_child, child, EVAS_CALLBACK_MOUSE_OUT, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_OUT);
|
2012-10-26 05:44:52 -07:00
|
|
|
if (e->delete_me) break;
|
|
|
|
|
|
|
|
}
|
|
|
|
if (e->delete_me || e->is_frozen) break;
|
|
|
|
}
|
|
|
|
eina_list_free(copy);
|
2016-05-27 04:06:06 -07:00
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
int event_id2 = _evas_object_event_new();
|
2012-10-26 05:44:52 -07:00
|
|
|
EINA_LIST_FOREACH(ins, l, eo_child)
|
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, child);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2013-01-16 23:21:06 -08:00
|
|
|
if (!eina_list_data_find(src->proxy->src_event_in, eo_child))
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata->mouse_in)
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
evas_events: Fix to set mouse_in state to all pointers in the seat.
Summary:
mouse coordinate is set by seat.
Therefore, mouse_in state should be set based on seat.
As a result, mouse_in state of all pointers in the seat should be
updated at the same time.
Reviewers: eagleeye, devilhorns, zmike
Reviewed By: eagleeye, devilhorns, zmike
Subscribers: devilhorns, Hermet, kimcinoo, cedric, iscaro, zmike, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6699
2018-08-02 02:16:46 -07:00
|
|
|
_evas_event_mouse_in_set(pdata->seat, child, 1);
|
2012-10-26 05:44:52 -07:00
|
|
|
if (e->is_frozen) continue;
|
2016-08-17 06:00:37 -07:00
|
|
|
ev->cur = curpt;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_child, child, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-17 06:00:37 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_IN;
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_child, child, EVAS_CALLBACK_MOUSE_IN, evt,
|
|
|
|
event_id2, EFL_EVENT_POINTER_IN);
|
2018-07-24 09:04:11 -07:00
|
|
|
if ((curpt.x != ev->prev.x) &&
|
|
|
|
(curpt.y != ev->prev.y))
|
2017-07-11 23:43:41 -07:00
|
|
|
{
|
|
|
|
ev->action = EFL_POINTER_ACTION_MOVE;
|
|
|
|
evas_object_event_callback_call(eo_child, child, EVAS_CALLBACK_MOUSE_MOVE, evt,
|
|
|
|
event_id2, EFL_EVENT_POINTER_MOVE);
|
|
|
|
}
|
2012-10-26 05:44:52 -07:00
|
|
|
if (e->delete_me) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-05-27 04:06:06 -07:00
|
|
|
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->mouse_grabbed == 0)
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2014-08-26 20:15:33 -07:00
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, src->proxy, Evas_Object_Proxy_Data, proxy_write)
|
|
|
|
{
|
|
|
|
eina_list_free(proxy_write->src_event_in);
|
|
|
|
proxy_write->src_event_in = ins;
|
|
|
|
}
|
|
|
|
EINA_COW_WRITE_END(evas_object_proxy_cow, src->proxy, proxy_write);
|
2012-10-26 05:44:52 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (ins) eina_list_free(ins);
|
|
|
|
}
|
|
|
|
}
|
2016-08-17 06:00:37 -07:00
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2012-10-25 08:12:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-05-27 04:06:06 -07:00
|
|
|
_evas_event_source_mouse_up_events(Evas_Object *eo_obj, Evas *eo_e,
|
2016-10-21 05:25:41 -07:00
|
|
|
Efl_Input_Pointer *parent_ev,
|
|
|
|
Evas_Pointer_Data *pdata,
|
2019-06-26 07:30:35 -07:00
|
|
|
int event_id, Eina_Bool cancel)
|
2012-10-25 08:12:54 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-25 08:12:54 -07:00
|
|
|
Evas_Object *eo_src = _evas_object_image_source_get(eo_obj);
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *src = efl_data_scope_get(eo_src, EFL_CANVAS_OBJECT_CLASS);
|
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-17 04:29:39 -07:00
|
|
|
Evas_Object_Protected_Data *child;
|
|
|
|
Evas_Object *eo_child;
|
|
|
|
Eina_List *copy, *l;
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev;
|
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-17 04:29:39 -07:00
|
|
|
Eina_Vector2 point;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2012-10-26 05:44:52 -07:00
|
|
|
if (obj->delete_me || src->delete_me || e->is_frozen) return;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2017-12-10 21:50:22 -08:00
|
|
|
evt = efl_duplicate(parent_ev);
|
2016-08-25 03:20:10 -07:00
|
|
|
ev = efl_data_scope_get(evt, EFL_INPUT_POINTER_CLASS);
|
2016-08-17 04:29:39 -07:00
|
|
|
if (!ev) return;
|
2013-01-03 17:55:07 -08:00
|
|
|
|
2016-08-17 04:29:39 -07:00
|
|
|
_transform_to_src_space_f(obj, src, &ev->cur);
|
|
|
|
point = ev->cur;
|
|
|
|
ev->source = eo_obj;
|
2019-06-20 03:13:37 -07:00
|
|
|
ev->touch_id = 0;
|
2012-10-26 05:44:52 -07:00
|
|
|
|
2016-08-17 04:29:39 -07:00
|
|
|
copy = evas_event_list_copy(src->proxy->src_event_in);
|
2012-10-26 05:44:52 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_child)
|
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
|
|
|
Evas_Object_Pointer_Mode pointer_mode;
|
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, child);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2019-06-26 07:30:35 -07:00
|
|
|
if ((!cancel) && ((obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_AUTOGRAB) ||
|
2018-10-16 22:26:23 -07:00
|
|
|
(obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)) &&
|
2016-10-21 05:25:41 -07:00
|
|
|
(obj_pdata->mouse_grabbed > 0))
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
obj_pdata->mouse_grabbed--;
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->mouse_grabbed--;
|
2012-10-26 05:44:52 -07:00
|
|
|
}
|
|
|
|
|
2016-08-17 04:29:39 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
pointer_mode = obj_pdata->pointer_mode;
|
|
|
|
_evas_event_havemap_adjust_f(eo_child, child, &ev->cur, obj_pdata->mouse_grabbed);
|
2019-06-26 07:30:35 -07:00
|
|
|
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);
|
2012-10-26 05:44:52 -07:00
|
|
|
if (e->delete_me) break;
|
2016-10-21 05:25:41 -07:00
|
|
|
if (pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2019-06-26 07:30:35 -07:00
|
|
|
if ((!cancel) && (pdata->seat->nogrep > 0)) pdata->seat->nogrep--;
|
2012-10-26 05:44:52 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
eina_list_free(copy);
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2012-10-25 08:12:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-08-25 03:20:10 -07:00
|
|
|
_evas_event_source_hold_events(Evas_Object *eo_obj, int event_id, Efl_Input_Hold *evt)
|
2012-10-25 08:12:54 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-25 08:12:54 -07:00
|
|
|
Evas_Object *eo_src = _evas_object_image_source_get(eo_obj);
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *src = efl_data_scope_get(eo_src, EFL_CANVAS_OBJECT_CLASS);
|
2016-09-08 05:38:38 -07:00
|
|
|
Evas_Object_Protected_Data *child;
|
2016-09-07 05:35:30 -07:00
|
|
|
Evas_Object *eo_child;
|
2016-05-30 23:31:17 -07:00
|
|
|
Eina_List *l;
|
2012-10-26 05:44:52 -07:00
|
|
|
|
2012-10-25 08:12:54 -07:00
|
|
|
if (obj->layer->evas->is_frozen) return;
|
2012-10-26 05:44:52 -07:00
|
|
|
|
2016-05-30 23:31:17 -07:00
|
|
|
EINA_LIST_FOREACH(src->proxy->src_event_in, l, eo_child)
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
|
|
|
if (src->delete_me) return;
|
2016-09-08 05:38:38 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
|
|
|
evas_object_event_callback_call(eo_child, child,
|
|
|
|
EVAS_CALLBACK_HOLD, evt,
|
2016-08-25 00:03:45 -07:00
|
|
|
event_id, EFL_EVENT_HOLD);
|
2012-10-26 05:44:52 -07:00
|
|
|
if (src->layer->evas->delete_me) break;
|
|
|
|
}
|
2012-10-25 08:12:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-05-27 04:06:06 -07:00
|
|
|
_evas_event_source_wheel_events(Evas_Object *eo_obj, Evas *eo_e,
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer *parent_ev, int event_id)
|
2012-10-25 08:12:54 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-25 08:12:54 -07:00
|
|
|
Evas_Object *eo_src = _evas_object_image_source_get(eo_obj);
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *src = efl_data_scope_get(eo_src, EFL_CANVAS_OBJECT_CLASS);
|
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-10 19:58:42 -07:00
|
|
|
Evas_Object_Protected_Data *child;
|
|
|
|
Evas_Object *eo_child;
|
|
|
|
Eina_List *copy, *l;
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev;
|
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-10 19:58:42 -07:00
|
|
|
Eina_Vector2 point;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
|
|
|
if (obj->delete_me || src->delete_me || obj->layer->evas->is_frozen) return;
|
|
|
|
|
2017-12-10 21:50:22 -08:00
|
|
|
evt = efl_duplicate(parent_ev);
|
2016-08-25 03:20:10 -07:00
|
|
|
ev = efl_data_scope_get(evt, EFL_INPUT_POINTER_CLASS);
|
2016-08-17 04:29:39 -07:00
|
|
|
if (!ev) return;
|
|
|
|
|
2016-10-21 05:25:41 -07:00
|
|
|
pdata = _evas_pointer_data_by_device_get(e, ev->device);
|
|
|
|
if (!pdata) return;
|
|
|
|
|
2016-08-10 19:58:42 -07:00
|
|
|
_transform_to_src_space_f(obj, src, &ev->cur);
|
|
|
|
point = ev->cur;
|
2016-08-17 04:29:39 -07:00
|
|
|
ev->source = eo_obj;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2016-08-10 19:58:42 -07:00
|
|
|
copy = evas_event_list_copy(src->proxy->src_event_in);
|
2012-10-26 05:44:52 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_child)
|
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
|
|
|
|
2012-10-26 05:44:52 -07:00
|
|
|
if (src->delete_me) return;
|
2016-08-15 06:44:41 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
2017-01-01 22:17:40 -08:00
|
|
|
//FIXME: When object is deleted in the src_event_in list,
|
|
|
|
//the src_event_in list should be updated. But now there is no way.
|
|
|
|
//So add checking NULL logic, please delete it if you make a better way.
|
|
|
|
if (!child) continue;
|
|
|
|
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, child);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2016-08-10 19:58:42 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_child, child, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_child, child, EVAS_CALLBACK_MOUSE_WHEEL, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_WHEEL);
|
2012-10-26 05:44:52 -07:00
|
|
|
if (e->delete_me) break;
|
|
|
|
}
|
|
|
|
eina_list_free(copy);
|
2016-08-17 04:29:39 -07:00
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2012-10-25 08:12:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-08-17 22:54:54 -07:00
|
|
|
_evas_event_source_multi_down_events(Evas_Object_Protected_Data *obj, Evas_Public_Data *e,
|
2016-10-21 05:25:41 -07:00
|
|
|
Efl_Input_Pointer *parent_ev, Evas_Pointer_Data *pdata,
|
|
|
|
int event_id)
|
2012-10-25 08:12:54 -07:00
|
|
|
{
|
2016-08-17 22:54:54 -07:00
|
|
|
Evas_Object *eo_src = _evas_object_image_source_get(obj->object);
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *src = efl_data_scope_get(eo_src, EFL_CANVAS_OBJECT_CLASS);
|
2016-08-17 22:54:54 -07:00
|
|
|
Evas_Object_Protected_Data *child;
|
|
|
|
Evas_Object *eo_child;
|
|
|
|
Eina_List *copy, *l;
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev;
|
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-17 22:54:54 -07:00
|
|
|
Eina_Vector2 point;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
2016-08-17 22:54:54 -07:00
|
|
|
int addgrab = 0;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
|
|
|
if (obj->delete_me || src->delete_me || obj->layer->evas->is_frozen) return;
|
|
|
|
|
2017-12-10 21:50:22 -08:00
|
|
|
evt = efl_duplicate(parent_ev);
|
2016-08-25 03:20:10 -07:00
|
|
|
ev = efl_data_scope_get(evt, EFL_INPUT_POINTER_CLASS);
|
2016-08-17 22:54:54 -07:00
|
|
|
if (!ev) return;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2016-08-17 22:54:54 -07:00
|
|
|
_transform_to_src_space_f(obj, src, &ev->cur);
|
|
|
|
point = ev->cur;
|
|
|
|
ev->source = obj->object;
|
|
|
|
ev->action = EFL_POINTER_ACTION_DOWN;
|
2012-10-26 05:44:52 -07:00
|
|
|
|
2019-04-25 21:24:01 -07:00
|
|
|
if (pdata->seat->mouse_grabbed == 0)
|
|
|
|
{
|
|
|
|
if (pdata->seat->downs > 1) addgrab = pdata->seat->downs - 1;
|
|
|
|
}
|
2012-10-26 05:44:52 -07:00
|
|
|
|
2013-01-16 23:21:06 -08:00
|
|
|
EINA_LIST_FOREACH(src->proxy->src_event_in, l, eo_child)
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, child);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (obj_pdata->pointer_mode != EVAS_OBJECT_POINTER_MODE_NOGRAB)
|
|
|
|
{
|
|
|
|
obj_pdata->mouse_grabbed += (addgrab + 1);
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->mouse_grabbed += (addgrab + 1);
|
2012-10-26 05:44:52 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-17 22:54:54 -07:00
|
|
|
copy = evas_event_list_copy(src->proxy->src_event_in);
|
2012-10-26 05:44:52 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_child)
|
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, child);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2016-08-17 22:54:54 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_child, child, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(obj->object, obj, EVAS_CALLBACK_MULTI_DOWN, evt,
|
|
|
|
event_id, EFL_EVENT_FINGER_DOWN);
|
2012-10-26 05:44:52 -07:00
|
|
|
if (e->delete_me) break;
|
|
|
|
}
|
2016-08-17 22:54:54 -07:00
|
|
|
eina_list_free(copy);
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2012-10-25 08:12:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-08-17 22:54:54 -07:00
|
|
|
_evas_event_source_multi_up_events(Evas_Object_Protected_Data *obj, Evas_Public_Data *e,
|
2016-10-21 05:25:41 -07:00
|
|
|
Efl_Input_Pointer *parent_ev, Evas_Pointer_Data *pdata,
|
|
|
|
int event_id)
|
2012-10-25 08:12:54 -07:00
|
|
|
{
|
2016-08-17 22:54:54 -07:00
|
|
|
Evas_Object *eo_src = _evas_object_image_source_get(obj->object);
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *src = efl_data_scope_get(eo_src, EFL_CANVAS_OBJECT_CLASS);
|
2016-08-17 22:54:54 -07:00
|
|
|
Evas_Object_Protected_Data *child;
|
|
|
|
Evas_Object *eo_child;
|
|
|
|
Eina_List *copy, *l;
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev;
|
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-17 22:54:54 -07:00
|
|
|
Eina_Vector2 point;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
|
|
|
if (obj->delete_me || src->delete_me || obj->layer->evas->is_frozen) return;
|
|
|
|
|
2017-12-10 21:50:22 -08:00
|
|
|
evt = efl_duplicate(parent_ev);
|
2016-08-25 03:20:10 -07:00
|
|
|
ev = efl_data_scope_get(evt, EFL_INPUT_POINTER_CLASS);
|
2016-08-17 22:54:54 -07:00
|
|
|
if (!ev) return;
|
2012-10-26 05:44:52 -07:00
|
|
|
|
2016-08-17 22:54:54 -07:00
|
|
|
_transform_to_src_space_f(obj, src, &ev->cur);
|
|
|
|
point = ev->cur;
|
|
|
|
ev->source = obj->object;
|
|
|
|
ev->action = EFL_POINTER_ACTION_UP;
|
2012-10-26 05:44:52 -07:00
|
|
|
|
2016-08-17 22:54:54 -07:00
|
|
|
copy = evas_event_list_copy(src->proxy->src_event_in);
|
2012-10-26 05:44:52 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_child)
|
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
2016-10-21 05:25:41 -07:00
|
|
|
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, child);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_AUTOGRAB) ||
|
2018-10-16 22:26:23 -07:00
|
|
|
(obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)) &&
|
2016-10-21 05:25:41 -07:00
|
|
|
(obj_pdata->mouse_grabbed > 0))
|
|
|
|
{
|
|
|
|
obj_pdata->mouse_grabbed--;
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->mouse_grabbed--;
|
2012-10-26 05:44:52 -07:00
|
|
|
}
|
2016-08-17 22:54:54 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_child, child, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(obj->object, obj, EVAS_CALLBACK_MULTI_UP, evt,
|
|
|
|
event_id, EFL_EVENT_FINGER_UP);
|
2012-10-26 05:44:52 -07:00
|
|
|
if (e->delete_me || e->is_frozen) break;
|
|
|
|
}
|
|
|
|
eina_list_free(copy);
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2012-10-25 08:12:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-08-17 23:33:36 -07:00
|
|
|
_evas_event_source_multi_move_events(Evas_Object_Protected_Data *obj, Evas_Public_Data *e,
|
2016-10-21 05:25:41 -07:00
|
|
|
Efl_Input_Pointer *parent_ev, Evas_Pointer_Data *pdata,
|
|
|
|
int event_id)
|
2012-10-25 08:12:54 -07:00
|
|
|
{
|
2016-08-17 23:33:36 -07:00
|
|
|
Evas_Object *eo_src = _evas_object_image_source_get(obj->object);
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *src = efl_data_scope_get(eo_src, EFL_CANVAS_OBJECT_CLASS);
|
2016-08-17 23:33:36 -07:00
|
|
|
Evas_Object_Protected_Data *child;
|
|
|
|
Evas_Object *eo_child;
|
|
|
|
Eina_List *copy, *l;
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev;
|
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-17 23:33:36 -07:00
|
|
|
Eina_Vector2 point;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
2016-08-17 23:33:36 -07:00
|
|
|
Evas *eo_e = e->evas;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2012-10-26 05:44:52 -07:00
|
|
|
if (obj->delete_me || src->delete_me || e->is_frozen) return;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2017-12-10 21:50:22 -08:00
|
|
|
evt = efl_duplicate(parent_ev);
|
2016-08-25 03:20:10 -07:00
|
|
|
ev = efl_data_scope_get(evt, EFL_INPUT_POINTER_CLASS);
|
2016-08-17 23:33:36 -07:00
|
|
|
if (!ev) return;
|
2012-10-26 05:44:52 -07:00
|
|
|
|
2016-08-17 23:33:36 -07:00
|
|
|
_transform_to_src_space_f(obj, src, &ev->cur);
|
|
|
|
point = ev->cur;
|
|
|
|
ev->source = obj->object;
|
|
|
|
ev->action = EFL_POINTER_ACTION_UP;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
/* Why a new event id here? Other 'source' events keep the same id. */
|
|
|
|
event_id = _evas_object_event_new();
|
2012-10-26 05:44:52 -07:00
|
|
|
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->mouse_grabbed > 0)
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2016-08-17 23:33:36 -07:00
|
|
|
copy = evas_event_list_copy(src->proxy->src_event_in);
|
2012-10-26 05:44:52 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_child)
|
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, child);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2017-06-16 12:03:09 -07:00
|
|
|
if (_evas_event_object_pointer_allow(eo_child, child, obj_pdata))
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2016-08-17 23:33:36 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_child, child, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(obj->object, obj, EVAS_CALLBACK_MULTI_MOVE, evt,
|
|
|
|
event_id, EFL_EVENT_FINGER_MOVE);
|
2012-10-26 05:44:52 -07:00
|
|
|
if (e->delete_me || e->is_frozen) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
eina_list_free(copy);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Eina_List *ins = NULL;
|
|
|
|
|
|
|
|
if (src->is_smart)
|
|
|
|
{
|
|
|
|
int no_rep = 0;
|
2016-08-17 23:33:36 -07:00
|
|
|
ins = _evas_event_object_list_raw_in_get
|
2017-06-14 12:42:25 -07:00
|
|
|
(eo_e, ins, evas_object_smart_members_get_direct(eo_src), NULL, NULL,
|
2019-06-15 01:38:06 -07:00
|
|
|
ev->cur.x, ev->cur.y, &no_rep, EINA_TRUE, EINA_FALSE);
|
evas: add new event_grabber smart-ish object
adding an "event rect" is a common use case for rectangles, but I needed
a smarter event rect so I sent one off to school and it came back like this.
an event_grabber is a smart object which functions like a normal event rect
which has color(0,0,0,0), but with an important difference: it can have smart
members. event propagation works differently for an event_grabber:
normal:
event -> layer -> smart(obj1,obj2,obj3) ->(?) other objects
in this case, obj1,obj2,obj3 are all "inside" the smart object and their stacking
will always be considered as being inside the smart object. rendering is also
tied to the smart object in this case, as is clipping.
an event which reaches a smart object will be sent to the objects inside,
and then may continue through the smart object if there are no objects which
block repeating.
event_grabber:
event -> layer -> event_grabber -> obj1,obj2,obj3 -> STOP
in this case, obj1,obj2,obj3 are unmodified after being added to the event_grabber
and can be stacked, rendered, and clipped completely independently of the
event_grabber.
the event_grabber is considered an "event_parent" for this case. member objects
are not "inside" the event_grabber, and they are unable to receive events on
their own. instead, the event_grabber, which must be stacked above all its
members, receives events and propagates them top->down through its member objects.
if none of the member objects block the repeat of an event then the event will
still be blocked from further propagation past the event_grabber.
object lifetimes are independent of the event_grabber; deleting the event_grabber
has no effect on its members.
@feature
2017-06-09 17:16:08 -07:00
|
|
|
}
|
|
|
|
if (src->is_event_parent)
|
|
|
|
{
|
|
|
|
int no_rep = 0;
|
|
|
|
ins = _evas_event_object_list_raw_in_get
|
2017-06-14 12:42:25 -07:00
|
|
|
(eo_e, ins, NULL, evas_object_event_grabber_members_list(eo_src), NULL,
|
2019-06-15 01:38:06 -07:00
|
|
|
ev->cur.x, ev->cur.y, &no_rep, EINA_TRUE, EINA_FALSE);
|
2012-10-26 05:44:52 -07:00
|
|
|
}
|
|
|
|
else
|
2012-10-29 22:01:20 -07:00
|
|
|
ins = eina_list_append(ins, eo_src);
|
2016-08-17 23:33:36 -07:00
|
|
|
|
|
|
|
copy = evas_event_list_copy(src->proxy->src_event_in);
|
2012-10-26 05:44:52 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_child)
|
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
2016-08-17 23:33:36 -07:00
|
|
|
ev->cur = point;
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, child);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2012-10-26 05:44:52 -07:00
|
|
|
|
2016-08-17 23:33:36 -07:00
|
|
|
if (evas_object_is_in_output_rect(eo_child, child, ev->cur.x, ev->cur.y, 1, 1) &&
|
2017-06-16 12:03:09 -07:00
|
|
|
_evas_event_object_pointer_allow(eo_child, child, obj_pdata) &&
|
2017-06-16 12:03:09 -07:00
|
|
|
_evas_event_object_pointer_allow_precise(eo_child, child, ev->cur.x, ev->cur.y, ins))
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_child, child, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(obj->object, obj, EVAS_CALLBACK_MULTI_MOVE, evt,
|
|
|
|
event_id, EFL_EVENT_FINGER_MOVE);
|
2012-10-26 05:44:52 -07:00
|
|
|
if (e->delete_me || e->is_frozen) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
eina_list_free(copy);
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->mouse_grabbed == 0)
|
2012-10-26 05:44:52 -07:00
|
|
|
{
|
2014-08-26 20:15:33 -07:00
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, src->proxy, Evas_Object_Proxy_Data, proxy_write)
|
|
|
|
{
|
|
|
|
eina_list_free(proxy_write->src_event_in);
|
|
|
|
proxy_write->src_event_in = ins;
|
|
|
|
}
|
|
|
|
EINA_COW_WRITE_END(evas_object_proxy_cow, src->proxy, proxy_write);
|
2012-10-26 05:44:52 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
eina_list_free(ins);
|
|
|
|
}
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2012-10-25 08:12:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-05-27 04:06:06 -07:00
|
|
|
_evas_event_source_mouse_in_events(Evas_Object *eo_obj, Evas *eo_e,
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer *parent_ev, int event_id)
|
2012-10-25 08:12:54 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-25 08:12:54 -07:00
|
|
|
Evas_Object *eo_src = _evas_object_image_source_get(eo_obj);
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *src = efl_data_scope_get(eo_src, EFL_CANVAS_OBJECT_CLASS);
|
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-17 20:01:39 -07:00
|
|
|
Evas_Object_Protected_Data *child;
|
2013-01-16 23:21:06 -08:00
|
|
|
Evas_Object *eo_child;
|
2016-08-17 20:01:39 -07:00
|
|
|
Eina_List *ins = NULL, *l;
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev;
|
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-17 20:01:39 -07:00
|
|
|
Eina_Vector2 point;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2012-10-28 07:48:43 -07:00
|
|
|
if (obj->delete_me || src->delete_me || e->is_frozen) return;
|
2017-12-10 21:50:22 -08:00
|
|
|
evt = efl_duplicate(parent_ev);
|
2016-10-21 05:25:41 -07:00
|
|
|
|
2016-08-25 03:20:10 -07:00
|
|
|
ev = efl_data_scope_get(evt, EFL_INPUT_POINTER_CLASS);
|
2016-08-17 20:01:39 -07:00
|
|
|
if (!ev) return;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2016-10-21 05:25:41 -07:00
|
|
|
pdata = _evas_pointer_data_by_device_get(e, ev->device);
|
|
|
|
if (!pdata) return;
|
|
|
|
|
2016-08-17 20:01:39 -07:00
|
|
|
_transform_to_src_space_f(obj, src, &ev->cur);
|
|
|
|
point = ev->cur;
|
|
|
|
ev->source = eo_obj;
|
|
|
|
ev->action = EFL_POINTER_ACTION_IN;
|
2013-01-03 17:55:07 -08:00
|
|
|
|
2012-10-28 07:48:43 -07:00
|
|
|
if (src->is_smart)
|
|
|
|
{
|
|
|
|
int no_rep = 0;
|
2016-08-17 20:01:39 -07:00
|
|
|
ins = _evas_event_object_list_raw_in_get(eo_e, ins, evas_object_smart_members_get_direct(eo_src),
|
2019-06-15 01:38:06 -07:00
|
|
|
NULL, NULL, ev->cur.x, ev->cur.y, &no_rep, EINA_TRUE, EINA_FALSE);
|
evas: add new event_grabber smart-ish object
adding an "event rect" is a common use case for rectangles, but I needed
a smarter event rect so I sent one off to school and it came back like this.
an event_grabber is a smart object which functions like a normal event rect
which has color(0,0,0,0), but with an important difference: it can have smart
members. event propagation works differently for an event_grabber:
normal:
event -> layer -> smart(obj1,obj2,obj3) ->(?) other objects
in this case, obj1,obj2,obj3 are all "inside" the smart object and their stacking
will always be considered as being inside the smart object. rendering is also
tied to the smart object in this case, as is clipping.
an event which reaches a smart object will be sent to the objects inside,
and then may continue through the smart object if there are no objects which
block repeating.
event_grabber:
event -> layer -> event_grabber -> obj1,obj2,obj3 -> STOP
in this case, obj1,obj2,obj3 are unmodified after being added to the event_grabber
and can be stacked, rendered, and clipped completely independently of the
event_grabber.
the event_grabber is considered an "event_parent" for this case. member objects
are not "inside" the event_grabber, and they are unable to receive events on
their own. instead, the event_grabber, which must be stacked above all its
members, receives events and propagates them top->down through its member objects.
if none of the member objects block the repeat of an event then the event will
still be blocked from further propagation past the event_grabber.
object lifetimes are independent of the event_grabber; deleting the event_grabber
has no effect on its members.
@feature
2017-06-09 17:16:08 -07:00
|
|
|
|
|
|
|
}
|
|
|
|
else if (src->is_event_parent)
|
|
|
|
{
|
|
|
|
int no_rep = 0;
|
|
|
|
ins = _evas_event_object_list_raw_in_get(eo_e, ins, NULL, evas_object_event_grabber_members_list(eo_src),
|
2019-06-15 01:38:06 -07:00
|
|
|
NULL, ev->cur.x, ev->cur.y, &no_rep, EINA_TRUE, EINA_FALSE);
|
2012-10-29 22:01:20 -07:00
|
|
|
|
2012-10-28 07:48:43 -07:00
|
|
|
}
|
|
|
|
else
|
2012-10-29 22:01:20 -07:00
|
|
|
ins = eina_list_append(ins, eo_src);
|
2012-10-28 07:48:43 -07:00
|
|
|
|
|
|
|
EINA_LIST_FOREACH(ins, l, eo_child)
|
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
|
|
|
|
2016-08-17 20:01:39 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, child);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2013-01-16 23:21:06 -08:00
|
|
|
if (!eina_list_data_find(src->proxy->src_event_in, eo_child))
|
2012-10-28 07:48:43 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
if (obj_pdata->mouse_in) continue;
|
evas_events: Fix to set mouse_in state to all pointers in the seat.
Summary:
mouse coordinate is set by seat.
Therefore, mouse_in state should be set based on seat.
As a result, mouse_in state of all pointers in the seat should be
updated at the same time.
Reviewers: eagleeye, devilhorns, zmike
Reviewed By: eagleeye, devilhorns, zmike
Subscribers: devilhorns, Hermet, kimcinoo, cedric, iscaro, zmike, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6699
2018-08-02 02:16:46 -07:00
|
|
|
_evas_event_mouse_in_set(pdata->seat, child, 1);
|
2016-08-17 20:01:39 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_child, child, &ev->cur, obj_pdata->mouse_grabbed);
|
2017-06-16 12:03:09 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_IN;
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_child, child, EVAS_CALLBACK_MOUSE_IN, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_IN);
|
2017-07-11 23:43:41 -07:00
|
|
|
if ((ev->cur.x != ev->prev.x) &&
|
|
|
|
(ev->cur.y != ev->prev.y))
|
|
|
|
{
|
|
|
|
ev->action = EFL_POINTER_ACTION_MOVE;
|
|
|
|
evas_object_event_callback_call(eo_child, child, EVAS_CALLBACK_MOUSE_MOVE, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_MOVE);
|
|
|
|
}
|
2012-10-28 07:48:43 -07:00
|
|
|
if (e->delete_me || e->is_frozen) break;
|
|
|
|
}
|
|
|
|
}
|
2013-01-16 23:21:06 -08:00
|
|
|
|
2013-01-20 19:12:39 -08:00
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, src->proxy, Evas_Object_Proxy_Data, proxy_write)
|
|
|
|
{
|
|
|
|
eina_list_free(proxy_write->src_event_in);
|
|
|
|
proxy_write->src_event_in = ins;
|
|
|
|
}
|
|
|
|
EINA_COW_WRITE_END(evas_object_proxy_cow, src->proxy, proxy_write);
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2012-10-25 08:12:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-05-27 04:06:06 -07:00
|
|
|
_evas_event_source_mouse_out_events(Evas_Object *eo_obj, Evas *eo_e,
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer *parent_ev, int event_id)
|
2012-10-23 21:36:02 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-25 08:12:54 -07:00
|
|
|
Evas_Object *eo_src = _evas_object_image_source_get(eo_obj);
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *src = efl_data_scope_get(eo_src, EFL_CANVAS_OBJECT_CLASS);
|
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-17 20:01:39 -07:00
|
|
|
Evas_Object_Protected_Data *child;
|
2013-01-16 23:21:06 -08:00
|
|
|
Evas_Object *eo_child;
|
2016-08-17 20:01:39 -07:00
|
|
|
Eina_List *copy, *l;
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev;
|
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-17 20:01:39 -07:00
|
|
|
Eina_Vector2 point;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2012-10-28 07:48:43 -07:00
|
|
|
if (obj->delete_me || src->delete_me || e->is_frozen) return;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2017-12-10 21:50:22 -08:00
|
|
|
evt = efl_duplicate(parent_ev);
|
2016-08-25 03:20:10 -07:00
|
|
|
ev = efl_data_scope_get(evt, EFL_INPUT_POINTER_CLASS);
|
2016-08-17 20:01:39 -07:00
|
|
|
if (!ev) return;
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2016-10-21 05:25:41 -07:00
|
|
|
pdata = _evas_pointer_data_by_device_get(e, ev->device);
|
|
|
|
if (!pdata) return;
|
2016-08-17 20:01:39 -07:00
|
|
|
_transform_to_src_space_f(obj, src, &ev->cur);
|
|
|
|
point = ev->cur;
|
|
|
|
ev->source = eo_obj;
|
|
|
|
ev->action = EFL_POINTER_ACTION_OUT;
|
2013-01-03 17:55:07 -08:00
|
|
|
|
2013-01-16 23:21:06 -08:00
|
|
|
copy = evas_event_list_copy(src->proxy->src_event_in);
|
2012-10-28 07:48:43 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_child)
|
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
2016-08-17 20:01:39 -07:00
|
|
|
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, child);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!obj_pdata->mouse_in) continue;
|
evas_events: Fix to set mouse_in state to all pointers in the seat.
Summary:
mouse coordinate is set by seat.
Therefore, mouse_in state should be set based on seat.
As a result, mouse_in state of all pointers in the seat should be
updated at the same time.
Reviewers: eagleeye, devilhorns, zmike
Reviewed By: eagleeye, devilhorns, zmike
Subscribers: devilhorns, Hermet, kimcinoo, cedric, iscaro, zmike, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6699
2018-08-02 02:16:46 -07:00
|
|
|
_evas_event_mouse_in_set(pdata->seat, child, 0);
|
2012-10-28 07:48:43 -07:00
|
|
|
if (child->delete_me) continue;
|
|
|
|
|
2016-08-17 20:01:39 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_child, child, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_OUT, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_OUT);
|
2012-10-28 07:48:43 -07:00
|
|
|
if (e->is_frozen) continue;
|
|
|
|
}
|
|
|
|
eina_list_free(copy);
|
2013-01-16 23:21:06 -08:00
|
|
|
|
2013-01-20 19:12:39 -08:00
|
|
|
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, src->proxy, Evas_Object_Proxy_Data, proxy_write)
|
|
|
|
proxy_write->src_event_in = eina_list_free(proxy_write->src_event_in);
|
|
|
|
EINA_COW_WRITE_END(evas_object_proxy_cow, src->proxy, proxy_write);
|
2012-10-25 08:12:54 -07:00
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2012-10-23 21:36:02 -07:00
|
|
|
}
|
|
|
|
|
2012-01-17 00:35:32 -08:00
|
|
|
static Eina_List *
|
2012-10-08 18:58:41 -07:00
|
|
|
_evas_event_object_list_in_get(Evas *eo_e, Eina_List *in,
|
2017-06-14 12:20:36 -07:00
|
|
|
const Eina_Inlist *ilist,
|
|
|
|
const Eina_List *list,
|
|
|
|
Evas_Object *stop,
|
2012-10-23 01:44:11 -07:00
|
|
|
int x, int y, int *no_rep, Eina_Bool source)
|
2012-01-17 00:35:32 -08:00
|
|
|
{
|
2017-06-14 12:42:25 -07:00
|
|
|
return _evas_event_object_list_raw_in_get(eo_e, in, ilist, list, stop, x, y,
|
2019-06-15 01:38:06 -07:00
|
|
|
no_rep, source, EINA_FALSE);
|
2012-01-17 00:35:32 -08:00
|
|
|
}
|
|
|
|
|
2013-10-12 20:55:28 -07:00
|
|
|
static Eina_List *
|
|
|
|
_evas_event_objects_event_list_no_frozen_check(Evas *eo_e, Evas_Object *stop, int x, int y)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2008-10-17 04:23:18 -07:00
|
|
|
Evas_Layer *lay;
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *in = NULL;
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2013-10-12 20:55:28 -07:00
|
|
|
if (!e->layers) return NULL;
|
2013-04-29 07:00:21 -07:00
|
|
|
|
2016-07-05 06:38:02 -07:00
|
|
|
D("@@@@@ layer count = %i\n", eina_inlist_count(EINA_INLIST_GET(e->layers)));
|
2008-10-21 05:19:57 -07:00
|
|
|
EINA_INLIST_REVERSE_FOREACH((EINA_INLIST_GET(e->layers)), lay)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2012-06-12 23:08:01 -07:00
|
|
|
int no_rep = 0;
|
2016-07-05 06:38:02 -07:00
|
|
|
D("############################# check layer %i\n", lay->layer);
|
2012-10-08 18:58:41 -07:00
|
|
|
in = _evas_event_object_list_in_get(eo_e, in,
|
2017-06-14 12:42:25 -07:00
|
|
|
EINA_INLIST_GET(lay->objects), NULL,
|
2012-10-23 01:44:11 -07:00
|
|
|
stop, x, y, &no_rep, EINA_FALSE);
|
2012-06-12 23:08:01 -07:00
|
|
|
if (no_rep) return in;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
return in;
|
|
|
|
}
|
|
|
|
|
2014-03-11 23:53:00 -07:00
|
|
|
EOLIAN Eina_List*
|
2014-06-26 14:29:46 -07:00
|
|
|
_evas_canvas_tree_objects_at_xy_get(Eo *eo_e, Evas_Public_Data *e EINA_UNUSED, Evas_Object *stop, int x, int y)
|
2013-10-12 20:55:28 -07:00
|
|
|
{
|
2014-03-11 23:53:00 -07:00
|
|
|
return _evas_event_objects_event_list_no_frozen_check(eo_e, stop, x, y);
|
2013-10-12 20:55:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Eina_List *
|
|
|
|
evas_event_objects_event_list(Evas *eo_e, Evas_Object *stop, int x, int y)
|
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2013-10-12 20:55:28 -07:00
|
|
|
|
|
|
|
if ((!e->layers) || (e->is_frozen)) return NULL;
|
2019-06-20 03:13:37 -07:00
|
|
|
D("------------------------------GET EVETNS AT ............... %i %i\n", x, y);
|
2013-10-12 20:55:28 -07:00
|
|
|
return _evas_event_objects_event_list_no_frozen_check(eo_e, stop, x, y);
|
|
|
|
}
|
|
|
|
|
2008-10-21 09:31:05 -07:00
|
|
|
static Eina_List *
|
|
|
|
evas_event_list_copy(Eina_List *list)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *l, *new_l = NULL;
|
|
|
|
const void *data;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2008-10-21 09:31:05 -07:00
|
|
|
EINA_LIST_FOREACH(list, l, data)
|
|
|
|
new_l = eina_list_append(new_l, data);
|
2002-11-08 00:02:15 -08:00
|
|
|
return new_l;
|
|
|
|
}
|
|
|
|
/* public functions */
|
|
|
|
|
2014-03-11 23:53:00 -07:00
|
|
|
EOLIAN void
|
2014-06-26 14:29:46 -07:00
|
|
|
_evas_canvas_event_default_flags_set(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, Evas_Event_Flags flags)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2011-12-16 01:24:18 -08:00
|
|
|
e->default_event_flags = flags;
|
|
|
|
}
|
|
|
|
|
2014-03-11 23:53:00 -07:00
|
|
|
EOLIAN Evas_Event_Flags
|
2018-04-17 11:09:44 -07:00
|
|
|
_evas_canvas_event_default_flags_get(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
|
2011-12-16 01:24:18 -08:00
|
|
|
{
|
2014-03-11 23:53:00 -07:00
|
|
|
return e->default_event_flags;
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
_canvas_event_thaw_eval_internal(Eo *eo_e, Evas_Public_Data *e)
|
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata = _evas_pointer_data_by_device_get(e, NULL);
|
|
|
|
if (!pdata) return;
|
2017-06-02 15:23:45 -07:00
|
|
|
_canvas_event_feed_mouse_move_legacy(eo_e, e, pdata->seat->x, pdata->seat->y,
|
2016-08-18 00:28:55 -07:00
|
|
|
e->last_timestamp, NULL);
|
2011-12-16 01:24:18 -08:00
|
|
|
}
|
|
|
|
|
2006-01-06 15:05:17 -08:00
|
|
|
EAPI void
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_freeze(Evas *eo_e)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2016-08-10 07:23:04 -07:00
|
|
|
efl_event_freeze(eo_e);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2006-01-06 15:05:17 -08:00
|
|
|
EAPI void
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_thaw(Evas *eo_e)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2016-08-10 07:23:04 -07:00
|
|
|
efl_event_thaw(eo_e);
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
|
|
|
|
2014-09-06 06:08:17 -07:00
|
|
|
EOLIAN void
|
2016-08-10 07:23:04 -07:00
|
|
|
_evas_canvas_efl_object_event_freeze(Eo *eo_e, Evas_Public_Data *e)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
efl_event_freeze(efl_super(eo_e, EVAS_CANVAS_CLASS));
|
2012-10-08 18:58:41 -07:00
|
|
|
e->is_frozen = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2014-09-06 06:08:17 -07:00
|
|
|
EOLIAN void
|
2016-08-10 07:23:04 -07:00
|
|
|
_evas_canvas_efl_object_event_thaw(Eo *eo_e, Evas_Public_Data *e)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
|
|
|
int fcount = -1;
|
2016-08-15 06:44:41 -07:00
|
|
|
efl_event_thaw(efl_super(eo_e, EVAS_CANVAS_CLASS));
|
|
|
|
fcount = efl_event_freeze_count_get(efl_super(eo_e, EVAS_CANVAS_CLASS));
|
2012-10-08 18:58:41 -07:00
|
|
|
if (0 == fcount)
|
2005-07-22 03:28:11 -07:00
|
|
|
{
|
2011-09-21 03:35:03 -07:00
|
|
|
Evas_Layer *lay;
|
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
e->is_frozen = EINA_FALSE;
|
2011-09-21 03:35:03 -07:00
|
|
|
EINA_INLIST_FOREACH((EINA_INLIST_GET(e->layers)), lay)
|
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj;
|
2011-09-21 03:35:03 -07:00
|
|
|
|
|
|
|
EINA_INLIST_FOREACH(lay->objects, obj)
|
|
|
|
{
|
2013-04-06 22:00:10 -07:00
|
|
|
evas_object_clip_recalc(obj);
|
|
|
|
evas_object_recalc_clippees(obj);
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
|
|
|
}
|
2012-10-08 18:58:41 -07:00
|
|
|
|
|
|
|
_canvas_event_thaw_eval_internal(eo_e, e);
|
2005-07-22 03:28:11 -07:00
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2006-01-06 15:05:17 -08:00
|
|
|
EAPI int
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_freeze_get(const Evas *eo_e)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2016-08-25 19:27:37 -07:00
|
|
|
return efl_event_freeze_count_get(eo_e);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2011-05-27 01:26:11 -07:00
|
|
|
EAPI void
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_thaw_eval(Evas *eo_e)
|
2011-05-27 01:26:11 -07:00
|
|
|
{
|
2016-08-25 19:27:37 -07:00
|
|
|
if (!evas_event_freeze_get(eo_e))
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-08-25 19:27:37 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2012-10-08 18:58:41 -07:00
|
|
|
_canvas_event_thaw_eval_internal(eo_e, e);
|
|
|
|
}
|
2011-05-27 01:26:11 -07:00
|
|
|
}
|
2009-09-17 15:38:10 -07:00
|
|
|
|
2016-05-27 00:21:13 -07:00
|
|
|
static void
|
2016-08-25 03:20:10 -07:00
|
|
|
_canvas_event_feed_mouse_down_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data *ev)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer *evt;
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *l, *copy;
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object *eo_obj;
|
2016-08-17 04:29:39 -07:00
|
|
|
int event_id, b;
|
|
|
|
Evas *eo_e;
|
2011-12-12 21:59:36 -08:00
|
|
|
int addgrab = 0;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata;
|
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
2011-12-14 21:25:37 -08:00
|
|
|
|
2016-08-29 01:04:31 -07:00
|
|
|
static const int value_flags =
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TIMESTAMP) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_X) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_Y) |
|
2019-06-20 03:13:37 -07:00
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TOUCH_ID) |
|
2016-08-29 01:04:31 -07:00
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_BUTTON);
|
|
|
|
|
2016-08-17 04:29:39 -07:00
|
|
|
if (!e || !ev) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
2016-08-17 04:29:39 -07:00
|
|
|
|
2016-10-21 05:25:41 -07:00
|
|
|
pdata = _evas_pointer_data_by_device_get(e, ev->device);
|
|
|
|
if (!pdata) return;
|
|
|
|
|
2016-08-17 04:29:39 -07:00
|
|
|
b = ev->button;
|
|
|
|
DBG("ButtonEvent:down time=%u x=%d y=%d button=%d downs=%d",
|
2017-06-02 15:23:45 -07:00
|
|
|
ev->timestamp, pdata->seat->x, pdata->seat->y, b, pdata->seat->downs);
|
2002-11-08 00:02:15 -08:00
|
|
|
if ((b < 1) || (b > 32)) return;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2016-10-21 05:25:41 -07:00
|
|
|
pdata->button |= (1u << (b - 1));
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->downs++;
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
if (e->is_frozen) return;
|
2016-08-17 04:29:39 -07:00
|
|
|
e->last_timestamp = ev->timestamp;
|
|
|
|
eo_e = e->evas;
|
2016-08-25 00:03:45 -07:00
|
|
|
evt = ev->eo;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2016-08-17 04:29:39 -07:00
|
|
|
|
2017-06-02 15:23:45 -07:00
|
|
|
ev->cur.x = pdata->seat->x;
|
|
|
|
ev->cur.y = pdata->seat->y;
|
2016-08-17 04:29:39 -07:00
|
|
|
ev->modifiers = &(e->modifiers);
|
|
|
|
ev->locks = &(e->locks);
|
|
|
|
ev->event_flags = e->default_event_flags;
|
2019-06-20 03:13:37 -07:00
|
|
|
ev->touch_id = 0;
|
2016-08-29 01:04:31 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_DOWN;
|
|
|
|
ev->value_flags |= value_flags;
|
2016-08-17 04:29:39 -07:00
|
|
|
if (ev->device) efl_ref(ev->device);
|
2008-07-18 04:04:06 -07:00
|
|
|
|
2007-04-29 21:22:42 -07:00
|
|
|
_evas_walk(e);
|
From: EunMi Lee <eunmi15.lee@samsung.com>
Subject: [E-devel] [Patch] [Evas] Patch to provide information of
touched points
Hello,
I made a new patch to get information of current touched point instead
of Touch Event.
I added touch_points (Eina_List) to the Evas structure and it maintains touched points on the evas.
New touched point is added to the touch_points when we get Mouse_Down and Multi_Down,
touched point is updated when we get Mouse_Move and Mult_Move,
and touched point is removed when we get Mouse_Up and Multi_Up.
The each touch point has coordinate, id and state information as follows:
id - identifier. 0 for Mouse Event and device id for Multi Event. coordinate - (x, y) coordinate of point.
state - state of point. type is Evas_Touch_Point_State enum.
(EVAS_TOUCH_POINT_DOWN, EVAS_TOUCH_POINT_UP, EVAS_TOUCH_POINT_MOVE,
EVAS_TOUCH_POINT_STILL, EVAS_TOUCH_POINT_CANCEL)
There are 4 new APIs to get touch point's information as follows:
unsigned int evas_touch_point_list_count(Evas *e);
void evas_touch_point_list_nth_xy_get(Evas *e, unsigned int n, Evas_Coord *x, Evas_Coord *y);
int evas_touch_point_list_nth_id_get(Evas *e, unsigned int n);
Evas_Touch_Point_State evas_touch_point_list_nth_state_get(Evas *e, unsigned int n);
I added APIs to get each information instead of exposing whole
structure to make it easy to expand in the future as you mentioned in
the below e-mail :)
SVN revision: 64373
2011-10-24 22:03:50 -07:00
|
|
|
/* append new touch point to the touch point list */
|
2017-06-02 15:23:45 -07:00
|
|
|
_evas_touch_point_append(e->evas, 0, pdata->seat->x, pdata->seat->y);
|
2011-06-28 22:05:32 -07:00
|
|
|
/* If this is the first finger down, i.e no other fingers pressed,
|
|
|
|
* get a new event list, otherwise, keep the current grabbed list. */
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->mouse_grabbed == 0)
|
2011-06-28 22:05:32 -07:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
Eina_List *ins = evas_event_objects_event_list(eo_e,
|
2011-10-27 03:36:09 -07:00
|
|
|
NULL,
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->x,
|
|
|
|
pdata->seat->y);
|
2011-06-28 22:05:32 -07:00
|
|
|
/* free our old list of ins */
|
2017-07-28 08:46:01 -07:00
|
|
|
eina_list_free(pdata->seat->object.in);
|
2011-06-28 22:05:32 -07:00
|
|
|
/* and set up the new one */
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->object.in = ins;
|
2011-12-12 21:59:36 -08:00
|
|
|
/* adjust grabbed count by the nuymber of currently held down
|
|
|
|
* fingers/buttons */
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->downs > 1) addgrab = pdata->seat->downs - 1;
|
2011-06-28 22:05:32 -07:00
|
|
|
}
|
2017-06-02 15:23:45 -07:00
|
|
|
copy = evas_event_list_copy(pdata->seat->object.in);
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_obj)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_AUTOGRAB) ||
|
|
|
|
(obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN))
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
obj_pdata->mouse_grabbed += addgrab + 1;
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->mouse_grabbed += addgrab + 1;
|
2016-10-21 05:25:41 -07:00
|
|
|
if (obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)
|
2012-01-17 00:35:32 -08:00
|
|
|
{
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->nogrep++;
|
2012-01-17 00:35:32 -08:00
|
|
|
break;
|
|
|
|
}
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2011-09-25 19:45:06 -07:00
|
|
|
}
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_obj)
|
2011-09-25 19:45:06 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Mode pointer_mode;
|
2011-09-25 19:45:06 -07:00
|
|
|
if (obj->delete_me) continue;
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2017-06-02 15:23:45 -07:00
|
|
|
ev->cur.x = pdata->seat->x;
|
|
|
|
ev->cur.y = pdata->seat->y;
|
2016-10-21 05:25:41 -07:00
|
|
|
pointer_mode = obj_pdata->pointer_mode;
|
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_DOWN, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_DOWN);
|
2013-01-16 23:21:06 -08:00
|
|
|
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_source_mouse_down_events(eo_obj, eo_e, evt, pdata, event_id);
|
2012-10-25 21:41:59 -07:00
|
|
|
if (e->is_frozen || e->delete_me) break;
|
2016-10-21 05:25:41 -07:00
|
|
|
if (pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)
|
2012-01-17 00:35:32 -08:00
|
|
|
break;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2009-06-12 17:04:25 -07:00
|
|
|
if (copy) eina_list_free(copy);
|
2006-08-25 13:47:32 -07:00
|
|
|
e->last_mouse_down_counter++;
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
From: EunMi Lee <eunmi15.lee@samsung.com>
Subject: [E-devel] [Patch] [Evas] Patch to provide information of
touched points
Hello,
I made a new patch to get information of current touched point instead
of Touch Event.
I added touch_points (Eina_List) to the Evas structure and it maintains touched points on the evas.
New touched point is added to the touch_points when we get Mouse_Down and Multi_Down,
touched point is updated when we get Mouse_Move and Mult_Move,
and touched point is removed when we get Mouse_Up and Multi_Up.
The each touch point has coordinate, id and state information as follows:
id - identifier. 0 for Mouse Event and device id for Multi Event. coordinate - (x, y) coordinate of point.
state - state of point. type is Evas_Touch_Point_State enum.
(EVAS_TOUCH_POINT_DOWN, EVAS_TOUCH_POINT_UP, EVAS_TOUCH_POINT_MOVE,
EVAS_TOUCH_POINT_STILL, EVAS_TOUCH_POINT_CANCEL)
There are 4 new APIs to get touch point's information as follows:
unsigned int evas_touch_point_list_count(Evas *e);
void evas_touch_point_list_nth_xy_get(Evas *e, unsigned int n, Evas_Coord *x, Evas_Coord *y);
int evas_touch_point_list_nth_id_get(Evas *e, unsigned int n);
Evas_Touch_Point_State evas_touch_point_list_nth_state_get(Evas *e, unsigned int n);
I added APIs to get each information instead of exposing whole
structure to make it easy to expand in the future as you mentioned in
the below e-mail :)
SVN revision: 64373
2011-10-24 22:03:50 -07:00
|
|
|
/* update touch point's state to EVAS_TOUCH_POINT_STILL */
|
2017-06-02 15:23:45 -07:00
|
|
|
_evas_touch_point_update(eo_e, 0, pdata->seat->x, pdata->seat->y, EVAS_TOUCH_POINT_STILL);
|
2007-04-29 21:22:42 -07:00
|
|
|
_evas_unwalk(e);
|
2016-05-27 00:21:13 -07:00
|
|
|
|
2016-08-17 04:29:39 -07:00
|
|
|
if (ev->device) efl_unref(ev->device);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2017-02-16 02:34:08 -08:00
|
|
|
static void
|
2016-10-21 05:25:41 -07:00
|
|
|
_post_up_handle(Evas_Public_Data *e, Efl_Input_Pointer *parent_ev,
|
|
|
|
Evas_Pointer_Data *pdata)
|
2011-06-13 03:00:25 -07:00
|
|
|
{
|
|
|
|
Eina_List *l, *copy, *ins, *ll;
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev;
|
|
|
|
Efl_Input_Pointer *evt;
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object *eo_obj;
|
2016-08-17 04:29:39 -07:00
|
|
|
Evas *eo_e = e->evas;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
2016-08-18 21:33:11 -07:00
|
|
|
int event_id;
|
2011-09-21 03:35:03 -07:00
|
|
|
|
2016-08-17 04:29:39 -07:00
|
|
|
/* Duplicating UP event */
|
2017-12-10 21:50:22 -08:00
|
|
|
evt = efl_duplicate(parent_ev);
|
2016-08-25 03:20:10 -07:00
|
|
|
ev = efl_data_scope_get(evt, EFL_INPUT_POINTER_CLASS);
|
2017-02-16 02:34:08 -08:00
|
|
|
if (!ev) return;
|
2016-08-17 04:29:39 -07:00
|
|
|
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
event_id = _evas_object_event_new();
|
|
|
|
|
2016-08-17 04:29:39 -07:00
|
|
|
/* Actually we want an OUT */
|
|
|
|
ev->action = EFL_POINTER_ACTION_OUT;
|
2014-08-26 20:15:33 -07:00
|
|
|
|
2011-06-13 03:00:25 -07:00
|
|
|
/* get new list of ins */
|
2017-06-02 15:23:45 -07:00
|
|
|
ins = evas_event_objects_event_list(eo_e, NULL, pdata->seat->x, pdata->seat->y);
|
2011-06-13 03:00:25 -07:00
|
|
|
/* go thru old list of in objects */
|
2017-06-02 15:23:45 -07:00
|
|
|
copy = evas_event_list_copy(pdata->seat->object.in);
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(copy, ll, eo_obj)
|
2011-06-13 03:00:25 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2017-06-02 15:23:45 -07:00
|
|
|
if ((!eina_list_data_find(ins, eo_obj)) || (!pdata->seat->inside))
|
2011-06-13 03:00:25 -07:00
|
|
|
{
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!obj_pdata->mouse_in) continue;
|
evas_events: Fix to set mouse_in state to all pointers in the seat.
Summary:
mouse coordinate is set by seat.
Therefore, mouse_in state should be set based on seat.
As a result, mouse_in state of all pointers in the seat should be
updated at the same time.
Reviewers: eagleeye, devilhorns, zmike
Reviewed By: eagleeye, devilhorns, zmike
Subscribers: devilhorns, Hermet, kimcinoo, cedric, iscaro, zmike, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6699
2018-08-02 02:16:46 -07:00
|
|
|
_evas_event_mouse_in_set(pdata->seat, obj, 0);
|
2012-10-25 22:52:42 -07:00
|
|
|
if (!e->is_frozen)
|
2011-06-13 03:00:25 -07:00
|
|
|
{
|
2017-06-02 15:23:45 -07:00
|
|
|
ev->cur.x = pdata->seat->x;
|
|
|
|
ev->cur.y = pdata->seat->y;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_OUT, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_OUT);
|
2013-01-16 23:21:06 -08:00
|
|
|
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
|
2016-08-17 20:01:39 -07:00
|
|
|
_evas_event_source_mouse_out_events(eo_obj, eo_e, evt, event_id);
|
2012-10-25 22:52:42 -07:00
|
|
|
if (e->delete_me) break;
|
2011-06-13 03:00:25 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2011-09-21 03:35:03 -07:00
|
|
|
|
2013-11-28 00:00:35 -08:00
|
|
|
eina_list_free(copy);
|
|
|
|
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->inside)
|
2011-06-13 03:00:25 -07:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object *eo_obj_itr;
|
2011-09-21 03:35:03 -07:00
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2016-08-17 04:29:39 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_IN;
|
2011-09-21 03:35:03 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(ins, l, eo_obj_itr)
|
2011-06-13 03:00:25 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj_itr = efl_data_scope_get(eo_obj_itr, EFL_CANVAS_OBJECT_CLASS);
|
2017-06-02 15:23:45 -07:00
|
|
|
if (!eina_list_data_find(pdata->seat->object.in, eo_obj_itr))
|
2011-06-13 03:00:25 -07:00
|
|
|
{
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj_itr);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (obj_pdata->mouse_in) continue;
|
evas_events: Fix to set mouse_in state to all pointers in the seat.
Summary:
mouse coordinate is set by seat.
Therefore, mouse_in state should be set based on seat.
As a result, mouse_in state of all pointers in the seat should be
updated at the same time.
Reviewers: eagleeye, devilhorns, zmike
Reviewed By: eagleeye, devilhorns, zmike
Subscribers: devilhorns, Hermet, kimcinoo, cedric, iscaro, zmike, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6699
2018-08-02 02:16:46 -07:00
|
|
|
_evas_event_mouse_in_set(pdata->seat, obj_itr, 1);
|
2012-10-25 22:52:42 -07:00
|
|
|
if (e->is_frozen) continue;
|
2017-06-02 15:23:45 -07:00
|
|
|
ev->cur.x = pdata->seat->x;
|
|
|
|
ev->cur.y = pdata->seat->y;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj_itr, obj_itr, &ev->cur, obj_pdata->mouse_grabbed);
|
2017-06-16 12:03:09 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_IN;
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj_itr, obj_itr, EVAS_CALLBACK_MOUSE_IN, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_IN);
|
2018-07-24 09:04:11 -07:00
|
|
|
if ((pdata->seat->x != ev->prev.x) &&
|
|
|
|
(pdata->seat->y != ev->prev.y))
|
2017-07-11 23:43:41 -07:00
|
|
|
{
|
|
|
|
ev->action = EFL_POINTER_ACTION_MOVE;
|
|
|
|
evas_object_event_callback_call(eo_obj_itr, obj_itr, EVAS_CALLBACK_MOUSE_MOVE, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_MOVE);
|
|
|
|
}
|
2013-01-16 23:21:06 -08:00
|
|
|
if ((obj_itr->proxy->is_proxy) &&
|
|
|
|
(obj_itr->proxy->src_events))
|
2016-08-17 20:01:39 -07:00
|
|
|
_evas_event_source_mouse_in_events(eo_obj_itr, eo_e, evt, event_id);
|
2012-10-25 22:52:42 -07:00
|
|
|
if (e->delete_me) break;
|
2011-06-13 03:00:25 -07:00
|
|
|
}
|
|
|
|
}
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2011-06-13 03:00:25 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ins = eina_list_free(ins);
|
|
|
|
}
|
2011-06-28 22:05:35 -07:00
|
|
|
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->mouse_grabbed == 0)
|
2011-06-28 22:05:35 -07:00
|
|
|
{
|
|
|
|
/* free our old list of ins */
|
2017-06-02 15:23:45 -07:00
|
|
|
eina_list_free(pdata->seat->object.in);
|
2011-06-28 22:05:35 -07:00
|
|
|
/* and set up the new one */
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->object.in = ins;
|
2011-06-28 22:05:35 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* free our cur ins */
|
|
|
|
eina_list_free(ins);
|
|
|
|
}
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->inside)
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_canvas_event_pointer_move_event_dispatch(e, pdata, ev->data);
|
2016-08-17 04:29:39 -07:00
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2011-06-13 03:00:25 -07:00
|
|
|
}
|
|
|
|
|
2016-05-27 00:21:13 -07:00
|
|
|
static void
|
2016-08-25 03:20:10 -07:00
|
|
|
_canvas_event_feed_mouse_up_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data *ev)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer *evt;
|
2012-10-08 18:58:41 -07:00
|
|
|
Eina_List *l, *copy;
|
2016-08-17 04:29:39 -07:00
|
|
|
Evas_Object *eo_obj;
|
2019-06-26 07:30:35 -07:00
|
|
|
int event_id = 0, b;
|
2016-08-17 04:29:39 -07:00
|
|
|
Evas *eo_e;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata;
|
2019-06-26 07:30:35 -07:00
|
|
|
Eina_Bool cancel;
|
2016-08-17 04:29:39 -07:00
|
|
|
|
2016-08-29 01:04:31 -07:00
|
|
|
static const int value_flags =
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TIMESTAMP) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_X) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_Y) |
|
2019-06-20 03:13:37 -07:00
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TOUCH_ID) |
|
2016-08-29 01:04:31 -07:00
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_BUTTON);
|
|
|
|
|
2016-08-17 04:29:39 -07:00
|
|
|
if (!e || !ev) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
2012-10-08 18:58:41 -07:00
|
|
|
|
2016-10-21 05:25:41 -07:00
|
|
|
pdata = _evas_pointer_data_by_device_get(e, ev->device);
|
|
|
|
if (!pdata) return;
|
|
|
|
|
2016-08-17 04:29:39 -07:00
|
|
|
b = ev->button;
|
2019-06-26 07:30:35 -07:00
|
|
|
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);
|
2002-11-08 00:02:15 -08:00
|
|
|
if ((b < 1) || (b > 32)) return;
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->downs <= 0) return;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2019-06-26 07:30:35 -07:00
|
|
|
if (!cancel)
|
|
|
|
{
|
|
|
|
pdata->button &= ~(1u << (b - 1));
|
|
|
|
pdata->seat->downs--;
|
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
if (e->is_frozen) return;
|
2016-08-17 04:29:39 -07:00
|
|
|
e->last_timestamp = ev->timestamp;
|
|
|
|
eo_e = e->evas;
|
2016-08-25 00:03:45 -07:00
|
|
|
evt = ev->eo;
|
2011-09-21 03:35:03 -07:00
|
|
|
|
2019-06-26 07:30:35 -07:00
|
|
|
if (!cancel)
|
|
|
|
event_id = _evas_object_event_new();
|
2011-09-21 03:35:03 -07:00
|
|
|
|
2017-06-02 15:23:45 -07:00
|
|
|
ev->cur.x = pdata->seat->x;
|
|
|
|
ev->cur.y = pdata->seat->y;
|
2016-08-17 04:29:39 -07:00
|
|
|
ev->modifiers = &(e->modifiers);
|
|
|
|
ev->locks = &(e->locks);
|
|
|
|
ev->event_flags = e->default_event_flags;
|
2019-06-20 03:13:37 -07:00
|
|
|
ev->touch_id = 0;
|
2016-08-29 01:04:31 -07:00
|
|
|
ev->value_flags |= value_flags;
|
2016-08-17 04:29:39 -07:00
|
|
|
if (ev->device) efl_ref(ev->device);
|
2014-08-26 20:15:33 -07:00
|
|
|
|
2016-08-17 04:29:39 -07:00
|
|
|
_evas_walk(e);
|
2019-06-26 07:30:35 -07:00
|
|
|
if (!cancel)
|
|
|
|
/* update released touch point */
|
|
|
|
_evas_touch_point_update(eo_e, 0, pdata->seat->x, pdata->seat->y, EVAS_TOUCH_POINT_UP);
|
2017-06-02 15:23:45 -07:00
|
|
|
copy = evas_event_list_copy(pdata->seat->object.in);
|
2016-08-17 04:29:39 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_obj)
|
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Mode pointer_mode;
|
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
2016-08-17 04:29:39 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2016-10-21 05:25:41 -07:00
|
|
|
|
|
|
|
if (obj->delete_me) continue;
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
2016-08-17 04:29:39 -07:00
|
|
|
}
|
2019-06-26 07:30:35 -07:00
|
|
|
if ((!cancel) && ((obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_AUTOGRAB) ||
|
2016-10-21 05:25:41 -07:00
|
|
|
(obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)) &&
|
|
|
|
(obj_pdata->mouse_grabbed > 0))
|
2016-08-17 04:29:39 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
obj_pdata->mouse_grabbed--;
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->mouse_grabbed--;
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2016-10-21 05:25:41 -07:00
|
|
|
pointer_mode = obj_pdata->pointer_mode;
|
|
|
|
if ((!e->is_frozen) &&
|
|
|
|
(!evas_event_freezes_through(eo_obj, obj)))
|
2016-08-17 04:29:39 -07:00
|
|
|
{
|
2017-06-02 15:23:45 -07:00
|
|
|
ev->cur.x = pdata->seat->x;
|
|
|
|
ev->cur.y = pdata->seat->y;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
2019-06-26 07:30:35 -07:00
|
|
|
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);
|
2016-10-21 05:25:41 -07:00
|
|
|
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
|
2019-06-26 07:30:35 -07:00
|
|
|
_evas_event_source_mouse_up_events(eo_obj, eo_e, evt, pdata, event_id, cancel);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (e->delete_me) break;
|
|
|
|
}
|
|
|
|
if (pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)
|
|
|
|
{
|
2019-06-26 07:30:35 -07:00
|
|
|
if ((!cancel) && (pdata->seat->nogrep > 0)) pdata->seat->nogrep--;
|
2016-08-17 04:29:39 -07:00
|
|
|
break;
|
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2016-08-17 04:29:39 -07:00
|
|
|
eina_list_free(copy);
|
2019-06-26 07:30:35 -07:00
|
|
|
if (!cancel)
|
|
|
|
{
|
|
|
|
e->last_mouse_up_counter++;
|
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2008-07-18 04:04:06 -07:00
|
|
|
|
2019-06-26 07:30:35 -07:00
|
|
|
if (pdata->seat->mouse_grabbed == 0)
|
|
|
|
_post_up_handle(e, evt, pdata);
|
2007-07-24 07:20:07 -07:00
|
|
|
|
2019-06-26 07:30:35 -07:00
|
|
|
if (pdata->seat->mouse_grabbed < 0)
|
|
|
|
{
|
|
|
|
ERR("BUG? pdata->seat->mouse_grabbed (=%d) < 0!",
|
|
|
|
pdata->seat->mouse_grabbed);
|
|
|
|
}
|
2008-11-14 21:13:09 -08:00
|
|
|
}
|
2011-12-30 07:17:13 -08:00
|
|
|
/* remove released touch point from the touch point list */
|
2012-10-08 18:58:41 -07:00
|
|
|
_evas_touch_point_remove(eo_e, 0);
|
2007-04-29 21:22:42 -07:00
|
|
|
_evas_unwalk(e);
|
2016-08-17 04:29:39 -07:00
|
|
|
|
|
|
|
if (ev->device) efl_unref(ev->device);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-10-21 05:25:41 -07:00
|
|
|
_canvas_event_feed_mouse_updown(Eo *eo_e, int b, Evas_Button_Flags flags,
|
|
|
|
unsigned int timestamp, const void *data,
|
2019-06-26 07:30:35 -07:00
|
|
|
Eina_Bool down, Efl_Input_Device *device, Eina_Bool cancel)
|
2016-08-17 04:29:39 -07:00
|
|
|
{
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev = NULL;
|
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-17 04:29:39 -07:00
|
|
|
Evas_Public_Data *e;
|
|
|
|
|
|
|
|
e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
|
|
|
if (!e) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
2016-08-17 04:29:39 -07:00
|
|
|
|
2019-02-09 10:08:45 -08:00
|
|
|
evt = efl_input_pointer_instance_get( eo_e, (void **) &ev);
|
2016-08-17 04:29:39 -07:00
|
|
|
if (!ev) return;
|
|
|
|
|
|
|
|
ev->data = (void *) data;
|
|
|
|
ev->timestamp = timestamp;
|
2016-10-21 05:25:41 -07:00
|
|
|
ev->device = efl_ref(device ? device : _evas_event_legacy_device_get(eo_e, EINA_TRUE));
|
2019-06-26 07:30:35 -07:00
|
|
|
if (cancel)
|
|
|
|
ev->action = EFL_POINTER_ACTION_CANCEL;
|
|
|
|
else
|
|
|
|
ev->action = down ? EFL_POINTER_ACTION_DOWN : EFL_POINTER_ACTION_UP;
|
2016-08-17 04:29:39 -07:00
|
|
|
ev->button = b;
|
|
|
|
ev->button_flags = flags;
|
|
|
|
ev->radius = 1;
|
|
|
|
ev->radius_x = 1;
|
|
|
|
ev->radius_y = 1;
|
|
|
|
ev->pressure = 1;
|
|
|
|
ev->angle = 0;
|
|
|
|
//ev->window_pos = ?;
|
|
|
|
//ev->fake = 1;
|
|
|
|
|
2019-06-26 07:30:35 -07:00
|
|
|
/* 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
|
|
|
|
*/
|
2016-08-17 04:29:39 -07:00
|
|
|
if (down)
|
|
|
|
_canvas_event_feed_mouse_down_internal(e, ev);
|
|
|
|
else
|
|
|
|
_canvas_event_feed_mouse_up_internal(e, ev);
|
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2019-06-26 07:30:35 -07:00
|
|
|
|
|
|
|
/* 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);
|
2016-08-17 04:29:39 -07:00
|
|
|
}
|
|
|
|
|
2016-10-21 05:25:41 -07:00
|
|
|
static void
|
|
|
|
_canvas_event_feed_mouse_updown_legacy(Eo *eo_e, int b, Evas_Button_Flags flags,
|
|
|
|
unsigned int timestamp, const void *data,
|
|
|
|
Eina_Bool down)
|
|
|
|
{
|
2019-06-26 07:30:35 -07:00
|
|
|
_canvas_event_feed_mouse_updown(eo_e, b, flags, timestamp, data, down, NULL, EINA_FALSE);
|
2016-10-21 05:25:41 -07:00
|
|
|
}
|
|
|
|
|
2016-08-17 04:29:39 -07:00
|
|
|
EAPI void
|
|
|
|
evas_event_feed_mouse_down(Eo *eo_e, int b, Evas_Button_Flags flags, unsigned int timestamp, const void *data)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
|
|
|
_canvas_event_feed_mouse_updown_legacy(eo_e, b, flags, timestamp, data, 1);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2016-05-11 00:21:49 -07:00
|
|
|
EAPI void
|
2016-05-27 00:21:13 -07:00
|
|
|
evas_event_feed_mouse_up(Eo *eo_e, int b, Evas_Button_Flags flags, unsigned int timestamp, const void *data)
|
|
|
|
{
|
2016-08-17 04:29:39 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
|
|
|
_canvas_event_feed_mouse_updown_legacy(eo_e, b, flags, timestamp, data, 0);
|
2016-05-27 00:21:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-08-25 03:20:10 -07:00
|
|
|
_canvas_event_feed_mouse_cancel_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data *ev)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2013-08-27 00:52:24 -07:00
|
|
|
Evas_Coord_Touch_Point *point;
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data save;
|
2013-08-27 00:52:24 -07:00
|
|
|
Eina_List *l, *ll;
|
2015-06-12 07:10:07 -07:00
|
|
|
Evas_Event_Flags flags;
|
2016-08-17 22:54:54 -07:00
|
|
|
Evas *eo_e;
|
2012-10-08 18:58:41 -07:00
|
|
|
int i;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata;
|
2012-10-08 18:58:41 -07:00
|
|
|
|
2016-08-29 01:04:31 -07:00
|
|
|
static const int value_flags =
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TIMESTAMP) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_X) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_Y) |
|
2019-06-20 03:13:37 -07:00
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TOUCH_ID);
|
2016-08-29 01:04:31 -07:00
|
|
|
|
2016-08-17 22:54:54 -07:00
|
|
|
if (!e || !ev) return;
|
2012-10-08 18:58:41 -07:00
|
|
|
if (e->is_frozen) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
2008-07-18 04:04:06 -07:00
|
|
|
|
2016-10-21 05:25:41 -07:00
|
|
|
pdata = _evas_pointer_data_by_device_get(e, ev->device);
|
|
|
|
if (!pdata) return;
|
|
|
|
|
2016-08-17 22:54:54 -07:00
|
|
|
save = *ev;
|
|
|
|
eo_e = e->evas;
|
2008-05-18 21:15:22 -07:00
|
|
|
_evas_walk(e);
|
2015-06-12 07:10:07 -07:00
|
|
|
|
|
|
|
flags = evas_event_default_flags_get(eo_e);
|
|
|
|
evas_event_default_flags_set(eo_e, (flags | EVAS_EVENT_FLAG_ON_HOLD));
|
|
|
|
|
2008-05-18 21:15:22 -07:00
|
|
|
for (i = 0; i < 32; i++)
|
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
if ((pdata->button & (1u << i)))
|
2019-06-26 07:30:35 -07:00
|
|
|
_canvas_event_feed_mouse_updown(eo_e, i + 1, 0, ev->timestamp, ev->data, 0, ev->device, EINA_TRUE);
|
2008-05-18 21:15:22 -07:00
|
|
|
}
|
2016-08-17 22:54:54 -07:00
|
|
|
|
2016-08-29 01:04:31 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_CANCEL;
|
|
|
|
ev->value_flags |= value_flags;
|
2016-08-17 22:54:54 -07:00
|
|
|
ev->event_flags = flags;
|
2013-08-27 00:52:24 -07:00
|
|
|
EINA_LIST_FOREACH_SAFE(e->touch_points, l, ll, point)
|
|
|
|
{
|
2013-08-27 21:40:27 -07:00
|
|
|
if ((point->state == EVAS_TOUCH_POINT_DOWN) ||
|
2017-09-19 01:22:48 -07:00
|
|
|
(point->state == EVAS_TOUCH_POINT_MOVE) ||
|
|
|
|
(point->state == EVAS_TOUCH_POINT_STILL))
|
2016-08-17 22:54:54 -07:00
|
|
|
{
|
2019-06-20 03:13:37 -07:00
|
|
|
ev->touch_id = point->id;
|
2016-08-17 22:54:54 -07:00
|
|
|
ev->cur.x = point->x;
|
|
|
|
ev->cur.y = point->y;
|
2016-08-30 23:41:12 -07:00
|
|
|
ev->prev = ev->cur;
|
2016-08-17 22:54:54 -07:00
|
|
|
_canvas_event_feed_multi_up_internal(e, ev);
|
|
|
|
}
|
2013-08-27 00:52:24 -07:00
|
|
|
}
|
2015-06-12 07:10:07 -07:00
|
|
|
evas_event_default_flags_set(eo_e, flags);
|
2008-05-18 21:15:22 -07:00
|
|
|
_evas_unwalk(e);
|
2016-08-17 22:54:54 -07:00
|
|
|
|
|
|
|
*ev = save;
|
2008-05-18 21:15:22 -07:00
|
|
|
}
|
|
|
|
|
2016-04-28 02:43:18 -07:00
|
|
|
EAPI void
|
2016-05-27 00:21:13 -07:00
|
|
|
evas_event_feed_mouse_cancel(Eo *eo_e, unsigned int timestamp, const void *data)
|
|
|
|
{
|
2016-08-17 22:54:54 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev = NULL;
|
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-17 22:54:54 -07:00
|
|
|
|
2019-02-09 10:08:45 -08:00
|
|
|
evt = efl_input_pointer_instance_get( eo_e, (void **) &ev);
|
2016-08-17 22:54:54 -07:00
|
|
|
if (!ev) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
2016-08-17 22:54:54 -07:00
|
|
|
|
|
|
|
ev->timestamp = timestamp;
|
|
|
|
ev->data = (void *) data;
|
2016-10-26 05:37:29 -07:00
|
|
|
ev->device = efl_ref(_evas_event_legacy_device_get(e->evas, EINA_TRUE));
|
2016-08-17 22:54:54 -07:00
|
|
|
|
|
|
|
_canvas_event_feed_mouse_cancel_internal(e, ev);
|
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2016-05-27 00:21:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-08-25 03:20:10 -07:00
|
|
|
_canvas_event_feed_mouse_wheel_internal(Eo *eo_e, Efl_Input_Pointer_Data *pe)
|
2004-12-13 19:21:32 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev = NULL;
|
|
|
|
Efl_Input_Pointer *evt;
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *l, *copy;
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object *eo_obj;
|
2011-12-14 22:23:53 -08:00
|
|
|
int event_id = 0;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2016-08-29 01:04:31 -07:00
|
|
|
static const int value_flags =
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TIMESTAMP) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_X) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_Y) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_WHEEL_DELTA) |
|
2017-08-09 05:04:10 -07:00
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_WHEEL_HORIZONTAL);
|
2016-08-29 01:04:31 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
if (e->is_frozen) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
2016-10-21 05:25:41 -07:00
|
|
|
|
|
|
|
pdata = _evas_pointer_data_by_device_get(e, pe->device);
|
|
|
|
if (!pdata) return;
|
2016-08-10 19:58:42 -07:00
|
|
|
e->last_timestamp = pe->timestamp;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2016-08-10 19:58:42 -07:00
|
|
|
|
2017-12-10 21:50:22 -08:00
|
|
|
evt = efl_duplicate(pe->eo);
|
2016-08-25 03:20:10 -07:00
|
|
|
ev = efl_data_scope_get(evt, EFL_INPUT_POINTER_CLASS);
|
2016-08-10 19:58:42 -07:00
|
|
|
if (!ev) return;
|
|
|
|
|
|
|
|
// adjust missing data based on evas state
|
2017-06-02 15:23:45 -07:00
|
|
|
ev->cur.x = pdata->seat->x;
|
|
|
|
ev->cur.y = pdata->seat->y;
|
2016-08-10 19:58:42 -07:00
|
|
|
ev->modifiers = &(e->modifiers);
|
|
|
|
ev->locks = &(e->locks);
|
|
|
|
ev->event_flags = e->default_event_flags;
|
2016-08-17 20:01:39 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_WHEEL;
|
2016-08-29 01:04:31 -07:00
|
|
|
ev->value_flags |= value_flags;
|
2014-08-26 20:15:33 -07:00
|
|
|
|
2007-04-29 21:22:42 -07:00
|
|
|
_evas_walk(e);
|
2017-06-02 15:23:45 -07:00
|
|
|
copy = evas_event_list_copy(pdata->seat->object.in);
|
2008-07-18 04:04:06 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_obj)
|
2005-09-21 19:52:53 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-25 22:52:42 -07:00
|
|
|
if (!evas_event_freezes_through(eo_obj, obj))
|
2012-10-23 01:44:11 -07:00
|
|
|
{
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2017-06-02 15:23:45 -07:00
|
|
|
ev->cur.x = pdata->seat->x;
|
|
|
|
ev->cur.y = pdata->seat->y;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_WHEEL, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_WHEEL);
|
2013-01-16 23:21:06 -08:00
|
|
|
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
|
2016-08-10 19:58:42 -07:00
|
|
|
_evas_event_source_wheel_events(eo_obj, eo_e, evt, event_id);
|
2012-10-25 22:52:42 -07:00
|
|
|
if (e->delete_me || e->is_frozen) break;
|
2012-10-23 01:44:11 -07:00
|
|
|
}
|
2005-09-21 19:52:53 -07:00
|
|
|
}
|
2013-11-28 00:00:35 -08:00
|
|
|
eina_list_free(copy);
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2004-12-13 19:21:32 -08:00
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2007-04-29 21:22:42 -07:00
|
|
|
_evas_unwalk(e);
|
2016-05-27 00:21:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_event_feed_mouse_wheel(Eo *eo_e, int direction, int z, unsigned int timestamp, const void *data)
|
|
|
|
{
|
2016-08-25 19:27:37 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev = NULL;
|
2019-02-09 10:08:45 -08:00
|
|
|
Efl_Input_Pointer *evt = efl_input_pointer_instance_get( eo_e, (void **) &ev);
|
2016-08-10 19:58:42 -07:00
|
|
|
|
|
|
|
if (!ev) return;
|
|
|
|
|
2017-08-09 05:04:10 -07:00
|
|
|
ev->wheel.horizontal = !!direction;
|
2016-08-10 19:58:42 -07:00
|
|
|
ev->wheel.z = z;
|
|
|
|
ev->timestamp = timestamp;
|
|
|
|
ev->data = (void *) data;
|
2016-10-26 05:37:29 -07:00
|
|
|
ev->device = efl_ref(_evas_event_legacy_device_get(eo_e, EINA_TRUE));
|
2016-08-10 19:58:42 -07:00
|
|
|
|
|
|
|
_canvas_event_feed_mouse_wheel_internal(eo_e, ev);
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2004-12-13 19:21:32 -08:00
|
|
|
}
|
|
|
|
|
2013-05-03 11:43:31 -07:00
|
|
|
static void
|
2016-08-25 03:20:10 -07:00
|
|
|
_canvas_event_feed_mouse_move_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data *ev)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2012-01-17 00:35:32 -08:00
|
|
|
Evas_Object *nogrep_obj = NULL;
|
2016-08-18 00:28:55 -07:00
|
|
|
Evas_Object_Protected_Data *obj;
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-18 00:28:55 -07:00
|
|
|
Eina_List *l, *copy;
|
|
|
|
Evas_Object *eo_obj;
|
|
|
|
Eina_Vector2 point;
|
|
|
|
Evas *eo_e;
|
|
|
|
int event_id;
|
|
|
|
int x, y, px, py;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata;
|
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2016-08-29 01:04:31 -07:00
|
|
|
// inform which values are valid
|
|
|
|
static const int value_flags =
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TIMESTAMP) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_X) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_Y) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_PREVIOUS_X) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_PREVIOUS_Y) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_DX) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_DY) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_BUTTONS_PRESSED) |
|
2019-06-20 03:13:37 -07:00
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TOUCH_ID);
|
2016-08-29 01:04:31 -07:00
|
|
|
|
2016-08-18 00:28:55 -07:00
|
|
|
if (!e || !ev) return;
|
2012-10-08 18:58:41 -07:00
|
|
|
if (e->is_frozen) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2017-06-16 12:03:09 -07:00
|
|
|
if (ev->device)
|
|
|
|
{
|
|
|
|
pdata = _evas_pointer_data_by_device_get(e, ev->device);
|
|
|
|
if (!pdata) return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Evas_Pointer_Seat *pseat;
|
|
|
|
if (!e->seats) return;
|
|
|
|
pseat = EINA_INLIST_CONTAINER_GET(e->seats, Evas_Pointer_Seat);
|
|
|
|
pseat->inside = 1;
|
|
|
|
e->last_timestamp = ev->timestamp;
|
|
|
|
pseat->prev.x = pseat->x;
|
|
|
|
pseat->prev.y = pseat->y;
|
|
|
|
|
|
|
|
// new pos
|
|
|
|
pseat->x = ev->cur.x;
|
|
|
|
pseat->y = ev->cur.y;
|
|
|
|
return;
|
|
|
|
}
|
2016-10-21 05:25:41 -07:00
|
|
|
|
2016-08-18 00:28:55 -07:00
|
|
|
eo_e = e->evas;
|
|
|
|
e->last_timestamp = ev->timestamp;
|
|
|
|
|
|
|
|
// prev pos
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->prev.x = pdata->seat->x;
|
|
|
|
pdata->seat->prev.y = pdata->seat->y;
|
|
|
|
px = ev->prev.x = pdata->seat->x;
|
|
|
|
py = ev->prev.y = pdata->seat->y;
|
2016-08-18 00:28:55 -07:00
|
|
|
|
|
|
|
// new pos
|
2017-06-02 15:23:45 -07:00
|
|
|
x = pdata->seat->x = ev->cur.x;
|
|
|
|
y = pdata->seat->y = ev->cur.y;
|
2016-08-18 00:28:55 -07:00
|
|
|
point = ev->cur;
|
|
|
|
|
2017-06-02 15:23:45 -07:00
|
|
|
if ((!pdata->seat->inside) && (pdata->seat->mouse_grabbed == 0)) return;
|
2016-08-18 00:28:55 -07:00
|
|
|
|
|
|
|
evt = ev->eo;
|
|
|
|
ev->modifiers = &(e->modifiers);
|
|
|
|
ev->locks = &(e->locks);
|
|
|
|
ev->event_flags = e->default_event_flags;
|
2016-10-21 05:25:41 -07:00
|
|
|
ev->pressed_buttons = pdata->button;
|
2019-06-20 03:13:37 -07:00
|
|
|
ev->touch_id = 0;
|
2016-08-29 01:04:31 -07:00
|
|
|
ev->value_flags |= value_flags;
|
2016-08-18 00:28:55 -07:00
|
|
|
if (ev->device) efl_ref(ev->device);
|
|
|
|
|
2007-04-29 21:22:42 -07:00
|
|
|
_evas_walk(e);
|
From: EunMi Lee <eunmi15.lee@samsung.com>
Subject: [E-devel] [Patch] [Evas] Patch to provide information of
touched points
Hello,
I made a new patch to get information of current touched point instead
of Touch Event.
I added touch_points (Eina_List) to the Evas structure and it maintains touched points on the evas.
New touched point is added to the touch_points when we get Mouse_Down and Multi_Down,
touched point is updated when we get Mouse_Move and Mult_Move,
and touched point is removed when we get Mouse_Up and Multi_Up.
The each touch point has coordinate, id and state information as follows:
id - identifier. 0 for Mouse Event and device id for Multi Event. coordinate - (x, y) coordinate of point.
state - state of point. type is Evas_Touch_Point_State enum.
(EVAS_TOUCH_POINT_DOWN, EVAS_TOUCH_POINT_UP, EVAS_TOUCH_POINT_MOVE,
EVAS_TOUCH_POINT_STILL, EVAS_TOUCH_POINT_CANCEL)
There are 4 new APIs to get touch point's information as follows:
unsigned int evas_touch_point_list_count(Evas *e);
void evas_touch_point_list_nth_xy_get(Evas *e, unsigned int n, Evas_Coord *x, Evas_Coord *y);
int evas_touch_point_list_nth_id_get(Evas *e, unsigned int n);
Evas_Touch_Point_State evas_touch_point_list_nth_state_get(Evas *e, unsigned int n);
I added APIs to get each information instead of exposing whole
structure to make it easy to expand in the future as you mentioned in
the below e-mail :)
SVN revision: 64373
2011-10-24 22:03:50 -07:00
|
|
|
/* update moved touch point */
|
|
|
|
if ((px != x) || (py != y))
|
2017-06-02 15:23:45 -07:00
|
|
|
_evas_touch_point_update(eo_e, 0, pdata->seat->x, pdata->seat->y, EVAS_TOUCH_POINT_MOVE);
|
2005-05-21 19:49:50 -07:00
|
|
|
/* if our mouse button is grabbed to any objects */
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->mouse_grabbed > 0)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2011-09-21 03:35:03 -07:00
|
|
|
Eina_List *outs = NULL;
|
2012-10-25 22:52:42 -07:00
|
|
|
|
2016-08-18 00:28:55 -07:00
|
|
|
/* Send normal mouse move events */
|
|
|
|
ev->action = EFL_POINTER_ACTION_MOVE;
|
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2016-08-18 00:28:55 -07:00
|
|
|
|
|
|
|
/* go thru old list of in objects */
|
2017-06-02 15:23:45 -07:00
|
|
|
copy = evas_event_list_copy(pdata->seat->object.in);
|
2016-08-18 00:28:55 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_obj)
|
|
|
|
{
|
|
|
|
obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2016-08-18 00:28:55 -07:00
|
|
|
if ((!e->is_frozen) &&
|
2017-06-16 12:03:09 -07:00
|
|
|
_evas_event_object_pointer_allow(eo_obj, obj, obj_pdata) &&
|
2016-08-18 00:28:55 -07:00
|
|
|
(!evas_object_is_source_invisible(eo_obj, obj) ||
|
2017-06-16 12:03:09 -07:00
|
|
|
obj_pdata->mouse_grabbed))
|
2016-08-18 00:28:55 -07:00
|
|
|
{
|
|
|
|
if ((px != x) || (py != y))
|
2012-01-17 00:35:32 -08:00
|
|
|
{
|
2016-08-18 00:28:55 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_MOVE, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_MOVE);
|
2016-08-18 00:28:55 -07:00
|
|
|
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_source_mouse_move_events(eo_obj, eo_e, evt, pdata, event_id);
|
2012-01-17 00:35:32 -08:00
|
|
|
}
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2016-08-18 00:28:55 -07:00
|
|
|
else
|
|
|
|
outs = eina_list_append(outs, eo_obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if ((obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN) &&
|
2017-06-02 15:23:45 -07:00
|
|
|
(pdata->seat->nogrep > 0))
|
2016-08-18 00:28:55 -07:00
|
|
|
{
|
|
|
|
eina_list_free(copy);
|
|
|
|
eina_list_free(outs);
|
|
|
|
nogrep_obj = eo_obj;
|
|
|
|
goto nogrep;
|
|
|
|
}
|
|
|
|
if (e->delete_me) break;
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2016-08-18 00:28:55 -07:00
|
|
|
eina_list_free(copy);
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2011-09-21 03:35:03 -07:00
|
|
|
|
|
|
|
|
2016-08-18 00:28:55 -07:00
|
|
|
/* Send mouse out events */
|
|
|
|
ev->action = EFL_POINTER_ACTION_OUT;
|
2014-08-26 20:15:33 -07:00
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2013-11-28 00:00:35 -08:00
|
|
|
|
2016-08-18 00:28:55 -07:00
|
|
|
EINA_LIST_FREE(outs, eo_obj)
|
|
|
|
{
|
|
|
|
obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ((obj_pdata->mouse_grabbed == 0) && (!e->delete_me))
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata->mouse_in) continue;
|
evas_events: Fix to set mouse_in state to all pointers in the seat.
Summary:
mouse coordinate is set by seat.
Therefore, mouse_in state should be set based on seat.
As a result, mouse_in state of all pointers in the seat should be
updated at the same time.
Reviewers: eagleeye, devilhorns, zmike
Reviewed By: eagleeye, devilhorns, zmike
Subscribers: devilhorns, Hermet, kimcinoo, cedric, iscaro, zmike, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6699
2018-08-02 02:16:46 -07:00
|
|
|
_evas_event_mouse_in_set(pdata->seat, obj, 0);
|
2016-08-18 00:28:55 -07:00
|
|
|
if (obj->delete_me || e->is_frozen) continue;
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->object.in = eina_list_remove(pdata->seat->object.in, eo_obj);
|
2016-08-18 00:28:55 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_OUT, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_OUT);
|
2016-08-18 00:28:55 -07:00
|
|
|
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
|
|
|
|
_evas_event_source_mouse_out_events(eo_obj, eo_e, evt, event_id);
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
|
|
|
}
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-21 03:35:03 -07:00
|
|
|
Eina_List *ins;
|
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2011-09-21 03:35:03 -07:00
|
|
|
|
|
|
|
/* get all new in objects */
|
2012-10-08 18:58:41 -07:00
|
|
|
ins = evas_event_objects_event_list(eo_e, NULL, x, y);
|
2011-09-21 03:35:03 -07:00
|
|
|
/* go thru old list of in objects */
|
2017-06-02 15:23:45 -07:00
|
|
|
copy = evas_event_list_copy(pdata->seat->object.in);
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_obj)
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2016-08-18 00:28:55 -07:00
|
|
|
obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2014-12-22 05:14:22 -08:00
|
|
|
if (!obj) continue;
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2016-08-18 00:28:55 -07:00
|
|
|
|
2011-09-21 03:35:03 -07:00
|
|
|
/* if its under the pointer and its visible and its in the new */
|
|
|
|
/* in list */
|
|
|
|
// FIXME: i don't think we need this
|
2012-10-08 18:58:41 -07:00
|
|
|
// evas_object_clip_recalc(eo_obj);
|
|
|
|
if ((!e->is_frozen) &&
|
|
|
|
evas_object_is_in_output_rect(eo_obj, obj, x, y, 1, 1) &&
|
2017-06-16 12:03:09 -07:00
|
|
|
_evas_event_object_pointer_allow(eo_obj, obj, obj_pdata) &&
|
2017-06-16 12:03:09 -07:00
|
|
|
_evas_event_object_pointer_allow_precise(eo_obj, obj, x, y, ins) &&
|
2013-02-14 22:48:07 -08:00
|
|
|
(!evas_object_is_source_invisible(eo_obj, obj) ||
|
2017-06-16 12:03:09 -07:00
|
|
|
obj_pdata->mouse_grabbed))
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
|
|
|
if ((px != x) || (py != y))
|
|
|
|
{
|
2016-08-18 00:28:55 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-18 00:28:55 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_MOVE;
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_MOVE, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_MOVE);
|
2013-01-16 23:21:06 -08:00
|
|
|
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_source_mouse_move_events(eo_obj, eo_e, evt, pdata, event_id);
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/* otherwise it has left the object */
|
2016-10-21 05:25:41 -07:00
|
|
|
else if (obj_pdata->mouse_in)
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
evas_events: Fix to set mouse_in state to all pointers in the seat.
Summary:
mouse coordinate is set by seat.
Therefore, mouse_in state should be set based on seat.
As a result, mouse_in state of all pointers in the seat should be
updated at the same time.
Reviewers: eagleeye, devilhorns, zmike
Reviewed By: eagleeye, devilhorns, zmike
Subscribers: devilhorns, Hermet, kimcinoo, cedric, iscaro, zmike, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6699
2018-08-02 02:16:46 -07:00
|
|
|
_evas_event_mouse_in_set(pdata->seat, obj, 0);
|
2016-08-18 00:28:55 -07:00
|
|
|
if (e->is_frozen) continue;
|
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-18 00:28:55 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_OUT;
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_OUT, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_OUT);
|
2016-08-18 00:28:55 -07:00
|
|
|
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
|
|
|
|
_evas_event_source_mouse_out_events(eo_obj, eo_e, evt, event_id);
|
|
|
|
if (e->delete_me) break;
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
|
|
|
}
|
2016-08-18 00:28:55 -07:00
|
|
|
eina_list_free(copy);
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2010-03-04 06:48:21 -08:00
|
|
|
|
2016-08-18 00:28:55 -07:00
|
|
|
/* new event id for mouse in */
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2013-11-28 00:00:35 -08:00
|
|
|
|
2011-09-21 03:35:03 -07:00
|
|
|
/* go thru our current list of ins */
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(ins, l, eo_obj)
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2016-08-18 00:28:55 -07:00
|
|
|
obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2011-09-21 03:35:03 -07:00
|
|
|
/* if its not in the old list of ins send an enter event */
|
2017-06-02 15:23:45 -07:00
|
|
|
if (!eina_list_data_find(pdata->seat->object.in, eo_obj))
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
2010-09-03 20:53:34 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!obj_pdata->mouse_in)
|
|
|
|
{
|
evas_events: Fix to set mouse_in state to all pointers in the seat.
Summary:
mouse coordinate is set by seat.
Therefore, mouse_in state should be set based on seat.
As a result, mouse_in state of all pointers in the seat should be
updated at the same time.
Reviewers: eagleeye, devilhorns, zmike
Reviewed By: eagleeye, devilhorns, zmike
Subscribers: devilhorns, Hermet, kimcinoo, cedric, iscaro, zmike, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6699
2018-08-02 02:16:46 -07:00
|
|
|
_evas_event_mouse_in_set(pdata->seat, obj, 1);
|
2012-10-25 22:52:42 -07:00
|
|
|
if (e->is_frozen) continue;
|
2016-08-18 00:28:55 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-18 00:28:55 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_IN;
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_IN, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_IN);
|
2018-07-24 09:04:11 -07:00
|
|
|
if ((point.x != ev->prev.x) &&
|
|
|
|
(point.y != ev->prev.y))
|
2017-07-11 23:43:41 -07:00
|
|
|
{
|
|
|
|
ev->action = EFL_POINTER_ACTION_MOVE;
|
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_MOVE, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_MOVE);
|
|
|
|
}
|
2013-01-16 23:21:06 -08:00
|
|
|
if ((obj->proxy->is_proxy) &&
|
|
|
|
(obj->proxy->src_events))
|
2016-08-18 00:28:55 -07:00
|
|
|
_evas_event_source_mouse_in_events(eo_obj, eo_e, evt, event_id);
|
2012-10-25 22:52:42 -07:00
|
|
|
if (e->delete_me) break;
|
2010-09-03 20:53:34 -07:00
|
|
|
}
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
|
|
|
}
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->mouse_grabbed == 0)
|
2011-06-28 22:05:35 -07:00
|
|
|
{
|
|
|
|
/* free our old list of ins */
|
2017-06-02 15:23:45 -07:00
|
|
|
eina_list_free(pdata->seat->object.in);
|
2011-06-28 22:05:35 -07:00
|
|
|
/* and set up the new one */
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->object.in = ins;
|
2011-06-28 22:05:35 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* free our cur ins */
|
|
|
|
eina_list_free(ins);
|
|
|
|
}
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2016-08-18 00:28:55 -07:00
|
|
|
|
2012-01-17 00:35:32 -08:00
|
|
|
nogrep:
|
2016-08-18 00:28:55 -07:00
|
|
|
if (nogrep_obj)
|
2012-01-17 00:35:32 -08:00
|
|
|
{
|
2016-08-18 00:28:55 -07:00
|
|
|
Eina_List *ins = NULL, *newin = NULL, *lst = NULL;
|
|
|
|
Evas_Object *eo_below_obj;
|
2012-01-17 00:35:32 -08:00
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2012-01-17 00:35:32 -08:00
|
|
|
|
|
|
|
/* go thru old list of in objects */
|
2017-06-02 15:23:45 -07:00
|
|
|
copy = evas_event_list_copy(pdata->seat->object.in);
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_obj)
|
2012-01-17 00:35:32 -08:00
|
|
|
{
|
2016-08-18 00:28:55 -07:00
|
|
|
if (eo_obj == nogrep_obj)
|
2012-01-17 00:35:32 -08:00
|
|
|
{
|
2016-08-18 00:28:55 -07:00
|
|
|
lst = l->next;
|
2012-01-17 00:35:32 -08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-10-08 18:58:41 -07:00
|
|
|
|
2012-01-17 00:35:32 -08:00
|
|
|
/* get all new in objects */
|
2012-10-08 18:58:41 -07:00
|
|
|
eo_below_obj = evas_object_below_get(nogrep_obj);
|
|
|
|
if (eo_below_obj)
|
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *below_obj = efl_data_scope_get(eo_below_obj, EFL_CANVAS_OBJECT_CLASS);
|
2016-08-18 00:28:55 -07:00
|
|
|
int norep = 0;
|
2012-10-08 18:58:41 -07:00
|
|
|
ins = _evas_event_object_list_raw_in_get(eo_e, NULL,
|
2017-06-14 12:42:25 -07:00
|
|
|
EINA_INLIST_GET(below_obj), NULL, NULL,
|
|
|
|
pdata->seat->x, pdata->seat->y,
|
2019-06-15 01:38:06 -07:00
|
|
|
&norep, EINA_FALSE, EINA_TRUE);
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
2016-08-18 00:28:55 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_obj)
|
2012-01-17 00:35:32 -08:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
newin = eina_list_append(newin, eo_obj);
|
|
|
|
if (eo_obj == nogrep_obj) break;
|
2012-01-17 00:35:32 -08:00
|
|
|
}
|
2016-08-18 00:28:55 -07:00
|
|
|
|
|
|
|
// NOTE: was foreach + append without free (smelled bad)
|
|
|
|
newin = eina_list_merge(newin, ins);
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(lst, l, eo_obj)
|
2012-01-17 00:35:32 -08:00
|
|
|
{
|
2016-08-18 00:28:55 -07:00
|
|
|
obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2012-01-17 00:35:32 -08:00
|
|
|
/* if its under the pointer and its visible and its in the new */
|
|
|
|
/* in list */
|
|
|
|
// FIXME: i don't think we need this
|
2012-10-08 18:58:41 -07:00
|
|
|
// evas_object_clip_recalc(eo_obj);
|
|
|
|
if ((!e->is_frozen) &&
|
|
|
|
evas_object_is_in_output_rect(eo_obj, obj, x, y, 1, 1) &&
|
2017-06-16 12:03:09 -07:00
|
|
|
_evas_event_object_pointer_allow(eo_obj, obj, obj_pdata) &&
|
2017-06-16 12:03:09 -07:00
|
|
|
_evas_event_object_pointer_allow_precise(eo_obj, obj, x, y, newin) &&
|
2013-02-14 22:48:07 -08:00
|
|
|
(!evas_object_is_source_invisible(eo_obj, obj) ||
|
2017-06-16 12:03:09 -07:00
|
|
|
obj_pdata->mouse_grabbed))
|
2012-01-17 00:35:32 -08:00
|
|
|
{
|
|
|
|
if ((px != x) || (py != y))
|
|
|
|
{
|
2016-08-18 00:28:55 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-18 00:28:55 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_MOVE;
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_MOVE, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_MOVE);
|
2013-01-16 23:21:06 -08:00
|
|
|
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_source_mouse_move_events(eo_obj, eo_e, evt, pdata, event_id);
|
2012-01-17 00:35:32 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-18 00:28:55 -07:00
|
|
|
/* otherwise it has left the object */
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata->mouse_in) continue;
|
evas_events: Fix to set mouse_in state to all pointers in the seat.
Summary:
mouse coordinate is set by seat.
Therefore, mouse_in state should be set based on seat.
As a result, mouse_in state of all pointers in the seat should be
updated at the same time.
Reviewers: eagleeye, devilhorns, zmike
Reviewed By: eagleeye, devilhorns, zmike
Subscribers: devilhorns, Hermet, kimcinoo, cedric, iscaro, zmike, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6699
2018-08-02 02:16:46 -07:00
|
|
|
_evas_event_mouse_in_set(pdata->seat, obj, 0);
|
2012-10-25 22:52:42 -07:00
|
|
|
if (e->is_frozen) continue;
|
2016-08-18 00:28:55 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-18 00:28:55 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_OUT;
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_OUT, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_OUT);
|
2013-01-16 23:21:06 -08:00
|
|
|
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
|
2016-08-18 00:28:55 -07:00
|
|
|
_evas_event_source_mouse_out_events(eo_obj, eo_e, evt, event_id);
|
2012-01-17 00:35:32 -08:00
|
|
|
}
|
|
|
|
if (e->delete_me) break;
|
|
|
|
}
|
2016-08-18 00:28:55 -07:00
|
|
|
eina_list_free(copy);
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2012-01-17 00:35:32 -08:00
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2013-11-28 00:00:35 -08:00
|
|
|
|
2012-01-17 00:35:32 -08:00
|
|
|
/* go thru our current list of ins */
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(newin, l, eo_obj)
|
2012-01-17 00:35:32 -08:00
|
|
|
{
|
2016-08-18 00:28:55 -07:00
|
|
|
obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-01-17 00:35:32 -08:00
|
|
|
/* if its not in the old list of ins send an enter event */
|
2017-06-02 15:23:45 -07:00
|
|
|
if (!eina_list_data_find(pdata->seat->object.in, eo_obj))
|
2012-01-17 00:35:32 -08:00
|
|
|
{
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (obj_pdata->mouse_in) continue;
|
evas_events: Fix to set mouse_in state to all pointers in the seat.
Summary:
mouse coordinate is set by seat.
Therefore, mouse_in state should be set based on seat.
As a result, mouse_in state of all pointers in the seat should be
updated at the same time.
Reviewers: eagleeye, devilhorns, zmike
Reviewed By: eagleeye, devilhorns, zmike
Subscribers: devilhorns, Hermet, kimcinoo, cedric, iscaro, zmike, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6699
2018-08-02 02:16:46 -07:00
|
|
|
_evas_event_mouse_in_set(pdata->seat, obj, 1);
|
2012-10-25 22:52:42 -07:00
|
|
|
if (e->is_frozen) continue;
|
2016-08-18 00:28:55 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-18 00:28:55 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_IN;
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_IN, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_IN);
|
2018-07-24 09:04:11 -07:00
|
|
|
if ((point.x != ev->prev.x) &&
|
|
|
|
(point.y != ev->prev.y))
|
2017-07-11 23:43:41 -07:00
|
|
|
{
|
|
|
|
ev->action = EFL_POINTER_ACTION_MOVE;
|
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_MOVE, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_MOVE);
|
|
|
|
}
|
2013-01-16 23:21:06 -08:00
|
|
|
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
|
2016-08-18 00:28:55 -07:00
|
|
|
_evas_event_source_mouse_in_events(eo_obj, eo_e, evt, event_id);
|
2012-10-25 22:52:42 -07:00
|
|
|
if (e->delete_me) break;
|
2012-01-17 00:35:32 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/* free our old list of ins */
|
2017-06-02 15:23:45 -07:00
|
|
|
eina_list_free(pdata->seat->object.in);
|
2012-01-17 00:35:32 -08:00
|
|
|
/* and set up the new one */
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->object.in = newin;
|
2012-01-17 00:35:32 -08:00
|
|
|
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2012-01-17 00:35:32 -08:00
|
|
|
}
|
2016-08-18 00:28:55 -07:00
|
|
|
|
2007-04-29 21:22:42 -07:00
|
|
|
_evas_unwalk(e);
|
2016-08-18 00:28:55 -07:00
|
|
|
if (ev->device) efl_unref(ev->device);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_canvas_event_feed_mouse_move_legacy(Evas *eo_e, Evas_Public_Data *e, int x, int y,
|
|
|
|
unsigned int timestamp, const void *data)
|
|
|
|
{
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev = NULL;
|
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-18 00:28:55 -07:00
|
|
|
|
2019-02-09 10:08:45 -08:00
|
|
|
evt = efl_input_pointer_instance_get( eo_e, (void **) &ev);
|
2016-08-18 00:28:55 -07:00
|
|
|
if (!ev) return;
|
|
|
|
|
|
|
|
ev->data = (void *) data;
|
|
|
|
ev->timestamp = timestamp;
|
2016-10-26 05:37:29 -07:00
|
|
|
ev->device = efl_ref(_evas_event_legacy_device_get(eo_e, EINA_TRUE));
|
2016-08-18 00:28:55 -07:00
|
|
|
ev->cur.x = x;
|
|
|
|
ev->cur.y = y;
|
|
|
|
|
|
|
|
_canvas_event_feed_mouse_move_internal(e, ev);
|
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2016-04-28 02:43:18 -07:00
|
|
|
EAPI void
|
|
|
|
evas_event_input_mouse_move(Eo *eo_e, int x, int y, unsigned int timestamp, const void *data)
|
2013-05-03 11:43:31 -07:00
|
|
|
{
|
2016-08-18 00:28:55 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-18 00:28:55 -07:00
|
|
|
_canvas_event_feed_mouse_move_legacy(eo_e, e, x - e->framespace.x, y - e->framespace.y, timestamp, data);
|
2013-05-03 11:43:31 -07:00
|
|
|
}
|
|
|
|
|
2016-04-28 02:43:18 -07:00
|
|
|
EAPI void
|
|
|
|
evas_event_feed_mouse_move(Eo *eo_e, int x, int y, unsigned int timestamp, const void *data)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2016-08-18 00:28:55 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-18 00:28:55 -07:00
|
|
|
_canvas_event_feed_mouse_move_legacy(eo_e, e, x, y, timestamp, data);
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
|
|
|
|
2016-05-27 00:21:13 -07:00
|
|
|
static void
|
2016-08-25 03:20:10 -07:00
|
|
|
_canvas_event_feed_mouse_in_internal(Evas *eo_e, Efl_Input_Pointer_Data *ev)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer *evt;
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *ins;
|
|
|
|
Eina_List *l;
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object *eo_obj;
|
2016-08-17 20:01:39 -07:00
|
|
|
int event_id;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2016-08-29 01:04:31 -07:00
|
|
|
static const int value_flags =
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TIMESTAMP) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_X) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_Y) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_BUTTONS_PRESSED) |
|
2019-06-20 03:13:37 -07:00
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TOUCH_ID);
|
2016-08-29 01:04:31 -07:00
|
|
|
|
2016-08-17 20:01:39 -07:00
|
|
|
if (!e || !ev) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
2004-09-17 06:46:55 -07:00
|
|
|
|
2017-06-16 12:03:09 -07:00
|
|
|
if (ev->device)
|
|
|
|
{
|
|
|
|
pdata = _evas_pointer_data_by_device_get(e, ev->device);
|
|
|
|
if (!pdata) return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Evas_Pointer_Seat *pseat;
|
|
|
|
if (!e->seats) return;
|
|
|
|
pseat = EINA_INLIST_CONTAINER_GET(e->seats, Evas_Pointer_Seat);
|
|
|
|
pseat->inside = 1;
|
|
|
|
return;
|
|
|
|
}
|
2016-10-21 05:25:41 -07:00
|
|
|
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->inside = 1;
|
2012-10-08 18:58:41 -07:00
|
|
|
if (e->is_frozen) return;
|
2004-09-21 02:33:18 -07:00
|
|
|
|
2016-08-17 20:01:39 -07:00
|
|
|
e->last_timestamp = ev->timestamp;
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->mouse_grabbed != 0) return;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2016-08-25 00:03:45 -07:00
|
|
|
evt = ev->eo;
|
2016-08-17 20:01:39 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_IN;
|
2016-10-21 05:25:41 -07:00
|
|
|
ev->pressed_buttons = pdata->button;
|
2017-06-02 15:23:45 -07:00
|
|
|
ev->cur.x = pdata->seat->x;
|
|
|
|
ev->cur.y = pdata->seat->y;
|
2016-08-17 20:01:39 -07:00
|
|
|
ev->modifiers = &(e->modifiers);
|
|
|
|
ev->locks = &(e->locks);
|
|
|
|
ev->event_flags = e->default_event_flags;
|
2016-08-29 01:04:31 -07:00
|
|
|
ev->value_flags |= value_flags;
|
2016-08-17 20:01:39 -07:00
|
|
|
if (ev->device) efl_ref(ev->device);
|
2010-03-04 06:48:21 -08:00
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2016-08-17 20:01:39 -07:00
|
|
|
|
2007-04-29 21:22:42 -07:00
|
|
|
_evas_walk(e);
|
2004-09-17 06:46:55 -07:00
|
|
|
/* get new list of ins */
|
2017-06-02 15:23:45 -07:00
|
|
|
ins = evas_event_objects_event_list(eo_e, NULL, pdata->seat->x, pdata->seat->y);
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(ins, l, eo_obj)
|
2004-09-17 06:46:55 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2019-06-20 04:08:14 -07:00
|
|
|
if ((!obj) || (obj->delete_me)) continue;
|
2017-06-02 15:23:45 -07:00
|
|
|
if (!eina_list_data_find(pdata->seat->object.in, eo_obj))
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (obj_pdata->mouse_in) continue;
|
evas_events: Fix to set mouse_in state to all pointers in the seat.
Summary:
mouse coordinate is set by seat.
Therefore, mouse_in state should be set based on seat.
As a result, mouse_in state of all pointers in the seat should be
updated at the same time.
Reviewers: eagleeye, devilhorns, zmike
Reviewed By: eagleeye, devilhorns, zmike
Subscribers: devilhorns, Hermet, kimcinoo, cedric, iscaro, zmike, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6699
2018-08-02 02:16:46 -07:00
|
|
|
_evas_event_mouse_in_set(pdata->seat, obj, 1);
|
2017-06-02 15:23:45 -07:00
|
|
|
ev->cur.x = pdata->seat->x;
|
|
|
|
ev->cur.y = pdata->seat->y;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
2017-06-16 12:03:09 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_IN;
|
2019-06-20 04:08:14 -07:00
|
|
|
efl_ref(eo_obj);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_IN, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_IN);
|
2018-07-24 09:04:11 -07:00
|
|
|
if ((pdata->seat->x != ev->prev.x) &&
|
|
|
|
(pdata->seat->y != ev->prev.y))
|
2017-07-11 23:43:41 -07:00
|
|
|
{
|
|
|
|
ev->action = EFL_POINTER_ACTION_MOVE;
|
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_MOVE, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_MOVE);
|
|
|
|
}
|
2013-01-16 23:21:06 -08:00
|
|
|
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
|
2016-08-25 00:03:45 -07:00
|
|
|
_evas_event_source_mouse_in_events(eo_obj, eo_e, evt, event_id);
|
2019-06-20 04:08:14 -07:00
|
|
|
efl_unref(eo_obj);
|
2012-10-25 22:52:42 -07:00
|
|
|
if (e->delete_me || e->is_frozen) break;
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2004-09-17 06:46:55 -07:00
|
|
|
}
|
|
|
|
/* free our old list of ins */
|
2017-07-28 08:46:01 -07:00
|
|
|
eina_list_free(pdata->seat->object.in);
|
2004-09-17 06:46:55 -07:00
|
|
|
/* and set up the new one */
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->object.in = ins;
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2016-08-18 00:28:55 -07:00
|
|
|
_canvas_event_feed_mouse_move_internal(e, ev);
|
2007-04-29 21:22:42 -07:00
|
|
|
_evas_unwalk(e);
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2016-08-17 20:01:39 -07:00
|
|
|
if (ev->device) efl_unref(ev->device);
|
2016-05-27 00:21:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-08-25 03:20:10 -07:00
|
|
|
_canvas_event_feed_mouse_out_internal(Evas *eo_e, Efl_Input_Pointer_Data *ev)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-17 20:01:39 -07:00
|
|
|
Eina_List *l, *copy;
|
|
|
|
Evas_Object *eo_obj;
|
|
|
|
int event_id;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata;
|
2008-07-18 04:04:06 -07:00
|
|
|
|
2016-08-29 01:04:31 -07:00
|
|
|
static const int value_flags =
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TIMESTAMP) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_X) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_Y) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_BUTTONS_PRESSED) |
|
2019-06-20 03:13:37 -07:00
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TOUCH_ID);
|
2016-08-29 01:04:31 -07:00
|
|
|
|
2016-08-17 20:01:39 -07:00
|
|
|
if (!e || !ev) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
2017-06-16 12:03:09 -07:00
|
|
|
if (ev->device)
|
|
|
|
{
|
|
|
|
pdata = _evas_pointer_data_by_device_get(e, ev->device);
|
|
|
|
if (!pdata) return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Evas_Pointer_Seat *pseat;
|
|
|
|
if (!e->seats) return;
|
|
|
|
pseat = EINA_INLIST_CONTAINER_GET(e->seats, Evas_Pointer_Seat);
|
|
|
|
pseat->inside = 0;
|
|
|
|
return;
|
|
|
|
}
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->inside = 0;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
if (e->is_frozen) return;
|
2016-08-17 20:01:39 -07:00
|
|
|
e->last_timestamp = ev->timestamp;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2016-08-17 20:01:39 -07:00
|
|
|
|
2016-08-25 00:03:45 -07:00
|
|
|
evt = ev->eo;
|
2016-08-17 20:01:39 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_OUT;
|
2016-10-21 05:25:41 -07:00
|
|
|
ev->pressed_buttons = pdata->button;
|
2017-06-02 15:23:45 -07:00
|
|
|
ev->cur.x = pdata->seat->x;
|
|
|
|
ev->cur.y = pdata->seat->y;
|
2016-08-17 20:01:39 -07:00
|
|
|
ev->modifiers = &(e->modifiers);
|
|
|
|
ev->locks = &(e->locks);
|
|
|
|
ev->event_flags = e->default_event_flags;
|
2016-08-29 01:04:31 -07:00
|
|
|
ev->value_flags |= value_flags;
|
2016-08-17 20:01:39 -07:00
|
|
|
if (ev->device) efl_ref(ev->device);
|
2012-10-28 07:51:42 -07:00
|
|
|
|
2007-04-29 21:22:42 -07:00
|
|
|
_evas_walk(e);
|
2011-12-30 07:20:15 -08:00
|
|
|
/* if our mouse button is inside any objects */
|
2012-10-28 07:51:42 -07:00
|
|
|
/* go thru old list of in objects */
|
2017-06-02 15:23:45 -07:00
|
|
|
copy = evas_event_list_copy(pdata->seat->object.in);
|
2012-10-28 07:51:42 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_obj)
|
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2019-06-20 04:08:14 -07:00
|
|
|
if ((!obj) || (obj->delete_me)) continue;
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata->mouse_in) continue;
|
evas_events: Fix to set mouse_in state to all pointers in the seat.
Summary:
mouse coordinate is set by seat.
Therefore, mouse_in state should be set based on seat.
As a result, mouse_in state of all pointers in the seat should be
updated at the same time.
Reviewers: eagleeye, devilhorns, zmike
Reviewed By: eagleeye, devilhorns, zmike
Subscribers: devilhorns, Hermet, kimcinoo, cedric, iscaro, zmike, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D6699
2018-08-02 02:16:46 -07:00
|
|
|
_evas_event_mouse_in_set(pdata->seat, obj, 0);
|
2017-06-02 15:23:45 -07:00
|
|
|
ev->cur.x = pdata->seat->x;
|
|
|
|
ev->cur.y = pdata->seat->y;
|
2019-06-20 04:08:14 -07:00
|
|
|
efl_ref(eo_obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
_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_OUT, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_OUT);
|
|
|
|
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
|
|
|
|
_evas_event_source_mouse_out_events(eo_obj, eo_e, evt, event_id);
|
2019-06-20 04:08:14 -07:00
|
|
|
efl_unref(eo_obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (e->delete_me || e->is_frozen) break;
|
|
|
|
obj_pdata->mouse_grabbed = 0;
|
2004-09-17 06:46:55 -07:00
|
|
|
}
|
2013-11-28 00:00:35 -08:00
|
|
|
eina_list_free(copy);
|
|
|
|
|
2012-10-28 07:51:42 -07:00
|
|
|
/* free our old list of ins */
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->object.in = eina_list_free(pdata->seat->object.in);
|
|
|
|
pdata->seat->mouse_grabbed = 0;
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2007-04-29 21:22:42 -07:00
|
|
|
_evas_unwalk(e);
|
2016-08-17 20:01:39 -07:00
|
|
|
|
|
|
|
if (ev->device) efl_unref(ev->device);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_canvas_event_feed_mouse_inout_legacy(Eo *eo_e, unsigned int timestamp,
|
|
|
|
const void *data, Eina_Bool in)
|
|
|
|
{
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev = NULL;
|
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-17 20:01:39 -07:00
|
|
|
|
2019-02-09 10:08:45 -08:00
|
|
|
evt = efl_input_pointer_instance_get( eo_e, (void **) &ev);
|
2016-08-17 20:01:39 -07:00
|
|
|
if (!ev) return;
|
|
|
|
|
|
|
|
ev->timestamp = timestamp;
|
|
|
|
ev->data = (void *) data;
|
2016-10-26 05:37:29 -07:00
|
|
|
ev->device = efl_ref(_evas_event_legacy_device_get(eo_e, EINA_TRUE));
|
2016-08-17 20:01:39 -07:00
|
|
|
|
|
|
|
if (in)
|
|
|
|
_canvas_event_feed_mouse_in_internal(eo_e, ev);
|
|
|
|
else
|
|
|
|
_canvas_event_feed_mouse_out_internal(eo_e, ev);
|
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2016-08-17 20:01:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_event_feed_mouse_in(Eo *eo_e, unsigned int timestamp, const void *data)
|
|
|
|
{
|
2016-08-25 19:27:37 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2016-08-17 20:01:39 -07:00
|
|
|
_canvas_event_feed_mouse_inout_legacy(eo_e, timestamp, data, EINA_TRUE);
|
2016-05-27 00:21:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_event_feed_mouse_out(Eo *eo_e, unsigned int timestamp, const void *data)
|
|
|
|
{
|
2016-08-25 19:27:37 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2016-08-17 20:01:39 -07:00
|
|
|
_canvas_event_feed_mouse_inout_legacy(eo_e, timestamp, data, EINA_FALSE);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2013-05-07 13:53:42 -07:00
|
|
|
static void
|
2016-08-25 03:20:10 -07:00
|
|
|
_canvas_event_feed_multi_down_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data *ev)
|
2010-01-16 04:20:22 -08:00
|
|
|
{
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer *evt;
|
2010-01-16 04:20:22 -08:00
|
|
|
Eina_List *l, *copy;
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object *eo_obj;
|
2016-08-17 22:54:54 -07:00
|
|
|
Eina_Vector2 point;
|
|
|
|
Evas *eo_e;
|
|
|
|
int event_id;
|
2011-12-12 21:59:36 -08:00
|
|
|
int addgrab = 0;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata;
|
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
2010-01-16 04:20:22 -08:00
|
|
|
|
2016-08-29 01:04:31 -07:00
|
|
|
static const int value_flags =
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TIMESTAMP) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_X) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_Y) |
|
2019-06-20 03:13:37 -07:00
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TOUCH_ID) |
|
2016-08-29 01:04:31 -07:00
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_BUTTON);
|
|
|
|
|
2016-08-17 22:54:54 -07:00
|
|
|
if (!e || !ev) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
2016-08-17 22:54:54 -07:00
|
|
|
|
2016-10-21 05:25:41 -07:00
|
|
|
pdata = _evas_pointer_data_by_device_get(e, ev->device);
|
|
|
|
if (!pdata) return;
|
2016-08-17 22:54:54 -07:00
|
|
|
eo_e = e->evas;
|
|
|
|
DBG("ButtonEvent:multi down time=%u x=%.1f y=%.1f button=%d downs=%d",
|
2019-06-20 03:13:37 -07:00
|
|
|
ev->timestamp, ev->cur.x, ev->cur.y, ev->touch_id, pdata->seat->downs);
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->downs++;
|
2012-10-08 18:58:41 -07:00
|
|
|
if (e->is_frozen) return;
|
2016-08-17 22:54:54 -07:00
|
|
|
e->last_timestamp = ev->timestamp;
|
2010-01-16 04:20:22 -08:00
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2016-08-17 22:54:54 -07:00
|
|
|
|
|
|
|
point = ev->cur;
|
2016-08-25 00:03:45 -07:00
|
|
|
evt = ev->eo;
|
2016-08-17 22:54:54 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_DOWN;
|
|
|
|
ev->modifiers = &(e->modifiers);
|
|
|
|
ev->locks = &(e->locks);
|
|
|
|
ev->event_flags = e->default_event_flags;
|
2016-08-29 01:04:31 -07:00
|
|
|
ev->value_flags |= value_flags;
|
2016-08-17 22:54:54 -07:00
|
|
|
if (ev->device) efl_ref(ev->device);
|
2013-05-07 13:53:42 -07:00
|
|
|
|
2010-01-16 04:20:22 -08:00
|
|
|
_evas_walk(e);
|
From: EunMi Lee <eunmi15.lee@samsung.com>
Subject: [E-devel] [Patch] [Evas] Patch to provide information of
touched points
Hello,
I made a new patch to get information of current touched point instead
of Touch Event.
I added touch_points (Eina_List) to the Evas structure and it maintains touched points on the evas.
New touched point is added to the touch_points when we get Mouse_Down and Multi_Down,
touched point is updated when we get Mouse_Move and Mult_Move,
and touched point is removed when we get Mouse_Up and Multi_Up.
The each touch point has coordinate, id and state information as follows:
id - identifier. 0 for Mouse Event and device id for Multi Event. coordinate - (x, y) coordinate of point.
state - state of point. type is Evas_Touch_Point_State enum.
(EVAS_TOUCH_POINT_DOWN, EVAS_TOUCH_POINT_UP, EVAS_TOUCH_POINT_MOVE,
EVAS_TOUCH_POINT_STILL, EVAS_TOUCH_POINT_CANCEL)
There are 4 new APIs to get touch point's information as follows:
unsigned int evas_touch_point_list_count(Evas *e);
void evas_touch_point_list_nth_xy_get(Evas *e, unsigned int n, Evas_Coord *x, Evas_Coord *y);
int evas_touch_point_list_nth_id_get(Evas *e, unsigned int n);
Evas_Touch_Point_State evas_touch_point_list_nth_state_get(Evas *e, unsigned int n);
I added APIs to get each information instead of exposing whole
structure to make it easy to expand in the future as you mentioned in
the below e-mail :)
SVN revision: 64373
2011-10-24 22:03:50 -07:00
|
|
|
/* append new touch point to the touch point list */
|
2019-06-20 03:13:37 -07:00
|
|
|
_evas_touch_point_append(eo_e, ev->touch_id, ev->cur.x, ev->cur.y);
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->mouse_grabbed == 0)
|
2011-12-12 21:59:36 -08:00
|
|
|
{
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->downs > 1) addgrab = pdata->seat->downs - 1;
|
2011-12-12 21:59:36 -08:00
|
|
|
}
|
2017-06-02 15:23:45 -07:00
|
|
|
copy = evas_event_list_copy(pdata->seat->object.in);
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_obj)
|
2011-09-25 19:45:06 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
2011-09-25 19:45:06 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (obj_pdata->pointer_mode != EVAS_OBJECT_POINTER_MODE_NOGRAB)
|
|
|
|
{
|
|
|
|
obj_pdata->mouse_grabbed += addgrab + 1;
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->mouse_grabbed += addgrab + 1;
|
2011-09-25 19:45:06 -07:00
|
|
|
}
|
|
|
|
}
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_obj)
|
2010-01-16 04:20:22 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2016-08-17 22:54:54 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MULTI_DOWN, evt,
|
|
|
|
event_id, EFL_EVENT_FINGER_DOWN);
|
2013-01-16 23:21:06 -08:00
|
|
|
if ((obj->proxy->is_proxy) || (obj->proxy->src_events))
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_source_multi_down_events(obj, e, evt, pdata, event_id);
|
2012-10-25 21:41:59 -07:00
|
|
|
if (e->delete_me || e->is_frozen) break;
|
2010-01-16 04:20:22 -08:00
|
|
|
}
|
2013-11-28 00:00:35 -08:00
|
|
|
eina_list_free(copy);
|
|
|
|
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
From: EunMi Lee <eunmi15.lee@samsung.com>
Subject: [E-devel] [Patch] [Evas] Patch to provide information of
touched points
Hello,
I made a new patch to get information of current touched point instead
of Touch Event.
I added touch_points (Eina_List) to the Evas structure and it maintains touched points on the evas.
New touched point is added to the touch_points when we get Mouse_Down and Multi_Down,
touched point is updated when we get Mouse_Move and Mult_Move,
and touched point is removed when we get Mouse_Up and Multi_Up.
The each touch point has coordinate, id and state information as follows:
id - identifier. 0 for Mouse Event and device id for Multi Event. coordinate - (x, y) coordinate of point.
state - state of point. type is Evas_Touch_Point_State enum.
(EVAS_TOUCH_POINT_DOWN, EVAS_TOUCH_POINT_UP, EVAS_TOUCH_POINT_MOVE,
EVAS_TOUCH_POINT_STILL, EVAS_TOUCH_POINT_CANCEL)
There are 4 new APIs to get touch point's information as follows:
unsigned int evas_touch_point_list_count(Evas *e);
void evas_touch_point_list_nth_xy_get(Evas *e, unsigned int n, Evas_Coord *x, Evas_Coord *y);
int evas_touch_point_list_nth_id_get(Evas *e, unsigned int n);
Evas_Touch_Point_State evas_touch_point_list_nth_state_get(Evas *e, unsigned int n);
I added APIs to get each information instead of exposing whole
structure to make it easy to expand in the future as you mentioned in
the below e-mail :)
SVN revision: 64373
2011-10-24 22:03:50 -07:00
|
|
|
/* update touch point's state to EVAS_TOUCH_POINT_STILL */
|
2019-06-20 03:13:37 -07:00
|
|
|
_evas_touch_point_update(eo_e, ev->touch_id, ev->cur.x, ev->cur.y, EVAS_TOUCH_POINT_STILL);
|
2010-01-16 04:20:22 -08:00
|
|
|
_evas_unwalk(e);
|
|
|
|
|
2016-08-17 22:54:54 -07:00
|
|
|
if (ev->device) efl_unref(ev->device);
|
2013-05-07 13:53:42 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-08-25 03:20:10 -07:00
|
|
|
_canvas_event_feed_multi_up_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data *ev)
|
2013-05-07 13:53:42 -07:00
|
|
|
{
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer *evt;
|
2010-01-16 04:20:22 -08:00
|
|
|
Eina_List *l, *copy;
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object *eo_obj;
|
2016-08-17 22:54:54 -07:00
|
|
|
Eina_Vector2 point;
|
|
|
|
Evas *eo_e;
|
|
|
|
int event_id;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata;
|
2010-01-16 04:20:22 -08:00
|
|
|
|
2016-08-29 01:04:31 -07:00
|
|
|
static const int value_flags =
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TIMESTAMP) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_X) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_Y) |
|
2019-06-20 03:13:37 -07:00
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TOUCH_ID);
|
2016-08-29 01:04:31 -07:00
|
|
|
|
2016-08-17 22:54:54 -07:00
|
|
|
if (!e || !ev) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
2016-08-17 22:54:54 -07:00
|
|
|
|
2016-10-21 05:25:41 -07:00
|
|
|
pdata = _evas_pointer_data_by_device_get(e, ev->device);
|
|
|
|
if (!pdata) return;
|
2016-08-17 22:54:54 -07:00
|
|
|
eo_e = e->evas;
|
|
|
|
DBG("ButtonEvent:multi up time=%u x=%.1f y=%.1f device=%d downs=%d",
|
2019-06-20 03:13:37 -07:00
|
|
|
ev->timestamp, ev->cur.x, ev->cur.y, ev->touch_id, pdata->seat->downs);
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->downs <= 0) return;
|
|
|
|
pdata->seat->downs--;
|
2012-10-08 18:58:41 -07:00
|
|
|
if (e->is_frozen) return;
|
2016-08-17 22:54:54 -07:00
|
|
|
e->last_timestamp = ev->timestamp;
|
2010-01-16 04:20:22 -08:00
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2016-08-17 22:54:54 -07:00
|
|
|
|
|
|
|
point = ev->cur;
|
2016-08-25 00:03:45 -07:00
|
|
|
evt = ev->eo;
|
2016-08-17 22:54:54 -07:00
|
|
|
ev->action = EFL_POINTER_ACTION_UP;
|
|
|
|
ev->modifiers = &(e->modifiers);
|
|
|
|
ev->locks = &(e->locks);
|
|
|
|
ev->event_flags = e->default_event_flags;
|
2016-08-29 01:04:31 -07:00
|
|
|
ev->value_flags |= value_flags;
|
2016-08-17 22:54:54 -07:00
|
|
|
if (ev->device) efl_ref(ev->device);
|
2014-08-26 20:15:33 -07:00
|
|
|
|
2010-01-16 04:20:22 -08:00
|
|
|
_evas_walk(e);
|
From: EunMi Lee <eunmi15.lee@samsung.com>
Subject: [E-devel] [Patch] [Evas] Patch to provide information of
touched points
Hello,
I made a new patch to get information of current touched point instead
of Touch Event.
I added touch_points (Eina_List) to the Evas structure and it maintains touched points on the evas.
New touched point is added to the touch_points when we get Mouse_Down and Multi_Down,
touched point is updated when we get Mouse_Move and Mult_Move,
and touched point is removed when we get Mouse_Up and Multi_Up.
The each touch point has coordinate, id and state information as follows:
id - identifier. 0 for Mouse Event and device id for Multi Event. coordinate - (x, y) coordinate of point.
state - state of point. type is Evas_Touch_Point_State enum.
(EVAS_TOUCH_POINT_DOWN, EVAS_TOUCH_POINT_UP, EVAS_TOUCH_POINT_MOVE,
EVAS_TOUCH_POINT_STILL, EVAS_TOUCH_POINT_CANCEL)
There are 4 new APIs to get touch point's information as follows:
unsigned int evas_touch_point_list_count(Evas *e);
void evas_touch_point_list_nth_xy_get(Evas *e, unsigned int n, Evas_Coord *x, Evas_Coord *y);
int evas_touch_point_list_nth_id_get(Evas *e, unsigned int n);
Evas_Touch_Point_State evas_touch_point_list_nth_state_get(Evas *e, unsigned int n);
I added APIs to get each information instead of exposing whole
structure to make it easy to expand in the future as you mentioned in
the below e-mail :)
SVN revision: 64373
2011-10-24 22:03:50 -07:00
|
|
|
/* update released touch point */
|
2019-06-20 03:13:37 -07:00
|
|
|
_evas_touch_point_update(eo_e, ev->touch_id, ev->cur.x, ev->cur.y, EVAS_TOUCH_POINT_UP);
|
2017-06-02 15:23:45 -07:00
|
|
|
copy = evas_event_list_copy(pdata->seat->object.in);
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_obj)
|
2010-01-16 04:20:22 -08:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2016-08-17 22:54:54 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
|
|
|
if (((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))
|
2011-06-13 03:00:25 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
obj_pdata->mouse_grabbed--;
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->mouse_grabbed--;
|
2011-06-13 03:00:25 -07:00
|
|
|
}
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MULTI_UP, evt,
|
|
|
|
event_id, EFL_EVENT_FINGER_UP);
|
2013-01-16 23:21:06 -08:00
|
|
|
if ((obj->proxy->is_proxy) || (obj->proxy->src_events))
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_source_multi_up_events(obj, e, evt, pdata, event_id);
|
2012-10-25 21:41:59 -07:00
|
|
|
if (e->delete_me || e->is_frozen) break;
|
2010-01-16 04:20:22 -08:00
|
|
|
}
|
2013-11-28 00:00:35 -08:00
|
|
|
eina_list_free(copy);
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->mouse_grabbed == 0)
|
2017-02-16 02:34:08 -08:00
|
|
|
{
|
|
|
|
_post_up_handle(e, evt, pdata);
|
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
|
|
|
}
|
|
|
|
|
From: EunMi Lee <eunmi15.lee@samsung.com>
Subject: [E-devel] [Patch] [Evas] Patch to provide information of
touched points
Hello,
I made a new patch to get information of current touched point instead
of Touch Event.
I added touch_points (Eina_List) to the Evas structure and it maintains touched points on the evas.
New touched point is added to the touch_points when we get Mouse_Down and Multi_Down,
touched point is updated when we get Mouse_Move and Mult_Move,
and touched point is removed when we get Mouse_Up and Multi_Up.
The each touch point has coordinate, id and state information as follows:
id - identifier. 0 for Mouse Event and device id for Multi Event. coordinate - (x, y) coordinate of point.
state - state of point. type is Evas_Touch_Point_State enum.
(EVAS_TOUCH_POINT_DOWN, EVAS_TOUCH_POINT_UP, EVAS_TOUCH_POINT_MOVE,
EVAS_TOUCH_POINT_STILL, EVAS_TOUCH_POINT_CANCEL)
There are 4 new APIs to get touch point's information as follows:
unsigned int evas_touch_point_list_count(Evas *e);
void evas_touch_point_list_nth_xy_get(Evas *e, unsigned int n, Evas_Coord *x, Evas_Coord *y);
int evas_touch_point_list_nth_id_get(Evas *e, unsigned int n);
Evas_Touch_Point_State evas_touch_point_list_nth_state_get(Evas *e, unsigned int n);
I added APIs to get each information instead of exposing whole
structure to make it easy to expand in the future as you mentioned in
the below e-mail :)
SVN revision: 64373
2011-10-24 22:03:50 -07:00
|
|
|
/* remove released touch point from the touch point list */
|
2019-06-20 03:13:37 -07:00
|
|
|
_evas_touch_point_remove(eo_e, ev->touch_id);
|
2010-01-16 04:20:22 -08:00
|
|
|
_evas_unwalk(e);
|
2016-08-17 22:54:54 -07:00
|
|
|
|
|
|
|
if (ev->device) efl_unref(ev->device);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
2016-08-17 23:33:36 -07:00
|
|
|
_canvas_event_feed_multi_internal(Evas *eo_e, Evas_Public_Data *e,
|
|
|
|
int d, int x, int y,
|
|
|
|
double rad, double radx, double rady,
|
|
|
|
double pres, double ang,
|
|
|
|
double fx, double fy,
|
|
|
|
Evas_Button_Flags flags,
|
|
|
|
unsigned int timestamp,
|
|
|
|
const void *data, Efl_Pointer_Action action)
|
2016-08-17 22:54:54 -07:00
|
|
|
{
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev = NULL;
|
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-17 22:54:54 -07:00
|
|
|
|
2019-02-09 10:08:45 -08:00
|
|
|
evt = efl_input_pointer_instance_get( eo_e, (void **) &ev);
|
2016-08-17 22:54:54 -07:00
|
|
|
if (!e || !ev) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
2016-08-17 22:54:54 -07:00
|
|
|
|
2017-01-06 09:57:46 -08:00
|
|
|
if (EINA_DBL_EQ(fx, 0.0)) fx = x;
|
|
|
|
if (EINA_DBL_EQ(fy, 0.0)) fy = y;
|
2016-08-17 22:54:54 -07:00
|
|
|
|
2016-08-17 23:33:36 -07:00
|
|
|
ev->action = action;
|
2019-06-20 03:13:37 -07:00
|
|
|
ev->touch_id = d;
|
2016-08-17 22:54:54 -07:00
|
|
|
ev->cur.x = fx;
|
|
|
|
ev->cur.y = fy;
|
|
|
|
ev->pressure = pres;
|
|
|
|
ev->angle = ang;
|
|
|
|
ev->radius = rad;
|
|
|
|
ev->radius_x = radx;
|
|
|
|
ev->radius_y = rady;
|
|
|
|
ev->button_flags = flags;
|
|
|
|
ev->timestamp = timestamp;
|
|
|
|
ev->data = (void *) data;
|
2016-10-26 05:37:29 -07:00
|
|
|
ev->device = efl_ref(_evas_event_legacy_device_get(eo_e, EINA_TRUE));
|
2016-08-17 22:54:54 -07:00
|
|
|
|
2016-08-17 23:33:36 -07:00
|
|
|
switch (action)
|
2016-08-17 22:54:54 -07:00
|
|
|
{
|
2016-08-17 23:33:36 -07:00
|
|
|
case EFL_POINTER_ACTION_DOWN:
|
2016-08-17 22:54:54 -07:00
|
|
|
_canvas_event_feed_multi_down_internal(e, ev);
|
2016-08-17 23:33:36 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case EFL_POINTER_ACTION_UP:
|
2016-08-17 22:54:54 -07:00
|
|
|
_canvas_event_feed_multi_up_internal(e, ev);
|
2016-08-17 23:33:36 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case EFL_POINTER_ACTION_MOVE:
|
|
|
|
_canvas_event_feed_multi_move_internal(e, ev);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default: break;
|
2016-08-17 22:54:54 -07:00
|
|
|
}
|
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2016-08-17 22:54:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_event_input_multi_down(Eo *eo_e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, Evas_Button_Flags flags, unsigned int timestamp, const void *data)
|
|
|
|
{
|
2016-08-25 19:27:37 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2016-08-17 22:54:54 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-17 23:33:36 -07:00
|
|
|
_canvas_event_feed_multi_internal(eo_e, e, d,
|
|
|
|
x - e->framespace.x, y - e->framespace.y,
|
|
|
|
rad, radx, rady, pres, ang,
|
|
|
|
fx, fy, flags, timestamp, data, EFL_POINTER_ACTION_DOWN);
|
2016-08-17 22:54:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_event_feed_multi_down(Eo *eo_e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, Evas_Button_Flags flags, unsigned int timestamp, const void *data)
|
|
|
|
{
|
2016-08-25 19:27:37 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2016-08-17 22:54:54 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-17 23:33:36 -07:00
|
|
|
_canvas_event_feed_multi_internal(eo_e, e, d, x, y, rad, radx, rady, pres, ang,
|
|
|
|
fx, fy, flags, timestamp, data, EFL_POINTER_ACTION_DOWN);
|
2010-01-16 04:20:22 -08:00
|
|
|
}
|
|
|
|
|
2016-05-11 00:21:49 -07:00
|
|
|
EAPI void
|
|
|
|
evas_event_input_multi_up(Eo *eo_e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, Evas_Button_Flags flags, unsigned int timestamp, const void *data)
|
2013-05-07 13:53:42 -07:00
|
|
|
{
|
2016-08-25 19:27:37 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-17 23:33:36 -07:00
|
|
|
_canvas_event_feed_multi_internal(eo_e, e, d,
|
|
|
|
x - e->framespace.x, y - e->framespace.y,
|
|
|
|
rad, radx, rady, pres, ang,
|
|
|
|
fx, fy, flags, timestamp, data, EFL_POINTER_ACTION_UP);
|
2013-05-07 13:53:42 -07:00
|
|
|
}
|
|
|
|
|
2016-05-11 00:21:49 -07:00
|
|
|
EAPI void
|
|
|
|
evas_event_feed_multi_up(Eo *eo_e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, Evas_Button_Flags flags, unsigned int timestamp, const void *data)
|
2013-05-07 13:53:42 -07:00
|
|
|
{
|
2016-08-25 19:27:37 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-17 23:33:36 -07:00
|
|
|
_canvas_event_feed_multi_internal(eo_e, e, d, x, y, rad, radx, rady, pres, ang,
|
|
|
|
fx, fy, flags, timestamp, data, EFL_POINTER_ACTION_UP);
|
2013-05-07 13:53:42 -07:00
|
|
|
}
|
|
|
|
|
2013-05-03 12:38:59 -07:00
|
|
|
static void
|
2016-08-25 03:20:10 -07:00
|
|
|
_canvas_event_feed_multi_move_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data *ev)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-17 23:33:36 -07:00
|
|
|
Eina_List *l, *copy;
|
|
|
|
Evas_Object *eo_obj;
|
|
|
|
Eina_Vector2 point;
|
|
|
|
Evas *eo_e;
|
|
|
|
int event_id;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata;
|
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
2016-08-17 23:33:36 -07:00
|
|
|
|
2016-08-29 01:04:31 -07:00
|
|
|
/* FIXME: Add previous x,y information (from evas touch point list) */
|
|
|
|
static const int value_flags =
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TIMESTAMP) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_X) |
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_Y) |
|
2019-06-20 03:13:37 -07:00
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TOUCH_ID);
|
2016-08-29 01:04:31 -07:00
|
|
|
|
2016-08-17 23:33:36 -07:00
|
|
|
if (!e || !ev) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
2016-08-17 23:33:36 -07:00
|
|
|
|
2016-10-21 05:25:41 -07:00
|
|
|
pdata = _evas_pointer_data_by_device_get(e, ev->device);
|
|
|
|
if (!pdata) return;
|
2016-08-17 23:33:36 -07:00
|
|
|
eo_e = e->evas;
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2012-10-08 18:58:41 -07:00
|
|
|
|
|
|
|
if (e->is_frozen) return;
|
2016-08-17 23:33:36 -07:00
|
|
|
e->last_timestamp = ev->timestamp;
|
2010-01-16 04:20:22 -08:00
|
|
|
|
2017-06-02 15:23:45 -07:00
|
|
|
if ((!pdata->seat->inside) && (pdata->seat->mouse_grabbed == 0)) return;
|
2011-09-21 03:35:03 -07:00
|
|
|
|
2016-08-25 00:03:45 -07:00
|
|
|
evt = ev->eo;
|
2016-08-17 23:33:36 -07:00
|
|
|
ev->modifiers = &(e->modifiers);
|
|
|
|
ev->locks = &(e->locks);
|
|
|
|
ev->event_flags = e->default_event_flags;
|
|
|
|
ev->action = EFL_POINTER_ACTION_MOVE;
|
2016-08-29 01:04:31 -07:00
|
|
|
ev->value_flags |= value_flags;
|
2016-08-17 23:33:36 -07:00
|
|
|
if (ev->device) efl_ref(ev->device);
|
|
|
|
|
|
|
|
point = ev->cur;
|
|
|
|
|
2010-01-16 04:20:22 -08:00
|
|
|
_evas_walk(e);
|
From: EunMi Lee <eunmi15.lee@samsung.com>
Subject: [E-devel] [Patch] [Evas] Patch to provide information of
touched points
Hello,
I made a new patch to get information of current touched point instead
of Touch Event.
I added touch_points (Eina_List) to the Evas structure and it maintains touched points on the evas.
New touched point is added to the touch_points when we get Mouse_Down and Multi_Down,
touched point is updated when we get Mouse_Move and Mult_Move,
and touched point is removed when we get Mouse_Up and Multi_Up.
The each touch point has coordinate, id and state information as follows:
id - identifier. 0 for Mouse Event and device id for Multi Event. coordinate - (x, y) coordinate of point.
state - state of point. type is Evas_Touch_Point_State enum.
(EVAS_TOUCH_POINT_DOWN, EVAS_TOUCH_POINT_UP, EVAS_TOUCH_POINT_MOVE,
EVAS_TOUCH_POINT_STILL, EVAS_TOUCH_POINT_CANCEL)
There are 4 new APIs to get touch point's information as follows:
unsigned int evas_touch_point_list_count(Evas *e);
void evas_touch_point_list_nth_xy_get(Evas *e, unsigned int n, Evas_Coord *x, Evas_Coord *y);
int evas_touch_point_list_nth_id_get(Evas *e, unsigned int n);
Evas_Touch_Point_State evas_touch_point_list_nth_state_get(Evas *e, unsigned int n);
I added APIs to get each information instead of exposing whole
structure to make it easy to expand in the future as you mentioned in
the below e-mail :)
SVN revision: 64373
2011-10-24 22:03:50 -07:00
|
|
|
/* update moved touch point */
|
2019-06-20 03:13:37 -07:00
|
|
|
_evas_touch_point_update(eo_e, ev->touch_id, ev->cur.x, ev->cur.y, EVAS_TOUCH_POINT_MOVE);
|
2010-01-16 04:20:22 -08:00
|
|
|
/* if our mouse button is grabbed to any objects */
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->mouse_grabbed > 0)
|
2010-01-16 04:20:22 -08:00
|
|
|
{
|
2011-09-21 03:35:03 -07:00
|
|
|
/* go thru old list of in objects */
|
2017-06-02 15:23:45 -07:00
|
|
|
copy = evas_event_list_copy(pdata->seat->object.in);
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_obj)
|
2010-01-16 04:20:22 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2017-06-16 12:03:09 -07:00
|
|
|
if (_evas_event_object_pointer_allow(eo_obj, obj, obj_pdata) &&
|
2013-02-14 22:48:07 -08:00
|
|
|
(!evas_object_is_source_invisible(eo_obj, obj) ||
|
2017-06-16 12:03:09 -07:00
|
|
|
obj_pdata->mouse_grabbed))
|
2010-01-16 04:20:22 -08:00
|
|
|
{
|
2016-08-17 23:33:36 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MULTI_MOVE, evt,
|
|
|
|
event_id, EFL_EVENT_FINGER_MOVE);
|
2013-01-16 23:21:06 -08:00
|
|
|
if ((obj->proxy->is_proxy) || (obj->proxy->src_events))
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_source_multi_move_events(obj, e, evt, pdata, event_id);
|
2012-10-26 05:44:52 -07:00
|
|
|
|
|
|
|
if (e->delete_me || e->is_frozen) break;
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
|
|
|
}
|
2012-10-26 05:23:35 -07:00
|
|
|
eina_list_free(copy);
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2010-01-16 04:20:22 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-21 03:35:03 -07:00
|
|
|
Eina_List *ins;
|
2014-08-26 20:15:33 -07:00
|
|
|
|
2011-09-21 03:35:03 -07:00
|
|
|
/* get all new in objects */
|
2016-08-17 23:33:36 -07:00
|
|
|
ins = evas_event_objects_event_list(eo_e, NULL, ev->cur.x, ev->cur.y);
|
2011-09-21 03:35:03 -07:00
|
|
|
/* go thru old list of in objects */
|
2017-06-02 15:23:45 -07:00
|
|
|
copy = evas_event_list_copy(pdata->seat->object.in);
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_obj)
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata)
|
|
|
|
{
|
|
|
|
ERR("Could not find the object pointer data for device %p",
|
|
|
|
ev->device);
|
|
|
|
continue;
|
|
|
|
}
|
2011-09-21 03:35:03 -07:00
|
|
|
/* if its under the pointer and its visible and its in the new */
|
|
|
|
/* in list */
|
|
|
|
// FIXME: i don't think we need this
|
2012-10-08 18:58:41 -07:00
|
|
|
// evas_object_clip_recalc(eo_obj);
|
2016-08-17 23:33:36 -07:00
|
|
|
if (evas_object_is_in_output_rect(eo_obj, obj, ev->cur.x, ev->cur.y, 1, 1) &&
|
2017-06-16 12:03:09 -07:00
|
|
|
_evas_event_object_pointer_allow(eo_obj, obj, obj_pdata) &&
|
2017-06-16 12:03:09 -07:00
|
|
|
_evas_event_object_pointer_allow_precise(eo_obj, obj, ev->cur.x, ev->cur.y, ins) &&
|
2013-02-14 22:48:07 -08:00
|
|
|
(!evas_object_is_source_invisible(eo_obj, obj) ||
|
2017-06-16 12:03:09 -07:00
|
|
|
obj_pdata->mouse_grabbed))
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2016-08-17 23:33:36 -07:00
|
|
|
ev->cur = point;
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed);
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MULTI_MOVE, evt,
|
|
|
|
event_id, EFL_EVENT_FINGER_MOVE);
|
2013-01-16 23:21:06 -08:00
|
|
|
if ((obj->proxy->is_proxy) || (obj->proxy->src_events))
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_event_source_multi_move_events(obj, e, evt, pdata, event_id);
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2012-10-25 21:41:59 -07:00
|
|
|
if (e->delete_me || e->is_frozen) break;
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2013-11-28 00:00:35 -08:00
|
|
|
eina_list_free(copy);
|
2017-06-02 15:23:45 -07:00
|
|
|
if (pdata->seat->mouse_grabbed == 0)
|
2011-06-28 22:05:35 -07:00
|
|
|
{
|
|
|
|
/* free our old list of ins */
|
2017-06-02 15:23:45 -07:00
|
|
|
eina_list_free(pdata->seat->object.in);
|
2011-06-28 22:05:35 -07:00
|
|
|
/* and set up the new one */
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->object.in = ins;
|
2011-06-28 22:05:35 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* free our cur ins */
|
|
|
|
eina_list_free(ins);
|
|
|
|
}
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2010-01-16 04:20:22 -08:00
|
|
|
}
|
|
|
|
_evas_unwalk(e);
|
2016-08-17 23:33:36 -07:00
|
|
|
|
|
|
|
if (ev->device) efl_unref(ev->device);
|
2010-01-16 04:20:22 -08:00
|
|
|
}
|
|
|
|
|
2016-05-11 00:21:49 -07:00
|
|
|
EAPI void
|
|
|
|
evas_event_input_multi_move(Eo *eo_e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, unsigned int timestamp, const void *data)
|
2013-05-03 12:38:59 -07:00
|
|
|
{
|
2016-08-17 23:33:36 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-17 23:33:36 -07:00
|
|
|
_canvas_event_feed_multi_internal(eo_e, e, d, x - e->framespace.x, y - e->framespace.y,
|
|
|
|
rad, radx, rady,
|
|
|
|
pres, ang, fx, fy, EVAS_BUTTON_NONE, timestamp, data,
|
|
|
|
EFL_POINTER_ACTION_MOVE);
|
2013-05-03 12:38:59 -07:00
|
|
|
}
|
|
|
|
|
2016-05-11 00:21:49 -07:00
|
|
|
EAPI void
|
|
|
|
evas_event_feed_multi_move(Eo *eo_e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, unsigned int timestamp, const void *data)
|
2013-05-03 12:38:59 -07:00
|
|
|
{
|
2016-08-17 23:33:36 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-17 23:33:36 -07:00
|
|
|
_canvas_event_feed_multi_internal(eo_e, e, d, x, y, rad, radx, rady,
|
|
|
|
pres, ang, fx, fy, EVAS_BUTTON_NONE, timestamp, data,
|
|
|
|
EFL_POINTER_ACTION_MOVE);
|
2013-05-03 12:38:59 -07:00
|
|
|
}
|
|
|
|
|
2016-10-19 06:02:18 -07:00
|
|
|
static void
|
|
|
|
_key_event_dispatch(Evas_Public_Data *e, void *event_info,
|
|
|
|
Efl_Input_Device *device,
|
|
|
|
const Efl_Event_Description *efl_event_desc,
|
|
|
|
Evas_Callback_Type evas_event_type, int event_id)
|
|
|
|
{
|
|
|
|
Eo *focused;
|
|
|
|
|
|
|
|
if (!device)
|
|
|
|
device = e->default_seat;
|
|
|
|
else
|
|
|
|
{
|
2017-06-07 01:36:50 -07:00
|
|
|
const char *name = efl_name_get(device);
|
2016-10-19 06:02:18 -07:00
|
|
|
|
2017-06-02 15:23:45 -07:00
|
|
|
device = efl_input_device_seat_get(device);
|
2016-10-19 06:02:18 -07:00
|
|
|
if (!device)
|
|
|
|
{
|
|
|
|
ERR("Could not find the parent seat from device name '%s'. Using default seat instead", name);
|
|
|
|
device = e->default_seat;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
focused = eina_hash_find(e->focused_objects, &device);
|
|
|
|
|
|
|
|
if (!focused)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Evas_Object_Protected_Data *focused_obj =
|
|
|
|
efl_data_scope_get(focused, EFL_CANVAS_OBJECT_CLASS);
|
|
|
|
|
2018-09-12 12:18:03 -07:00
|
|
|
if (!focused_obj)
|
|
|
|
{
|
|
|
|
WRN("No element focused");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-10-19 06:02:18 -07:00
|
|
|
if (!e->is_frozen && !evas_event_freezes_through(focused, focused_obj))
|
|
|
|
{
|
|
|
|
evas_object_event_callback_call(focused, focused_obj,
|
|
|
|
evas_event_type, event_info,
|
|
|
|
event_id, efl_event_desc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-14 06:38:58 -07:00
|
|
|
static void
|
2016-08-25 03:20:10 -07:00
|
|
|
_canvas_event_feed_key_down_internal(Evas_Public_Data *e, Efl_Input_Key_Data *ev)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-08-17 03:39:10 -07:00
|
|
|
Eina_Bool exclusive = EINA_FALSE;
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer *evt;
|
2012-10-08 18:58:41 -07:00
|
|
|
int event_id = 0;
|
2017-02-16 02:34:08 -08:00
|
|
|
Eo *eo_e;
|
2011-11-11 23:51:58 -08:00
|
|
|
|
2016-08-17 03:39:10 -07:00
|
|
|
if (!e || !ev) return;
|
2012-10-08 18:58:41 -07:00
|
|
|
if (e->is_frozen) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
2017-02-16 02:34:08 -08:00
|
|
|
|
|
|
|
eo_e = e->evas;
|
2016-08-17 03:39:10 -07:00
|
|
|
e->last_timestamp = ev->timestamp;
|
2007-04-29 21:22:42 -07:00
|
|
|
_evas_walk(e);
|
2011-09-21 03:35:03 -07:00
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2014-08-26 20:15:33 -07:00
|
|
|
|
2016-08-25 00:03:45 -07:00
|
|
|
evt = ev->eo;
|
2016-08-17 03:39:10 -07:00
|
|
|
ev->modifiers = &(e->modifiers);
|
|
|
|
ev->locks = &(e->locks);
|
|
|
|
ev->event_flags = e->default_event_flags;
|
|
|
|
if (ev->device) efl_ref(ev->device);
|
2016-05-31 23:32:35 -07:00
|
|
|
|
2011-11-11 23:01:38 -08:00
|
|
|
if (e->grabs)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
Evas_Key_Grab *g;
|
2016-11-07 10:44:46 -08:00
|
|
|
Evas_Modifier_Mask *seat_mask, modifier_mask;
|
2017-03-23 15:00:44 -07:00
|
|
|
Efl_Input_Device *seat = NULL;
|
2011-11-11 23:01:38 -08:00
|
|
|
|
|
|
|
e->walking_grabs++;
|
2017-03-23 15:00:44 -07:00
|
|
|
if (ev->device)
|
|
|
|
seat = efl_input_device_seat_get(ev->device);
|
|
|
|
seat_mask = eina_hash_find(e->modifiers.masks, &seat);
|
2016-11-07 10:44:46 -08:00
|
|
|
modifier_mask = seat_mask ? *seat_mask : 0;
|
2011-11-11 23:01:38 -08:00
|
|
|
EINA_LIST_FOREACH(e->grabs, l, g)
|
|
|
|
{
|
|
|
|
if (g->just_added)
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2011-11-12 00:06:30 -08:00
|
|
|
g->just_added = EINA_FALSE;
|
2011-11-11 23:01:38 -08:00
|
|
|
continue;
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2011-11-11 23:01:38 -08:00
|
|
|
if (g->delete_me) continue;
|
2013-01-25 18:34:59 -08:00
|
|
|
if (!g->object) continue;
|
2016-06-01 01:44:12 -07:00
|
|
|
if (!g->is_active) continue;
|
2016-11-07 10:44:46 -08:00
|
|
|
if (((modifier_mask & g->modifiers) ||
|
|
|
|
(g->modifiers == modifier_mask)) &&
|
2016-08-17 03:39:10 -07:00
|
|
|
(!strcmp(ev->keyname, g->keyname)))
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2016-11-07 10:44:46 -08:00
|
|
|
if (!(modifier_mask & g->not_modifiers))
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *object_obj = efl_data_scope_get(g->object, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-08 18:58:41 -07:00
|
|
|
if (!e->is_frozen &&
|
|
|
|
!evas_event_freezes_through(g->object, object_obj))
|
2012-10-23 21:36:02 -07:00
|
|
|
{
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(g->object, object_obj, EVAS_CALLBACK_KEY_DOWN, evt,
|
|
|
|
event_id, EFL_EVENT_KEY_DOWN);
|
2012-10-23 21:36:02 -07:00
|
|
|
}
|
2011-11-11 23:01:38 -08:00
|
|
|
if (g->exclusive) exclusive = EINA_TRUE;
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
|
|
|
}
|
2011-11-11 23:01:38 -08:00
|
|
|
if (e->delete_me) break;
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2011-11-11 23:01:38 -08:00
|
|
|
e->walking_grabs--;
|
|
|
|
if (e->walking_grabs <= 0)
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2011-11-11 23:01:38 -08:00
|
|
|
while (e->delete_grabs > 0)
|
|
|
|
{
|
|
|
|
e->delete_grabs--;
|
|
|
|
for (l = e->grabs; l;)
|
|
|
|
{
|
|
|
|
g = eina_list_data_get(l);
|
|
|
|
l = eina_list_next(l);
|
|
|
|
if (g->delete_me)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *g_object_obj = efl_data_scope_get(g->object, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_key_grab_free(g->object, g_object_obj, g->keyname,
|
|
|
|
g->modifiers, g->not_modifiers);
|
|
|
|
}
|
2011-11-11 23:01:38 -08:00
|
|
|
}
|
|
|
|
}
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2003-01-05 04:55:37 -08:00
|
|
|
}
|
2016-10-19 06:02:18 -07:00
|
|
|
if (!exclusive)
|
|
|
|
_key_event_dispatch(e, evt, ev->device, EFL_EVENT_KEY_DOWN,
|
|
|
|
EVAS_CALLBACK_KEY_DOWN, event_id);
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2007-04-29 21:22:42 -07:00
|
|
|
_evas_unwalk(e);
|
2016-05-31 23:32:35 -07:00
|
|
|
|
2016-08-17 03:39:10 -07:00
|
|
|
if (ev->device) efl_unref(ev->device);
|
2002-12-16 16:00:38 -08:00
|
|
|
}
|
|
|
|
|
2014-04-14 06:38:58 -07:00
|
|
|
static void
|
2016-08-25 03:20:10 -07:00
|
|
|
_canvas_event_feed_key_up_internal(Evas_Public_Data *e, Efl_Input_Key_Data *ev)
|
2016-08-17 03:39:10 -07:00
|
|
|
{
|
|
|
|
Eina_Bool exclusive = EINA_FALSE;
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer *evt;
|
2012-10-08 18:58:41 -07:00
|
|
|
int event_id = 0;
|
2017-02-16 02:34:08 -08:00
|
|
|
Eo *eo_e;
|
2016-08-17 03:39:10 -07:00
|
|
|
|
|
|
|
if (!e || !ev) return;
|
2012-10-08 18:58:41 -07:00
|
|
|
if (e->is_frozen) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
2017-02-16 02:34:08 -08:00
|
|
|
|
|
|
|
eo_e = e->evas;
|
2016-08-17 03:39:10 -07:00
|
|
|
e->last_timestamp = ev->timestamp;
|
2007-04-29 21:22:42 -07:00
|
|
|
_evas_walk(e);
|
2011-09-21 03:35:03 -07:00
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2014-08-26 20:15:33 -07:00
|
|
|
|
2016-08-25 00:03:45 -07:00
|
|
|
evt = ev->eo;
|
2016-08-17 03:39:10 -07:00
|
|
|
ev->modifiers = &(e->modifiers);
|
|
|
|
ev->locks = &(e->locks);
|
|
|
|
ev->event_flags = e->default_event_flags;
|
|
|
|
if (ev->device) efl_ref(ev->device);
|
2016-05-31 23:32:35 -07:00
|
|
|
|
2011-11-11 23:01:38 -08:00
|
|
|
if (e->grabs)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
Evas_Key_Grab *g;
|
2016-11-07 10:44:46 -08:00
|
|
|
Evas_Modifier_Mask *seat_mask, modifier_mask;
|
2017-03-23 15:00:44 -07:00
|
|
|
Efl_Input_Device *seat = NULL;
|
2011-09-21 03:35:03 -07:00
|
|
|
|
2011-11-11 23:01:38 -08:00
|
|
|
e->walking_grabs++;
|
2017-03-23 15:00:44 -07:00
|
|
|
if (ev->device)
|
|
|
|
seat = efl_input_device_seat_get(ev->device);
|
|
|
|
seat_mask = eina_hash_find(e->modifiers.masks, &seat);
|
2016-11-07 10:44:46 -08:00
|
|
|
modifier_mask = seat_mask ? *seat_mask : 0;
|
2011-11-11 23:01:38 -08:00
|
|
|
EINA_LIST_FOREACH(e->grabs, l, g)
|
|
|
|
{
|
|
|
|
if (g->just_added)
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2011-11-12 00:06:30 -08:00
|
|
|
g->just_added = EINA_FALSE;
|
2011-11-11 23:01:38 -08:00
|
|
|
continue;
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2011-11-11 23:01:38 -08:00
|
|
|
if (g->delete_me) continue;
|
2013-01-25 18:34:59 -08:00
|
|
|
if (!g->object) continue;
|
2016-06-01 01:44:12 -07:00
|
|
|
if (!g->is_active) continue;
|
2016-11-07 10:44:46 -08:00
|
|
|
if (((modifier_mask & g->modifiers) ||
|
|
|
|
(g->modifiers == modifier_mask)) &&
|
|
|
|
(!(modifier_mask & g->not_modifiers)) &&
|
2016-08-17 03:39:10 -07:00
|
|
|
(!strcmp(ev->keyname, g->keyname)))
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *object_obj = efl_data_scope_get(g->object, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-08 18:58:41 -07:00
|
|
|
if (!e->is_frozen &&
|
|
|
|
!evas_event_freezes_through(g->object, object_obj))
|
2012-10-23 01:44:11 -07:00
|
|
|
{
|
2016-06-01 04:40:18 -07:00
|
|
|
evas_object_event_callback_call
|
2016-08-25 00:03:45 -07:00
|
|
|
(g->object, object_obj, EVAS_CALLBACK_KEY_UP, evt,
|
|
|
|
event_id, EFL_EVENT_KEY_UP);
|
2012-10-23 01:44:11 -07:00
|
|
|
}
|
2011-11-11 23:01:38 -08:00
|
|
|
if (g->exclusive) exclusive = EINA_TRUE;
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2011-11-11 23:01:38 -08:00
|
|
|
if (e->delete_me) break;
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2011-11-11 23:01:38 -08:00
|
|
|
e->walking_grabs--;
|
|
|
|
if (e->walking_grabs <= 0)
|
2011-09-21 03:35:03 -07:00
|
|
|
{
|
2011-11-11 23:01:38 -08:00
|
|
|
while (e->delete_grabs > 0)
|
|
|
|
{
|
|
|
|
Eina_List *ll, *l_next;
|
|
|
|
Evas_Key_Grab *gr;
|
|
|
|
|
|
|
|
e->delete_grabs--;
|
|
|
|
EINA_LIST_FOREACH_SAFE(e->grabs, ll, l_next, gr)
|
|
|
|
{
|
|
|
|
if (gr->delete_me)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *gr_object_obj =
|
2016-08-15 06:44:41 -07:00
|
|
|
efl_data_scope_get(gr->object, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_key_grab_free(gr->object, gr_object_obj, gr->keyname,
|
2011-11-11 23:01:38 -08:00
|
|
|
gr->modifiers, gr->not_modifiers);
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
2011-11-11 23:01:38 -08:00
|
|
|
}
|
|
|
|
}
|
2011-09-21 03:35:03 -07:00
|
|
|
}
|
2003-01-05 04:55:37 -08:00
|
|
|
}
|
2016-10-19 06:02:18 -07:00
|
|
|
if (!exclusive)
|
|
|
|
_key_event_dispatch(e, evt, ev->device, EFL_EVENT_KEY_UP,
|
|
|
|
EVAS_CALLBACK_KEY_UP, event_id);
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2007-04-29 21:22:42 -07:00
|
|
|
_evas_unwalk(e);
|
2016-05-31 23:32:35 -07:00
|
|
|
|
2016-08-17 03:39:10 -07:00
|
|
|
if (ev->device) efl_unref(ev->device);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_canvas_event_feed_key_legacy(Eo *eo_e, Evas_Public_Data *e,
|
|
|
|
const char *keyname, const char *key,
|
|
|
|
const char *string, const char *compose,
|
|
|
|
unsigned int timestamp, const void *data,
|
|
|
|
unsigned int keycode, Eina_Bool down)
|
|
|
|
{
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Key_Data *ev = NULL;
|
|
|
|
Efl_Input_Key *evt;
|
2016-08-17 03:39:10 -07:00
|
|
|
|
|
|
|
if (!keyname) return;
|
|
|
|
|
2019-02-09 10:08:45 -08:00
|
|
|
evt = efl_input_key_instance_get( eo_e, (void **) &ev);
|
2016-08-17 03:39:10 -07:00
|
|
|
if (!ev) return;
|
|
|
|
|
|
|
|
ev->keyname = (char *) keyname;
|
|
|
|
ev->data = (void *) data;
|
|
|
|
ev->key = key;
|
|
|
|
ev->string = string;
|
|
|
|
ev->compose = compose;
|
|
|
|
ev->timestamp = timestamp;
|
|
|
|
ev->keycode = keycode;
|
2019-06-26 05:50:59 -07:00
|
|
|
ev->pressed = down;
|
2016-08-17 03:39:10 -07:00
|
|
|
ev->no_stringshare = EINA_TRUE;
|
2016-10-26 05:37:29 -07:00
|
|
|
ev->device = efl_ref(_evas_event_legacy_device_get(e->evas, EINA_FALSE));
|
2016-08-17 03:39:10 -07:00
|
|
|
|
2019-06-26 05:50:59 -07:00
|
|
|
|
2016-08-17 03:39:10 -07:00
|
|
|
if (down)
|
|
|
|
_canvas_event_feed_key_down_internal(e, ev);
|
|
|
|
else
|
|
|
|
_canvas_event_feed_key_up_internal(e, ev);
|
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2002-12-16 16:00:38 -08:00
|
|
|
}
|
|
|
|
|
2016-05-11 00:21:49 -07:00
|
|
|
EAPI void
|
|
|
|
evas_event_feed_key_down(Eo *eo_e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data)
|
2014-04-14 06:38:58 -07:00
|
|
|
{
|
2016-08-25 19:27:37 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-17 03:39:10 -07:00
|
|
|
_canvas_event_feed_key_legacy(eo_e, e, keyname, key, string,
|
|
|
|
compose, timestamp, data, 0, 1);
|
2014-04-14 06:38:58 -07:00
|
|
|
}
|
|
|
|
|
2016-05-11 00:21:49 -07:00
|
|
|
EAPI void
|
|
|
|
evas_event_feed_key_up(Eo *eo_e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data)
|
2014-04-14 06:38:58 -07:00
|
|
|
{
|
2016-08-25 19:27:37 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-17 03:39:10 -07:00
|
|
|
_canvas_event_feed_key_legacy(eo_e, e, keyname, key, string,
|
|
|
|
compose, timestamp, data, 0, 0);
|
2014-04-14 06:38:58 -07:00
|
|
|
}
|
|
|
|
|
2016-05-11 00:21:49 -07:00
|
|
|
EAPI void
|
|
|
|
evas_event_feed_key_down_with_keycode(Eo *eo_e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data, unsigned int keycode)
|
2014-04-14 06:38:58 -07:00
|
|
|
{
|
2016-08-25 19:27:37 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-17 03:39:10 -07:00
|
|
|
_canvas_event_feed_key_legacy(eo_e, e, keyname, key, string,
|
|
|
|
compose, timestamp, data, keycode, 1);
|
2014-04-14 06:38:58 -07:00
|
|
|
}
|
|
|
|
|
2016-05-11 00:21:49 -07:00
|
|
|
EAPI void
|
|
|
|
evas_event_feed_key_up_with_keycode(Eo *eo_e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data, unsigned int keycode)
|
2014-04-14 06:38:58 -07:00
|
|
|
{
|
2016-08-25 19:27:37 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-17 03:39:10 -07:00
|
|
|
_canvas_event_feed_key_legacy(eo_e, e, keyname, key, string,
|
|
|
|
compose, timestamp, data, keycode, 0);
|
2014-04-14 06:38:58 -07:00
|
|
|
}
|
|
|
|
|
2016-05-11 00:21:49 -07:00
|
|
|
EAPI void
|
|
|
|
evas_event_feed_hold(Eo *eo_e, int hold, unsigned int timestamp, const void *data)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Hold_Data *ev = NULL;
|
|
|
|
Efl_Input_Hold *evt;
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *l, *copy;
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Object *eo_obj;
|
2011-12-14 22:23:53 -08:00
|
|
|
int event_id = 0;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata;
|
2008-03-31 14:38:38 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
if (e->is_frozen) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
2008-03-31 14:38:38 -07:00
|
|
|
e->last_timestamp = timestamp;
|
|
|
|
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2016-08-17 03:11:53 -07:00
|
|
|
|
2019-02-09 10:08:45 -08:00
|
|
|
evt = efl_input_hold_instance_get(eo_e, (void **) &ev);
|
2016-08-17 03:11:53 -07:00
|
|
|
if (!ev) return;
|
|
|
|
|
|
|
|
ev->hold = !!hold;
|
|
|
|
ev->data = (void *) data;
|
|
|
|
ev->timestamp = timestamp;
|
|
|
|
ev->event_flags = e->default_event_flags;
|
2016-10-26 05:37:29 -07:00
|
|
|
ev->device = efl_ref(_evas_event_legacy_device_get(eo_e, EINA_TRUE));
|
2014-08-26 20:15:33 -07:00
|
|
|
|
2016-10-21 05:25:41 -07:00
|
|
|
pdata = _evas_pointer_data_by_device_get(e, ev->device);
|
|
|
|
if (!pdata) return;
|
|
|
|
|
|
|
|
|
2008-03-31 14:38:38 -07:00
|
|
|
_evas_walk(e);
|
2017-06-02 15:23:45 -07:00
|
|
|
copy = evas_event_list_copy(pdata->seat->object.in);
|
2012-10-08 18:58:41 -07:00
|
|
|
EINA_LIST_FOREACH(copy, l, eo_obj)
|
2008-03-31 14:38:38 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-25 21:41:59 -07:00
|
|
|
if ( !evas_event_freezes_through(eo_obj, obj))
|
2012-10-23 01:44:11 -07:00
|
|
|
{
|
2016-08-25 00:03:45 -07:00
|
|
|
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_HOLD, evt,
|
|
|
|
event_id, EFL_EVENT_HOLD);
|
2013-01-16 23:21:06 -08:00
|
|
|
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
|
2016-08-17 03:11:53 -07:00
|
|
|
_evas_event_source_hold_events(eo_obj, event_id, evt);
|
2012-10-23 01:44:11 -07:00
|
|
|
}
|
2012-10-25 21:41:59 -07:00
|
|
|
if (e->delete_me || e->is_frozen) break;
|
2008-03-31 14:38:38 -07:00
|
|
|
}
|
2013-11-28 00:00:35 -08:00
|
|
|
eina_list_free(copy);
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
2008-03-31 14:38:38 -07:00
|
|
|
_evas_unwalk(e);
|
2010-03-22 00:04:04 -07:00
|
|
|
_evas_object_event_new();
|
2016-05-30 23:31:17 -07:00
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2008-03-31 14:38:38 -07:00
|
|
|
}
|
|
|
|
|
Expose device (e.g. pen) axis information to applications
Summary:
This patch set adds the necessary code to expose device axis state to applications. This was primarily written with graphics tablets in mind, which -- in addition to acting like a mouse -- also provide information about pen pressure, tilt, etc. Other devices could potentially benefit from this API as well: touchscreens, joysticks, knob controllers, "spaceballs", etc.
Whenever an update to the device state is recieved, an "Axis update" event is synthesized. This event contains the updated information, typically scaled and normalized to a particular logical range (e.g. zero to one for pressure, -pi to pi radians for angles, etc.). Information about the tool which generated the event is also stored so that applications can disambiguate events from multiple devices (or in the case of multitouch screens, individual fingers).
This API is only wired up for use with X11 at the moment. Support for other backends (e.g. Wayland) should be easy to add for those familiar them.
**Note**: The following is a list of changes from the "v2" patches originally sent to the mailinglist
//Define and implement new Ecore_Event_Axis_Update events//
* Harcode axis labels instead of including xserver-properties.h
* Use C89-style comments
* Use doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Create "Ecore_Axis" and "Ecore_Axis_Label" typedefs
* Reference typedef'd instead of raw types
* Adjust how we count through valuators to support tilt/az
* Add support for tilt and azimuth
* Tweak memory management in case number of valuators differ
* Expand TWIST axis normalization to declared range
* Only normalize TWIST axis if resolution == 1 (wacom bug)
* Cache label atoms on first use to minimize round-trips
//Implement EVAS_CALLBACK_AXIS_UPDATE event and friends//
* Update to doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Typedef 'Evas_Axis_Label', 'Evas_Axis'
* Move typedef for 'Evas_Event_Axis_Update'
* Reference typedef'd instead of raw types
//Wire the Ecore and Evas implementations of axis update events together//
* Expose ecore_event_evas_axis_update in Ecore_Input_Evas.h
* Move ecore_event_evas_axis_update to more logical position
//DEBUG: Add axis update logging to evas-multi-touch.c//
* Removed from patch set
//Make evas-multi-touch demo use new axis functionality//
* Have pressure adjust rectangle brightness instead of size
* Use more available axis data when rendering rectangle (azimuth, tilt, twist)
Test Plan: The evas-multi-touch demo was updated to support axis update events. A graphics tablet was then used to verify that the pressure, azimuth, tilt, and twist data was coming through correctly.
Reviewers: cedric, raster
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1514
Conflicts:
src/lib/ecore_input/Ecore_Input.h
Carsten Haitzler -
** fixed forward enum typedefs (make things unhappy)
** fixed conflict above
** fixed wrong param type for _evas_canvas_event_feed_axis_update()
** fixed @sinces to be 1.13
** fixed formatting/indeting
** fixed order of operation reliance in if's with ()'s to be clear
** fixed functions to be static that should have been
2014-11-24 19:07:50 -08:00
|
|
|
void
|
2016-08-25 03:20:10 -07:00
|
|
|
_canvas_event_feed_axis_update_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data *ev)
|
Expose device (e.g. pen) axis information to applications
Summary:
This patch set adds the necessary code to expose device axis state to applications. This was primarily written with graphics tablets in mind, which -- in addition to acting like a mouse -- also provide information about pen pressure, tilt, etc. Other devices could potentially benefit from this API as well: touchscreens, joysticks, knob controllers, "spaceballs", etc.
Whenever an update to the device state is recieved, an "Axis update" event is synthesized. This event contains the updated information, typically scaled and normalized to a particular logical range (e.g. zero to one for pressure, -pi to pi radians for angles, etc.). Information about the tool which generated the event is also stored so that applications can disambiguate events from multiple devices (or in the case of multitouch screens, individual fingers).
This API is only wired up for use with X11 at the moment. Support for other backends (e.g. Wayland) should be easy to add for those familiar them.
**Note**: The following is a list of changes from the "v2" patches originally sent to the mailinglist
//Define and implement new Ecore_Event_Axis_Update events//
* Harcode axis labels instead of including xserver-properties.h
* Use C89-style comments
* Use doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Create "Ecore_Axis" and "Ecore_Axis_Label" typedefs
* Reference typedef'd instead of raw types
* Adjust how we count through valuators to support tilt/az
* Add support for tilt and azimuth
* Tweak memory management in case number of valuators differ
* Expand TWIST axis normalization to declared range
* Only normalize TWIST axis if resolution == 1 (wacom bug)
* Cache label atoms on first use to minimize round-trips
//Implement EVAS_CALLBACK_AXIS_UPDATE event and friends//
* Update to doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Typedef 'Evas_Axis_Label', 'Evas_Axis'
* Move typedef for 'Evas_Event_Axis_Update'
* Reference typedef'd instead of raw types
//Wire the Ecore and Evas implementations of axis update events together//
* Expose ecore_event_evas_axis_update in Ecore_Input_Evas.h
* Move ecore_event_evas_axis_update to more logical position
//DEBUG: Add axis update logging to evas-multi-touch.c//
* Removed from patch set
//Make evas-multi-touch demo use new axis functionality//
* Have pressure adjust rectangle brightness instead of size
* Use more available axis data when rendering rectangle (azimuth, tilt, twist)
Test Plan: The evas-multi-touch demo was updated to support axis update events. A graphics tablet was then used to verify that the pressure, azimuth, tilt, and twist data was coming through correctly.
Reviewers: cedric, raster
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1514
Conflicts:
src/lib/ecore_input/Ecore_Input.h
Carsten Haitzler -
** fixed forward enum typedefs (make things unhappy)
** fixed conflict above
** fixed wrong param type for _evas_canvas_event_feed_axis_update()
** fixed @sinces to be 1.13
** fixed formatting/indeting
** fixed order of operation reliance in if's with ()'s to be clear
** fixed functions to be static that should have been
2014-11-24 19:07:50 -08:00
|
|
|
{
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer *evt;
|
Expose device (e.g. pen) axis information to applications
Summary:
This patch set adds the necessary code to expose device axis state to applications. This was primarily written with graphics tablets in mind, which -- in addition to acting like a mouse -- also provide information about pen pressure, tilt, etc. Other devices could potentially benefit from this API as well: touchscreens, joysticks, knob controllers, "spaceballs", etc.
Whenever an update to the device state is recieved, an "Axis update" event is synthesized. This event contains the updated information, typically scaled and normalized to a particular logical range (e.g. zero to one for pressure, -pi to pi radians for angles, etc.). Information about the tool which generated the event is also stored so that applications can disambiguate events from multiple devices (or in the case of multitouch screens, individual fingers).
This API is only wired up for use with X11 at the moment. Support for other backends (e.g. Wayland) should be easy to add for those familiar them.
**Note**: The following is a list of changes from the "v2" patches originally sent to the mailinglist
//Define and implement new Ecore_Event_Axis_Update events//
* Harcode axis labels instead of including xserver-properties.h
* Use C89-style comments
* Use doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Create "Ecore_Axis" and "Ecore_Axis_Label" typedefs
* Reference typedef'd instead of raw types
* Adjust how we count through valuators to support tilt/az
* Add support for tilt and azimuth
* Tweak memory management in case number of valuators differ
* Expand TWIST axis normalization to declared range
* Only normalize TWIST axis if resolution == 1 (wacom bug)
* Cache label atoms on first use to minimize round-trips
//Implement EVAS_CALLBACK_AXIS_UPDATE event and friends//
* Update to doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Typedef 'Evas_Axis_Label', 'Evas_Axis'
* Move typedef for 'Evas_Event_Axis_Update'
* Reference typedef'd instead of raw types
//Wire the Ecore and Evas implementations of axis update events together//
* Expose ecore_event_evas_axis_update in Ecore_Input_Evas.h
* Move ecore_event_evas_axis_update to more logical position
//DEBUG: Add axis update logging to evas-multi-touch.c//
* Removed from patch set
//Make evas-multi-touch demo use new axis functionality//
* Have pressure adjust rectangle brightness instead of size
* Use more available axis data when rendering rectangle (azimuth, tilt, twist)
Test Plan: The evas-multi-touch demo was updated to support axis update events. A graphics tablet was then used to verify that the pressure, azimuth, tilt, and twist data was coming through correctly.
Reviewers: cedric, raster
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1514
Conflicts:
src/lib/ecore_input/Ecore_Input.h
Carsten Haitzler -
** fixed forward enum typedefs (make things unhappy)
** fixed conflict above
** fixed wrong param type for _evas_canvas_event_feed_axis_update()
** fixed @sinces to be 1.13
** fixed formatting/indeting
** fixed order of operation reliance in if's with ()'s to be clear
** fixed functions to be static that should have been
2014-11-24 19:07:50 -08:00
|
|
|
Eina_List *l, *copy;
|
|
|
|
Evas_Object *eo_obj;
|
|
|
|
int event_id = 0;
|
2016-08-23 04:23:48 -07:00
|
|
|
Evas *eo_e;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata;
|
Expose device (e.g. pen) axis information to applications
Summary:
This patch set adds the necessary code to expose device axis state to applications. This was primarily written with graphics tablets in mind, which -- in addition to acting like a mouse -- also provide information about pen pressure, tilt, etc. Other devices could potentially benefit from this API as well: touchscreens, joysticks, knob controllers, "spaceballs", etc.
Whenever an update to the device state is recieved, an "Axis update" event is synthesized. This event contains the updated information, typically scaled and normalized to a particular logical range (e.g. zero to one for pressure, -pi to pi radians for angles, etc.). Information about the tool which generated the event is also stored so that applications can disambiguate events from multiple devices (or in the case of multitouch screens, individual fingers).
This API is only wired up for use with X11 at the moment. Support for other backends (e.g. Wayland) should be easy to add for those familiar them.
**Note**: The following is a list of changes from the "v2" patches originally sent to the mailinglist
//Define and implement new Ecore_Event_Axis_Update events//
* Harcode axis labels instead of including xserver-properties.h
* Use C89-style comments
* Use doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Create "Ecore_Axis" and "Ecore_Axis_Label" typedefs
* Reference typedef'd instead of raw types
* Adjust how we count through valuators to support tilt/az
* Add support for tilt and azimuth
* Tweak memory management in case number of valuators differ
* Expand TWIST axis normalization to declared range
* Only normalize TWIST axis if resolution == 1 (wacom bug)
* Cache label atoms on first use to minimize round-trips
//Implement EVAS_CALLBACK_AXIS_UPDATE event and friends//
* Update to doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Typedef 'Evas_Axis_Label', 'Evas_Axis'
* Move typedef for 'Evas_Event_Axis_Update'
* Reference typedef'd instead of raw types
//Wire the Ecore and Evas implementations of axis update events together//
* Expose ecore_event_evas_axis_update in Ecore_Input_Evas.h
* Move ecore_event_evas_axis_update to more logical position
//DEBUG: Add axis update logging to evas-multi-touch.c//
* Removed from patch set
//Make evas-multi-touch demo use new axis functionality//
* Have pressure adjust rectangle brightness instead of size
* Use more available axis data when rendering rectangle (azimuth, tilt, twist)
Test Plan: The evas-multi-touch demo was updated to support axis update events. A graphics tablet was then used to verify that the pressure, azimuth, tilt, and twist data was coming through correctly.
Reviewers: cedric, raster
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1514
Conflicts:
src/lib/ecore_input/Ecore_Input.h
Carsten Haitzler -
** fixed forward enum typedefs (make things unhappy)
** fixed conflict above
** fixed wrong param type for _evas_canvas_event_feed_axis_update()
** fixed @sinces to be 1.13
** fixed formatting/indeting
** fixed order of operation reliance in if's with ()'s to be clear
** fixed functions to be static that should have been
2014-11-24 19:07:50 -08:00
|
|
|
|
2016-08-29 01:04:31 -07:00
|
|
|
static const int value_flags =
|
|
|
|
_efl_input_value_mask(EFL_INPUT_VALUE_TIMESTAMP);
|
|
|
|
|
2016-08-23 04:23:48 -07:00
|
|
|
if (!e || !ev) return;
|
Expose device (e.g. pen) axis information to applications
Summary:
This patch set adds the necessary code to expose device axis state to applications. This was primarily written with graphics tablets in mind, which -- in addition to acting like a mouse -- also provide information about pen pressure, tilt, etc. Other devices could potentially benefit from this API as well: touchscreens, joysticks, knob controllers, "spaceballs", etc.
Whenever an update to the device state is recieved, an "Axis update" event is synthesized. This event contains the updated information, typically scaled and normalized to a particular logical range (e.g. zero to one for pressure, -pi to pi radians for angles, etc.). Information about the tool which generated the event is also stored so that applications can disambiguate events from multiple devices (or in the case of multitouch screens, individual fingers).
This API is only wired up for use with X11 at the moment. Support for other backends (e.g. Wayland) should be easy to add for those familiar them.
**Note**: The following is a list of changes from the "v2" patches originally sent to the mailinglist
//Define and implement new Ecore_Event_Axis_Update events//
* Harcode axis labels instead of including xserver-properties.h
* Use C89-style comments
* Use doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Create "Ecore_Axis" and "Ecore_Axis_Label" typedefs
* Reference typedef'd instead of raw types
* Adjust how we count through valuators to support tilt/az
* Add support for tilt and azimuth
* Tweak memory management in case number of valuators differ
* Expand TWIST axis normalization to declared range
* Only normalize TWIST axis if resolution == 1 (wacom bug)
* Cache label atoms on first use to minimize round-trips
//Implement EVAS_CALLBACK_AXIS_UPDATE event and friends//
* Update to doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Typedef 'Evas_Axis_Label', 'Evas_Axis'
* Move typedef for 'Evas_Event_Axis_Update'
* Reference typedef'd instead of raw types
//Wire the Ecore and Evas implementations of axis update events together//
* Expose ecore_event_evas_axis_update in Ecore_Input_Evas.h
* Move ecore_event_evas_axis_update to more logical position
//DEBUG: Add axis update logging to evas-multi-touch.c//
* Removed from patch set
//Make evas-multi-touch demo use new axis functionality//
* Have pressure adjust rectangle brightness instead of size
* Use more available axis data when rendering rectangle (azimuth, tilt, twist)
Test Plan: The evas-multi-touch demo was updated to support axis update events. A graphics tablet was then used to verify that the pressure, azimuth, tilt, and twist data was coming through correctly.
Reviewers: cedric, raster
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1514
Conflicts:
src/lib/ecore_input/Ecore_Input.h
Carsten Haitzler -
** fixed forward enum typedefs (make things unhappy)
** fixed conflict above
** fixed wrong param type for _evas_canvas_event_feed_axis_update()
** fixed @sinces to be 1.13
** fixed formatting/indeting
** fixed order of operation reliance in if's with ()'s to be clear
** fixed functions to be static that should have been
2014-11-24 19:07:50 -08:00
|
|
|
if (e->is_frozen) return;
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
Expose device (e.g. pen) axis information to applications
Summary:
This patch set adds the necessary code to expose device axis state to applications. This was primarily written with graphics tablets in mind, which -- in addition to acting like a mouse -- also provide information about pen pressure, tilt, etc. Other devices could potentially benefit from this API as well: touchscreens, joysticks, knob controllers, "spaceballs", etc.
Whenever an update to the device state is recieved, an "Axis update" event is synthesized. This event contains the updated information, typically scaled and normalized to a particular logical range (e.g. zero to one for pressure, -pi to pi radians for angles, etc.). Information about the tool which generated the event is also stored so that applications can disambiguate events from multiple devices (or in the case of multitouch screens, individual fingers).
This API is only wired up for use with X11 at the moment. Support for other backends (e.g. Wayland) should be easy to add for those familiar them.
**Note**: The following is a list of changes from the "v2" patches originally sent to the mailinglist
//Define and implement new Ecore_Event_Axis_Update events//
* Harcode axis labels instead of including xserver-properties.h
* Use C89-style comments
* Use doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Create "Ecore_Axis" and "Ecore_Axis_Label" typedefs
* Reference typedef'd instead of raw types
* Adjust how we count through valuators to support tilt/az
* Add support for tilt and azimuth
* Tweak memory management in case number of valuators differ
* Expand TWIST axis normalization to declared range
* Only normalize TWIST axis if resolution == 1 (wacom bug)
* Cache label atoms on first use to minimize round-trips
//Implement EVAS_CALLBACK_AXIS_UPDATE event and friends//
* Update to doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Typedef 'Evas_Axis_Label', 'Evas_Axis'
* Move typedef for 'Evas_Event_Axis_Update'
* Reference typedef'd instead of raw types
//Wire the Ecore and Evas implementations of axis update events together//
* Expose ecore_event_evas_axis_update in Ecore_Input_Evas.h
* Move ecore_event_evas_axis_update to more logical position
//DEBUG: Add axis update logging to evas-multi-touch.c//
* Removed from patch set
//Make evas-multi-touch demo use new axis functionality//
* Have pressure adjust rectangle brightness instead of size
* Use more available axis data when rendering rectangle (azimuth, tilt, twist)
Test Plan: The evas-multi-touch demo was updated to support axis update events. A graphics tablet was then used to verify that the pressure, azimuth, tilt, and twist data was coming through correctly.
Reviewers: cedric, raster
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1514
Conflicts:
src/lib/ecore_input/Ecore_Input.h
Carsten Haitzler -
** fixed forward enum typedefs (make things unhappy)
** fixed conflict above
** fixed wrong param type for _evas_canvas_event_feed_axis_update()
** fixed @sinces to be 1.13
** fixed formatting/indeting
** fixed order of operation reliance in if's with ()'s to be clear
** fixed functions to be static that should have been
2014-11-24 19:07:50 -08:00
|
|
|
|
2016-10-21 05:25:41 -07:00
|
|
|
pdata = _evas_pointer_data_by_device_get(e, ev->device);
|
|
|
|
if (!pdata) return;
|
2016-08-23 04:23:48 -07:00
|
|
|
eo_e = e->evas;
|
|
|
|
e->last_timestamp = ev->timestamp;
|
|
|
|
|
|
|
|
ev->action = EFL_POINTER_ACTION_AXIS;
|
2016-08-29 01:04:31 -07:00
|
|
|
ev->value_flags |= value_flags;
|
2016-08-18 21:33:11 -07:00
|
|
|
event_id = _evas_object_event_new();
|
2016-08-25 00:03:45 -07:00
|
|
|
evt = ev->eo;
|
Expose device (e.g. pen) axis information to applications
Summary:
This patch set adds the necessary code to expose device axis state to applications. This was primarily written with graphics tablets in mind, which -- in addition to acting like a mouse -- also provide information about pen pressure, tilt, etc. Other devices could potentially benefit from this API as well: touchscreens, joysticks, knob controllers, "spaceballs", etc.
Whenever an update to the device state is recieved, an "Axis update" event is synthesized. This event contains the updated information, typically scaled and normalized to a particular logical range (e.g. zero to one for pressure, -pi to pi radians for angles, etc.). Information about the tool which generated the event is also stored so that applications can disambiguate events from multiple devices (or in the case of multitouch screens, individual fingers).
This API is only wired up for use with X11 at the moment. Support for other backends (e.g. Wayland) should be easy to add for those familiar them.
**Note**: The following is a list of changes from the "v2" patches originally sent to the mailinglist
//Define and implement new Ecore_Event_Axis_Update events//
* Harcode axis labels instead of including xserver-properties.h
* Use C89-style comments
* Use doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Create "Ecore_Axis" and "Ecore_Axis_Label" typedefs
* Reference typedef'd instead of raw types
* Adjust how we count through valuators to support tilt/az
* Add support for tilt and azimuth
* Tweak memory management in case number of valuators differ
* Expand TWIST axis normalization to declared range
* Only normalize TWIST axis if resolution == 1 (wacom bug)
* Cache label atoms on first use to minimize round-trips
//Implement EVAS_CALLBACK_AXIS_UPDATE event and friends//
* Update to doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Typedef 'Evas_Axis_Label', 'Evas_Axis'
* Move typedef for 'Evas_Event_Axis_Update'
* Reference typedef'd instead of raw types
//Wire the Ecore and Evas implementations of axis update events together//
* Expose ecore_event_evas_axis_update in Ecore_Input_Evas.h
* Move ecore_event_evas_axis_update to more logical position
//DEBUG: Add axis update logging to evas-multi-touch.c//
* Removed from patch set
//Make evas-multi-touch demo use new axis functionality//
* Have pressure adjust rectangle brightness instead of size
* Use more available axis data when rendering rectangle (azimuth, tilt, twist)
Test Plan: The evas-multi-touch demo was updated to support axis update events. A graphics tablet was then used to verify that the pressure, azimuth, tilt, and twist data was coming through correctly.
Reviewers: cedric, raster
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1514
Conflicts:
src/lib/ecore_input/Ecore_Input.h
Carsten Haitzler -
** fixed forward enum typedefs (make things unhappy)
** fixed conflict above
** fixed wrong param type for _evas_canvas_event_feed_axis_update()
** fixed @sinces to be 1.13
** fixed formatting/indeting
** fixed order of operation reliance in if's with ()'s to be clear
** fixed functions to be static that should have been
2014-11-24 19:07:50 -08:00
|
|
|
|
2016-08-23 04:23:48 -07:00
|
|
|
if (ev->device) efl_ref(ev->device);
|
Expose device (e.g. pen) axis information to applications
Summary:
This patch set adds the necessary code to expose device axis state to applications. This was primarily written with graphics tablets in mind, which -- in addition to acting like a mouse -- also provide information about pen pressure, tilt, etc. Other devices could potentially benefit from this API as well: touchscreens, joysticks, knob controllers, "spaceballs", etc.
Whenever an update to the device state is recieved, an "Axis update" event is synthesized. This event contains the updated information, typically scaled and normalized to a particular logical range (e.g. zero to one for pressure, -pi to pi radians for angles, etc.). Information about the tool which generated the event is also stored so that applications can disambiguate events from multiple devices (or in the case of multitouch screens, individual fingers).
This API is only wired up for use with X11 at the moment. Support for other backends (e.g. Wayland) should be easy to add for those familiar them.
**Note**: The following is a list of changes from the "v2" patches originally sent to the mailinglist
//Define and implement new Ecore_Event_Axis_Update events//
* Harcode axis labels instead of including xserver-properties.h
* Use C89-style comments
* Use doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Create "Ecore_Axis" and "Ecore_Axis_Label" typedefs
* Reference typedef'd instead of raw types
* Adjust how we count through valuators to support tilt/az
* Add support for tilt and azimuth
* Tweak memory management in case number of valuators differ
* Expand TWIST axis normalization to declared range
* Only normalize TWIST axis if resolution == 1 (wacom bug)
* Cache label atoms on first use to minimize round-trips
//Implement EVAS_CALLBACK_AXIS_UPDATE event and friends//
* Update to doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Typedef 'Evas_Axis_Label', 'Evas_Axis'
* Move typedef for 'Evas_Event_Axis_Update'
* Reference typedef'd instead of raw types
//Wire the Ecore and Evas implementations of axis update events together//
* Expose ecore_event_evas_axis_update in Ecore_Input_Evas.h
* Move ecore_event_evas_axis_update to more logical position
//DEBUG: Add axis update logging to evas-multi-touch.c//
* Removed from patch set
//Make evas-multi-touch demo use new axis functionality//
* Have pressure adjust rectangle brightness instead of size
* Use more available axis data when rendering rectangle (azimuth, tilt, twist)
Test Plan: The evas-multi-touch demo was updated to support axis update events. A graphics tablet was then used to verify that the pressure, azimuth, tilt, and twist data was coming through correctly.
Reviewers: cedric, raster
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1514
Conflicts:
src/lib/ecore_input/Ecore_Input.h
Carsten Haitzler -
** fixed forward enum typedefs (make things unhappy)
** fixed conflict above
** fixed wrong param type for _evas_canvas_event_feed_axis_update()
** fixed @sinces to be 1.13
** fixed formatting/indeting
** fixed order of operation reliance in if's with ()'s to be clear
** fixed functions to be static that should have been
2014-11-24 19:07:50 -08:00
|
|
|
|
|
|
|
_evas_walk(e);
|
2017-06-02 15:23:45 -07:00
|
|
|
copy = evas_event_list_copy(pdata->seat->object.in);
|
Expose device (e.g. pen) axis information to applications
Summary:
This patch set adds the necessary code to expose device axis state to applications. This was primarily written with graphics tablets in mind, which -- in addition to acting like a mouse -- also provide information about pen pressure, tilt, etc. Other devices could potentially benefit from this API as well: touchscreens, joysticks, knob controllers, "spaceballs", etc.
Whenever an update to the device state is recieved, an "Axis update" event is synthesized. This event contains the updated information, typically scaled and normalized to a particular logical range (e.g. zero to one for pressure, -pi to pi radians for angles, etc.). Information about the tool which generated the event is also stored so that applications can disambiguate events from multiple devices (or in the case of multitouch screens, individual fingers).
This API is only wired up for use with X11 at the moment. Support for other backends (e.g. Wayland) should be easy to add for those familiar them.
**Note**: The following is a list of changes from the "v2" patches originally sent to the mailinglist
//Define and implement new Ecore_Event_Axis_Update events//
* Harcode axis labels instead of including xserver-properties.h
* Use C89-style comments
* Use doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Create "Ecore_Axis" and "Ecore_Axis_Label" typedefs
* Reference typedef'd instead of raw types
* Adjust how we count through valuators to support tilt/az
* Add support for tilt and azimuth
* Tweak memory management in case number of valuators differ
* Expand TWIST axis normalization to declared range
* Only normalize TWIST axis if resolution == 1 (wacom bug)
* Cache label atoms on first use to minimize round-trips
//Implement EVAS_CALLBACK_AXIS_UPDATE event and friends//
* Update to doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Typedef 'Evas_Axis_Label', 'Evas_Axis'
* Move typedef for 'Evas_Event_Axis_Update'
* Reference typedef'd instead of raw types
//Wire the Ecore and Evas implementations of axis update events together//
* Expose ecore_event_evas_axis_update in Ecore_Input_Evas.h
* Move ecore_event_evas_axis_update to more logical position
//DEBUG: Add axis update logging to evas-multi-touch.c//
* Removed from patch set
//Make evas-multi-touch demo use new axis functionality//
* Have pressure adjust rectangle brightness instead of size
* Use more available axis data when rendering rectangle (azimuth, tilt, twist)
Test Plan: The evas-multi-touch demo was updated to support axis update events. A graphics tablet was then used to verify that the pressure, azimuth, tilt, and twist data was coming through correctly.
Reviewers: cedric, raster
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1514
Conflicts:
src/lib/ecore_input/Ecore_Input.h
Carsten Haitzler -
** fixed forward enum typedefs (make things unhappy)
** fixed conflict above
** fixed wrong param type for _evas_canvas_event_feed_axis_update()
** fixed @sinces to be 1.13
** fixed formatting/indeting
** fixed order of operation reliance in if's with ()'s to be clear
** fixed functions to be static that should have been
2014-11-24 19:07:50 -08:00
|
|
|
|
|
|
|
EINA_LIST_FOREACH(copy, l, eo_obj)
|
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
Expose device (e.g. pen) axis information to applications
Summary:
This patch set adds the necessary code to expose device axis state to applications. This was primarily written with graphics tablets in mind, which -- in addition to acting like a mouse -- also provide information about pen pressure, tilt, etc. Other devices could potentially benefit from this API as well: touchscreens, joysticks, knob controllers, "spaceballs", etc.
Whenever an update to the device state is recieved, an "Axis update" event is synthesized. This event contains the updated information, typically scaled and normalized to a particular logical range (e.g. zero to one for pressure, -pi to pi radians for angles, etc.). Information about the tool which generated the event is also stored so that applications can disambiguate events from multiple devices (or in the case of multitouch screens, individual fingers).
This API is only wired up for use with X11 at the moment. Support for other backends (e.g. Wayland) should be easy to add for those familiar them.
**Note**: The following is a list of changes from the "v2" patches originally sent to the mailinglist
//Define and implement new Ecore_Event_Axis_Update events//
* Harcode axis labels instead of including xserver-properties.h
* Use C89-style comments
* Use doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Create "Ecore_Axis" and "Ecore_Axis_Label" typedefs
* Reference typedef'd instead of raw types
* Adjust how we count through valuators to support tilt/az
* Add support for tilt and azimuth
* Tweak memory management in case number of valuators differ
* Expand TWIST axis normalization to declared range
* Only normalize TWIST axis if resolution == 1 (wacom bug)
* Cache label atoms on first use to minimize round-trips
//Implement EVAS_CALLBACK_AXIS_UPDATE event and friends//
* Update to doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Typedef 'Evas_Axis_Label', 'Evas_Axis'
* Move typedef for 'Evas_Event_Axis_Update'
* Reference typedef'd instead of raw types
//Wire the Ecore and Evas implementations of axis update events together//
* Expose ecore_event_evas_axis_update in Ecore_Input_Evas.h
* Move ecore_event_evas_axis_update to more logical position
//DEBUG: Add axis update logging to evas-multi-touch.c//
* Removed from patch set
//Make evas-multi-touch demo use new axis functionality//
* Have pressure adjust rectangle brightness instead of size
* Use more available axis data when rendering rectangle (azimuth, tilt, twist)
Test Plan: The evas-multi-touch demo was updated to support axis update events. A graphics tablet was then used to verify that the pressure, azimuth, tilt, and twist data was coming through correctly.
Reviewers: cedric, raster
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1514
Conflicts:
src/lib/ecore_input/Ecore_Input.h
Carsten Haitzler -
** fixed forward enum typedefs (make things unhappy)
** fixed conflict above
** fixed wrong param type for _evas_canvas_event_feed_axis_update()
** fixed @sinces to be 1.13
** fixed formatting/indeting
** fixed order of operation reliance in if's with ()'s to be clear
** fixed functions to be static that should have been
2014-11-24 19:07:50 -08:00
|
|
|
if (!evas_event_freezes_through(eo_obj, obj))
|
|
|
|
{
|
|
|
|
evas_object_event_callback_call(eo_obj, obj,
|
2016-08-25 00:03:45 -07:00
|
|
|
EVAS_CALLBACK_AXIS_UPDATE, evt,
|
|
|
|
event_id, EFL_EVENT_POINTER_AXIS);
|
Expose device (e.g. pen) axis information to applications
Summary:
This patch set adds the necessary code to expose device axis state to applications. This was primarily written with graphics tablets in mind, which -- in addition to acting like a mouse -- also provide information about pen pressure, tilt, etc. Other devices could potentially benefit from this API as well: touchscreens, joysticks, knob controllers, "spaceballs", etc.
Whenever an update to the device state is recieved, an "Axis update" event is synthesized. This event contains the updated information, typically scaled and normalized to a particular logical range (e.g. zero to one for pressure, -pi to pi radians for angles, etc.). Information about the tool which generated the event is also stored so that applications can disambiguate events from multiple devices (or in the case of multitouch screens, individual fingers).
This API is only wired up for use with X11 at the moment. Support for other backends (e.g. Wayland) should be easy to add for those familiar them.
**Note**: The following is a list of changes from the "v2" patches originally sent to the mailinglist
//Define and implement new Ecore_Event_Axis_Update events//
* Harcode axis labels instead of including xserver-properties.h
* Use C89-style comments
* Use doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Create "Ecore_Axis" and "Ecore_Axis_Label" typedefs
* Reference typedef'd instead of raw types
* Adjust how we count through valuators to support tilt/az
* Add support for tilt and azimuth
* Tweak memory management in case number of valuators differ
* Expand TWIST axis normalization to declared range
* Only normalize TWIST axis if resolution == 1 (wacom bug)
* Cache label atoms on first use to minimize round-trips
//Implement EVAS_CALLBACK_AXIS_UPDATE event and friends//
* Update to doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Typedef 'Evas_Axis_Label', 'Evas_Axis'
* Move typedef for 'Evas_Event_Axis_Update'
* Reference typedef'd instead of raw types
//Wire the Ecore and Evas implementations of axis update events together//
* Expose ecore_event_evas_axis_update in Ecore_Input_Evas.h
* Move ecore_event_evas_axis_update to more logical position
//DEBUG: Add axis update logging to evas-multi-touch.c//
* Removed from patch set
//Make evas-multi-touch demo use new axis functionality//
* Have pressure adjust rectangle brightness instead of size
* Use more available axis data when rendering rectangle (azimuth, tilt, twist)
Test Plan: The evas-multi-touch demo was updated to support axis update events. A graphics tablet was then used to verify that the pressure, azimuth, tilt, and twist data was coming through correctly.
Reviewers: cedric, raster
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1514
Conflicts:
src/lib/ecore_input/Ecore_Input.h
Carsten Haitzler -
** fixed forward enum typedefs (make things unhappy)
** fixed conflict above
** fixed wrong param type for _evas_canvas_event_feed_axis_update()
** fixed @sinces to be 1.13
** fixed formatting/indeting
** fixed order of operation reliance in if's with ()'s to be clear
** fixed functions to be static that should have been
2014-11-24 19:07:50 -08:00
|
|
|
if (e->delete_me || e->is_frozen) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
eina_list_free(copy);
|
2017-02-16 02:34:08 -08:00
|
|
|
_evas_post_event_callback_call(eo_e, e, event_id);
|
Expose device (e.g. pen) axis information to applications
Summary:
This patch set adds the necessary code to expose device axis state to applications. This was primarily written with graphics tablets in mind, which -- in addition to acting like a mouse -- also provide information about pen pressure, tilt, etc. Other devices could potentially benefit from this API as well: touchscreens, joysticks, knob controllers, "spaceballs", etc.
Whenever an update to the device state is recieved, an "Axis update" event is synthesized. This event contains the updated information, typically scaled and normalized to a particular logical range (e.g. zero to one for pressure, -pi to pi radians for angles, etc.). Information about the tool which generated the event is also stored so that applications can disambiguate events from multiple devices (or in the case of multitouch screens, individual fingers).
This API is only wired up for use with X11 at the moment. Support for other backends (e.g. Wayland) should be easy to add for those familiar them.
**Note**: The following is a list of changes from the "v2" patches originally sent to the mailinglist
//Define and implement new Ecore_Event_Axis_Update events//
* Harcode axis labels instead of including xserver-properties.h
* Use C89-style comments
* Use doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Create "Ecore_Axis" and "Ecore_Axis_Label" typedefs
* Reference typedef'd instead of raw types
* Adjust how we count through valuators to support tilt/az
* Add support for tilt and azimuth
* Tweak memory management in case number of valuators differ
* Expand TWIST axis normalization to declared range
* Only normalize TWIST axis if resolution == 1 (wacom bug)
* Cache label atoms on first use to minimize round-trips
//Implement EVAS_CALLBACK_AXIS_UPDATE event and friends//
* Update to doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Typedef 'Evas_Axis_Label', 'Evas_Axis'
* Move typedef for 'Evas_Event_Axis_Update'
* Reference typedef'd instead of raw types
//Wire the Ecore and Evas implementations of axis update events together//
* Expose ecore_event_evas_axis_update in Ecore_Input_Evas.h
* Move ecore_event_evas_axis_update to more logical position
//DEBUG: Add axis update logging to evas-multi-touch.c//
* Removed from patch set
//Make evas-multi-touch demo use new axis functionality//
* Have pressure adjust rectangle brightness instead of size
* Use more available axis data when rendering rectangle (azimuth, tilt, twist)
Test Plan: The evas-multi-touch demo was updated to support axis update events. A graphics tablet was then used to verify that the pressure, azimuth, tilt, and twist data was coming through correctly.
Reviewers: cedric, raster
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1514
Conflicts:
src/lib/ecore_input/Ecore_Input.h
Carsten Haitzler -
** fixed forward enum typedefs (make things unhappy)
** fixed conflict above
** fixed wrong param type for _evas_canvas_event_feed_axis_update()
** fixed @sinces to be 1.13
** fixed formatting/indeting
** fixed order of operation reliance in if's with ()'s to be clear
** fixed functions to be static that should have been
2014-11-24 19:07:50 -08:00
|
|
|
|
|
|
|
_evas_unwalk(e);
|
2016-08-23 04:23:48 -07:00
|
|
|
if (ev->device) efl_unref(ev->device);
|
Expose device (e.g. pen) axis information to applications
Summary:
This patch set adds the necessary code to expose device axis state to applications. This was primarily written with graphics tablets in mind, which -- in addition to acting like a mouse -- also provide information about pen pressure, tilt, etc. Other devices could potentially benefit from this API as well: touchscreens, joysticks, knob controllers, "spaceballs", etc.
Whenever an update to the device state is recieved, an "Axis update" event is synthesized. This event contains the updated information, typically scaled and normalized to a particular logical range (e.g. zero to one for pressure, -pi to pi radians for angles, etc.). Information about the tool which generated the event is also stored so that applications can disambiguate events from multiple devices (or in the case of multitouch screens, individual fingers).
This API is only wired up for use with X11 at the moment. Support for other backends (e.g. Wayland) should be easy to add for those familiar them.
**Note**: The following is a list of changes from the "v2" patches originally sent to the mailinglist
//Define and implement new Ecore_Event_Axis_Update events//
* Harcode axis labels instead of including xserver-properties.h
* Use C89-style comments
* Use doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Create "Ecore_Axis" and "Ecore_Axis_Label" typedefs
* Reference typedef'd instead of raw types
* Adjust how we count through valuators to support tilt/az
* Add support for tilt and azimuth
* Tweak memory management in case number of valuators differ
* Expand TWIST axis normalization to declared range
* Only normalize TWIST axis if resolution == 1 (wacom bug)
* Cache label atoms on first use to minimize round-trips
//Implement EVAS_CALLBACK_AXIS_UPDATE event and friends//
* Update to doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Typedef 'Evas_Axis_Label', 'Evas_Axis'
* Move typedef for 'Evas_Event_Axis_Update'
* Reference typedef'd instead of raw types
//Wire the Ecore and Evas implementations of axis update events together//
* Expose ecore_event_evas_axis_update in Ecore_Input_Evas.h
* Move ecore_event_evas_axis_update to more logical position
//DEBUG: Add axis update logging to evas-multi-touch.c//
* Removed from patch set
//Make evas-multi-touch demo use new axis functionality//
* Have pressure adjust rectangle brightness instead of size
* Use more available axis data when rendering rectangle (azimuth, tilt, twist)
Test Plan: The evas-multi-touch demo was updated to support axis update events. A graphics tablet was then used to verify that the pressure, azimuth, tilt, and twist data was coming through correctly.
Reviewers: cedric, raster
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1514
Conflicts:
src/lib/ecore_input/Ecore_Input.h
Carsten Haitzler -
** fixed forward enum typedefs (make things unhappy)
** fixed conflict above
** fixed wrong param type for _evas_canvas_event_feed_axis_update()
** fixed @sinces to be 1.13
** fixed formatting/indeting
** fixed order of operation reliance in if's with ()'s to be clear
** fixed functions to be static that should have been
2014-11-24 19:07:50 -08:00
|
|
|
}
|
|
|
|
|
2016-05-11 00:21:49 -07:00
|
|
|
EAPI void
|
2016-08-23 04:23:48 -07:00
|
|
|
evas_event_feed_axis_update(Evas *eo_e, unsigned int timestamp, int device, int toolid, int naxis, const Evas_Axis *axes, const void *data)
|
Expose device (e.g. pen) axis information to applications
Summary:
This patch set adds the necessary code to expose device axis state to applications. This was primarily written with graphics tablets in mind, which -- in addition to acting like a mouse -- also provide information about pen pressure, tilt, etc. Other devices could potentially benefit from this API as well: touchscreens, joysticks, knob controllers, "spaceballs", etc.
Whenever an update to the device state is recieved, an "Axis update" event is synthesized. This event contains the updated information, typically scaled and normalized to a particular logical range (e.g. zero to one for pressure, -pi to pi radians for angles, etc.). Information about the tool which generated the event is also stored so that applications can disambiguate events from multiple devices (or in the case of multitouch screens, individual fingers).
This API is only wired up for use with X11 at the moment. Support for other backends (e.g. Wayland) should be easy to add for those familiar them.
**Note**: The following is a list of changes from the "v2" patches originally sent to the mailinglist
//Define and implement new Ecore_Event_Axis_Update events//
* Harcode axis labels instead of including xserver-properties.h
* Use C89-style comments
* Use doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Create "Ecore_Axis" and "Ecore_Axis_Label" typedefs
* Reference typedef'd instead of raw types
* Adjust how we count through valuators to support tilt/az
* Add support for tilt and azimuth
* Tweak memory management in case number of valuators differ
* Expand TWIST axis normalization to declared range
* Only normalize TWIST axis if resolution == 1 (wacom bug)
* Cache label atoms on first use to minimize round-trips
//Implement EVAS_CALLBACK_AXIS_UPDATE event and friends//
* Update to doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Typedef 'Evas_Axis_Label', 'Evas_Axis'
* Move typedef for 'Evas_Event_Axis_Update'
* Reference typedef'd instead of raw types
//Wire the Ecore and Evas implementations of axis update events together//
* Expose ecore_event_evas_axis_update in Ecore_Input_Evas.h
* Move ecore_event_evas_axis_update to more logical position
//DEBUG: Add axis update logging to evas-multi-touch.c//
* Removed from patch set
//Make evas-multi-touch demo use new axis functionality//
* Have pressure adjust rectangle brightness instead of size
* Use more available axis data when rendering rectangle (azimuth, tilt, twist)
Test Plan: The evas-multi-touch demo was updated to support axis update events. A graphics tablet was then used to verify that the pressure, azimuth, tilt, and twist data was coming through correctly.
Reviewers: cedric, raster
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1514
Conflicts:
src/lib/ecore_input/Ecore_Input.h
Carsten Haitzler -
** fixed forward enum typedefs (make things unhappy)
** fixed conflict above
** fixed wrong param type for _evas_canvas_event_feed_axis_update()
** fixed @sinces to be 1.13
** fixed formatting/indeting
** fixed order of operation reliance in if's with ()'s to be clear
** fixed functions to be static that should have been
2014-11-24 19:07:50 -08:00
|
|
|
{
|
2016-08-23 04:23:48 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev = NULL;
|
2016-08-25 01:54:04 -07:00
|
|
|
Eina_Bool haswinx = 0, haswiny = 0;
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer *evt;
|
2016-08-25 01:54:04 -07:00
|
|
|
double x = 0, y = 0;
|
2016-08-23 04:23:48 -07:00
|
|
|
int n;
|
|
|
|
|
evas: Strengthen post-event callbacks
See T3144 that I marked as Wontfix.
Bryce in E manually feeds events from a post-event callback
resulting in Evas going insane and leading to frequent crashes.
The ideal solution (for E) would be to ensure that everything works
smoothly, the input event data is valid up until the post-event cb
is called, etc... Unfortunately, with recursive events the exact
order of operations may be messed up: the post-event
I don't want to add yet more complexity to Evas events here (it's
already spaghetti all over the place) so I'm simply blocking any
new event feed when running the post-event callback list.
It's not possible to just freeze the events (I tried, it failed).
**********************
Some more explanation:
post-event callbacks are used to implement reverse-order logic
where the on-hold flag of an input event may be set by an event
listener that does not come first.
Here's a situation to illustrate: scroller A inside scroller B.
As events are propagated from children to parents (assuming the
propagate flag is set), we'd assume the events to go first to A
and then to B, which means a mouse wheel event would make the
inner-most scroller (A) scroll, and the outer-most scroller (B)
wouldn't budge.
But as things are designed, A and B are not simple evas objects,
and the actual event-catching object is a top-most transparent
rectangle (top-most in Z stack order). Since A is inside B, B's
rectangle BR is over A's rectangle AR, thus catches the wheel
event first. But in terms of UX we still want A to scroll, not B.
The solution then is to reverse the event processing order and
post-event callbacks are the way to do that. This comes with the
consequence that the event_info needs to remain valid until the
post-event is called, and stay the same (so that the on-hold flag
set by A can be read by B).
Recursive events (by explicit feed or modifying the canvas so
that mouse,in or mouse,out are triggered) mess with this logic,
and trigger the post-events too early (event is not fully
processed) or too late (event_info is not valid anymore... and
crash!).
Thanks @raster for explaining the goal of post-event callbacks!
2017-02-15 23:47:57 -08:00
|
|
|
if (!e) return;
|
|
|
|
EVAS_EVENT_FEED_SAFETY_CHECK(e);
|
|
|
|
|
2019-02-09 10:08:45 -08:00
|
|
|
evt = efl_input_pointer_instance_get( eo_e, (void **) &ev);
|
2016-08-23 04:23:48 -07:00
|
|
|
if (!ev) return;
|
|
|
|
|
|
|
|
ev->data = (void *) data;
|
|
|
|
ev->timestamp = timestamp;
|
|
|
|
ev->action = EFL_POINTER_ACTION_AXIS;
|
2019-06-20 03:13:37 -07:00
|
|
|
ev->touch_id = toolid;
|
2016-08-23 04:23:48 -07:00
|
|
|
|
|
|
|
// see also ecore_evas.c
|
|
|
|
for (n = 0; n < naxis; n++)
|
|
|
|
{
|
|
|
|
const Evas_Axis *axis = &(axes[n]);
|
|
|
|
switch (axis->label)
|
|
|
|
{
|
2016-08-25 01:54:04 -07:00
|
|
|
case EVAS_AXIS_LABEL_WINDOW_X:
|
2016-08-23 04:23:48 -07:00
|
|
|
_efl_input_value_mark(ev, EFL_INPUT_VALUE_X);
|
2016-08-25 01:54:04 -07:00
|
|
|
x = axis->value;
|
|
|
|
haswinx = EINA_TRUE;
|
2016-08-23 04:23:48 -07:00
|
|
|
break;
|
|
|
|
|
2016-08-25 01:54:04 -07:00
|
|
|
case EVAS_AXIS_LABEL_WINDOW_Y:
|
2016-08-23 04:23:48 -07:00
|
|
|
_efl_input_value_mark(ev, EFL_INPUT_VALUE_Y);
|
2016-08-25 01:54:04 -07:00
|
|
|
y = axis->value;
|
|
|
|
haswiny = EINA_TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EVAS_AXIS_LABEL_X:
|
|
|
|
if (!haswinx)
|
|
|
|
{
|
|
|
|
_efl_input_value_mark(ev, EFL_INPUT_VALUE_X);
|
|
|
|
x = axis->value;
|
|
|
|
}
|
2016-08-30 21:35:15 -07:00
|
|
|
ev->raw.x = axis->value;
|
|
|
|
ev->has_raw = EINA_TRUE;
|
2016-08-25 01:54:04 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case EVAS_AXIS_LABEL_Y:
|
|
|
|
if (!haswiny)
|
|
|
|
{
|
|
|
|
_efl_input_value_mark(ev, EFL_INPUT_VALUE_Y);
|
|
|
|
y = axis->value;
|
|
|
|
}
|
2016-08-30 21:35:15 -07:00
|
|
|
ev->raw.y = axis->value;
|
|
|
|
ev->has_raw = EINA_TRUE;
|
2016-08-25 01:54:04 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case EVAS_AXIS_LABEL_NORMAL_X:
|
2016-08-30 21:35:15 -07:00
|
|
|
ev->norm.x = axis->value;
|
|
|
|
ev->has_norm = EINA_TRUE;
|
2016-08-25 01:54:04 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case EVAS_AXIS_LABEL_NORMAL_Y:
|
2016-08-30 21:35:15 -07:00
|
|
|
ev->norm.y = axis->value;
|
|
|
|
ev->has_norm = EINA_TRUE;
|
2016-08-23 04:23:48 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case EVAS_AXIS_LABEL_PRESSURE:
|
|
|
|
_efl_input_value_mark(ev, EFL_INPUT_VALUE_PRESSURE);
|
|
|
|
ev->pressure = axis->value;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EVAS_AXIS_LABEL_DISTANCE:
|
2016-08-30 21:35:15 -07:00
|
|
|
_efl_input_value_mark(ev, EFL_INPUT_VALUE_DISTANCE);
|
|
|
|
ev->distance = axis->value;
|
|
|
|
break;
|
|
|
|
|
2016-08-23 04:23:48 -07:00
|
|
|
case EVAS_AXIS_LABEL_AZIMUTH:
|
2016-08-30 21:35:15 -07:00
|
|
|
_efl_input_value_mark(ev, EFL_INPUT_VALUE_AZIMUTH);
|
|
|
|
ev->azimuth = axis->value;
|
|
|
|
break;
|
|
|
|
|
2016-08-23 04:23:48 -07:00
|
|
|
case EVAS_AXIS_LABEL_TILT:
|
2016-08-30 21:35:15 -07:00
|
|
|
_efl_input_value_mark(ev, EFL_INPUT_VALUE_TILT);
|
|
|
|
ev->tilt = axis->value;
|
|
|
|
break;
|
|
|
|
|
2016-08-23 04:23:48 -07:00
|
|
|
case EVAS_AXIS_LABEL_TWIST:
|
2016-08-30 21:35:15 -07:00
|
|
|
_efl_input_value_mark(ev, EFL_INPUT_VALUE_TWIST);
|
|
|
|
ev->twist = axis->value;
|
|
|
|
break;
|
2016-08-23 04:23:48 -07:00
|
|
|
|
|
|
|
case EVAS_AXIS_LABEL_UNKNOWN:
|
|
|
|
case EVAS_AXIS_LABEL_TOUCH_WIDTH_MAJOR:
|
|
|
|
case EVAS_AXIS_LABEL_TOUCH_WIDTH_MINOR:
|
|
|
|
case EVAS_AXIS_LABEL_TOOL_WIDTH_MAJOR:
|
|
|
|
case EVAS_AXIS_LABEL_TOOL_WIDTH_MINOR:
|
|
|
|
default:
|
|
|
|
DBG("Unsupported axis label %d, value %f (discarded)",
|
|
|
|
axis->label, axis->value);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-25 01:54:04 -07:00
|
|
|
ev->cur.x = x;
|
|
|
|
ev->cur.y = y;
|
|
|
|
|
2016-08-25 00:03:45 -07:00
|
|
|
/* FIXME: set proper device based on the device id (X or WL specific) */
|
2016-10-26 05:37:29 -07:00
|
|
|
ev->device = efl_ref(_evas_event_legacy_device_get(eo_e, EINA_TRUE)); // FIXME
|
2016-08-25 00:03:45 -07:00
|
|
|
(void) device;
|
|
|
|
|
2016-08-23 04:23:48 -07:00
|
|
|
_canvas_event_feed_axis_update_internal(e, ev);
|
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
Expose device (e.g. pen) axis information to applications
Summary:
This patch set adds the necessary code to expose device axis state to applications. This was primarily written with graphics tablets in mind, which -- in addition to acting like a mouse -- also provide information about pen pressure, tilt, etc. Other devices could potentially benefit from this API as well: touchscreens, joysticks, knob controllers, "spaceballs", etc.
Whenever an update to the device state is recieved, an "Axis update" event is synthesized. This event contains the updated information, typically scaled and normalized to a particular logical range (e.g. zero to one for pressure, -pi to pi radians for angles, etc.). Information about the tool which generated the event is also stored so that applications can disambiguate events from multiple devices (or in the case of multitouch screens, individual fingers).
This API is only wired up for use with X11 at the moment. Support for other backends (e.g. Wayland) should be easy to add for those familiar them.
**Note**: The following is a list of changes from the "v2" patches originally sent to the mailinglist
//Define and implement new Ecore_Event_Axis_Update events//
* Harcode axis labels instead of including xserver-properties.h
* Use C89-style comments
* Use doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Create "Ecore_Axis" and "Ecore_Axis_Label" typedefs
* Reference typedef'd instead of raw types
* Adjust how we count through valuators to support tilt/az
* Add support for tilt and azimuth
* Tweak memory management in case number of valuators differ
* Expand TWIST axis normalization to declared range
* Only normalize TWIST axis if resolution == 1 (wacom bug)
* Cache label atoms on first use to minimize round-trips
//Implement EVAS_CALLBACK_AXIS_UPDATE event and friends//
* Update to doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Typedef 'Evas_Axis_Label', 'Evas_Axis'
* Move typedef for 'Evas_Event_Axis_Update'
* Reference typedef'd instead of raw types
//Wire the Ecore and Evas implementations of axis update events together//
* Expose ecore_event_evas_axis_update in Ecore_Input_Evas.h
* Move ecore_event_evas_axis_update to more logical position
//DEBUG: Add axis update logging to evas-multi-touch.c//
* Removed from patch set
//Make evas-multi-touch demo use new axis functionality//
* Have pressure adjust rectangle brightness instead of size
* Use more available axis data when rendering rectangle (azimuth, tilt, twist)
Test Plan: The evas-multi-touch demo was updated to support axis update events. A graphics tablet was then used to verify that the pressure, azimuth, tilt, and twist data was coming through correctly.
Reviewers: cedric, raster
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1514
Conflicts:
src/lib/ecore_input/Ecore_Input.h
Carsten Haitzler -
** fixed forward enum typedefs (make things unhappy)
** fixed conflict above
** fixed wrong param type for _evas_canvas_event_feed_axis_update()
** fixed @sinces to be 1.13
** fixed formatting/indeting
** fixed order of operation reliance in if's with ()'s to be clear
** fixed functions to be static that should have been
2014-11-24 19:07:50 -08:00
|
|
|
}
|
|
|
|
|
2012-10-18 05:13:04 -07:00
|
|
|
static void
|
|
|
|
_feed_mouse_move_eval_internal(Eo *eo_obj, Evas_Object_Protected_Data *obj)
|
|
|
|
{
|
|
|
|
Evas_Public_Data *evas = obj->layer->evas;
|
|
|
|
Eina_Bool in_output_rect;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata = _evas_pointer_data_by_device_get(evas, NULL);
|
|
|
|
|
|
|
|
if (!pdata) return;
|
2017-06-02 15:23:45 -07:00
|
|
|
in_output_rect = evas_object_is_in_output_rect(eo_obj, obj, pdata->seat->x,
|
|
|
|
pdata->seat->y, 1, 1);
|
2012-10-18 05:13:04 -07:00
|
|
|
if ((in_output_rect) &&
|
|
|
|
((!obj->precise_is_inside) || (evas_object_is_inside(eo_obj, obj,
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->x,
|
|
|
|
pdata->seat->y))))
|
2016-05-29 22:26:48 -07:00
|
|
|
{
|
2016-08-18 00:28:55 -07:00
|
|
|
_canvas_event_feed_mouse_move_legacy(evas->evas, evas,
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->x, pdata->seat->y,
|
2016-08-18 00:28:55 -07:00
|
|
|
evas->last_timestamp, NULL);
|
2016-05-29 22:26:48 -07:00
|
|
|
}
|
2012-10-18 05:13:04 -07:00
|
|
|
}
|
2019-02-23 06:32:02 -08:00
|
|
|
EOLIAN void
|
|
|
|
_efl_canvas_object_efl_object_event_freeze(Eo *obj, Evas_Object_Protected_Data *pd)
|
|
|
|
{
|
|
|
|
efl_event_freeze(efl_super(obj, EFL_CANVAS_OBJECT_CLASS));
|
|
|
|
if (efl_event_freeze_count_get(obj) == 1)
|
|
|
|
{
|
|
|
|
pd->freeze_events = EINA_TRUE;
|
|
|
|
evas_object_smart_member_cache_invalidate(obj, EINA_FALSE, EINA_TRUE,
|
|
|
|
EINA_FALSE);
|
|
|
|
}
|
|
|
|
}
|
2012-10-18 05:13:04 -07:00
|
|
|
|
2014-03-11 04:51:35 -07:00
|
|
|
EOLIAN void
|
2019-02-23 06:32:02 -08:00
|
|
|
_efl_canvas_object_efl_object_event_thaw(Eo *obj, Evas_Object_Protected_Data *pd)
|
|
|
|
{
|
|
|
|
if (efl_event_freeze_count_get(obj) == 1)
|
|
|
|
{
|
|
|
|
pd->freeze_events = EINA_FALSE;
|
|
|
|
evas_object_smart_member_cache_invalidate(obj, EINA_FALSE, EINA_TRUE,
|
|
|
|
EINA_FALSE);
|
|
|
|
_feed_mouse_move_eval_internal(obj, pd);
|
|
|
|
}
|
|
|
|
efl_event_thaw(efl_super(obj, EFL_CANVAS_OBJECT_CLASS));
|
2011-10-27 03:36:09 -07:00
|
|
|
}
|
|
|
|
|
2019-02-23 06:32:02 -08:00
|
|
|
EAPI void
|
|
|
|
evas_object_freeze_events_set(Eo *eo_obj, Eina_Bool freeze)
|
|
|
|
{
|
2019-03-15 07:35:17 -07:00
|
|
|
Evas_Object_Protected_Data *pd = EVAS_OBJECT_DATA_SAFE_GET(eo_obj);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(pd);
|
|
|
|
|
|
|
|
freeze = !!freeze;
|
|
|
|
if (pd->freeze_events == freeze) return;
|
|
|
|
|
2019-02-23 06:32:02 -08:00
|
|
|
if (freeze)
|
|
|
|
efl_event_freeze(eo_obj);
|
|
|
|
else
|
|
|
|
// The following check is needed, as eo does not accept more thaw calls than freeze calls.
|
|
|
|
// However, evas legacy stuff accepted multiple flase sets
|
|
|
|
if (efl_event_freeze_count_get(eo_obj) > 0)
|
|
|
|
efl_event_thaw(eo_obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_Bool
|
|
|
|
evas_object_freeze_events_get(const Eo *eo_obj EINA_UNUSED)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2019-02-23 06:32:02 -08:00
|
|
|
return (efl_event_freeze_count_get(eo_obj) > 0);
|
2011-10-27 03:36:09 -07:00
|
|
|
}
|
|
|
|
|
2014-03-11 04:51:35 -07:00
|
|
|
EOLIAN void
|
2016-06-20 21:26:15 -07:00
|
|
|
_efl_canvas_object_pass_events_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, Eina_Bool pass)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2010-08-23 19:55:09 -07:00
|
|
|
pass = !!pass;
|
|
|
|
if (obj->pass_events == pass) return;
|
2002-11-08 00:02:15 -08:00
|
|
|
obj->pass_events = pass;
|
2012-10-18 04:30:04 -07:00
|
|
|
evas_object_smart_member_cache_invalidate(eo_obj, EINA_TRUE, EINA_FALSE, EINA_FALSE);
|
2012-10-18 05:13:04 -07:00
|
|
|
_feed_mouse_move_eval_internal(eo_obj, obj);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2014-03-11 04:51:35 -07:00
|
|
|
EOLIAN Eina_Bool
|
2018-04-17 11:09:44 -07:00
|
|
|
_efl_canvas_object_pass_events_get(const Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2014-03-11 04:51:35 -07:00
|
|
|
return obj->pass_events;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2014-03-11 04:51:35 -07:00
|
|
|
EOLIAN void
|
2016-06-20 21:26:15 -07:00
|
|
|
_efl_canvas_object_repeat_events_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, Eina_Bool repeat)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2010-08-23 19:55:09 -07:00
|
|
|
repeat = !!repeat;
|
|
|
|
if (obj->repeat_events == repeat) return;
|
2002-11-08 00:02:15 -08:00
|
|
|
obj->repeat_events = repeat;
|
2012-10-18 05:13:04 -07:00
|
|
|
_feed_mouse_move_eval_internal(eo_obj, obj);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2014-03-11 04:51:35 -07:00
|
|
|
EOLIAN Eina_Bool
|
2018-04-17 11:09:44 -07:00
|
|
|
_efl_canvas_object_repeat_events_get(const Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2014-03-11 04:51:35 -07:00
|
|
|
return obj->repeat_events;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2005-10-29 22:07:51 -07:00
|
|
|
|
2014-03-11 04:51:35 -07:00
|
|
|
EOLIAN void
|
2016-06-20 21:26:15 -07:00
|
|
|
_efl_canvas_object_propagate_events_set(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, Eina_Bool prop)
|
2005-10-29 22:07:51 -07:00
|
|
|
{
|
|
|
|
obj->no_propagate = !prop;
|
|
|
|
}
|
|
|
|
|
2014-03-11 04:51:35 -07:00
|
|
|
EOLIAN Eina_Bool
|
2018-04-17 11:09:44 -07:00
|
|
|
_efl_canvas_object_propagate_events_get(const Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2014-03-11 04:51:35 -07:00
|
|
|
return !(obj->no_propagate);
|
2005-10-29 22:07:51 -07:00
|
|
|
}
|
2007-07-24 07:20:07 -07:00
|
|
|
|
2017-05-09 15:54:45 -07:00
|
|
|
EOLIAN Eina_Bool
|
2016-10-21 05:25:41 -07:00
|
|
|
_efl_canvas_object_pointer_mode_by_device_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, Efl_Input_Device *dev, Evas_Object_Pointer_Mode setting)
|
2007-07-24 07:20:07 -07:00
|
|
|
{
|
2015-12-22 13:10:36 -08:00
|
|
|
int addgrab;
|
|
|
|
Evas_Object *cobj;
|
|
|
|
const Eina_List *l;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Pointer_Data *pdata;
|
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
|
|
|
|
|
|
|
pdata = _evas_pointer_data_by_device_get(obj->layer->evas, dev);
|
2017-05-09 15:54:45 -07:00
|
|
|
if (!pdata) return EINA_FALSE;
|
2016-10-21 05:25:41 -07:00
|
|
|
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2017-05-09 15:54:45 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(obj_pdata, EINA_FALSE);
|
2015-12-22 13:10:36 -08:00
|
|
|
|
|
|
|
/* ignore no-ops */
|
2017-05-09 15:54:45 -07:00
|
|
|
if (obj_pdata->pointer_mode == setting) return EINA_FALSE;
|
2015-12-22 13:10:36 -08:00
|
|
|
|
|
|
|
/* adjust by number of pointer down events */
|
2017-06-02 15:23:45 -07:00
|
|
|
addgrab = pdata->seat->downs;
|
2016-10-21 05:25:41 -07:00
|
|
|
switch (obj_pdata->pointer_mode)
|
2015-12-22 13:10:36 -08:00
|
|
|
{
|
|
|
|
/* nothing needed */
|
|
|
|
case EVAS_OBJECT_POINTER_MODE_NOGRAB: break;
|
|
|
|
/* decrement canvas nogrep (NO Grab/REPeat) counter */
|
|
|
|
case EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN:
|
2016-10-21 05:25:41 -07:00
|
|
|
if (obj_pdata->mouse_grabbed)
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->nogrep--;
|
2015-12-22 13:10:36 -08:00
|
|
|
/* fall through */
|
|
|
|
/* remove related grabs from canvas and object */
|
|
|
|
case EVAS_OBJECT_POINTER_MODE_AUTOGRAB:
|
2016-10-21 05:25:41 -07:00
|
|
|
if (obj_pdata->mouse_grabbed)
|
2015-12-22 13:10:36 -08:00
|
|
|
{
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->mouse_grabbed -= obj_pdata->mouse_grabbed;
|
2016-10-21 05:25:41 -07:00
|
|
|
obj_pdata->mouse_grabbed = 0;
|
2015-12-22 13:10:36 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/* adjustments for new mode */
|
|
|
|
switch (setting)
|
|
|
|
{
|
|
|
|
/* nothing needed */
|
|
|
|
case EVAS_OBJECT_POINTER_MODE_NOGRAB: break;
|
|
|
|
/* increment canvas nogrep (NO Grab/REPeat) counter */
|
|
|
|
case EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN:
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->nogrep++;
|
2015-12-22 13:10:36 -08:00
|
|
|
/* having nogrep set indicates that any object following it in
|
|
|
|
* the pointer.object.in list will not be receiving events, meaning
|
|
|
|
* that they will fail to unset any existing grabs/flags. unset them
|
|
|
|
* now to avoid breaking the canvas
|
|
|
|
*/
|
2017-06-02 15:23:45 -07:00
|
|
|
EINA_LIST_FOREACH(pdata->seat->object.in, l, cobj)
|
2015-12-22 13:10:36 -08:00
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *cobj_data;
|
|
|
|
|
|
|
|
/* skip to the current object */
|
|
|
|
if (cobj != eo_obj) continue;
|
|
|
|
/* only change objects past it */
|
|
|
|
EINA_LIST_FOREACH(l->next, l, cobj)
|
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *cobj_pdata;
|
2016-08-15 06:44:41 -07:00
|
|
|
cobj_data = efl_data_scope_get(cobj, EFL_CANVAS_OBJECT_CLASS);
|
2016-12-05 08:48:58 -08:00
|
|
|
cobj_pdata = _evas_object_pointer_data_get(pdata, cobj_data);
|
2016-12-06 01:21:50 -08:00
|
|
|
if (!cobj_pdata) continue;
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!cobj_pdata->mouse_grabbed) continue;
|
|
|
|
cobj_pdata->mouse_grabbed -= addgrab;
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->mouse_grabbed -= addgrab;
|
2016-10-21 05:25:41 -07:00
|
|
|
if (cobj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->nogrep--;
|
2015-12-22 13:10:36 -08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* fall through */
|
|
|
|
/* add all button grabs to this object */
|
|
|
|
case EVAS_OBJECT_POINTER_MODE_AUTOGRAB:
|
2016-10-21 05:25:41 -07:00
|
|
|
obj_pdata->mouse_grabbed += addgrab;
|
2017-06-02 15:23:45 -07:00
|
|
|
pdata->seat->mouse_grabbed += addgrab;
|
2015-12-22 13:10:36 -08:00
|
|
|
}
|
2016-10-21 05:25:41 -07:00
|
|
|
obj_pdata->pointer_mode = setting;
|
2017-05-09 15:54:45 -07:00
|
|
|
return EINA_TRUE;
|
2007-07-24 07:20:07 -07:00
|
|
|
}
|
|
|
|
|
2014-03-11 04:51:35 -07:00
|
|
|
EOLIAN Evas_Object_Pointer_Mode
|
2018-04-17 11:09:44 -07:00
|
|
|
_efl_canvas_object_pointer_mode_by_device_get(const Eo *eo_obj EINA_UNUSED,
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
Efl_Input_Device *dev)
|
2007-07-24 07:20:07 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
|
|
|
|
Evas_Pointer_Data *pdata;
|
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
|
|
|
|
|
|
|
pdata = _evas_pointer_data_by_device_get(obj->layer->evas, dev);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(pdata, EVAS_OBJECT_POINTER_MODE_AUTOGRAB);
|
|
|
|
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(obj_pdata, EVAS_OBJECT_POINTER_MODE_AUTOGRAB);
|
|
|
|
return obj_pdata->pointer_mode;
|
|
|
|
}
|
|
|
|
|
2017-05-09 15:54:45 -07:00
|
|
|
EOLIAN Eina_Bool
|
2016-10-21 05:25:41 -07:00
|
|
|
_efl_canvas_object_pointer_mode_set(Eo *eo_obj, Evas_Object_Protected_Data *obj,
|
|
|
|
Evas_Object_Pointer_Mode setting)
|
|
|
|
{
|
|
|
|
return _efl_canvas_object_pointer_mode_by_device_set(eo_obj, obj, NULL, setting);
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN Evas_Object_Pointer_Mode
|
2018-04-17 11:09:44 -07:00
|
|
|
_efl_canvas_object_pointer_mode_get(const Eo *eo_obj, Evas_Object_Protected_Data *obj)
|
2016-10-21 05:25:41 -07:00
|
|
|
{
|
|
|
|
return _efl_canvas_object_pointer_mode_by_device_get(eo_obj, obj, NULL);
|
2007-07-24 07:20:07 -07:00
|
|
|
}
|
2011-07-07 06:59:50 -07:00
|
|
|
|
2016-11-14 19:17:18 -08:00
|
|
|
EOLIAN Eina_Bool
|
2018-04-17 11:09:44 -07:00
|
|
|
_efl_canvas_object_efl_canvas_pointer_pointer_inside_get(const Eo *eo_obj,
|
2017-12-07 23:04:18 -08:00
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
Efl_Input_Device *pointer)
|
2016-11-14 19:17:18 -08:00
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *in, *parent;
|
|
|
|
Eo *eo_in, *eo_parent;
|
|
|
|
Eina_List *l;
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Object_Pointer_Data *obj_pdata;
|
|
|
|
Evas_Pointer_Data *pdata;
|
2016-11-14 19:17:18 -08:00
|
|
|
|
|
|
|
EVAS_OBJECT_DATA_ALIVE_CHECK(obj, EINA_FALSE);
|
2016-10-21 05:25:41 -07:00
|
|
|
|
|
|
|
if (!pointer)
|
|
|
|
pointer = obj->layer->evas->default_mouse;
|
|
|
|
|
|
|
|
if (!pointer) return EINA_FALSE;
|
|
|
|
|
|
|
|
pdata = _evas_pointer_data_by_device_get(obj->layer->evas, pointer);
|
|
|
|
if (!pdata) return EINA_FALSE;
|
2016-12-05 08:48:58 -08:00
|
|
|
obj_pdata = _evas_object_pointer_data_get(pdata, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj_pdata) return EINA_FALSE;
|
2016-11-14 19:17:18 -08:00
|
|
|
if (!obj->is_smart)
|
2016-10-21 05:25:41 -07:00
|
|
|
return obj_pdata->mouse_in;
|
2016-11-14 19:17:18 -08:00
|
|
|
|
2019-06-20 03:13:37 -07:00
|
|
|
/* This is to keep the legacy APIs evas_object_pointer_inside_by_device_get() &
|
2017-12-08 05:57:20 -08:00
|
|
|
* evas_object_pointer_inside_get() old behaviour. */
|
2017-12-07 23:04:18 -08:00
|
|
|
if (obj->is_pointer_inside_legacy) return EINA_FALSE;
|
|
|
|
|
2016-11-14 19:17:18 -08:00
|
|
|
/* For smart objects, this is a bit expensive obj->mouse_in will not be set.
|
|
|
|
* Alternatively we could count the number of in and out events propagated
|
|
|
|
* to the smart object, assuming they always match. */
|
2017-06-02 15:23:45 -07:00
|
|
|
EINA_LIST_FOREACH(pdata->seat->object.in, l, eo_in)
|
2016-11-14 19:17:18 -08:00
|
|
|
{
|
|
|
|
if (EINA_UNLIKELY(eo_in == eo_obj))
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
|
|
|
in = EVAS_OBJECT_DATA_GET(eo_in);
|
|
|
|
if (!EVAS_OBJECT_DATA_ALIVE(in)) continue;
|
|
|
|
eo_parent = in->smart.parent;
|
|
|
|
while (eo_parent)
|
|
|
|
{
|
|
|
|
if ((eo_parent == eo_obj) && !in->no_propagate)
|
|
|
|
return EINA_TRUE;
|
|
|
|
parent = EVAS_OBJECT_DATA_GET(eo_parent);
|
|
|
|
if (!EVAS_OBJECT_DATA_ALIVE(parent)) break;
|
|
|
|
eo_parent = parent->smart.parent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2016-05-11 00:21:49 -07:00
|
|
|
EAPI void
|
|
|
|
evas_event_refeed_event(Eo *eo_e, void *event_copy, Evas_Callback_Type event_type)
|
2011-07-07 06:59:50 -07:00
|
|
|
{
|
2016-08-25 19:27:37 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
|
2012-05-01 19:40:03 -07:00
|
|
|
if (!event_copy) return;
|
|
|
|
|
2011-12-27 04:03:03 -08:00
|
|
|
switch (event_type)
|
2011-07-07 06:59:50 -07:00
|
|
|
{
|
|
|
|
case EVAS_CALLBACK_MOUSE_IN:
|
2011-12-27 04:03:03 -08:00
|
|
|
{
|
|
|
|
Evas_Event_Mouse_In *ev = event_copy;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_feed_mouse_in(eo_e, ev->timestamp, ev->data);
|
2011-12-27 04:03:03 -08:00
|
|
|
break;
|
|
|
|
}
|
2011-07-07 06:59:50 -07:00
|
|
|
case EVAS_CALLBACK_MOUSE_OUT:
|
2011-12-27 04:03:03 -08:00
|
|
|
{
|
|
|
|
Evas_Event_Mouse_Out *ev = event_copy;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_feed_mouse_out(eo_e, ev->timestamp, ev->data);
|
2011-12-27 04:03:03 -08:00
|
|
|
break;
|
|
|
|
}
|
2011-07-07 06:59:50 -07:00
|
|
|
case EVAS_CALLBACK_MOUSE_DOWN:
|
2011-12-27 04:03:03 -08:00
|
|
|
{
|
|
|
|
Evas_Event_Mouse_Down *ev = event_copy;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_feed_mouse_down(eo_e, ev->button, ev->flags, ev-> timestamp, ev->data);
|
2011-12-27 04:03:03 -08:00
|
|
|
break;
|
|
|
|
}
|
2011-07-07 06:59:50 -07:00
|
|
|
case EVAS_CALLBACK_MOUSE_UP:
|
2011-12-27 04:03:03 -08:00
|
|
|
{
|
|
|
|
Evas_Event_Mouse_Up *ev = event_copy;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_feed_mouse_up(eo_e, ev->button, ev->flags, ev-> timestamp, ev->data);
|
2011-12-27 04:03:03 -08:00
|
|
|
break;
|
|
|
|
}
|
2011-07-07 06:59:50 -07:00
|
|
|
case EVAS_CALLBACK_MOUSE_MOVE:
|
2011-12-27 04:03:03 -08:00
|
|
|
{
|
|
|
|
Evas_Event_Mouse_Move *ev = event_copy;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_feed_mouse_move(eo_e, ev->cur.canvas.x, ev->cur.canvas.y, ev->timestamp, ev->data);
|
2011-12-27 04:03:03 -08:00
|
|
|
break;
|
|
|
|
}
|
2011-07-07 06:59:50 -07:00
|
|
|
case EVAS_CALLBACK_MOUSE_WHEEL:
|
2011-12-27 04:03:03 -08:00
|
|
|
{
|
|
|
|
Evas_Event_Mouse_Wheel *ev = event_copy;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_feed_mouse_wheel(eo_e, ev->direction, ev-> z, ev->timestamp, ev->data);
|
2011-12-27 04:03:03 -08:00
|
|
|
break;
|
|
|
|
}
|
2011-07-07 06:59:50 -07:00
|
|
|
case EVAS_CALLBACK_MULTI_DOWN:
|
2011-12-27 04:03:03 -08:00
|
|
|
{
|
|
|
|
Evas_Event_Multi_Down *ev = event_copy;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_feed_multi_down(eo_e, ev->device, ev->canvas.x, ev->canvas.y, ev->radius, ev->radius_x, ev->radius_y, ev->pressure, ev->angle, ev->canvas.xsub, ev->canvas.ysub, ev->flags, ev->timestamp, ev->data);
|
2011-12-27 04:03:03 -08:00
|
|
|
break;
|
|
|
|
}
|
2011-07-07 06:59:50 -07:00
|
|
|
case EVAS_CALLBACK_MULTI_UP:
|
2011-12-27 04:03:03 -08:00
|
|
|
{
|
|
|
|
Evas_Event_Multi_Up *ev = event_copy;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_feed_multi_up(eo_e, ev->device, ev->canvas.x, ev->canvas.y, ev->radius, ev->radius_x, ev->radius_y, ev->pressure, ev->angle, ev->canvas.xsub, ev->canvas.ysub, ev->flags, ev->timestamp, ev->data);
|
2011-12-27 04:03:03 -08:00
|
|
|
break;
|
|
|
|
}
|
2011-07-07 06:59:50 -07:00
|
|
|
case EVAS_CALLBACK_MULTI_MOVE:
|
2011-12-27 04:03:03 -08:00
|
|
|
{
|
|
|
|
Evas_Event_Multi_Move *ev = event_copy;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_feed_multi_move(eo_e, ev->device, ev->cur.canvas.x, ev->cur.canvas.y, ev->radius, ev->radius_x, ev->radius_y, ev->pressure, ev->angle, ev->cur.canvas.xsub, ev->cur.canvas.ysub, ev->timestamp, ev->data);
|
2011-12-27 04:03:03 -08:00
|
|
|
break;
|
|
|
|
}
|
2011-07-07 06:59:50 -07:00
|
|
|
case EVAS_CALLBACK_KEY_DOWN:
|
2011-12-27 04:03:03 -08:00
|
|
|
{
|
|
|
|
Evas_Event_Key_Down *ev = event_copy;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_feed_key_down(eo_e, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, ev->data);
|
2011-12-27 04:03:03 -08:00
|
|
|
break;
|
|
|
|
}
|
2011-07-07 06:59:50 -07:00
|
|
|
case EVAS_CALLBACK_KEY_UP:
|
2011-12-27 04:03:03 -08:00
|
|
|
{
|
|
|
|
Evas_Event_Key_Up *ev = event_copy;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_feed_key_up(eo_e, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, ev->data);
|
2011-12-27 04:03:03 -08:00
|
|
|
break;
|
|
|
|
}
|
Expose device (e.g. pen) axis information to applications
Summary:
This patch set adds the necessary code to expose device axis state to applications. This was primarily written with graphics tablets in mind, which -- in addition to acting like a mouse -- also provide information about pen pressure, tilt, etc. Other devices could potentially benefit from this API as well: touchscreens, joysticks, knob controllers, "spaceballs", etc.
Whenever an update to the device state is recieved, an "Axis update" event is synthesized. This event contains the updated information, typically scaled and normalized to a particular logical range (e.g. zero to one for pressure, -pi to pi radians for angles, etc.). Information about the tool which generated the event is also stored so that applications can disambiguate events from multiple devices (or in the case of multitouch screens, individual fingers).
This API is only wired up for use with X11 at the moment. Support for other backends (e.g. Wayland) should be easy to add for those familiar them.
**Note**: The following is a list of changes from the "v2" patches originally sent to the mailinglist
//Define and implement new Ecore_Event_Axis_Update events//
* Harcode axis labels instead of including xserver-properties.h
* Use C89-style comments
* Use doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Create "Ecore_Axis" and "Ecore_Axis_Label" typedefs
* Reference typedef'd instead of raw types
* Adjust how we count through valuators to support tilt/az
* Add support for tilt and azimuth
* Tweak memory management in case number of valuators differ
* Expand TWIST axis normalization to declared range
* Only normalize TWIST axis if resolution == 1 (wacom bug)
* Cache label atoms on first use to minimize round-trips
//Implement EVAS_CALLBACK_AXIS_UPDATE event and friends//
* Update to doxygen comments
* Update comment text to note axes with unbounded/undefined ranges/units
* Typedef 'Evas_Axis_Label', 'Evas_Axis'
* Move typedef for 'Evas_Event_Axis_Update'
* Reference typedef'd instead of raw types
//Wire the Ecore and Evas implementations of axis update events together//
* Expose ecore_event_evas_axis_update in Ecore_Input_Evas.h
* Move ecore_event_evas_axis_update to more logical position
//DEBUG: Add axis update logging to evas-multi-touch.c//
* Removed from patch set
//Make evas-multi-touch demo use new axis functionality//
* Have pressure adjust rectangle brightness instead of size
* Use more available axis data when rendering rectangle (azimuth, tilt, twist)
Test Plan: The evas-multi-touch demo was updated to support axis update events. A graphics tablet was then used to verify that the pressure, azimuth, tilt, and twist data was coming through correctly.
Reviewers: cedric, raster
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D1514
Conflicts:
src/lib/ecore_input/Ecore_Input.h
Carsten Haitzler -
** fixed forward enum typedefs (make things unhappy)
** fixed conflict above
** fixed wrong param type for _evas_canvas_event_feed_axis_update()
** fixed @sinces to be 1.13
** fixed formatting/indeting
** fixed order of operation reliance in if's with ()'s to be clear
** fixed functions to be static that should have been
2014-11-24 19:07:50 -08:00
|
|
|
case EVAS_CALLBACK_AXIS_UPDATE:
|
|
|
|
{
|
|
|
|
Evas_Event_Axis_Update *ev = event_copy;
|
|
|
|
evas_event_feed_axis_update(eo_e, ev->timestamp, ev->device, ev->toolid, ev->naxis, ev->axis, ev->data);
|
|
|
|
break;
|
|
|
|
}
|
2011-07-07 06:59:50 -07:00
|
|
|
default: /* All non-input events are not handeled */
|
2011-12-27 04:03:03 -08:00
|
|
|
break;
|
2011-07-07 06:59:50 -07:00
|
|
|
}
|
|
|
|
}
|
2011-12-27 04:01:17 -08:00
|
|
|
|
2016-10-21 05:25:41 -07:00
|
|
|
|
|
|
|
EOLIAN int
|
2018-04-17 11:09:44 -07:00
|
|
|
_evas_canvas_event_down_count_by_device_get(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e,
|
2016-10-21 05:25:41 -07:00
|
|
|
Efl_Input_Device *dev)
|
|
|
|
{
|
|
|
|
Evas_Pointer_Data *pdata = _evas_pointer_data_by_device_get(e, dev);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(pdata, 0);
|
2017-06-02 15:23:45 -07:00
|
|
|
return pdata->seat->downs;
|
2016-10-21 05:25:41 -07:00
|
|
|
}
|
|
|
|
|
2014-03-11 23:53:00 -07:00
|
|
|
EOLIAN int
|
2018-04-17 11:09:44 -07:00
|
|
|
_evas_canvas_event_down_count_get(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-10-21 05:25:41 -07:00
|
|
|
return _evas_canvas_event_down_count_by_device_get(eo_e, e, NULL);
|
2011-12-27 04:01:17 -08:00
|
|
|
}
|
2016-04-28 02:43:18 -07:00
|
|
|
|
2016-06-20 07:31:31 -07:00
|
|
|
static void
|
2016-08-30 05:34:10 -07:00
|
|
|
_evas_canvas_event_pointer_cb(void *data, const Efl_Event *event)
|
2016-05-10 05:26:07 -07:00
|
|
|
{
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Pointer_Data *ev = efl_data_scope_get(event->info, EFL_INPUT_POINTER_CLASS);
|
2016-05-10 05:26:07 -07:00
|
|
|
Evas_Public_Data *e = data;
|
|
|
|
Evas *eo_e = event->object;
|
2016-08-17 04:29:39 -07:00
|
|
|
Eina_Bool nodev = 0;
|
2016-05-10 05:26:07 -07:00
|
|
|
|
2016-06-20 07:31:31 -07:00
|
|
|
if (!ev) return;
|
2016-05-10 05:26:07 -07:00
|
|
|
|
2016-05-11 04:26:07 -07:00
|
|
|
ev->evas_done = EINA_TRUE;
|
2016-05-29 23:34:31 -07:00
|
|
|
ev->modifiers = &e->modifiers;
|
|
|
|
ev->locks = &e->locks;
|
|
|
|
|
2016-08-17 04:29:39 -07:00
|
|
|
if (!ev->device)
|
|
|
|
{
|
|
|
|
nodev = 1;
|
2016-10-26 05:37:29 -07:00
|
|
|
ev->device = _evas_event_legacy_device_get(e->evas, EINA_TRUE);
|
2016-08-17 04:29:39 -07:00
|
|
|
}
|
|
|
|
|
2016-05-10 05:26:07 -07:00
|
|
|
switch (ev->action)
|
|
|
|
{
|
2016-05-11 04:13:19 -07:00
|
|
|
case EFL_POINTER_ACTION_MOVE:
|
2019-06-20 03:13:37 -07:00
|
|
|
if (ev->touch_id == 0)
|
2016-08-18 00:28:55 -07:00
|
|
|
_canvas_event_feed_mouse_move_internal(e, ev);
|
2016-05-10 05:26:07 -07:00
|
|
|
else
|
2016-08-17 23:33:36 -07:00
|
|
|
_canvas_event_feed_multi_move_internal(e, ev);
|
2016-05-10 05:26:07 -07:00
|
|
|
break;
|
|
|
|
|
2016-05-11 04:13:19 -07:00
|
|
|
case EFL_POINTER_ACTION_DOWN:
|
2019-06-20 03:13:37 -07:00
|
|
|
if (ev->touch_id == 0)
|
2016-08-17 04:29:39 -07:00
|
|
|
_canvas_event_feed_mouse_down_internal(e, ev);
|
2016-05-10 22:54:11 -07:00
|
|
|
else
|
2016-08-17 22:54:54 -07:00
|
|
|
_canvas_event_feed_multi_down_internal(e, ev);
|
2016-05-10 05:26:07 -07:00
|
|
|
break;
|
|
|
|
|
2016-05-11 04:13:19 -07:00
|
|
|
case EFL_POINTER_ACTION_UP:
|
2019-06-20 03:13:37 -07:00
|
|
|
if (ev->touch_id == 0)
|
2016-08-17 04:29:39 -07:00
|
|
|
_canvas_event_feed_mouse_up_internal(e, ev);
|
2016-05-10 22:54:11 -07:00
|
|
|
else
|
2016-08-17 22:54:54 -07:00
|
|
|
_canvas_event_feed_multi_up_internal(e, ev);
|
2016-05-11 04:26:07 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case EFL_POINTER_ACTION_CANCEL:
|
2016-08-17 22:54:54 -07:00
|
|
|
_canvas_event_feed_mouse_cancel_internal(e, ev);
|
2016-05-11 04:26:07 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case EFL_POINTER_ACTION_IN:
|
2016-08-17 20:01:39 -07:00
|
|
|
_canvas_event_feed_mouse_in_internal(eo_e, ev);
|
2016-05-11 04:26:07 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case EFL_POINTER_ACTION_OUT:
|
2016-08-17 20:01:39 -07:00
|
|
|
_canvas_event_feed_mouse_out_internal(eo_e, ev);
|
2016-05-10 05:26:07 -07:00
|
|
|
break;
|
|
|
|
|
2016-05-11 04:13:19 -07:00
|
|
|
case EFL_POINTER_ACTION_WHEEL:
|
2016-08-10 19:58:42 -07:00
|
|
|
_canvas_event_feed_mouse_wheel_internal(eo_e, ev);
|
2016-05-10 05:26:07 -07:00
|
|
|
break;
|
|
|
|
|
2016-08-23 04:23:48 -07:00
|
|
|
case EFL_POINTER_ACTION_AXIS:
|
|
|
|
_canvas_event_feed_axis_update_internal(e, ev);
|
|
|
|
break;
|
|
|
|
|
2016-05-10 05:26:07 -07:00
|
|
|
default:
|
2016-05-11 04:26:07 -07:00
|
|
|
ERR("unsupported event type: %d", ev->action);
|
|
|
|
ev->evas_done = EINA_FALSE;
|
2016-05-10 05:26:07 -07:00
|
|
|
break;
|
|
|
|
}
|
2016-08-17 04:29:39 -07:00
|
|
|
|
|
|
|
if (nodev) ev->device = NULL;
|
2016-05-10 05:26:07 -07:00
|
|
|
}
|
|
|
|
|
2016-06-20 07:31:31 -07:00
|
|
|
static void
|
2016-08-30 05:34:10 -07:00
|
|
|
_evas_canvas_event_key_cb(void *data, const Efl_Event *event)
|
2016-05-31 23:32:35 -07:00
|
|
|
{
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Key *evt = event->info;
|
2016-05-31 23:32:35 -07:00
|
|
|
Evas_Public_Data *e = data;
|
2016-08-25 03:20:10 -07:00
|
|
|
Efl_Input_Key_Data *ev;
|
2016-08-17 03:39:10 -07:00
|
|
|
Eina_Bool nodev = 0;
|
2016-05-31 23:32:35 -07:00
|
|
|
|
2016-08-25 03:20:10 -07:00
|
|
|
ev = efl_data_scope_get(evt, EFL_INPUT_KEY_CLASS);
|
2016-06-20 07:31:31 -07:00
|
|
|
if (!ev) return;
|
2016-05-31 23:32:35 -07:00
|
|
|
|
2016-08-17 03:39:10 -07:00
|
|
|
if (!ev->device)
|
2016-05-31 23:32:35 -07:00
|
|
|
{
|
2016-08-17 03:39:10 -07:00
|
|
|
nodev = 1;
|
2016-10-26 05:37:29 -07:00
|
|
|
ev->device = _evas_event_legacy_device_get(e->evas, EINA_FALSE);
|
2016-05-31 23:32:35 -07:00
|
|
|
}
|
2016-08-17 03:39:10 -07:00
|
|
|
|
2017-05-30 03:16:48 -07:00
|
|
|
ev->modifiers = &e->modifiers;
|
|
|
|
ev->locks = &e->locks;
|
|
|
|
|
2016-08-17 03:39:10 -07:00
|
|
|
if (ev->pressed)
|
|
|
|
_canvas_event_feed_key_down_internal(e, ev);
|
2016-05-31 23:32:35 -07:00
|
|
|
else
|
2016-08-17 03:39:10 -07:00
|
|
|
_canvas_event_feed_key_up_internal(e, ev);
|
2016-05-31 23:32:35 -07:00
|
|
|
|
2016-08-17 03:39:10 -07:00
|
|
|
if (nodev) ev->device = NULL;
|
2016-06-01 04:40:18 -07:00
|
|
|
ev->evas_done = EINA_TRUE;
|
2016-05-31 23:32:35 -07:00
|
|
|
}
|
|
|
|
|
2016-11-17 11:30:58 -08:00
|
|
|
static void
|
|
|
|
_evas_canvas_event_focus_cb(void *data, const Efl_Event *event)
|
|
|
|
{
|
2019-06-26 23:13:04 -07:00
|
|
|
Efl_Input_Device *seat = efl_canvas_scene_seat_default_get(event->object);
|
2016-11-17 11:30:58 -08:00
|
|
|
Evas_Public_Data *e = data;
|
|
|
|
|
2019-06-26 23:13:04 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(seat);
|
|
|
|
|
|
|
|
if (event->desc == EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_IN)
|
2016-11-17 11:30:58 -08:00
|
|
|
{
|
2016-11-01 11:30:26 -07:00
|
|
|
if (eina_list_data_find(e->focused_by, seat)) return;
|
|
|
|
e->focused_by = eina_list_append(e->focused_by, seat);
|
2016-11-17 11:30:58 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-11-01 11:30:26 -07:00
|
|
|
if (!eina_list_data_find(e->focused_by, seat)) return;
|
|
|
|
e->focused_by = eina_list_remove(e->focused_by, seat);
|
2016-11-17 11:30:58 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-30 23:31:17 -07:00
|
|
|
// note: "hold" event comes from above (elm), not below (ecore)
|
2016-08-15 06:44:41 -07:00
|
|
|
EFL_CALLBACKS_ARRAY_DEFINE(_evas_canvas_event_pointer_callbacks,
|
2016-05-30 04:53:07 -07:00
|
|
|
{ EFL_EVENT_POINTER_MOVE, _evas_canvas_event_pointer_cb },
|
|
|
|
{ EFL_EVENT_POINTER_DOWN, _evas_canvas_event_pointer_cb },
|
|
|
|
{ EFL_EVENT_POINTER_UP, _evas_canvas_event_pointer_cb },
|
|
|
|
{ EFL_EVENT_POINTER_IN, _evas_canvas_event_pointer_cb },
|
|
|
|
{ EFL_EVENT_POINTER_OUT, _evas_canvas_event_pointer_cb },
|
|
|
|
{ EFL_EVENT_POINTER_CANCEL, _evas_canvas_event_pointer_cb },
|
2016-05-31 23:32:35 -07:00
|
|
|
{ EFL_EVENT_POINTER_WHEEL, _evas_canvas_event_pointer_cb },
|
2016-08-23 04:23:48 -07:00
|
|
|
{ EFL_EVENT_POINTER_AXIS, _evas_canvas_event_pointer_cb },
|
2016-08-30 23:41:12 -07:00
|
|
|
{ EFL_EVENT_FINGER_MOVE, _evas_canvas_event_pointer_cb },
|
|
|
|
{ EFL_EVENT_FINGER_DOWN, _evas_canvas_event_pointer_cb },
|
|
|
|
{ EFL_EVENT_FINGER_UP, _evas_canvas_event_pointer_cb },
|
2016-05-31 23:32:35 -07:00
|
|
|
{ EFL_EVENT_KEY_DOWN, _evas_canvas_event_key_cb },
|
2016-11-17 11:30:58 -08:00
|
|
|
{ EFL_EVENT_KEY_UP, _evas_canvas_event_key_cb },
|
2019-06-26 23:13:04 -07:00
|
|
|
{ EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_IN, _evas_canvas_event_focus_cb },
|
|
|
|
{ EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_OUT, _evas_canvas_event_focus_cb })
|
2016-05-30 04:53:07 -07:00
|
|
|
|
2016-05-10 05:26:07 -07:00
|
|
|
void
|
|
|
|
_evas_canvas_event_init(Evas *eo_e, Evas_Public_Data *e)
|
|
|
|
{
|
2016-08-10 07:23:04 -07:00
|
|
|
efl_event_callback_array_add(eo_e, _evas_canvas_event_pointer_callbacks(), e);
|
2016-05-10 05:26:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_evas_canvas_event_shutdown(Evas *eo_e, Evas_Public_Data *e)
|
2016-04-28 02:43:18 -07:00
|
|
|
{
|
2016-08-10 07:23:04 -07:00
|
|
|
efl_event_callback_array_del(eo_e, _evas_canvas_event_pointer_callbacks(), e);
|
2016-04-28 02:43:18 -07:00
|
|
|
}
|
2016-10-21 05:25:41 -07:00
|
|
|
|
|
|
|
void
|
|
|
|
_evas_canvas_event_pointer_move_event_dispatch(Evas_Public_Data *edata,
|
|
|
|
Evas_Pointer_Data *pdata,
|
|
|
|
void *data)
|
|
|
|
{
|
|
|
|
Efl_Input_Pointer_Data *ev = NULL;
|
|
|
|
Efl_Input_Pointer *evt;
|
|
|
|
|
2019-02-09 10:08:45 -08:00
|
|
|
evt = efl_input_pointer_instance_get( edata->evas,
|
2016-10-21 05:25:41 -07:00
|
|
|
(void **) &ev);
|
|
|
|
if (!evt) return;
|
|
|
|
|
|
|
|
ev->data = (void *) data;
|
|
|
|
ev->timestamp = edata->last_timestamp;
|
|
|
|
ev->device = efl_ref(pdata->pointer);
|
2017-06-02 15:23:45 -07:00
|
|
|
ev->cur.x = pdata->seat->x;
|
|
|
|
ev->cur.y = pdata->seat->y;
|
2016-10-21 05:25:41 -07:00
|
|
|
|
|
|
|
_canvas_event_feed_mouse_move_internal(edata, ev);
|
|
|
|
|
2018-03-20 10:21:19 -07:00
|
|
|
efl_unref(evt);
|
2016-10-21 05:25:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_evas_canvas_event_pointer_in_rect_mouse_move_feed(Evas_Public_Data *edata,
|
|
|
|
Evas_Object *obj,
|
|
|
|
Evas_Object_Protected_Data *obj_data,
|
|
|
|
int w, int h,
|
|
|
|
Eina_Bool in_objects_list,
|
|
|
|
void *data)
|
|
|
|
{
|
2017-06-16 12:03:09 -07:00
|
|
|
Evas_Pointer_Seat *pseat;
|
2016-10-21 05:25:41 -07:00
|
|
|
|
2017-06-16 12:03:09 -07:00
|
|
|
EINA_INLIST_FOREACH(edata->seats, pseat)
|
2016-10-21 05:25:41 -07:00
|
|
|
{
|
2017-06-16 12:03:09 -07:00
|
|
|
if (!pseat->pointers) continue;
|
2017-06-16 12:03:09 -07:00
|
|
|
if (!evas_object_is_in_output_rect(obj, obj_data, pseat->x,
|
|
|
|
pseat->y, w, h))
|
2016-10-21 05:25:41 -07:00
|
|
|
continue;
|
2017-06-16 12:03:09 -07:00
|
|
|
if ((in_objects_list && eina_list_data_find(pseat->object.in, obj)) || !in_objects_list)
|
|
|
|
{
|
|
|
|
Evas_Pointer_Data *pdata = EINA_INLIST_CONTAINER_GET(pseat->pointers, Evas_Pointer_Data);
|
|
|
|
_evas_canvas_event_pointer_move_event_dispatch(edata, pdata, data);
|
|
|
|
}
|
2016-10-21 05:25:41 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_evas_canvas_event_pointer_in_list_mouse_move_feed(Evas_Public_Data *edata,
|
|
|
|
Eina_List *was,
|
|
|
|
Evas_Object *obj,
|
|
|
|
Evas_Object_Protected_Data *obj_data,
|
|
|
|
int w, int h,
|
|
|
|
Eina_Bool xor_rule,
|
|
|
|
void *data)
|
|
|
|
{
|
2017-06-16 12:03:09 -07:00
|
|
|
Evas_Pointer_Seat *pseat;
|
2016-10-21 05:25:41 -07:00
|
|
|
|
2017-06-16 12:03:09 -07:00
|
|
|
EINA_INLIST_FOREACH(edata->seats, pseat)
|
2016-10-21 05:25:41 -07:00
|
|
|
{
|
2017-06-16 12:03:09 -07:00
|
|
|
Evas_Pointer_Data *pdata, *found = NULL;
|
|
|
|
Eina_List *l;
|
2017-06-16 12:03:09 -07:00
|
|
|
int in;
|
|
|
|
|
|
|
|
if (!pseat->pointers) continue;
|
|
|
|
in = evas_object_is_in_output_rect(obj, obj_data, pseat->x,
|
2017-06-16 12:03:09 -07:00
|
|
|
pseat->y, w, h);
|
|
|
|
EINA_LIST_FOREACH(was, l, pdata)
|
|
|
|
if (pdata->seat == pseat)
|
|
|
|
{
|
|
|
|
found = pdata;
|
|
|
|
break;
|
|
|
|
}
|
2016-10-21 05:25:41 -07:00
|
|
|
|
|
|
|
if ((xor_rule && ((in && !found) || (!in && found))) ||
|
|
|
|
(!xor_rule && (in || found)))
|
2017-06-16 12:03:09 -07:00
|
|
|
{
|
|
|
|
if (!pdata) pdata = EINA_INLIST_CONTAINER_GET(pseat->pointers, Evas_Pointer_Data);
|
|
|
|
_evas_canvas_event_pointer_move_event_dispatch(edata, pdata, data);
|
|
|
|
}
|
2016-10-21 05:25:41 -07:00
|
|
|
}
|
|
|
|
}
|