elm_gen****: do not call realize on items
authorMarcel Hollerbach <marcel@osg.samsung.com>
Wed, 24 Jan 2018 22:41:20 +0000 (23:41 +0100)
committerWonki Kim <wonki_.kim@samsung.com>
Tue, 3 Apr 2018 09:50:14 +0000 (18:50 +0900)
better rely on the adapter and wait for realization so the adapter is
wether created or not even created but used with content. This fixes
item content focus, crashes at startup and a freeze in genlist test!

src/lib/elementary/elm_gengrid.c
src/lib/elementary/elm_genlist.c
src/lib/elementary/elm_widget_item_static_focus.c
src/lib/elementary/elm_widget_item_static_focus.eo

index f668ca4..f7e2bab 100644 (file)
@@ -6201,8 +6201,6 @@ _elm_gengrid_item_efl_ui_focus_object_prepare_logical(Eo *obj, Elm_Gen_Item *pd)
    Eina_List *n;
    Efl_Ui_Widget *wid;
 
-   _item_realize(pd);
-
    EINA_LIST_FOREACH(pd->contents, n, wid)
      {
         if (efl_isa(wid, EFL_UI_WIDGET_CLASS))
index a919948..6f7647f 100644 (file)
@@ -9046,7 +9046,7 @@ _elm_genlist_efl_ui_focus_composition_prepare(Eo *obj, Elm_Genlist_Data *pd)
      {
         if (item->base->disabled)
           continue;
-        
+
         efl_ui_focus_object_prepare_logical(item->base->eo_obj);
      }
 
@@ -9058,8 +9058,6 @@ _elm_genlist_item_efl_ui_focus_object_prepare_logical(Eo *obj, Elm_Gen_Item *pd)
    Eina_List *n;
    Efl_Ui_Widget *wid;
 
-   _item_realize(pd, pd->item->order_num_in, EINA_FALSE);
-
    EINA_LIST_FOREACH(pd->contents, n, wid)
      {
         if (efl_isa(wid, EFL_UI_WIDGET_CLASS))
index 21d2f99..2826c9a 100644 (file)
@@ -3,31 +3,63 @@
 #endif
 
 #define ELM_WIDGET_ITEM_PROTECTED
+#define MY_CLASS ELM_WIDGET_ITEM_STATIC_FOCUS_CLASS
 
 #include <Elementary.h>
+#include "elm_genlist.eo.h"
+#include "elm_gengrid.eo.h"
 #include "elm_priv.h"
 #include "efl_ui_focus_composition_adapter.eo.h"
 
 typedef struct {
    Eo *adapter;
+   Eina_Bool realized;
 } Elm_Widget_Item_Static_Focus_Data;
 
+static void
+_realized_cb(void *data, const Efl_Event *ev)
+{
+   Elm_Widget_Item_Static_Focus_Data *pd = efl_data_scope_get(data, MY_CLASS);
+
+   if (ev->info != data) return;
+
+   pd->realized = EINA_TRUE;
+   efl_ui_focus_object_prepare_logical(ev->object);
+}
+
+static void
+_unrealized_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+   Elm_Widget_Item_Static_Focus_Data *pd = efl_data_scope_get(data, MY_CLASS);
+
+   if (ev->info != data) return;
+
+   if (pd) /* if the obect is dead pd is NULL */
+     pd->realized = EINA_FALSE;
+}
+
 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)
 {
    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, ELM_WIDGET_ITEM_STATIC_FOCUS_CLASS));
+   efl_ui_focus_object_prepare_logical(efl_super(obj, MY_CLASS));
+
+   if (!pd->realized)
+     {
+        WRN("This item is not realized, thus things will fall over, better return NOW");
+        return;
+     }
+
    logical_child = efl_ui_focus_manager_request_subchild(wpd->widget, obj);
 
    if (!logical_child)
      {
         if (!pd->adapter)
           {
-             pd->adapter = efl_add(EFL_UI_FOCUS_COMPOSITION_ADAPTER_CLASS, wpd->view, 
-              efl_ui_focus_composition_adapter_canvas_object_set(efl_added,  wpd->view)
-             );
+             pd->adapter = efl_add(EFL_UI_FOCUS_COMPOSITION_ADAPTER_CLASS, wpd->view);
+             efl_ui_focus_composition_adapter_canvas_object_set(pd->adapter,  wpd->view);
              efl_wref_add(pd->adapter, &pd->adapter);
              efl_ui_focus_manager_calc_register(wpd->widget, pd->adapter, obj, NULL);
           }
@@ -40,4 +72,41 @@ _elm_widget_item_static_focus_efl_ui_focus_object_prepare_logical(Eo *obj, Elm_W
      }
 }
 
+EOLIAN static Efl_Object*
+_elm_widget_item_static_focus_efl_object_constructor(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);
+   Eo *ret = efl_constructor(efl_super(obj, MY_CLASS));
+
+   if (efl_isa(wpd->widget, ELM_GENLIST_CLASS))
+     {
+        efl_event_callback_add(wpd->widget, ELM_GENLIST_EVENT_REALIZED, _realized_cb, obj);
+        efl_event_callback_add(wpd->widget, ELM_GENLIST_EVENT_UNREALIZED, _unrealized_cb, obj);
+     }
+   else
+     {
+        efl_event_callback_add(wpd->widget, ELM_GENGRID_EVENT_REALIZED, _realized_cb, obj);
+        efl_event_callback_add(wpd->widget, ELM_GENGRID_EVENT_UNREALIZED, _unrealized_cb, obj);
+     }
+   return ret;
+}
+
+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);
+   if (efl_isa(wpd->widget, ELM_GENLIST_CLASS))
+     {
+        efl_event_callback_del(wpd->widget, ELM_GENLIST_EVENT_REALIZED, _realized_cb, obj);
+        efl_event_callback_del(wpd->widget, ELM_GENLIST_EVENT_UNREALIZED, _unrealized_cb, obj);
+     }
+   else
+     {
+        efl_event_callback_del(wpd->widget, ELM_GENGRID_EVENT_REALIZED, _realized_cb, obj);
+        efl_event_callback_del(wpd->widget, ELM_GENGRID_EVENT_UNREALIZED, _unrealized_cb, obj);
+     }
+   return efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+
 #include "elm_widget_item_static_focus.eo.c"
index 874466c..1ea4b93 100644 (file)
@@ -2,6 +2,8 @@ class Elm.Widget.Item.Static_Focus (Elm.Widget.Item, Efl.Ui.Focus.Object)
 {
    [[A class that ensures that at least ONE focusable target is behind this widget item. If there is none registered to it after a prepare call it will register the view of the item as item.]]
    implements {
+           Efl.Object.constructor;
+           Efl.Object.destructor;
            Efl.Ui.Focus.Object.prepare_logical;
    }
 }