From 3cb11abb254ddeb9ca5f4dfe812325a784570293 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 1 Apr 2016 14:16:21 -0400 Subject: [PATCH] move x11 client icon caching to private functions in comp_x ref 57ce6419e5c257e6fee6809cdb9c63d39c0b0a98 --- src/bin/e_client.c | 103 +------------------------------------------- src/bin/e_client.h | 2 - src/bin/e_comp_x.c | 104 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 103 insertions(+), 106 deletions(-) diff --git a/src/bin/e_client.c b/src/bin/e_client.c index e2a2bf652..3d529848b 100644 --- a/src/bin/e_client.c +++ b/src/bin/e_client.c @@ -532,12 +532,7 @@ _e_client_free(E_Client *ec) ec->group = eina_list_free(ec->group); ec->transients = eina_list_free(ec->transients); ec->stick_desks = eina_list_free(ec->stick_desks); - if (ec->netwm.icons) - { - e_client_icon_free(ec->netwm.icons, ec->netwm.num_icons); - ec->netwm.icons = NULL; - ec->netwm.num_icons = 0; - } + E_FREE(ec->netwm.extra_types); eina_stringshare_replace(&ec->border.name, NULL); eina_stringshare_replace(&ec->bordername, NULL); @@ -5022,99 +5017,3 @@ e_client_layout_cb_set(E_Client_Layout_Cb cb) CRI("ATTEMPTING TO OVERWRITE EXISTING CLIENT LAYOUT HOOK!!!"); _e_client_layout_cb = cb; } - -//////////////////////////////////////////// -static Eina_List *iconshare = NULL; - -typedef struct _E_Client_Icon_Entry E_Client_Icon_Entry; - -struct _E_Client_Icon_Entry -{ - Ecore_X_Icon *icons; - int num_icons; - int ref; -}; - -E_API Ecore_X_Icon * -e_client_icon_deduplicate(Ecore_X_Icon *icons, int num_icons) -{ - int i; - Eina_List *l; - E_Client_Icon_Entry *ie; - - // unless the rest of e uses border icons OTHER than icon #0 - // then free the rest that we don't need anymore. - for (i = 1; i < num_icons; i++) - { - free(icons[i].data); - icons[i].data = NULL; - } - // lookup icon data in icons cache/share - EINA_LIST_FOREACH(iconshare, l, ie) - { - if ((ie->num_icons == num_icons) && - (num_icons > 0) && - (ie->icons[0].width == icons[0].width) && - (ie->icons[0].height == icons[0].height) && - (!memcmp(ie->icons[0].data, icons[0].data, - icons[0].width * icons[0].height * 4))) - { - // found so free the input icons - for (i = 0; i < num_icons; i++) - free(icons[i].data); - free(icons); - // ref the shared/cached one - ie->ref++; - iconshare = eina_list_promote_list(iconshare, l); - // and return that - return ie->icons; - } - } - // no hit - new entry to cache. add it - ie = calloc(1, sizeof(E_Client_Icon_Entry)); - if (ie) - { - ie->icons = icons; - ie->num_icons = num_icons; - ie->ref = 1; - iconshare = eina_list_prepend(iconshare, ie); - } - return icons; -} - -E_API void -e_client_icon_free(Ecore_X_Icon *icons, int num_icons) -{ - int i; - Eina_List *l; - E_Client_Icon_Entry *ie; - - // lookup in icon share cache - EINA_LIST_FOREACH(iconshare, l, ie) - { - if ((ie->num_icons == num_icons) && - (num_icons > 0) && - (ie->icons[0].width == icons[0].width) && - (ie->icons[0].height == icons[0].height) && - (!memcmp(ie->icons[0].data, icons[0].data, - icons[0].width * icons[0].height * 4))) - { - // found so deref - ie->ref--; - if (ie->ref <= 0) - { - // no refs left - free the icon from the share/cache - iconshare = eina_list_remove_list(iconshare, l); - for (i = 0; i < ie->num_icons; i++) - free(ie->icons[i].data); - free(ie->icons); - free(ie); - } - return; - } - } - // not found - so just free it ... odd - we should never be here - for (i = 0; i < num_icons; i++) - free(icons[i].data); - free(icons); -} diff --git a/src/bin/e_client.h b/src/bin/e_client.h index 94ef059af..13d24fd56 100644 --- a/src/bin/e_client.h +++ b/src/bin/e_client.h @@ -827,8 +827,6 @@ E_API Eina_Bool e_client_has_xwindow(const E_Client *ec); E_API Eina_Bool e_client_desk_window_profile_available_check(E_Client *ec, const char *profile); E_API void e_client_desk_window_profile_wait_desk_set(E_Client *ec, E_Desk *desk); E_API void e_client_layout_cb_set(E_Client_Layout_Cb cb); -E_API Ecore_X_Icon *e_client_icon_deduplicate(Ecore_X_Icon *icons, int num_icons); -E_API void e_client_icon_free(Ecore_X_Icon *icons, int num_icons); YOLO E_API void e_client_focus_stack_set(Eina_List *l); diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c index 2bff1106e..4c1e4192e 100644 --- a/src/bin/e_comp_x.c +++ b/src/bin/e_comp_x.c @@ -152,6 +152,100 @@ _e_comp_x_client_frame_update(E_Client *ec, int l, int r, int t, int b) _e_comp_x_client_data_get(ec)->frame_update = 0; } +static Eina_List *iconshare = NULL; + +typedef struct _E_Client_Icon_Entry E_Client_Icon_Entry; + +struct _E_Client_Icon_Entry +{ + Ecore_X_Icon *icons; + int num_icons; + int ref; +}; + +static Ecore_X_Icon * +_e_comp_x_client_icon_deduplicate(Ecore_X_Icon *icons, int num_icons) +{ + int i; + Eina_List *l; + E_Client_Icon_Entry *ie; + + // unless the rest of e uses border icons OTHER than icon #0 + // then free the rest that we don't need anymore. + for (i = 1; i < num_icons; i++) + { + E_FREE(icons[i].data); + } + // lookup icon data in icons cache/share + EINA_LIST_FOREACH(iconshare, l, ie) + { + if ((ie->num_icons == num_icons) && + (num_icons > 0) && + (ie->icons[0].width == icons[0].width) && + (ie->icons[0].height == icons[0].height) && + (!memcmp(ie->icons[0].data, icons[0].data, + icons[0].width * icons[0].height * 4))) + { + // found so free the input icons + for (i = 0; i < num_icons; i++) + free(icons[i].data); + free(icons); + // ref the shared/cached one + ie->ref++; + iconshare = eina_list_promote_list(iconshare, l); + // and return that + return ie->icons; + } + } + // no hit - new entry to cache. add it + ie = calloc(1, sizeof(E_Client_Icon_Entry)); + if (ie) + { + ie->icons = icons; + ie->num_icons = num_icons; + ie->ref = 1; + iconshare = eina_list_prepend(iconshare, ie); + } + return icons; +} + +static void +_e_comp_x_client_icon_free(Ecore_X_Icon *icons, int num_icons) +{ + int i; + Eina_List *l; + E_Client_Icon_Entry *ie; + + // lookup in icon share cache + EINA_LIST_FOREACH(iconshare, l, ie) + { + if ((ie->num_icons == num_icons) && + (num_icons > 0) && + (ie->icons[0].width == icons[0].width) && + (ie->icons[0].height == icons[0].height) && + (!memcmp(ie->icons[0].data, icons[0].data, + icons[0].width * icons[0].height * 4))) + { + // found so deref + ie->ref--; + if (ie->ref <= 0) + { + // no refs left - free the icon from the share/cache + iconshare = eina_list_remove_list(iconshare, l); + for (i = 0; i < ie->num_icons; i++) + free(ie->icons[i].data); + free(ie->icons); + free(ie); + } + return; + } + } + // not found - so just free it ... odd - we should never be here + for (i = 0; i < num_icons; i++) + free(icons[i].data); + free(icons); +} + static void _e_comp_x_client_event_free(void *d EINA_UNUSED, void *e) { @@ -3795,7 +3889,7 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, E_Client *ec) } if (ec->netwm.fetch.icon) { - e_client_icon_free(ec->netwm.icons, ec->netwm.num_icons); + _e_comp_x_client_icon_free(ec->netwm.icons, ec->netwm.num_icons); ec->netwm.icons = NULL; ec->netwm.num_icons = 0; if (ecore_x_netwm_icons_get(win, @@ -3803,7 +3897,7 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, E_Client *ec) &ec->netwm.num_icons)) { if (ec->netwm.icons) - ec->netwm.icons = e_client_icon_deduplicate + ec->netwm.icons = _e_comp_x_client_icon_deduplicate (ec->netwm.icons, ec->netwm.num_icons); ec->changes.icon = 1; } @@ -4687,6 +4781,12 @@ _e_comp_x_hook_client_del(void *d EINA_UNUSED, E_Client *ec) e_pixmap_client_set(ec->pixmap, NULL); ec->pixmap = NULL; } + if (ec->netwm.icons) + { + _e_comp_x_client_icon_free(ec->netwm.icons, ec->netwm.num_icons); + ec->netwm.icons = NULL; + ec->netwm.num_icons = 0; + } if (post_clients) post_clients = eina_list_remove(post_clients, ec);