elementary widget: fix a wrong disabled behavior. 09/82309/3
authorHermet Park <hermet@hermet.pe.kr>
Thu, 4 Aug 2016 07:56:11 +0000 (16:56 +0900)
committerHermet Park <hermet@hermet.pe.kr>
Thu, 4 Aug 2016 07:56:11 +0000 (16:56 +0900)
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

http://git.enlightenment.org/core/efl.git/commit/?id=ea2b5e40485a49b5c5aadae98ed379f1c3cf5f71

Change-Id: Ibaf3d58e0059857e3bf5dede127ce5484fd0eacc

src/lib/elm_widget.c

index 0444e78..3a3a15f 100644 (file)
@@ -97,6 +97,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 Eina_Bool
 _on_sub_obj_del(void *data,
                 Eo *obj,
@@ -996,8 +998,8 @@ 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));
+   if (elm_widget_disabled_get(obj))
+     elm_widget_disabled_internal(obj, elm_widget_disabled_get(obj));
 
    return ELM_THEME_APPLY_SUCCESS;
 }
@@ -3131,12 +3133,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)
      {
@@ -3154,6 +3154,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)
 {