[all] Implement an atom cache in xutil as an ordered linked-list
This commit is contained in:
parent
6a06e44461
commit
162b8a690c
|
@ -386,7 +386,8 @@ main(int argc, char **argv)
|
||||||
xutil_getlockmask(globalconf.connection, globalconf.keysyms, &globalconf.numlockmask,
|
xutil_getlockmask(globalconf.connection, globalconf.keysyms, &globalconf.numlockmask,
|
||||||
&globalconf.shiftlockmask, &globalconf.capslockmask);
|
&globalconf.shiftlockmask, &globalconf.capslockmask);
|
||||||
|
|
||||||
/* init EWMH atoms */
|
/* init Atoms cache and then EWMH atoms */
|
||||||
|
atom_cache_list_init(&globalconf.atoms);
|
||||||
ewmh_init_atoms();
|
ewmh_init_atoms();
|
||||||
|
|
||||||
/* init screens struct */
|
/* init screens struct */
|
||||||
|
|
51
client.c
51
client.c
|
@ -60,8 +60,11 @@ client_loadprops(client_t * c, int screen)
|
||||||
for(tag = globalconf.screens[screen].tags; tag; tag = tag->next)
|
for(tag = globalconf.screens[screen].tags; tag; tag = tag->next)
|
||||||
ntags++;
|
ntags++;
|
||||||
|
|
||||||
if(xutil_gettextprop(globalconf.connection, c->win,
|
if(xutil_gettextprop(globalconf.connection, c->win, &globalconf.atoms,
|
||||||
xutil_intern_atom(globalconf.connection, "_AWESOME_PROPERTIES"),
|
xutil_intern_atom_reply(globalconf.connection, &globalconf.atoms,
|
||||||
|
xutil_intern_atom(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
"_AWESOME_PROPERTIES")),
|
||||||
&prop))
|
&prop))
|
||||||
{
|
{
|
||||||
for(i = 0, tag = globalconf.screens[screen].tags; tag && i < ntags && prop[i]; i++, tag = tag->next)
|
for(i = 0, tag = globalconf.screens[screen].tags; tag && i < ntags && prop[i]; i++, tag = tag->next)
|
||||||
|
@ -90,13 +93,19 @@ static bool
|
||||||
client_isprotodel(xcb_window_t win)
|
client_isprotodel(xcb_window_t win)
|
||||||
{
|
{
|
||||||
uint32_t i, n;
|
uint32_t i, n;
|
||||||
|
xcb_atom_t wm_delete_win_atom;
|
||||||
xcb_atom_t *protocols;
|
xcb_atom_t *protocols;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if(xcb_get_wm_protocols(globalconf.connection, win, &n, &protocols))
|
if(xcb_get_wm_protocols(globalconf.connection, win, &n, &protocols))
|
||||||
{
|
{
|
||||||
|
wm_delete_win_atom = xutil_intern_atom_reply(globalconf.connection, &globalconf.atoms,
|
||||||
|
xutil_intern_atom(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
"WM_DELETE_WINDOW"));
|
||||||
|
|
||||||
for(i = 0; !ret && i < n; i++)
|
for(i = 0; !ret && i < n; i++)
|
||||||
if(protocols[i] == xutil_intern_atom(globalconf.connection, "WM_DELETE_WINDOW"))
|
if(protocols[i] == wm_delete_win_atom)
|
||||||
ret = true;
|
ret = true;
|
||||||
p_delete(&protocols);
|
p_delete(&protocols);
|
||||||
}
|
}
|
||||||
|
@ -188,11 +197,18 @@ client_updatetitle(client_t *c)
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
if(!xutil_gettextprop(globalconf.connection, c->win,
|
if(!xutil_gettextprop(globalconf.connection, c->win, &globalconf.atoms,
|
||||||
xutil_intern_atom(globalconf.connection, "_NET_WM_NAME"),
|
xutil_intern_atom_reply(globalconf.connection, &globalconf.atoms,
|
||||||
|
xutil_intern_atom(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
"_NET_WM_NAME")),
|
||||||
&name))
|
&name))
|
||||||
if(!xutil_gettextprop(globalconf.connection, c->win,
|
if(!xutil_gettextprop(globalconf.connection, c->win, &globalconf.atoms,
|
||||||
xutil_intern_atom(globalconf.connection, "WM_NAME"),
|
xutil_intern_atom_reply(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
xutil_intern_atom(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
"WM_NAME")),
|
||||||
&name))
|
&name))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -687,7 +703,10 @@ client_saveprops(client_t *c)
|
||||||
prop[++i] = '\0';
|
prop[++i] = '\0';
|
||||||
|
|
||||||
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, c->win,
|
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, c->win,
|
||||||
xutil_intern_atom(globalconf.connection, "_AWESOME_PROPERTIES"),
|
xutil_intern_atom_reply(globalconf.connection, &globalconf.atoms,
|
||||||
|
xutil_intern_atom(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
"_AWESOME_PROPERTIES")),
|
||||||
STRING, 8, i, (unsigned char *) prop);
|
STRING, 8, i, (unsigned char *) prop);
|
||||||
|
|
||||||
p_delete(&prop);
|
p_delete(&prop);
|
||||||
|
@ -871,7 +890,11 @@ uicb_client_settrans(int screen __attribute__ ((unused)), char *arg)
|
||||||
prop_r = xcb_get_property_reply(globalconf.connection,
|
prop_r = xcb_get_property_reply(globalconf.connection,
|
||||||
xcb_get_property_unchecked(globalconf.connection,
|
xcb_get_property_unchecked(globalconf.connection,
|
||||||
false, sel->win,
|
false, sel->win,
|
||||||
xutil_intern_atom(globalconf.connection, "_NET_WM_WINDOW_OPACITY"),
|
xutil_intern_atom_reply(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
xutil_intern_atom(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
"_NET_WM_WINDOW_OPACITY")),
|
||||||
CARDINAL,
|
CARDINAL,
|
||||||
0, 1),
|
0, 1),
|
||||||
NULL);
|
NULL);
|
||||||
|
@ -1048,10 +1071,16 @@ client_kill(client_t *c)
|
||||||
|
|
||||||
ev.response_type = XCB_CLIENT_MESSAGE;
|
ev.response_type = XCB_CLIENT_MESSAGE;
|
||||||
ev.window = c->win;
|
ev.window = c->win;
|
||||||
ev.type = xutil_intern_atom(globalconf.connection, "WM_PROTOCOLS");
|
ev.type = xutil_intern_atom_reply(globalconf.connection, &globalconf.atoms,
|
||||||
|
xutil_intern_atom(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
"WM_PROTOCOLS"));
|
||||||
ev.format = 32;
|
ev.format = 32;
|
||||||
|
|
||||||
ev.data.data32[0] = xutil_intern_atom(globalconf.connection, "WM_DELETE_WINDOW");
|
ev.data.data32[0] = xutil_intern_atom_reply(globalconf.connection, &globalconf.atoms,
|
||||||
|
xutil_intern_atom(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
"WM_DELETE_WINDOW"));
|
||||||
ev.data.data32[1] = XCB_CURRENT_TIME;
|
ev.data.data32[1] = XCB_CURRENT_TIME;
|
||||||
|
|
||||||
xcb_send_event(globalconf.connection, false, c->win,
|
xcb_send_event(globalconf.connection, false, c->win,
|
||||||
|
|
116
common/xutil.c
116
common/xutil.c
|
@ -33,13 +33,14 @@
|
||||||
/** Get the string value of an atom.
|
/** Get the string value of an atom.
|
||||||
* \param conn X connection
|
* \param conn X connection
|
||||||
* \param w window
|
* \param w window
|
||||||
|
* \param atoms atoms cache
|
||||||
* \param atom the atom
|
* \param atom the atom
|
||||||
* \param text buffer to fill
|
* \param text buffer to fill
|
||||||
* \return true on sucess, falsse on failure
|
* \return true on sucess, falsse on failure
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
xutil_gettextprop(xcb_connection_t *conn, xcb_window_t w, xcb_atom_t atom,
|
xutil_gettextprop(xcb_connection_t *conn, xcb_window_t w, xutil_atom_cache_t **atoms,
|
||||||
char **text)
|
xcb_atom_t atom, char **text)
|
||||||
{
|
{
|
||||||
xcb_get_property_cookie_t prop_c;
|
xcb_get_property_cookie_t prop_c;
|
||||||
xcb_get_property_reply_t *prop_r;
|
xcb_get_property_reply_t *prop_r;
|
||||||
|
@ -67,7 +68,9 @@ xutil_gettextprop(xcb_connection_t *conn, xcb_window_t w, xcb_atom_t atom,
|
||||||
* string or utf8 string. At the moment it doesn't handle
|
* string or utf8 string. At the moment it doesn't handle
|
||||||
* COMPOUND_TEXT and multibyte but it's not needed... */
|
* COMPOUND_TEXT and multibyte but it's not needed... */
|
||||||
if(prop_r->type == STRING ||
|
if(prop_r->type == STRING ||
|
||||||
prop_r->type == xutil_intern_atom(conn, "UTF8_STRING"))
|
prop_r->type == xutil_intern_atom_reply(conn, atoms,
|
||||||
|
xutil_intern_atom(conn, atoms,
|
||||||
|
"UTF8_STRING")))
|
||||||
{
|
{
|
||||||
*text = p_new(char, prop_r->value_len + 1);
|
*text = p_new(char, prop_r->value_len + 1);
|
||||||
/* use memcpy() because prop_val may not be \0 terminated */
|
/* use memcpy() because prop_val may not be \0 terminated */
|
||||||
|
@ -152,29 +155,106 @@ xutil_get_transient_for_hint(xcb_connection_t *c, xcb_window_t win,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get an internal atom.
|
/** Send an unchecked InternAtom request if it is not already in the
|
||||||
|
* cache, in the second case it stores the cache entry (an ordered
|
||||||
|
* linked-list)
|
||||||
* \param c X connection
|
* \param c X connection
|
||||||
|
* \param atoms atoms cache
|
||||||
* \param property atom name
|
* \param property atom name
|
||||||
* \return an brand new xcb_atom_t
|
* \return a request structure
|
||||||
*/
|
*/
|
||||||
xcb_atom_t
|
xutil_intern_atom_request_t
|
||||||
xutil_intern_atom(xcb_connection_t *c, const char *property)
|
xutil_intern_atom(xcb_connection_t *c, xutil_atom_cache_t **atoms,
|
||||||
|
const char *name)
|
||||||
{
|
{
|
||||||
xcb_atom_t atom = 0;
|
xutil_intern_atom_request_t atom_req;
|
||||||
xcb_intern_atom_reply_t *r_atom;
|
xutil_atom_cache_t *atom_next;
|
||||||
|
int cmp_cache;
|
||||||
|
|
||||||
if((r_atom = xcb_intern_atom_reply(c,
|
atom_req.name = strdup(name);
|
||||||
xcb_intern_atom_unchecked(c,
|
|
||||||
false,
|
/* Check if this atom is present in the cache ordered
|
||||||
a_strlen(property),
|
* linked-list */
|
||||||
property),
|
for(atom_next = *atoms;
|
||||||
NULL)))
|
atom_next && (cmp_cache = a_strcmp(name, atom_next->name)) >= 0;
|
||||||
|
atom_next = atom_cache_list_next(NULL, atom_next))
|
||||||
|
if(cmp_cache == 0)
|
||||||
{
|
{
|
||||||
atom = r_atom->atom;
|
atom_req.cache_hit = true;
|
||||||
p_delete(&r_atom);
|
atom_req.cache = atom_next;
|
||||||
|
return atom_req;
|
||||||
}
|
}
|
||||||
|
|
||||||
return atom;
|
/* Otherwise send an InternAtom request to the server */
|
||||||
|
atom_req.cache_hit = false;
|
||||||
|
atom_req.cookie = xcb_intern_atom_unchecked(c, false, a_strlen(name),
|
||||||
|
name);
|
||||||
|
|
||||||
|
return atom_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Treat the reply which may be a cache entry or a reply from
|
||||||
|
* InternAtom request (cookie), in the second case, add the atom to
|
||||||
|
* the cache
|
||||||
|
* \param c X connection
|
||||||
|
* \param atoms atoms cache
|
||||||
|
* \param atom_req atom request
|
||||||
|
* \return a brand new xcb_atom_t
|
||||||
|
*/
|
||||||
|
xcb_atom_t
|
||||||
|
xutil_intern_atom_reply(xcb_connection_t *c, xutil_atom_cache_t **atoms,
|
||||||
|
xutil_intern_atom_request_t atom_req)
|
||||||
|
{
|
||||||
|
xcb_intern_atom_reply_t *atom_rep;
|
||||||
|
xutil_atom_cache_t *atom_cache, *atom_next;
|
||||||
|
|
||||||
|
/* If the atom is present in the cache, just returns the
|
||||||
|
* atom... */
|
||||||
|
if(atom_req.cache_hit)
|
||||||
|
return atom_req.cache->atom;
|
||||||
|
|
||||||
|
/* Get the reply from InternAtom request */
|
||||||
|
if((atom_rep = xcb_intern_atom_reply(c, atom_req.cookie, NULL)) == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Create a new atom cache entry */
|
||||||
|
atom_cache = p_new(xutil_atom_cache_t, 1);
|
||||||
|
atom_cache->atom = atom_rep->atom;
|
||||||
|
atom_cache->name = atom_req.name;
|
||||||
|
|
||||||
|
/* Add the entry in the list at the beginning of the cache list */
|
||||||
|
if(*atoms == NULL || a_strcmp(atom_req.name, (*atoms)->name) < 0)
|
||||||
|
atom_cache_list_push(atoms, atom_cache);
|
||||||
|
/* Otherwise insert it at the proper position in the cache list
|
||||||
|
* according to its name */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(atom_next = *atoms;
|
||||||
|
atom_next && atom_next->next && a_strcmp(atom_req.name, atom_next->next->name) > 0;
|
||||||
|
atom_next = atom_cache_list_next(NULL, atom_next));
|
||||||
|
|
||||||
|
atom_cache->prev = atom_next;
|
||||||
|
atom_cache->next = atom_next->next;
|
||||||
|
|
||||||
|
if(atom_next->next)
|
||||||
|
atom_next->next->prev = atom_cache;
|
||||||
|
|
||||||
|
atom_next->next = atom_cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_delete(&atom_rep);
|
||||||
|
|
||||||
|
return atom_cache->atom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete a cache entry
|
||||||
|
* \param entry cache entry
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xutil_atom_cache_delete(xutil_atom_cache_t **entry)
|
||||||
|
{
|
||||||
|
p_delete(&(*entry)->name);
|
||||||
|
p_delete(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
class_hint_t *
|
class_hint_t *
|
||||||
|
|
|
@ -31,9 +31,7 @@
|
||||||
/* XCB doesn't provide keysyms definition */
|
/* XCB doesn't provide keysyms definition */
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
|
|
||||||
bool xutil_gettextprop(xcb_connection_t *, xcb_window_t, xcb_atom_t, char **);
|
#include "common/list.h"
|
||||||
void xutil_getlockmask(xcb_connection_t *, xcb_key_symbols_t *,
|
|
||||||
unsigned int *, unsigned int *, unsigned int *);
|
|
||||||
|
|
||||||
/* See http://tronche.com/gui/x/xlib/appendix/b/ for values */
|
/* See http://tronche.com/gui/x/xlib/appendix/b/ for values */
|
||||||
#define CURSOR_FLEUR 52
|
#define CURSOR_FLEUR 52
|
||||||
|
@ -81,7 +79,7 @@ void xutil_getlockmask(xcb_connection_t *, xcb_key_symbols_t *,
|
||||||
/* Common function defined in Xlib but not in XCB */
|
/* Common function defined in Xlib but not in XCB */
|
||||||
bool xutil_get_transient_for_hint(xcb_connection_t *, xcb_window_t, xcb_window_t *);
|
bool xutil_get_transient_for_hint(xcb_connection_t *, xcb_window_t, xcb_window_t *);
|
||||||
|
|
||||||
typedef struct _class_hint_t
|
typedef struct
|
||||||
{
|
{
|
||||||
char *res_name;
|
char *res_name;
|
||||||
char *res_class;
|
char *res_class;
|
||||||
|
@ -97,18 +95,61 @@ typedef struct
|
||||||
|
|
||||||
class_hint_t *xutil_get_class_hint(xcb_connection_t *, xcb_window_t);
|
class_hint_t *xutil_get_class_hint(xcb_connection_t *, xcb_window_t);
|
||||||
|
|
||||||
/* Equivalent call to XInternAtom
|
/** Cache entry */
|
||||||
*
|
typedef struct xutil_atom_cache_t xutil_atom_cache_t;
|
||||||
* WARNING: should not be used in loop, in this case, it should send
|
struct xutil_atom_cache_t
|
||||||
* the queries first and then treat the answer as late as possible)
|
{
|
||||||
*/
|
/** Atom X identifier */
|
||||||
xcb_atom_t xutil_intern_atom(xcb_connection_t *, const char *);
|
xcb_atom_t atom;
|
||||||
|
/** Atom name */
|
||||||
|
char *name;
|
||||||
|
/** Next and previous atom cache entries */
|
||||||
|
xutil_atom_cache_t *prev, *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** InternAtom request data structure which may hold the cookie if the
|
||||||
|
* atom is not already present in the cache */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* Cache hit */
|
||||||
|
bool cache_hit;
|
||||||
|
/* Atom string name */
|
||||||
|
char *name;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
/* Cookie of the InternAtom request */
|
||||||
|
xcb_intern_atom_cookie_t cookie;
|
||||||
|
/* Cache entry */
|
||||||
|
xutil_atom_cache_t *cache;
|
||||||
|
};
|
||||||
|
} xutil_intern_atom_request_t;
|
||||||
|
|
||||||
|
/* InternATom request which relies on a cache stored as a ordered
|
||||||
|
* linked-list */
|
||||||
|
xutil_intern_atom_request_t xutil_intern_atom(xcb_connection_t *, xutil_atom_cache_t **,
|
||||||
|
const char *);
|
||||||
|
|
||||||
|
/** Treat reply from InternAtom request */
|
||||||
|
xcb_atom_t xutil_intern_atom_reply(xcb_connection_t *, xutil_atom_cache_t **,
|
||||||
|
xutil_intern_atom_request_t);
|
||||||
|
|
||||||
|
/** Delete a entry in the cache */
|
||||||
|
void xutil_atom_cache_delete(xutil_atom_cache_t **);
|
||||||
|
|
||||||
|
/** Cache list utils functions */
|
||||||
|
DO_SLIST(xutil_atom_cache_t, atom_cache, xutil_atom_cache_delete)
|
||||||
|
|
||||||
|
bool xutil_gettextprop(xcb_connection_t *, xcb_window_t, xutil_atom_cache_t **,
|
||||||
|
xcb_atom_t, char **);
|
||||||
|
|
||||||
|
void xutil_getlockmask(xcb_connection_t *, xcb_key_symbols_t *,
|
||||||
|
unsigned int *, unsigned int *, unsigned int *);
|
||||||
|
|
||||||
/** Set the same handler for all errors */
|
/** Set the same handler for all errors */
|
||||||
void xutil_set_error_handler_catch_all(xcb_event_handlers_t *,
|
void xutil_set_error_handler_catch_all(xcb_event_handlers_t *,
|
||||||
xcb_generic_error_handler_t, void *);
|
xcb_generic_error_handler_t, void *);
|
||||||
|
|
||||||
typedef struct xutil_error_t
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t request_code;
|
uint8_t request_code;
|
||||||
char *request_label;
|
char *request_label;
|
||||||
|
|
5
event.c
5
event.c
|
@ -520,7 +520,10 @@ event_handle_propertynotify(void *data __attribute__ ((unused)),
|
||||||
client_updatewmhints(c);
|
client_updatewmhints(c);
|
||||||
|
|
||||||
if(ev->atom == WM_NAME
|
if(ev->atom == WM_NAME
|
||||||
|| ev->atom == xutil_intern_atom(globalconf.connection, "_NET_WM_NAME"))
|
|| ev->atom == xutil_intern_atom_reply(globalconf.connection, &globalconf.atoms,
|
||||||
|
xutil_intern_atom(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
"_NET_WM_NAME")))
|
||||||
client_updatetitle(c);
|
client_updatetitle(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
8
rules.c
8
rules.c
|
@ -83,8 +83,12 @@ rule_matching_client(client_t *c)
|
||||||
if(!ret
|
if(!ret
|
||||||
&& r->xprop
|
&& r->xprop
|
||||||
&& r->xpropval_r
|
&& r->xpropval_r
|
||||||
&& xutil_gettextprop(globalconf.connection, c->win,
|
&& xutil_gettextprop(globalconf.connection, c->win, &globalconf.atoms,
|
||||||
xutil_intern_atom(globalconf.connection, r->xprop),
|
xutil_intern_atom_reply(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
xutil_intern_atom(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
r->xprop)),
|
||||||
&buf))
|
&buf))
|
||||||
ret = !regexec(r->xpropval_r, buf, 1, &tmp, 0);
|
ret = !regexec(r->xpropval_r, buf, 1, &tmp, 0);
|
||||||
|
|
||||||
|
|
|
@ -380,6 +380,8 @@ struct AwesomeConf
|
||||||
char *argv;
|
char *argv;
|
||||||
/** Last XMotionEvent coords */
|
/** Last XMotionEvent coords */
|
||||||
int pointer_x, pointer_y;
|
int pointer_x, pointer_y;
|
||||||
|
/** Atoms cache */
|
||||||
|
xutil_atom_cache_t *atoms;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
23
window.c
23
window.c
|
@ -41,11 +41,13 @@ void
|
||||||
window_setstate(xcb_window_t win, long state)
|
window_setstate(xcb_window_t win, long state)
|
||||||
{
|
{
|
||||||
long data[] = { state, XCB_NONE };
|
long data[] = { state, XCB_NONE };
|
||||||
|
const xcb_atom_t wm_state_atom = xutil_intern_atom_reply(globalconf.connection, &globalconf.atoms,
|
||||||
|
xutil_intern_atom(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
"WM_STATE"));
|
||||||
|
|
||||||
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, win,
|
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, win,
|
||||||
xutil_intern_atom(globalconf.connection, "WM_STATE"),
|
wm_state_atom, wm_state_atom, 32, 2, data);
|
||||||
xutil_intern_atom(globalconf.connection, "WM_STATE"), 32,
|
|
||||||
2, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get a window state (WM_STATE).
|
/** Get a window state (WM_STATE).
|
||||||
|
@ -58,7 +60,10 @@ window_getstate(xcb_window_t w)
|
||||||
long result = -1;
|
long result = -1;
|
||||||
unsigned char *p = NULL;
|
unsigned char *p = NULL;
|
||||||
xcb_get_property_cookie_t prop_c;
|
xcb_get_property_cookie_t prop_c;
|
||||||
xcb_atom_t wm_state_atom = xutil_intern_atom(globalconf.connection, "WM_STATE");
|
xcb_atom_t wm_state_atom = xutil_intern_atom_reply(globalconf.connection, &globalconf.atoms,
|
||||||
|
xutil_intern_atom(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
"WM_STATE"));
|
||||||
xcb_get_property_reply_t *prop_r;
|
xcb_get_property_reply_t *prop_r;
|
||||||
|
|
||||||
prop_c = xcb_get_property_unchecked(globalconf.connection, false, w,
|
prop_c = xcb_get_property_unchecked(globalconf.connection, false, w,
|
||||||
|
@ -224,17 +229,21 @@ void
|
||||||
window_settrans(xcb_window_t win, double opacity)
|
window_settrans(xcb_window_t win, double opacity)
|
||||||
{
|
{
|
||||||
unsigned int real_opacity = 0xffffffff;
|
unsigned int real_opacity = 0xffffffff;
|
||||||
|
const xcb_atom_t wopacity_atom = xutil_intern_atom_reply(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
xutil_intern_atom(globalconf.connection,
|
||||||
|
&globalconf.atoms,
|
||||||
|
"_NET_WM_WINDOW_OPACITY"));
|
||||||
|
|
||||||
if(opacity >= 0 && opacity <= 1)
|
if(opacity >= 0 && opacity <= 1)
|
||||||
{
|
{
|
||||||
real_opacity = opacity * 0xffffffff;
|
real_opacity = opacity * 0xffffffff;
|
||||||
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, win,
|
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, win,
|
||||||
xutil_intern_atom(globalconf.connection, "_NET_WM_WINDOW_OPACITY"),
|
wopacity_atom, CARDINAL, 32, 1L, &real_opacity);
|
||||||
CARDINAL, 32, 1L, &real_opacity);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
xcb_delete_property(globalconf.connection, win,
|
xcb_delete_property(globalconf.connection, win,
|
||||||
xutil_intern_atom(globalconf.connection, "_NET_WM_WINDOW_OPACITY"));
|
wopacity_atom);
|
||||||
}
|
}
|
||||||
|
|
||||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
||||||
|
|
Loading…
Reference in New Issue