forked from enlightenment/enlightenment
move x11 client icon caching to private functions in comp_x
ref 57ce6419e5
This commit is contained in:
parent
8f0f9ce4f7
commit
3cb11abb25
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue