From 78f4babbb5bc13eb4349cfaca419ef60736333a9 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Fri, 6 Apr 2018 12:48:41 +0200 Subject: [PATCH] efl_ui_focus_object: make the prepare call safe to recursive calls. There is no need to prepare a item again if it is already in prepare. --- src/lib/elementary/efl_ui_focus_composition.c | 4 ++-- src/lib/elementary/efl_ui_focus_composition.eo | 2 +- src/lib/elementary/efl_ui_focus_object.c | 14 ++++++++++++++ src/lib/elementary/efl_ui_focus_object.eo | 6 +++++- src/lib/elementary/elm_gengrid.c | 4 ++-- src/lib/elementary/elm_gengrid_item.eo | 2 +- src/lib/elementary/elm_genlist.c | 8 ++++---- src/lib/elementary/elm_genlist_item.eo | 2 +- src/lib/elementary/elm_widget_item_static_focus.c | 6 +++--- src/lib/elementary/elm_widget_item_static_focus.eo | 2 +- 10 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/lib/elementary/efl_ui_focus_composition.c b/src/lib/elementary/efl_ui_focus_composition.c index c1a76ef271..261dab2882 100644 --- a/src/lib/elementary/efl_ui_focus_composition.c +++ b/src/lib/elementary/efl_ui_focus_composition.c @@ -155,7 +155,7 @@ _efl_ui_focus_composition_dirty(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Composition_Da } EOLIAN static void -_efl_ui_focus_composition_efl_ui_focus_object_prepare_logical(Eo *obj, Efl_Ui_Focus_Composition_Data *pd EINA_UNUSED) +_efl_ui_focus_composition_efl_ui_focus_object_prepare_logical_none_recursive(Eo *obj, Efl_Ui_Focus_Composition_Data *pd EINA_UNUSED) { if (pd->dirty) { @@ -163,7 +163,7 @@ _efl_ui_focus_composition_efl_ui_focus_object_prepare_logical(Eo *obj, Efl_Ui_Fo pd->dirty = EINA_FALSE; } - efl_ui_focus_object_prepare_logical(efl_super(obj, MY_CLASS)); + efl_ui_focus_object_prepare_logical_none_recursive(efl_super(obj, MY_CLASS)); } EOLIAN static void diff --git a/src/lib/elementary/efl_ui_focus_composition.eo b/src/lib/elementary/efl_ui_focus_composition.eo index 11e632bca8..2538078d84 100644 --- a/src/lib/elementary/efl_ui_focus_composition.eo +++ b/src/lib/elementary/efl_ui_focus_composition.eo @@ -47,7 +47,7 @@ mixin Efl.Ui.Focus.Composition (Efl.Interface, Efl.Ui.Widget) { } implements { Efl.Ui.Widget.focus_state_apply; - Efl.Ui.Focus.Object.prepare_logical; + Efl.Ui.Focus.Object.prepare_logical_none_recursive; @empty .prepare; } } diff --git a/src/lib/elementary/efl_ui_focus_object.c b/src/lib/elementary/efl_ui_focus_object.c index df565b4300..71764c4eae 100644 --- a/src/lib/elementary/efl_ui_focus_object.c +++ b/src/lib/elementary/efl_ui_focus_object.c @@ -9,6 +9,7 @@ typedef struct { Eina_Bool old_focus; + Eina_Bool ongoing_prepare_call; } Efl_Ui_Focus_Object_Data; EOLIAN static void @@ -26,5 +27,18 @@ _efl_ui_focus_object_focus_get(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Object_Data *pd return pd->old_focus; } +EOLIAN static void +_efl_ui_focus_object_prepare_logical(Eo *obj, Efl_Ui_Focus_Object_Data *pd) +{ + if (pd->ongoing_prepare_call) return; + + pd->ongoing_prepare_call = EINA_TRUE; + + efl_ui_focus_object_prepare_logical_none_recursive(obj); + + pd->ongoing_prepare_call = EINA_FALSE; +} + + #include "efl_ui_focus_object.eo.c" diff --git a/src/lib/elementary/efl_ui_focus_object.eo b/src/lib/elementary/efl_ui_focus_object.eo index a8ce1130b8..901de5d44b 100644 --- a/src/lib/elementary/efl_ui_focus_object.eo +++ b/src/lib/elementary/efl_ui_focus_object.eo @@ -56,10 +56,14 @@ mixin Efl.Ui.Focus.Object } prepare_logical { [[Tells the object that its children will be queried soon by the given manager. + The call will be a NOP if there is already a active preprare_logical call on this object Deleting manager items in this call will result in undefied behaviour and may cause your system to crash. ]] } + prepare_logical_none_recursive @protected { + [[]] + } on_focus_update @protected @pure_virtual { [[Virtual function handling focus in/out events on the widget]] return: bool; [[$true if this widget can handle focus, $false otherwise]] @@ -67,7 +71,7 @@ mixin Efl.Ui.Focus.Object } implements { @empty .focus_geometry; - @empty .prepare_logical; + @empty .prepare_logical_none_recursive; @empty .focus_manager; @empty .focus_parent; } diff --git a/src/lib/elementary/elm_gengrid.c b/src/lib/elementary/elm_gengrid.c index 2659ff0b22..be5879cae7 100644 --- a/src/lib/elementary/elm_gengrid.c +++ b/src/lib/elementary/elm_gengrid.c @@ -5742,7 +5742,7 @@ _elm_gengrid_efl_ui_widget_focus_state_apply(Eo *obj, Elm_Gengrid_Data *pd EINA_ } EOLIAN static void -_elm_gengrid_item_efl_ui_focus_object_prepare_logical(Eo *obj, Elm_Gen_Item *pd) +_elm_gengrid_item_efl_ui_focus_object_prepare_logical_none_recursive(Eo *obj, Elm_Gen_Item *pd) { Eina_List *n; Efl_Ui_Widget *wid; @@ -5753,7 +5753,7 @@ _elm_gengrid_item_efl_ui_focus_object_prepare_logical(Eo *obj, Elm_Gen_Item *pd) _elm_widget_full_eval(wid); } - efl_ui_focus_object_prepare_logical(efl_super(obj, ELM_GENGRID_ITEM_CLASS)); + efl_ui_focus_object_prepare_logical_none_recursive(efl_super(obj, ELM_GENGRID_ITEM_CLASS)); } /* Standard widget overrides */ diff --git a/src/lib/elementary/elm_gengrid_item.eo b/src/lib/elementary/elm_gengrid_item.eo index e761d9deb9..4f2b0370a8 100644 --- a/src/lib/elementary/elm_gengrid_item.eo +++ b/src/lib/elementary/elm_gengrid_item.eo @@ -255,6 +255,6 @@ class Elm.Gengrid.Item(Elm.Widget.Item.Static_Focus, Efl.Ui.Focus.Object, Efl.Ui Elm.Widget.Item.cursor_unset; Efl.Access.i18n_name { get; } Efl.Access.state_set { get; } - Efl.Ui.Focus.Object.prepare_logical; + Efl.Ui.Focus.Object.prepare_logical_none_recursive; } } diff --git a/src/lib/elementary/elm_genlist.c b/src/lib/elementary/elm_genlist.c index ff361b8cb1..82025ebe0a 100644 --- a/src/lib/elementary/elm_genlist.c +++ b/src/lib/elementary/elm_genlist.c @@ -8988,7 +8988,7 @@ _elm_genlist_efl_object_provider_find(const Eo *obj, Elm_Genlist_Data *pd, const return efl_provider_find(efl_super(obj, ELM_GENLIST_CLASS), klass); } -EOLIAN static void +EOLIAN static void _elm_genlist_efl_ui_focus_composition_prepare(Eo *obj, Elm_Genlist_Data *pd) { Elm_Gen_Item *item; @@ -9015,7 +9015,7 @@ _elm_genlist_efl_ui_focus_composition_prepare(Eo *obj, Elm_Genlist_Data *pd) } EOLIAN static void -_elm_genlist_item_efl_ui_focus_object_prepare_logical(Eo *obj, Elm_Gen_Item *pd) +_elm_genlist_item_efl_ui_focus_object_prepare_logical_none_recursive(Eo *obj, Elm_Gen_Item *pd) { Eina_List *n; Efl_Ui_Widget *wid; @@ -9026,10 +9026,10 @@ _elm_genlist_item_efl_ui_focus_object_prepare_logical(Eo *obj, Elm_Gen_Item *pd) _elm_widget_full_eval(wid); } - efl_ui_focus_object_prepare_logical(efl_super(obj, ELM_GENLIST_ITEM_CLASS)); + efl_ui_focus_object_prepare_logical_none_recursive(efl_super(obj, ELM_GENLIST_ITEM_CLASS)); } -EOLIAN static Eina_Bool +EOLIAN static Eina_Bool _elm_genlist_efl_ui_widget_focus_state_apply(Eo *obj, Elm_Genlist_Data *pd EINA_UNUSED, Efl_Ui_Widget_Focus_State current_state, Efl_Ui_Widget_Focus_State *configured_state, Efl_Ui_Widget *redirect EINA_UNUSED) { return efl_ui_widget_focus_state_apply(efl_super(obj, MY_CLASS), current_state, configured_state, obj); diff --git a/src/lib/elementary/elm_genlist_item.eo b/src/lib/elementary/elm_genlist_item.eo index fcc789ddbf..aba6d872bb 100644 --- a/src/lib/elementary/elm_genlist_item.eo +++ b/src/lib/elementary/elm_genlist_item.eo @@ -462,6 +462,6 @@ class Elm.Genlist.Item(Elm.Widget.Item.Static_Focus, Efl.Ui.Legacy) Elm.Widget.Item.cursor_unset; Efl.Access.i18n_name { get; } Efl.Access.state_set { get; } - Efl.Ui.Focus.Object.prepare_logical; + Efl.Ui.Focus.Object.prepare_logical_none_recursive; } } diff --git a/src/lib/elementary/elm_widget_item_static_focus.c b/src/lib/elementary/elm_widget_item_static_focus.c index 09a892326c..a1301ff793 100644 --- a/src/lib/elementary/elm_widget_item_static_focus.c +++ b/src/lib/elementary/elm_widget_item_static_focus.c @@ -46,12 +46,12 @@ _unrealized_cb(void *data, const Efl_Event *ev EINA_UNUSED) } EOLIAN static void -_elm_widget_item_static_focus_efl_ui_focus_object_prepare_logical(Eo *obj, Elm_Widget_Item_Static_Focus_Data *pd EINA_UNUSED) +_elm_widget_item_static_focus_efl_ui_focus_object_prepare_logical_none_recursive(Eo *obj, Elm_Widget_Item_Static_Focus_Data *pd EINA_UNUSED) { Eo *logical_child; Elm_Widget_Item_Data *wpd = efl_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS); - efl_ui_focus_object_prepare_logical(efl_super(obj, MY_CLASS)); + efl_ui_focus_object_prepare_logical_none_recursive(efl_super(obj, MY_CLASS)); if (!pd->realized) { @@ -102,7 +102,7 @@ _elm_widget_item_static_focus_efl_object_constructor(Eo *obj, Elm_Widget_Item_St return ret; } -EOLIAN static void +EOLIAN static void _elm_widget_item_static_focus_efl_object_destructor(Eo *obj, Elm_Widget_Item_Static_Focus_Data *pd EINA_UNUSED) { Elm_Widget_Item_Data *wpd = efl_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS); diff --git a/src/lib/elementary/elm_widget_item_static_focus.eo b/src/lib/elementary/elm_widget_item_static_focus.eo index 1ea4b9344e..51d0fd0e46 100644 --- a/src/lib/elementary/elm_widget_item_static_focus.eo +++ b/src/lib/elementary/elm_widget_item_static_focus.eo @@ -4,6 +4,6 @@ class Elm.Widget.Item.Static_Focus (Elm.Widget.Item, Efl.Ui.Focus.Object) implements { Efl.Object.constructor; Efl.Object.destructor; - Efl.Ui.Focus.Object.prepare_logical; + Efl.Ui.Focus.Object.prepare_logical_none_recursive; } }