add an option to set the preferred client icon size
_NET_WM_ICON contains a list of icons and until now, the first one was picked without regard to it's size. This adds a global option to set the preferred icon size. When getting the client icon, the best size match is picked. The size can be set via awesome.set_preferred_icon_size() and the default is 0, which will pick the smallest non-zero size icon available. Signed-off-by: Lukáš Hrázký <lukkash@email.cz>
This commit is contained in:
parent
0516203610
commit
ea94f7f7e6
|
@ -543,6 +543,9 @@ main(int argc, char **argv)
|
|||
/* We have no clue where the input focus is right now */
|
||||
globalconf.focus.need_update = true;
|
||||
|
||||
/* set the default preferred icon size */
|
||||
globalconf.preferred_icon_size = 0;
|
||||
|
||||
/* XLib sucks */
|
||||
XkbIgnoreExtension(True);
|
||||
|
||||
|
|
46
ewmh.c
46
ewmh.c
|
@ -662,27 +662,45 @@ ewmh_window_icon_get_unchecked(xcb_window_t w)
|
|||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
ewmh_window_icon_from_reply(xcb_get_property_reply_t *r)
|
||||
ewmh_window_icon_from_reply(xcb_get_property_reply_t *r, uint32_t preferred_size)
|
||||
{
|
||||
uint32_t *data;
|
||||
uint64_t len;
|
||||
uint32_t *data, *end, *found_data = 0;
|
||||
uint32_t found_size = 0;
|
||||
|
||||
if(!r || r->type != XCB_ATOM_CARDINAL || r->format != 32 || r->length < 2)
|
||||
return 0;
|
||||
|
||||
data = (uint32_t *) xcb_get_property_value(r);
|
||||
if (!data)
|
||||
return 0;
|
||||
if (!data) return 0;
|
||||
|
||||
/* Check that the property is as long as it should be, handling integer
|
||||
* overflow. <uint32_t> times <another uint32_t casted to uint64_t> always
|
||||
* fits into an uint64_t and thus this multiplication cannot overflow.
|
||||
end = data + r->length;
|
||||
|
||||
/* Goes over the icon data and picks the icon that best matches the size preference.
|
||||
* In case the size match is not exact, picks the closest bigger size if present,
|
||||
* closest smaller size otherwise.
|
||||
*/
|
||||
len = data[0] * (uint64_t) data[1];
|
||||
if (!data[0] || !data[1] || len > r->length - 2)
|
||||
return 0;
|
||||
while (data + 1 < end) {
|
||||
/* check whether the data size specified by width and height fits into the array we got */
|
||||
uint64_t data_size = (uint64_t) data[0] * data[1];
|
||||
if (data_size > (uint64_t) (end - data - 2)) break;
|
||||
|
||||
return draw_surface_from_data(data[0], data[1], data + 2);
|
||||
/* use the greater of the two dimensions to match against the preferred size */
|
||||
uint32_t size = MAX(data[0], data[1]);
|
||||
/* pick the icon if it's a better match than the one we already have */
|
||||
if (data[0] && data[1] && (
|
||||
(found_size < preferred_size && size > found_size) ||
|
||||
(found_size > preferred_size && size >= preferred_size && size < found_size)))
|
||||
{
|
||||
found_data = data;
|
||||
found_size = size;
|
||||
}
|
||||
|
||||
data += data_size + 2;
|
||||
}
|
||||
|
||||
if (!found_data) return 0;
|
||||
|
||||
return draw_surface_from_data(found_data[0], found_data[1], found_data + 2);
|
||||
}
|
||||
|
||||
/** Get NET_WM_ICON.
|
||||
|
@ -690,10 +708,10 @@ ewmh_window_icon_from_reply(xcb_get_property_reply_t *r)
|
|||
* \return The number of elements on stack.
|
||||
*/
|
||||
cairo_surface_t *
|
||||
ewmh_window_icon_get_reply(xcb_get_property_cookie_t cookie)
|
||||
ewmh_window_icon_get_reply(xcb_get_property_cookie_t cookie, uint32_t preferred_size)
|
||||
{
|
||||
xcb_get_property_reply_t *r = xcb_get_property_reply(globalconf.connection, cookie, NULL);
|
||||
cairo_surface_t *surface = ewmh_window_icon_from_reply(r);
|
||||
cairo_surface_t *surface = ewmh_window_icon_from_reply(r, preferred_size);
|
||||
p_delete(&r);
|
||||
return surface;
|
||||
}
|
||||
|
|
2
ewmh.h
2
ewmh.h
|
@ -41,7 +41,7 @@ void ewmh_process_client_strut(client_t *);
|
|||
void ewmh_update_strut(xcb_window_t, strut_t *);
|
||||
void ewmh_update_window_type(xcb_window_t window, uint32_t type);
|
||||
xcb_get_property_cookie_t ewmh_window_icon_get_unchecked(xcb_window_t);
|
||||
cairo_surface_t *ewmh_window_icon_get_reply(xcb_get_property_cookie_t);
|
||||
cairo_surface_t *ewmh_window_icon_get_reply(xcb_get_property_cookie_t, uint32_t preferred_size);
|
||||
|
||||
#endif
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
||||
|
|
|
@ -167,6 +167,8 @@ typedef struct
|
|||
struct xkb_context *xkb_ctx;
|
||||
/* xkb state of dead keys on keyboard */
|
||||
struct xkb_state *xkb_state;
|
||||
/** The preferred size of client icons for this screen */
|
||||
uint32_t preferred_icon_size;
|
||||
} awesome_t;
|
||||
|
||||
extern awesome_t globalconf;
|
||||
|
|
16
luaa.c
16
luaa.c
|
@ -162,6 +162,21 @@ luaA_load_image(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/** Set the preferred size for client icons.
|
||||
*
|
||||
* The closest equal or bigger size is picked if present, otherwise the closest
|
||||
* smaller size is picked. The default is 0 pixels, ie. the smallest icon.
|
||||
*
|
||||
* @param size The size of the icons in pixels.
|
||||
* @function set_preferred_icon_size
|
||||
*/
|
||||
static int
|
||||
luaA_set_preferred_icon_size(lua_State *L)
|
||||
{
|
||||
globalconf.preferred_icon_size = luaL_checknumber(L, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** UTF-8 aware string length computing.
|
||||
* \param L The Lua VM state.
|
||||
* \return The number of elements pushed on stack.
|
||||
|
@ -407,6 +422,7 @@ luaA_init(xdgHandle* xdg)
|
|||
{ "emit_signal", luaA_awesome_emit_signal },
|
||||
{ "systray", luaA_systray },
|
||||
{ "load_image", luaA_load_image },
|
||||
{ "set_preferred_icon_size", luaA_set_preferred_icon_size },
|
||||
{ "register_xproperty", luaA_register_xproperty },
|
||||
{ "set_xproperty", luaA_set_xproperty },
|
||||
{ "get_xproperty", luaA_get_xproperty },
|
||||
|
|
|
@ -273,7 +273,7 @@ property_get_net_wm_icon(client_t *c)
|
|||
void
|
||||
property_update_net_wm_icon(client_t *c, xcb_get_property_cookie_t cookie)
|
||||
{
|
||||
cairo_surface_t *surface = ewmh_window_icon_get_reply(cookie);
|
||||
cairo_surface_t *surface = ewmh_window_icon_get_reply(cookie, globalconf.preferred_icon_size);
|
||||
|
||||
if(!surface)
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue