evas: Add function on object to check is pointer is in

This fixes invalid mouse cursor used when windows are
created.

Due to the changes in the border theme and the fact that
a border is now always created, the event region
"elm.resize.bl" contains the point (0,0) when the window
size itself is 1x1. As a consequence every EFL application
would permanently have a cursor like the resize bottom/left
handle.

This fixes that by properly checking whether the pointer is
inside an object based on the ins list, and not just the
object geometry.

@feature

See also: b735386a45
This commit is contained in:
Jean-Philippe Andre 2016-11-15 12:17:18 +09:00
parent 9fb4f0ab2b
commit aac8f6f114
4 changed files with 52 additions and 4 deletions

View File

@ -543,10 +543,7 @@ _elm_cursor_cur_set(Elm_Cursor *cur)
}
}
Evas_Coord x, y, w, h, px, py;
evas_object_geometry_get(cur->eventarea, &x, &y, &w, &h);
evas_pointer_canvas_xy_get(cur->evas, &px, &py);
if (IS_INSIDE(px, py, x, y, w, h))
if (efl_canvas_object_pointer_in_get(cur->eventarea))
_elm_cursor_set(cur);
}

View File

@ -42,6 +42,20 @@ abstract Efl.Canvas.Object (Efl.Object, Efl.Gfx, Efl.Gfx.Stack, Efl.Animator,
pointer_mode: Efl.Input.Object_Pointer_Mode; [[Input pointer mode]]
}
}
@property pointer_in {
[[Read-only value indicating whether the main pointer is in the object.
This shall be true between pointer,in and pointer,out events (coming
in matching numbers). Note that group objects may receive multiple
pointer,in in a row.
@since 1.19
]]
get{}
values {
in: bool; [[If $true the main pointer has entered this object.]]
}
}
@property render_op {
[[Render mode to be used for compositing the Evas object.

View File

@ -3304,6 +3304,41 @@ _efl_canvas_object_pointer_mode_get(Eo *eo_obj EINA_UNUSED, Evas_Object_Protecte
return obj->pointer_mode;
}
EOLIAN Eina_Bool
_efl_canvas_object_pointer_in_get(Eo *eo_obj, Evas_Object_Protected_Data *obj)
{
Evas_Object_Protected_Data *in, *parent;
Eo *eo_in, *eo_parent;
Eina_List *l;
EVAS_OBJECT_DATA_ALIVE_CHECK(obj, EINA_FALSE);
if (!obj->is_smart)
return obj->mouse_in;
/* 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. */
EINA_LIST_FOREACH(obj->layer->evas->pointer.object.in, l, eo_in)
{
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;
}
EAPI void
evas_event_refeed_event(Eo *eo_e, void *event_copy, Evas_Callback_Type event_type)
{

View File

@ -13,6 +13,8 @@
if (EINA_UNLIKELY(!EVAS_OBJECT_DATA_VALID(o))) return __VA_ARGS__; } while (0)
#define EVAS_OBJECT_DATA_ALIVE_CHECK(o, ...) do { \
if (EINA_UNLIKELY(!EVAS_OBJECT_DATA_ALIVE(o))) return __VA_ARGS__; } while (0)
#define EVAS_OBJECT_DATA_GET(eo_o) \
efl_data_scope_get((eo_o), EFL_CANVAS_OBJECT_CLASS)
#define EVAS_OBJECT_DATA_SAFE_GET(eo_o) \
(((eo_o) && efl_isa((eo_o), EFL_CANVAS_OBJECT_CLASS)) ? efl_data_scope_get((eo_o), EFL_CANVAS_OBJECT_CLASS) : NULL)