elementary widget: fix a wrong disabled behavior.

This is a corner case bug I spontaneously found.

* Scenario.

A. Disable A widget.
B. Add a child B widget to A.
C. Now B Widget theme will be followed to A that is performed by
   elm_widget_theme_apply()
D. This elm_widget_theme_apply() calls elm_widget_disabled_set() (originally.)
E. Now B widget will be logically disabled.
D. Let's enable A widget again.
E. After going through widget disabled sequence, elm_widget_disabled_eval()
   will be called in the last
F. In this function, A widget tries to enable its children. But B widget won't
    be enabled because its logically disabled!

Acutally, nowhere widget change children's disabled states logically,
but it propagates its state to children within volatile way so that
A widget perfectly keeps the disabled/enabled state with its children and
recover the children's enable/disable state once their relationship is cut off.

@fix
This commit is contained in:
Hermet Park 2016-08-02 22:38:30 +09:00
parent 7a70d41541
commit ea2b5e4048
1 changed files with 14 additions and 6 deletions

View File

@ -99,6 +99,8 @@ _elm_scrollable_is(const Evas_Object *obj)
eo_isa(obj, ELM_INTERFACE_SCROLLABLE_MIXIN);
}
static void
elm_widget_disabled_internal(Eo *obj, Eina_Bool disabled);
static void
_on_sub_obj_del(void *data, const Eo_Event *event);
static void
@ -1020,8 +1022,7 @@ EOLIAN static Elm_Theme_Apply
_elm_widget_theme_apply(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
{
_elm_widget_mirrored_reload(obj);
elm_widget_disabled_set(obj, elm_widget_disabled_get(obj));
elm_widget_disabled_internal(obj, elm_widget_disabled_get(obj));
return ELM_THEME_APPLY_SUCCESS;
}
@ -3122,12 +3123,10 @@ _elm_widget_disabled_eval(const Evas_Object *obj, Eina_Bool disabled)
}
}
EOLIAN static void
_elm_widget_disabled_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool disabled)
static void
elm_widget_disabled_internal(Eo *obj, Eina_Bool disabled)
{
Eina_Bool parent_state = EINA_FALSE;
if (sd->disabled == disabled) return;
sd->disabled = !!disabled;
if (disabled)
{
@ -3145,6 +3144,15 @@ _elm_widget_disabled_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool disabled)
}
}
EOLIAN static void
_elm_widget_disabled_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool disabled)
{
if (sd->disabled == disabled) return;
sd->disabled = !!disabled;
elm_widget_disabled_internal(obj, disabled);
}
EOLIAN static Eina_Bool
_elm_widget_disabled_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
{