From 51ce8b45198dd8cd5f5b229efa9b24e0cf558e02 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 1 Aug 2012 07:08:06 +0000 Subject: [PATCH] menus now realize their items using idlers to improve responsiveness when loading large/complex menus SVN revision: 74713 --- src/bin/e_menu.c | 49 +++++++++++++++++++++++++++++++++++++++++------- src/bin/e_menu.h | 3 +++ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/bin/e_menu.c b/src/bin/e_menu.c index 3c55c34af..5a1907b12 100644 --- a/src/bin/e_menu.c +++ b/src/bin/e_menu.c @@ -30,6 +30,7 @@ struct _E_Menu_Category }; /* local subsystem functions */ +static Eina_Bool _e_menu_idler(E_Menu *m); static void _e_menu_free(E_Menu *m); static void _e_menu_item_free(E_Menu_Item *mi); static void _e_menu_item_realize(E_Menu_Item *mi); @@ -447,16 +448,18 @@ e_menu_thaw(E_Menu *m) E_OBJECT_TYPE_CHECK_RETURN(m, E_MENU_TYPE, 0); m->frozen--; if (m->frozen < 0) m->frozen = 0; - if (!m->frozen) + if ((!m->frozen) && (m->realized)) { - Eina_List *l; E_Menu_Item *mi; + Eina_List *l; + evas_event_freeze(m->evas); e_box_freeze(m->container_object); EINA_LIST_FOREACH(m->items, l, mi) _e_menu_item_unrealize(mi); - EINA_LIST_FOREACH(m->items, l, mi) - _e_menu_item_realize(mi); + if (!m->idler) + m->idler = ecore_idler_add((Ecore_Task_Cb)_e_menu_idler, m); + m->idler_pos = m->items; _e_menu_items_layout_update(m); e_box_thaw(m->container_object); @@ -1158,6 +1161,31 @@ e_menu_find_by_window(Ecore_X_Window win) } /* local subsystem functions */ +static Eina_Bool +_e_menu_idler(E_Menu *m) +{ + E_Menu_Item *mi; + double t; + + t = ecore_loop_time_get(); + evas_event_freeze(m->evas); + e_box_freeze(m->container_object); + EINA_LIST_FOREACH(m->items, m->idler_pos, mi) + { + if (ecore_loop_time_get() - t >= 0.5 * ecore_animator_frametime_get()) + break; + _e_menu_item_realize(mi); + } + + _e_menu_items_layout_update(m); + e_box_thaw(m->container_object); + evas_object_resize(m->bg_object, m->cur.w, m->cur.h); + evas_event_thaw(m->evas); + if (!m->idler_pos) + m->idler = NULL; + return !!m->idler_pos; +} + static void _e_menu_free(E_Menu *m) { @@ -1519,12 +1547,13 @@ static void _e_menu_realize(E_Menu *m) { Evas_Object *o; - Eina_List *l; E_Menu_Item *mi; int ok = 0; + double t; if (m->realized) return; m->realized = 1; + t = ecore_loop_time_get(); m->ecore_evas = e_canvas_new(m->zone->container->win, m->cur.x, m->cur.y, m->cur.w, m->cur.h, 1, 1, &(m->evas_win)); @@ -1596,8 +1625,14 @@ _e_menu_realize(E_Menu *m) e_box_homogenous_set(o, 0); edje_object_part_swallow(m->bg_object, "e.swallow.content", m->container_object); - EINA_LIST_FOREACH(m->items, l, mi) - _e_menu_item_realize(mi); + EINA_LIST_FOREACH(m->items, m->idler_pos, mi) + { + if (ecore_loop_time_get() - t >= 0.5 * ecore_animator_frametime_get()) + break; + _e_menu_item_realize(mi); + } + if (m->idler_pos) + m->idler = ecore_idler_add((Ecore_Task_Cb)_e_menu_idler, m); _e_menu_items_layout_update(m); e_box_thaw(m->container_object); diff --git a/src/bin/e_menu.h b/src/bin/e_menu.h index 556279aeb..0f15e11a1 100644 --- a/src/bin/e_menu.h +++ b/src/bin/e_menu.h @@ -45,6 +45,9 @@ struct _E_Menu Eina_List *items; + Ecore_Idler *idler; + Eina_List *idler_pos; + /* the zone it belongs to */ E_Zone *zone;