make deleting of grabs within a key callback "safe"

SVN revision: 7117
This commit is contained in:
Carsten Haitzler 2003-07-08 06:08:26 +00:00
parent 0656623f54
commit 0c5a435128
3 changed files with 97 additions and 22 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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
@ -296,7 +298,9 @@ struct _Evas
void *info;
int info_magic;
} engine;
int delete_grabs;
int walking_grabs;
Evas_List *grabs;
Evas_List *font_path;
@ -584,7 +588,8 @@ 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;
#ifdef __cplusplus