elm: Fix extra mouse,in events in layout_content_unset

Problem: crash in assert() in terminology.

Scenario:
 Open Terminology,
 Split V by keyboard,
 Move mouse to split 2,
 Create tab by keyboard
 --> abort() in terminology

Cause:
 An extra mouse,in event happens during edje_object_unswallow
 inside elm_layout_content_unset.

Root cause:
 efl_part() in elm_layout had a side effect: edje_recalc on the
 edje object. Causing its geometry to be "properly" defined and
 the mouse event to trigger callbacks.

Solution:
 Avoid calling recalc... somehow.

Conclusion:
 Without adding any new API, edje edit provides internally the
 information that we want: type of an edje part (for box & table).

Fixes T4221
See T4028
See T3509
This commit is contained in:
Jean-Philippe Andre 2016-07-27 16:31:52 +09:00
parent bd91ebbbd7
commit ccac110d71
4 changed files with 49 additions and 46 deletions

View File

@ -12,7 +12,6 @@ class Efl.Ui.Layout_Internal.Box (Eo.Base, Efl.Pack.Linear,
set {} set {}
values { values {
layout: Eo.Base; layout: Eo.Base;
pack: Eo.Base;
part: string; part: string;
} }
} }

View File

@ -11,7 +11,6 @@ class Efl.Ui.Layout_Internal.Table (Eo.Base, Efl.Pack.Grid)
set {} set {}
values { values {
layout: Eo.Base; layout: Eo.Base;
pack: Eo.Base;
part: string; part: string;
} }
} }

View File

@ -13,12 +13,15 @@
#include "elm_layout_internal_part.eo.h" #include "elm_layout_internal_part.eo.h"
#include "elm_part_helper.h" #include "elm_part_helper.h"
#define EDJE_EDIT_IS_UNSTABLE_AND_I_KNOW_ABOUT_IT
#include <Edje_Edit.h>
#define MY_CLASS ELM_LAYOUT_CLASS #define MY_CLASS ELM_LAYOUT_CLASS
#define MY_CLASS_NAME "Elm_Layout" #define MY_CLASS_NAME "Elm_Layout"
#define MY_CLASS_NAME_LEGACY "elm_layout" #define MY_CLASS_NAME_LEGACY "elm_layout"
Eo *_elm_layout_pack_proxy_get(Elm_Layout *obj, Evas_Object *pack, const char *part); Eo *_elm_layout_pack_proxy_get(Elm_Layout *obj, Edje_Part_Type type, const char *part);
static const char SIG_THEME_CHANGED[] = "theme,changed"; static const char SIG_THEME_CHANGED[] = "theme,changed";
const char SIG_LAYOUT_FOCUSED[] = "focused"; const char SIG_LAYOUT_FOCUSED[] = "focused";
@ -2020,7 +2023,7 @@ static EOLIAN Eo_Base *
_elm_layout_efl_part_part(const Eo *obj, Elm_Layout_Smart_Data *sd, _elm_layout_efl_part_part(const Eo *obj, Elm_Layout_Smart_Data *sd,
const char *part) const char *part)
{ {
const Evas_Object *subobj; Edje_Part_Type type;
Elm_Part_Data *pd; Elm_Part_Data *pd;
Eo *proxy; Eo *proxy;
@ -2029,14 +2032,11 @@ _elm_layout_efl_part_part(const Eo *obj, Elm_Layout_Smart_Data *sd,
ELM_WIDGET_DATA_GET_OR_RETURN((Eo *) obj, wd, NULL); ELM_WIDGET_DATA_GET_OR_RETURN((Eo *) obj, wd, NULL);
// Ask edje for existing parts // Check part type with edje_edit, as edje_object_part_object_get()
subobj = edje_object_part_object_get(wd->resize_obj, part); // has side effects (it calls recalc, which may be really bad).
if (subobj) type = edje_edit_part_type_get(wd->resize_obj, part);
{ if ((type == EDJE_PART_TYPE_BOX) || (type == EDJE_PART_TYPE_TABLE))
// Support BOX & TABLE return _elm_layout_pack_proxy_get((Eo *) obj, type, part);
proxy = _elm_layout_pack_proxy_get((Eo *) obj, (Eo *) subobj, part);
if (proxy) return proxy;
}
// Generic parts (text, anything, ...) // Generic parts (text, anything, ...)
proxy = eo_add(ELM_LAYOUT_INTERNAL_PART_CLASS, (Eo *) obj); proxy = eo_add(ELM_LAYOUT_INTERNAL_PART_CLASS, (Eo *) obj);

View File

@ -40,7 +40,6 @@ struct _Layout_Part_Data
Elm_Layout *obj; // no ref Elm_Layout *obj; // no ref
Elm_Layout_Smart_Data *sd; // data xref Elm_Layout_Smart_Data *sd; // data xref
Eina_Stringshare *part; Eina_Stringshare *part;
Evas_Object *pack;
unsigned char temp; unsigned char temp;
}; };
@ -53,20 +52,16 @@ struct _Part_Item_Iterator
}; };
Eo * Eo *
_elm_layout_pack_proxy_get(Elm_Layout *obj, Evas_Object *pack, const char *part) _elm_layout_pack_proxy_get(Elm_Layout *obj, Edje_Part_Type type, const char *part)
{ {
Efl_Ui_Layout_Internal_Box *eo; if (type == EDJE_PART_TYPE_BOX)
return eo_add(BOX_CLASS, obj,
if (eo_isa(pack, EVAS_BOX_CLASS)) efl_ui_layout_internal_box_real_part_set(eo_self, obj, part));
eo = eo_add(BOX_CLASS, obj, else if (type == EDJE_PART_TYPE_TABLE)
efl_ui_layout_internal_box_real_part_set(eo_self, obj, pack, part)); return eo_add(TABLE_CLASS, obj,
else if (eo_isa(pack, EVAS_TABLE_CLASS)) efl_ui_layout_internal_table_real_part_set(eo_self, obj, part));
eo = eo_add(TABLE_CLASS, obj,
efl_ui_layout_internal_table_real_part_set(eo_self, obj, pack, part));
else else
return NULL; return NULL;
return eo;
} }
EOLIAN static void EOLIAN static void
@ -79,12 +74,11 @@ _efl_ui_layout_internal_box_eo_base_destructor(Eo *obj, Efl_Ui_Layout_Table_Data
} }
EOLIAN static void EOLIAN static void
_efl_ui_layout_internal_box_real_part_set(Eo *obj, Efl_Ui_Layout_Box_Data *pd, Eo *layout, Eo *pack, const char *part) _efl_ui_layout_internal_box_real_part_set(Eo *obj, Efl_Ui_Layout_Box_Data *pd, Eo *layout, const char *part)
{ {
pd->obj = layout; pd->obj = layout;
pd->sd = eo_data_xref(pd->obj, ELM_LAYOUT_CLASS, obj); pd->sd = eo_data_xref(pd->obj, ELM_LAYOUT_CLASS, obj);
eina_stringshare_replace(&pd->part, part); eina_stringshare_replace(&pd->part, part);
pd->pack = pack;
pd->temp = 1; pd->temp = 1;
} }
@ -142,15 +136,16 @@ EOLIAN static Eina_Iterator *
_efl_ui_layout_internal_box_efl_container_content_iterate(Eo *obj, Efl_Ui_Layout_Box_Data *pd) _efl_ui_layout_internal_box_efl_container_content_iterate(Eo *obj, Efl_Ui_Layout_Box_Data *pd)
{ {
Eina_Iterator *it; Eina_Iterator *it;
Eo *pack = (Eo *) edje_object_part_object_get(pd->obj, pd->part);
it = evas_object_box_iterator_new(pd->pack); it = evas_object_box_iterator_new(pack);
ELM_PART_RETURN_VAL(_part_item_iterator_create(obj, it, NULL)); ELM_PART_RETURN_VAL(_part_item_iterator_create(obj, it, NULL));
} }
EOLIAN static int EOLIAN static int
_efl_ui_layout_internal_box_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd) _efl_ui_layout_internal_box_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd)
{ {
ELM_PART_RETURN_VAL(evas_obj_box_count(pd->pack)); Eo *pack = (Eo *) edje_object_part_object_get(pd->obj, pd->part);
ELM_PART_RETURN_VAL(evas_obj_box_count(pack));
} }
EOLIAN static Eina_Bool EOLIAN static Eina_Bool
@ -207,11 +202,11 @@ _efl_ui_layout_internal_box_efl_pack_linear_pack_after(Eo *obj EINA_UNUSED, Efl_
{ {
const Efl_Gfx *other; const Efl_Gfx *other;
int index; int index;
Eo *pack = (Eo *) edje_object_part_object_get(pd->obj, pd->part);
index = efl_pack_index_get(pd->pack, existing); index = efl_pack_index_get(pack, existing);
if (index < 0) ELM_PART_RETURN_VAL(EINA_FALSE); if (index < 0) ELM_PART_RETURN_VAL(EINA_FALSE);
other = efl_pack_content_get(pd->pack, index + 1); other = efl_pack_content_get(pack, index + 1);
if (other) if (other)
ELM_PART_RETURN_VAL(_elm_layout_box_insert_before(pd->obj, pd->sd, pd->part, subobj, other)); ELM_PART_RETURN_VAL(_elm_layout_box_insert_before(pd->obj, pd->sd, pd->part, subobj, other));
@ -230,8 +225,9 @@ _efl_ui_layout_internal_box_efl_pack_linear_pack_content_get(Eo *obj EINA_UNUSED
{ {
Evas_Object_Box_Option *opt; Evas_Object_Box_Option *opt;
Evas_Object_Box_Data *priv; Evas_Object_Box_Data *priv;
Eo *pack = (Eo *) edje_object_part_object_get(pd->obj, pd->part);
priv = eo_data_scope_get(pd->pack, EVAS_BOX_CLASS); priv = eo_data_scope_get(pack, EVAS_BOX_CLASS);
opt = eina_list_nth(priv->children, index); opt = eina_list_nth(priv->children, index);
if (!opt) ELM_PART_RETURN_VAL(NULL); if (!opt) ELM_PART_RETURN_VAL(NULL);
ELM_PART_RETURN_VAL(opt->obj); ELM_PART_RETURN_VAL(opt->obj);
@ -241,8 +237,9 @@ EOLIAN static Efl_Gfx *
_efl_ui_layout_internal_box_efl_pack_linear_pack_unpack_at(Eo *obj, Efl_Ui_Layout_Box_Data *pd, int index) _efl_ui_layout_internal_box_efl_pack_linear_pack_unpack_at(Eo *obj, Efl_Ui_Layout_Box_Data *pd, int index)
{ {
Efl_Gfx *subobj; Efl_Gfx *subobj;
Eo *pack = (Eo *) edje_object_part_object_get(pd->obj, pd->part);
subobj = efl_pack_content_get(pd->pack, index); subobj = efl_pack_content_get(pack, index);
if (!subobj) ELM_PART_RETURN_VAL(NULL); if (!subobj) ELM_PART_RETURN_VAL(NULL);
if (efl_pack_unpack(obj, subobj)) if (efl_pack_unpack(obj, subobj))
ELM_PART_RETURN_VAL(subobj); ELM_PART_RETURN_VAL(subobj);
@ -254,7 +251,8 @@ _efl_ui_layout_internal_box_efl_pack_linear_pack_unpack_at(Eo *obj, Efl_Ui_Layou
EOLIAN static int EOLIAN static int
_efl_ui_layout_internal_box_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd, const Efl_Gfx *subobj) _efl_ui_layout_internal_box_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd, const Efl_Gfx *subobj)
{ {
ELM_PART_RETURN_VAL(efl_pack_index_get(pd->pack, subobj)); Eo *pack = (Eo *) edje_object_part_object_get(pd->obj, pd->part);
ELM_PART_RETURN_VAL(efl_pack_index_get(pack, subobj));
} }
EOLIAN static Efl_Orient EOLIAN static Efl_Orient
@ -269,12 +267,11 @@ _efl_ui_layout_internal_box_efl_orientation_orientation_get(Eo *obj EINA_UNUSED,
/* Table proxy implementation */ /* Table proxy implementation */
EOLIAN static void EOLIAN static void
_efl_ui_layout_internal_table_real_part_set(Eo *obj, Efl_Ui_Layout_Table_Data *pd, Eo *layout, Eo *pack, const char *part) _efl_ui_layout_internal_table_real_part_set(Eo *obj, Efl_Ui_Layout_Table_Data *pd, Eo *layout, const char *part)
{ {
pd->obj = layout; pd->obj = layout;
pd->sd = eo_data_xref(pd->obj, ELM_LAYOUT_CLASS, obj); pd->sd = eo_data_xref(pd->obj, ELM_LAYOUT_CLASS, obj);
eina_stringshare_replace(&pd->part, part); eina_stringshare_replace(&pd->part, part);
pd->pack = pack;
pd->temp = 1; pd->temp = 1;
} }
@ -291,8 +288,9 @@ EOLIAN static Eina_Iterator *
_efl_ui_layout_internal_table_efl_container_content_iterate(Eo *obj, Efl_Ui_Layout_Table_Data *pd) _efl_ui_layout_internal_table_efl_container_content_iterate(Eo *obj, Efl_Ui_Layout_Table_Data *pd)
{ {
Eina_Iterator *it; Eina_Iterator *it;
Eo *pack = (Eo *) edje_object_part_object_get(pd->obj, pd->part);
it = evas_object_table_iterator_new(pd->pack); it = evas_object_table_iterator_new(pack);
ELM_PART_RETURN_VAL(_part_item_iterator_create(obj, it, NULL)); ELM_PART_RETURN_VAL(_part_item_iterator_create(obj, it, NULL));
} }
@ -300,7 +298,8 @@ _efl_ui_layout_internal_table_efl_container_content_iterate(Eo *obj, Efl_Ui_Layo
EOLIAN static int EOLIAN static int
_efl_ui_layout_internal_table_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd) _efl_ui_layout_internal_table_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd)
{ {
ELM_PART_RETURN_VAL(evas_obj_table_count(pd->pack)); Eo *pack = (Eo *) edje_object_part_object_get(pd->obj, pd->part);
ELM_PART_RETURN_VAL(evas_obj_table_count(pack));
} }
EOLIAN static Eina_Bool EOLIAN static Eina_Bool
@ -338,7 +337,8 @@ _efl_ui_layout_internal_table_efl_pack_grid_pack_grid(Eo *obj EINA_UNUSED, Efl_U
EOLIAN static Efl_Gfx * EOLIAN static Efl_Gfx *
_efl_ui_layout_internal_table_efl_pack_grid_grid_content_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd, int col, int row) _efl_ui_layout_internal_table_efl_pack_grid_grid_content_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd, int col, int row)
{ {
ELM_PART_RETURN_VAL(evas_object_table_child_get(pd->pack, col, row)); Eo *pack = (Eo *) edje_object_part_object_get(pd->obj, pd->part);
ELM_PART_RETURN_VAL(evas_object_table_child_get(pack, col, row));
} }
EOLIAN static Eina_Iterator * EOLIAN static Eina_Iterator *
@ -350,11 +350,12 @@ _efl_ui_layout_internal_table_efl_pack_grid_grid_contents_get(Eo *obj EINA_UNUSE
Eina_List *list, *l = NULL; Eina_List *list, *l = NULL;
Evas_Object *sobj; Evas_Object *sobj;
unsigned short c, r, cs, rs; unsigned short c, r, cs, rs;
Eo *pack = (Eo *) edje_object_part_object_get(pd->obj, pd->part);
list = evas_object_table_children_get(pd->pack); list = evas_object_table_children_get(pack);
EINA_LIST_FREE(list, sobj) EINA_LIST_FREE(list, sobj)
{ {
evas_object_table_pack_get(pd->pack, sobj, &c, &r, &cs, &rs); evas_object_table_pack_get(pack, sobj, &c, &r, &cs, &rs);
if (((int) c == col) && ((int) r == row)) if (((int) c == col) && ((int) r == row))
list = eina_list_append(list, sobj); list = eina_list_append(list, sobj);
@ -374,8 +375,9 @@ _efl_ui_layout_internal_table_efl_pack_grid_grid_position_get(Eo *obj EINA_UNUSE
{ {
unsigned short c, r, cs, rs; unsigned short c, r, cs, rs;
Eina_Bool ret; Eina_Bool ret;
Eo *pack = (Eo *) edje_object_part_object_get(pd->obj, pd->part);
ret = evas_object_table_pack_get(pd->pack, subobj, &c, &r, &cs, &rs); ret = evas_object_table_pack_get(pack, subobj, &c, &r, &cs, &rs);
if (col) *col = c; if (col) *col = c;
if (row) *row = r; if (row) *row = r;
if (colspan) *colspan = cs; if (colspan) *colspan = cs;
@ -387,14 +389,16 @@ _efl_ui_layout_internal_table_efl_pack_grid_grid_position_get(Eo *obj EINA_UNUSE
EOLIAN static void EOLIAN static void
_efl_ui_layout_internal_table_efl_pack_grid_grid_size_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd, int *cols, int *rows) _efl_ui_layout_internal_table_efl_pack_grid_grid_size_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd, int *cols, int *rows)
{ {
evas_object_table_col_row_size_get(pd->pack, cols, rows); Eo *pack = (Eo *) edje_object_part_object_get(pd->obj, pd->part);
evas_object_table_col_row_size_get(pack, cols, rows);
} }
EOLIAN static int EOLIAN static int
_efl_ui_layout_internal_table_efl_pack_grid_grid_columns_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd) _efl_ui_layout_internal_table_efl_pack_grid_grid_columns_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd)
{ {
int cols, rows; int cols, rows;
evas_object_table_col_row_size_get(pd->pack, &cols, &rows); Eo *pack = (Eo *) edje_object_part_object_get(pd->obj, pd->part);
evas_object_table_col_row_size_get(pack, &cols, &rows);
ELM_PART_RETURN_VAL(cols); ELM_PART_RETURN_VAL(cols);
} }
@ -402,7 +406,8 @@ EOLIAN static int
_efl_ui_layout_internal_table_efl_pack_grid_grid_rows_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd) _efl_ui_layout_internal_table_efl_pack_grid_grid_rows_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd)
{ {
int cols, rows; int cols, rows;
evas_object_table_col_row_size_get(pd->pack, &cols, &rows); Eo *pack = (Eo *) edje_object_part_object_get(pd->obj, pd->part);
evas_object_table_col_row_size_get(pack, &cols, &rows);
ELM_PART_RETURN_VAL(rows); ELM_PART_RETURN_VAL(rows);
} }