elm_gen****: do not call realize on items

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!
This commit is contained in:
Marcel Hollerbach 2018-01-24 23:41:20 +01:00
parent 7255954ccc
commit d447967b76
4 changed files with 77 additions and 10 deletions

View File

@ -5753,8 +5753,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))

View File

@ -8777,20 +8777,18 @@ _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);
}
}
EOLIAN static void
EOLIAN static void
_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))

View 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"

View 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;
}
}