reorder shelf startup slightly, add gadcon populate event, only show created shelf...
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Thu, 20 Sep 2012 08:44:30 +0000 (08:44 +0000)
committerMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Thu, 20 Sep 2012 08:44:30 +0000 (08:44 +0000)
this commit reduces my startup time by 0.5-1.0 seconds on average when using two shelves

SVN revision: 76894

src/bin/e_gadcon.c
src/bin/e_gadcon.h
src/bin/e_int_gadcon_config.c
src/bin/e_main.c
src/bin/e_shelf.c

index 65f3fb4..7e8c376 100644 (file)
@@ -5,7 +5,7 @@
  */
 
 #define E_LAYOUT_ITEM_DRAG_RESIST_LEVEL 10
-
+static void                     _e_gadcon_event_populate(E_Gadcon *gc);
 static Eina_Bool               _e_gadcon_client_populate(E_Gadcon *gc, const E_Gadcon_Client_Class *cc, E_Config_Gadcon_Client *cf_gcc);
 static void                     _e_gadcon_client_unpopulate(E_Gadcon_Client *gcc);
 static void                     _e_gadcon_free(E_Gadcon *gc);
@@ -81,6 +81,7 @@ static void                     e_gadcon_layout_unpack(Evas_Object *obj);
 static void                     _e_gadcon_provider_populate_request(E_Gadcon *gc, const E_Gadcon_Client_Class *cc);
 static void                     _e_gadcon_provider_populate_unrequest(const E_Gadcon_Client_Class *cc);
 static Eina_Bool                _e_gadcon_provider_populate_idler(void *data);
+static void                      _e_gadcon_event_populate_free(void *data __UNUSED__, void *event);
 static Eina_Bool                _e_gadcon_custom_populate_idler(void *data);
 
 static int                      _e_gadcon_location_change(E_Gadcon_Client *gcc, E_Gadcon_Location *src, E_Gadcon_Location *dst);
@@ -183,6 +184,7 @@ EAPI int E_EVENT_GADCON_CLIENT_CLASS_ADD = -1;
 EAPI int E_EVENT_GADCON_CLIENT_CLASS_DEL = -1;
 EAPI int E_EVENT_GADCON_CLIENT_ADD = -1;
 EAPI int E_EVENT_GADCON_CLIENT_DEL = -1;
+EAPI int E_EVENT_GADCON_POPULATE = -1;
 
 static Eina_Hash *providers = NULL;
 static Eina_List *providers_list = NULL;
@@ -222,6 +224,7 @@ e_gadcon_init(void)
    E_EVENT_GADCON_CLIENT_CLASS_DEL = ecore_event_type_new();
    E_EVENT_GADCON_CLIENT_ADD = ecore_event_type_new();
    E_EVENT_GADCON_CLIENT_DEL = ecore_event_type_new();
+   E_EVENT_GADCON_POPULATE = ecore_event_type_new();
    _module_init_end_handler = ecore_event_handler_add(E_EVENT_MODULE_INIT_END, _module_init_end_cb, NULL);
    return 1;
 }
@@ -244,8 +247,6 @@ e_gadcon_shutdown(void)
    if (_module_init_end_handler)
      ecore_event_handler_del(_module_init_end_handler);
    _module_init_end_handler = NULL;
-   E_EVENT_GADCON_CLIENT_ADD = E_EVENT_GADCON_CLIENT_DEL =
-     E_EVENT_GADCON_CLIENT_CLASS_ADD = E_EVENT_GADCON_CLIENT_CLASS_DEL = -1;
 
    return 1;
 }
@@ -582,6 +583,8 @@ e_gadcon_populate(E_Gadcon *gc)
           e_gadcon_client_queue(gc, cf_gcc);
      }
    e_gadcon_layout_thaw(gc->o_container);
+   if (gc->populated_classes && (!gc->populate_requests))
+     _e_gadcon_event_populate(gc);
    return EINA_TRUE;
 }
 
@@ -2009,6 +2012,17 @@ _e_gadcon_client_event_free(void *d __UNUSED__, void *e)
 }
 
 static void
+_e_gadcon_event_populate(E_Gadcon *gc)
+{
+   E_Event_Gadcon_Populate *ev;
+
+   ev = E_NEW(E_Event_Gadcon_Populate, 1);
+   e_object_ref(E_OBJECT(gc));
+   ev->gc = gc;
+   ecore_event_add(E_EVENT_GADCON_POPULATE, ev, _e_gadcon_event_populate_free, NULL);
+}
+
+static void
 _e_gadcon_client_delfn(void *d __UNUSED__, void *o)
 {
    E_Gadcon_Client *gcc = o;
@@ -5455,6 +5469,15 @@ _e_gadcon_layout_smart_restore_gadcons_position_before_move(E_Smart_Data *sd, E_
      }
 }
 
+static void
+_e_gadcon_event_populate_free(void *data __UNUSED__, void *event)
+{
+   E_Event_Gadcon_Populate *ev = event;
+
+   e_object_unref(E_OBJECT(ev->gc));
+   free(ev);
+}
+
 static Eina_Bool
 _e_gadcon_custom_populate_idler(void *data __UNUSED__)
 {
@@ -5483,6 +5506,7 @@ _e_gadcon_custom_populate_idler(void *data __UNUSED__)
                e_gadcon_populate_class(gc, cc);
           }
         e_gadcon_layout_thaw(gc->o_container);
+        _e_gadcon_event_populate(gc);
      }
 
 #ifndef E17_RELEASE_BUILD
@@ -5506,55 +5530,70 @@ _e_gadcon_provider_populate_idler(void *data __UNUSED__)
    E_Gadcon_Client_Class *cc;
    Eina_List *l;
    E_Gadcon *gc;
+   Eina_Bool cont = EINA_FALSE;
 
    if (!_modules_loaded) return EINA_TRUE;
 
-   EINA_LIST_FOREACH(gadcons, l, gc)
-     e_gadcon_layout_freeze(gc->o_container);
-
 #ifndef E17_RELEASE_BUILD
    static Eina_Bool first = EINA_TRUE;
    if (first)
      e_main_ts("gadcon populate idler start");
 #endif
    EINA_LIST_FOREACH(gadcons, l, gc)
-     EINA_LIST_FREE(gc->populate_requests, cc)
-       {
+     {
+        int x = 0;
+        Eina_Bool freeze = EINA_FALSE;
+        if (gc->populate_requests)
+          {
+             freeze = EINA_TRUE;
+             e_gadcon_layout_freeze(gc->o_container);
+          }
+        EINA_LIST_FREE(gc->populate_requests, cc)
+          {
+             if (x)
+               {
+                  cont = EINA_TRUE;
+                  e_gadcon_layout_thaw(gc->o_container);
+                  goto out;
+               }
 #ifndef E17_RELEASE_BUILD
-          if (first) e_main_ts(cc->name);
+             if (first) e_main_ts(cc->name);
 #endif
-          if (gc->populate_class.func)
-            gc->populate_class.func(gc->populate_class.data, gc, cc);
-          else
-            e_gadcon_populate_class(gc, cc);
-          if (!eina_list_data_find(gc->populated_classes, cc))
-            {
-               gc->populated_classes = eina_list_append(gc->populated_classes, cc);
-               if (gc->cf)
-                 {
-                    Eina_List *ll;
-                    E_Config_Gadcon_Client *cf_gcc;
-
-                    if (!gc->awaiting_classes) continue;
-                    ll = eina_hash_set(gc->awaiting_classes, cc->name, NULL);
-                    EINA_LIST_FREE(ll, cf_gcc)
-                      _e_gadcon_client_populate(gc, cc, cf_gcc);
-                 }
-            }
-       }
+             if (gc->populate_class.func)
+               gc->populate_class.func(gc->populate_class.data, gc, cc);
+             else
+               e_gadcon_populate_class(gc, cc);
+             if (!eina_list_data_find(gc->populated_classes, cc))
+               {
+                  gc->populated_classes = eina_list_append(gc->populated_classes, cc);
+                  if (gc->cf)
+                    {
+                       Eina_List *ll;
+                       E_Config_Gadcon_Client *cf_gcc;
 
+                       if (!gc->awaiting_classes) continue;
+                       ll = eina_hash_set(gc->awaiting_classes, cc->name, NULL);
+                       EINA_LIST_FREE(ll, cf_gcc)
+                         _e_gadcon_client_populate(gc, cc, cf_gcc);
+                    }
+               }
+             x++;
+          }
+          if (freeze) e_gadcon_layout_thaw(gc->o_container);
+          if (x) _e_gadcon_event_populate(gc);
+       }
+out:
 #ifndef E17_RELEASE_BUILD
    if (first)
      e_main_ts("gadcon populate idler end");
 #endif
-   EINA_LIST_FOREACH(gadcons, l, gc)
-     e_gadcon_layout_thaw(gc->o_container);
 
-   populate_idler = NULL;
+   if (cont)
+     populate_idler = NULL;
 #ifndef E17_RELEASE_BUILD
    first = EINA_FALSE;
 #endif
-   return ECORE_CALLBACK_CANCEL;
+   return cont;
 }
 
 static void
index 53b4bfc..4d97a6a 100644 (file)
@@ -50,6 +50,7 @@ typedef struct _E_Gadcon_Client_Class E_Gadcon_Client_Class;
 typedef struct _E_Event_Gadcon_Client_Class E_Event_Gadcon_Client_Class_Add;
 typedef struct _E_Event_Gadcon_Client_Class E_Event_Gadcon_Client_Class_Del;
 typedef struct _E_Gadcon_Location     E_Gadcon_Location;
+typedef struct _E_Event_Gadcon_Populate E_Event_Gadcon_Populate;
 
 #else
 #ifndef E_GADCON_H
@@ -63,6 +64,7 @@ EAPI extern int E_EVENT_GADCON_CLIENT_ADD;
 EAPI extern int E_EVENT_GADCON_CLIENT_DEL;
 EAPI extern int E_EVENT_GADCON_CLIENT_CLASS_ADD;
 EAPI extern int E_EVENT_GADCON_CLIENT_CLASS_DEL;
+EAPI extern int E_EVENT_GADCON_POPULATE;
 
 struct _E_Gadcon
 {
@@ -240,6 +242,11 @@ struct _E_Event_Gadcon_Client
    E_Gadcon_Client *gcc;
 };
 
+struct _E_Event_Gadcon_Populate
+{
+   E_Gadcon *gc;
+};
+
 /* defines usable gadget placements such as Desktop, Shelf #, etc */
 /* next fields are mandatory (not NULL): name, add_gadget.func, remove_gadget.func */
 struct _E_Gadcon_Location
index 89bb64d..b433864 100644 (file)
@@ -595,6 +595,8 @@ _cb_del(void *data, void *data2 __UNUSED__)
      {
         if (!cfdata->gc->custom)
           {
+             if (cfdata->gc->shelf)
+               e_shelf_hide(cfdata->gc->shelf);
              e_gadcon_unpopulate(cfdata->gc);
              e_gadcon_populate(cfdata->gc);
           }
index 3c76d5b..5e26320 100644 (file)
@@ -911,17 +911,6 @@ main(int argc, char **argv)
    _e_main_shutdown_push(e_bindings_shutdown);
 
    if (e_config->show_splash)
-     e_init_status_set(_("Setup Shelves"));
-   TS("E_Shelf Init");
-   if (!e_shelf_init())
-     {
-        e_error_message_show(_("Enlightenment cannot set up its module system."));
-        _e_main_shutdown(-1);
-     }
-   TS("E_Shelf Init Done");
-   _e_main_shutdown_push(e_shelf_shutdown);
-
-   if (e_config->show_splash)
      e_init_status_set(_("Setup Thumbnailer"));
    TS("E_Thumb Init");
    if (!e_thumb_init())
@@ -1022,6 +1011,18 @@ main(int argc, char **argv)
    e_test();
    TS("E_Test Done");
 
+
+   if (e_config->show_splash)
+     e_init_status_set(_("Setup Shelves"));
+   TS("E_Shelf Init");
+   if (!e_shelf_init())
+     {
+        e_error_message_show(_("Enlightenment cannot set up its module system."));
+        _e_main_shutdown(-1);
+     }
+   TS("E_Shelf Init Done");
+   _e_main_shutdown_push(e_shelf_shutdown);
+
    if (e_config->show_splash)
      e_init_status_set(_("Configure Shelves"));
    TS("E_Shelf Config Update");
index 7a78a74..b699d37 100644 (file)
@@ -35,6 +35,7 @@ static void         _e_shelf_bindings_del(E_Shelf *es);
 static Eina_Bool    _e_shelf_on_current_desk(E_Shelf *es, E_Event_Zone_Edge *ev);
 static void          _e_shelf_cb_dummy_del(E_Shelf *, Evas *e, Evas_Object *obj, void *event_info);
 static void          _e_shelf_cb_dummy_moveresize(E_Shelf *, Evas *e, Evas_Object *obj, void *event_info);
+static Eina_Bool    _e_shelf_gadcon_populate_handler_cb(void *, int, void *);
 
 static Eina_List *shelves = NULL;
 static Eina_List *dummies = NULL;
@@ -80,6 +81,7 @@ static const char *orient_names[] =
 
 EAPI int E_EVENT_SHELF_ADD = -1;
 EAPI int E_EVENT_SHELF_DEL = -1;
+static Ecore_Event_Handler *_e_shelf_gadcon_populate_handler = NULL;
 
 /* externally accessible functions */
 EINTERN int
@@ -87,6 +89,7 @@ e_shelf_init(void)
 {
    E_EVENT_SHELF_ADD = ecore_event_type_new();
    E_EVENT_SHELF_DEL = ecore_event_type_new();
+   _e_shelf_gadcon_populate_handler = ecore_event_handler_add(E_EVENT_GADCON_POPULATE, _e_shelf_gadcon_populate_handler_cb, NULL);
    return 1;
 }
 
@@ -101,6 +104,7 @@ e_shelf_shutdown(void)
         es = eina_list_data_get(shelves);
         e_object_del(E_OBJECT(es));
      }
+   _e_shelf_gadcon_populate_handler = ecore_event_handler_del(_e_shelf_gadcon_populate_handler);
 
    return 1;
 }
@@ -998,6 +1002,7 @@ EAPI E_Shelf *
 e_shelf_config_new(E_Zone *zone, E_Config_Shelf *cf_es)
 {
    E_Shelf *es;
+   Eina_Bool can_show = EINA_FALSE;
 
    es = e_shelf_zone_new(zone, cf_es->name, cf_es->style,
                          cf_es->popup, cf_es->layer, cf_es->id);
@@ -1025,13 +1030,23 @@ e_shelf_config_new(E_Zone *zone, E_Config_Shelf *cf_es)
           {
              if ((desk->x == sd->x) && (desk->y == sd->y))
                {
-                  e_shelf_show(es);
+                  can_show = EINA_TRUE;
                   break;
                }
           }
      }
    else
-     e_shelf_show(es);
+     can_show = EINA_TRUE;
+
+   if (can_show)
+     {
+        /* at this point, we cleverly avoid showing the shelf
+         * if its gadcon has not populated; instead we show it in
+         * the E_EVENT_GADCON_POPULATE handler
+         */
+        if (es->gadcon->clients)
+          e_shelf_show(es);
+     }
 
    e_shelf_toggle(es, 0);
    return es;
@@ -2127,6 +2142,26 @@ _e_shelf_cb_instant_hide_timer(void *data)
    return ECORE_CALLBACK_CANCEL;
 }
 
+static Eina_Bool
+_e_shelf_gadcon_populate_handler_cb(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   E_Event_Gadcon_Populate *ev = event;
+   Eina_List *l;
+   E_Shelf *es;
+
+   EINA_LIST_FOREACH(shelves, l, es)
+     if (es->gadcon == ev->gc)
+       {
+          /* any shelf that's not already shown at this point will be
+           * waiting for this event to show it so that we don't ever resize the shelf
+           * object
+           */
+          e_shelf_show(es);
+          break;
+       }
+   return ECORE_CALLBACK_RENEW;
+}
+
 static void
 _e_shelf_cb_menu_rename_yes_cb(void *data, char *text)
 {