forked from enlightenment/efl
make deleting of grabs within a key callback "safe"
SVN revision: 7117
This commit is contained in:
parent
0656623f54
commit
0c5a435128
|
@ -515,7 +515,9 @@ evas_event_feed_key_down_data(Evas *e, const char *keyname, const void *data)
|
|||
if (e->events_frozen > 0) return;
|
||||
{
|
||||
Evas_Event_Key_Down ev;
|
||||
int exclusive;
|
||||
|
||||
exclusive = 0;
|
||||
ev.keyname = (char *)keyname;
|
||||
ev.data = (void *)data;
|
||||
ev.modifiers = &(e->modifiers);
|
||||
|
@ -524,11 +526,18 @@ evas_event_feed_key_down_data(Evas *e, const char *keyname, const void *data)
|
|||
{
|
||||
Evas_List *l;
|
||||
|
||||
e->walking_grabs++;
|
||||
for (l = e->grabs; l; l= l->next)
|
||||
{
|
||||
Evas_Key_Grab *g;
|
||||
|
||||
g = l->data;
|
||||
if (g->just_added)
|
||||
{
|
||||
g->just_added = 0;
|
||||
continue;
|
||||
}
|
||||
if (g->delete_me) continue;
|
||||
if (((e->modifiers.mask & g->modifiers) ||
|
||||
(g->modifiers == e->modifiers.mask)) &&
|
||||
(!((e->modifiers.mask & g->not_modifiers) ||
|
||||
|
@ -537,11 +546,32 @@ evas_event_feed_key_down_data(Evas *e, const char *keyname, const void *data)
|
|||
{
|
||||
if (!e->events_frozen)
|
||||
evas_object_event_callback_call(g->object, EVAS_CALLBACK_KEY_DOWN, &ev);
|
||||
if (g->exclusive) return;
|
||||
if (g->exclusive) exclusive = 1;
|
||||
}
|
||||
}
|
||||
e->walking_grabs--;
|
||||
if (e->walking_grabs <= 0)
|
||||
{
|
||||
while (e->delete_grabs > 0)
|
||||
{
|
||||
Evas_List *l;
|
||||
|
||||
e->delete_grabs--;
|
||||
for (l = e->grabs; l; l= l->next)
|
||||
{
|
||||
Evas_Key_Grab *g;
|
||||
|
||||
g = l->data;
|
||||
if (g->delete_me)
|
||||
{
|
||||
evas_key_grab_free(g->object, g->keyname, g->modifiers, g->not_modifiers);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e->focused)
|
||||
if ((e->focused) && (!exclusive))
|
||||
{
|
||||
if (!e->events_frozen)
|
||||
evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_DOWN, &ev);
|
||||
|
@ -565,7 +595,9 @@ evas_event_feed_key_up_data(Evas *e, const char *keyname, const void *data)
|
|||
if (e->events_frozen > 0) return;
|
||||
{
|
||||
Evas_Event_Key_Up ev;
|
||||
int exclusive;
|
||||
|
||||
exclusive = 0;
|
||||
ev.keyname = (char *)keyname;
|
||||
ev.data = (void *)data;
|
||||
ev.modifiers = &(e->modifiers);
|
||||
|
@ -574,11 +606,18 @@ evas_event_feed_key_up_data(Evas *e, const char *keyname, const void *data)
|
|||
{
|
||||
Evas_List *l;
|
||||
|
||||
e->walking_grabs++;
|
||||
for (l = e->grabs; l; l= l->next)
|
||||
{
|
||||
Evas_Key_Grab *g;
|
||||
|
||||
g = l->data;
|
||||
if (g->just_added)
|
||||
{
|
||||
g->just_added = 0;
|
||||
continue;
|
||||
}
|
||||
if (g->delete_me) continue;
|
||||
if (((e->modifiers.mask & g->modifiers) ||
|
||||
(g->modifiers == e->modifiers.mask)) &&
|
||||
(!((e->modifiers.mask & g->not_modifiers) ||
|
||||
|
@ -587,11 +626,32 @@ evas_event_feed_key_up_data(Evas *e, const char *keyname, const void *data)
|
|||
{
|
||||
if (!e->events_frozen)
|
||||
evas_object_event_callback_call(g->object, EVAS_CALLBACK_KEY_UP, &ev);
|
||||
if (g->exclusive) return;
|
||||
if (g->exclusive) exclusive = 1;
|
||||
}
|
||||
}
|
||||
e->walking_grabs--;
|
||||
if (e->walking_grabs <= 0)
|
||||
{
|
||||
while (e->delete_grabs > 0)
|
||||
{
|
||||
Evas_List *l;
|
||||
|
||||
e->delete_grabs--;
|
||||
for (l = e->grabs; l; l= l->next)
|
||||
{
|
||||
Evas_Key_Grab *g;
|
||||
|
||||
g = l->data;
|
||||
if (g->delete_me)
|
||||
{
|
||||
evas_key_grab_free(g->object, g->keyname, g->modifiers, g->not_modifiers);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e->focused)
|
||||
if ((e->focused) && (!exclusive))
|
||||
{
|
||||
if (!e->events_frozen)
|
||||
evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_UP, &ev);
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
/* modifiers/not_modifers they use */
|
||||
|
||||
static Evas_Key_Grab *evas_key_grab_new (Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, int exclusive);
|
||||
static void evas_key_grab_free (Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers);
|
||||
static Evas_Key_Grab *evas_key_grab_find (Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, int exclusive);
|
||||
|
||||
static Evas_Key_Grab *
|
||||
|
@ -25,6 +24,8 @@ evas_key_grab_new(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modi
|
|||
g->not_modifiers = not_modifiers;
|
||||
g->exclusive = exclusive;
|
||||
g->keyname = strdup(keyname);
|
||||
if (obj->layer->evas->walking_grabs)
|
||||
g->just_added = 1;
|
||||
if (!g->keyname)
|
||||
{
|
||||
if (!evas_mem_free(strlen(keyname) + 1))
|
||||
|
@ -71,19 +72,6 @@ evas_key_grab_new(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modi
|
|||
return g;
|
||||
}
|
||||
|
||||
static void
|
||||
evas_key_grab_free(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers)
|
||||
{
|
||||
/* MEM OK */
|
||||
Evas_Key_Grab *g;
|
||||
|
||||
g = evas_key_grab_find(obj, keyname, modifiers, not_modifiers, 0);
|
||||
if (!g) return;
|
||||
g->object->grabs = evas_list_remove(g->object->grabs, g);
|
||||
if (g->keyname) free(g->keyname);
|
||||
free(g);
|
||||
}
|
||||
|
||||
static Evas_Key_Grab *
|
||||
evas_key_grab_find(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, int exclusive)
|
||||
{
|
||||
|
@ -122,6 +110,19 @@ evas_object_grabs_cleanup(Evas_Object *obj)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
evas_key_grab_free(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers)
|
||||
{
|
||||
/* MEM OK */
|
||||
Evas_Key_Grab *g;
|
||||
|
||||
g = evas_key_grab_find(obj, keyname, modifiers, not_modifiers, 0);
|
||||
if (!g) return;
|
||||
g->object->grabs = evas_list_remove(g->object->grabs, g);
|
||||
if (g->keyname) free(g->keyname);
|
||||
free(g);
|
||||
}
|
||||
|
||||
/* public calls */
|
||||
|
||||
/**
|
||||
|
@ -168,5 +169,14 @@ evas_object_key_ungrab(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask
|
|||
if (!keyname) return;
|
||||
g = evas_key_grab_find(obj, keyname, modifiers, not_modifiers, 0);
|
||||
if (!g) return;
|
||||
evas_key_grab_free(g->object, keyname, modifiers, not_modifiers);
|
||||
if (g->object->layer->evas->walking_grabs)
|
||||
{
|
||||
if (!g->delete_me)
|
||||
{
|
||||
g->object->layer->evas->delete_grabs++;
|
||||
g->delete_me = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
evas_key_grab_free(g->object, keyname, modifiers, not_modifiers);
|
||||
}
|
||||
|
|
|
@ -160,6 +160,8 @@ struct _Evas_Key_Grab
|
|||
Evas_Modifier_Mask not_modifiers;
|
||||
Evas_Object *object;
|
||||
char exclusive : 1;
|
||||
char just_added : 1;
|
||||
char delete_me : 1;
|
||||
};
|
||||
|
||||
struct _Evas_Intercept_Func
|
||||
|
@ -297,6 +299,8 @@ struct _Evas
|
|||
int info_magic;
|
||||
} engine;
|
||||
|
||||
int delete_grabs;
|
||||
int walking_grabs;
|
||||
Evas_List *grabs;
|
||||
|
||||
Evas_List *font_path;
|
||||
|
@ -584,6 +588,7 @@ int evas_object_intercept_call_stack_above(Evas_Object *obj, Evas_Object *above)
|
|||
int evas_object_intercept_call_stack_below(Evas_Object *obj, Evas_Object *below);
|
||||
int evas_object_intercept_call_layer_set(Evas_Object *obj, int l);
|
||||
void evas_object_grabs_cleanup(Evas_Object *obj);
|
||||
void evas_key_grab_free(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers);
|
||||
|
||||
extern int _evas_alloc_error;
|
||||
|
||||
|
|
Loading…
Reference in New Issue