evas: handle existing pointer grabs when changing object pointer mode

in the case that pointer mode is changed on an object at any time after
a grab has been acquired by the object, grabs/flags must be adjusted for
this and other "pointer-in" objects in order to avoid permanently
breaking canvas events

@fix
This commit is contained in:
Mike Blumenkrantz 2015-12-22 16:10:36 -05:00
parent e4d11e2e4f
commit 8981f08555
1 changed files with 64 additions and 1 deletions

View File

@ -2863,8 +2863,71 @@ _evas_object_propagate_events_get(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_
}
EOLIAN void
_evas_object_pointer_mode_set(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, Evas_Object_Pointer_Mode setting)
_evas_object_pointer_mode_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, Evas_Object_Pointer_Mode setting)
{
int addgrab;
Evas_Object *cobj;
const Eina_List *l;
/* ignore no-ops */
if (obj->pointer_mode == setting) return;
/* adjust by number of pointer down events */
addgrab = obj->layer->evas->pointer.downs;
switch (obj->pointer_mode)
{
/* 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:
if (obj->mouse_grabbed)
obj->layer->evas->pointer.nogrep--;
/* fall through */
/* remove related grabs from canvas and object */
case EVAS_OBJECT_POINTER_MODE_AUTOGRAB:
if (obj->mouse_grabbed)
{
obj->layer->evas->pointer.mouse_grabbed -= obj->mouse_grabbed;
obj->mouse_grabbed = 0;
}
}
/* 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:
obj->layer->evas->pointer.nogrep++;
/* 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
*/
EINA_LIST_FOREACH(obj->layer->evas->pointer.object.in, l, cobj)
{
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)
{
cobj_data = eo_data_scope_get(cobj, EVAS_OBJECT_CLASS);
if (!cobj_data->mouse_grabbed) continue;
cobj_data->mouse_grabbed -= addgrab;
cobj_data->layer->evas->pointer.mouse_grabbed -= addgrab;
if (cobj_data->pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)
cobj_data->layer->evas->pointer.nogrep--;
}
break;
}
/* fall through */
/* add all button grabs to this object */
case EVAS_OBJECT_POINTER_MODE_AUTOGRAB:
obj->mouse_grabbed += addgrab;
obj->layer->evas->pointer.mouse_grabbed += addgrab;
}
obj->pointer_mode = setting;
}