Overhaul property handling

For each property we handle, there is now a function which sends a request and
returns the cookie and a second function that takes the cookie and saves the
result in the client_t struct. This should make it possible to improve our
latency later on.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2010-08-09 12:47:29 +02:00
parent 0eb9363533
commit 2f20494676
3 changed files with 142 additions and 160 deletions

View File

@ -525,14 +525,14 @@ HANDLE_GEOM(height)
luaA_object_emit_signal(globalconf.L, -1, "property::size_hints_honor", 0); luaA_object_emit_signal(globalconf.L, -1, "property::size_hints_honor", 0);
/* update hints */ /* update hints */
property_update_wm_normal_hints(c, NULL); property_update_wm_normal_hints(c, property_get_wm_normal_hints(c));
property_update_wm_hints(c, NULL); property_update_wm_hints(c, property_get_wm_hints(c));
property_update_wm_transient_for(c, NULL); property_update_wm_transient_for(c, property_get_wm_transient_for(c));
property_update_wm_client_leader(c, NULL); property_update_wm_client_leader(c, property_get_wm_client_leader(c));
property_update_wm_client_machine(c, NULL); property_update_wm_client_machine(c, property_get_wm_client_machine(c));
property_update_wm_window_role(c, NULL); property_update_wm_window_role(c, property_get_wm_window_role(c));
property_update_net_wm_pid(c, NULL); property_update_net_wm_pid(c, property_get_net_wm_pid(c));
property_update_net_wm_icon(c, NULL); property_update_net_wm_icon(c, property_get_net_wm_icon(c));
window_set_opacity(globalconf.L, -1, xwindow_get_opacity(c->window)); window_set_opacity(globalconf.L, -1, xwindow_get_opacity(c->window));
@ -543,12 +543,12 @@ HANDLE_GEOM(height)
client_raise(c); client_raise(c);
/* update window title */ /* update window title */
property_update_wm_name(c, NULL); property_update_wm_name(c, property_get_wm_name(c));
property_update_net_wm_name(c, NULL); property_update_net_wm_name(c, property_get_net_wm_name(c));
property_update_wm_icon_name(c, NULL); property_update_wm_icon_name(c, property_get_wm_icon_name(c));
property_update_net_wm_icon_name(c, NULL); property_update_net_wm_icon_name(c, property_get_net_wm_icon_name(c));
property_update_wm_class(c, NULL); property_update_wm_class(c, property_get_wm_class(c));
property_update_wm_protocols(c, NULL); property_update_wm_protocols(c, property_get_wm_protocols(c));
/* update strut */ /* update strut */
ewmh_process_client_strut(c, NULL); ewmh_process_client_strut(c, NULL);

View File

@ -31,25 +31,26 @@
#include "common/atoms.h" #include "common/atoms.h"
#include "common/xutil.h" #include "common/xutil.h"
#define HANDLE_TEXT_PROPERTY(funcname, atom, setfunc) \ #define HANDLE_TEXT_PROPERTY(funcname, atom, setfunc) \
void \ xcb_get_property_cookie_t \
property_update_##funcname(client_t *c, xcb_get_property_reply_t *reply) \ property_get_##funcname(client_t *c) \
{ \ { \
bool no_reply = !reply; \ return xcb_get_property(globalconf.connection, \
if(no_reply) \
reply = xcb_get_property_reply(globalconf.connection, \
xcb_get_property(globalconf.connection, \
false, \ false, \
c->window, \ c->window, \
atom, \ atom, \
XCB_GET_PROPERTY_TYPE_ANY, \ XCB_GET_PROPERTY_TYPE_ANY, \
0, \ 0, \
UINT_MAX), NULL); \ UINT_MAX); \
} \
void \
property_update_##funcname(client_t *c, xcb_get_property_cookie_t cookie) \
{ \
xcb_get_property_reply_t * reply = \
xcb_get_property_reply(globalconf.connection, cookie, NULL); \
luaA_object_push(globalconf.L, c); \ luaA_object_push(globalconf.L, c); \
setfunc(globalconf.L, -1, xutil_get_text_property_from_reply(reply)); \ setfunc(globalconf.L, -1, xutil_get_text_property_from_reply(reply)); \
lua_pop(globalconf.L, 1); \ lua_pop(globalconf.L, 1); \
if(no_reply) \
p_delete(&reply); \ p_delete(&reply); \
} \ } \
static int \ static int \
@ -60,7 +61,7 @@
{ \ { \
client_t *c = client_getbywin(window); \ client_t *c = client_getbywin(window); \
if(c) \ if(c) \
property_update_##funcname(c, reply); \ property_update_##funcname(c, property_get_##funcname(c));\
return 0; \ return 0; \
} }
@ -83,7 +84,7 @@ HANDLE_TEXT_PROPERTY(wm_window_role, WM_WINDOW_ROLE, client_set_role)
{ \ { \
client_t *c = client_getbywin(window); \ client_t *c = client_getbywin(window); \
if(c) \ if(c) \
property_update_##name(c, reply); \ property_update_##name(c, property_get_##name(c));\
return 0; \ return 0; \
} }
@ -98,24 +99,21 @@ HANDLE_PROPERTY(net_wm_pid)
#undef HANDLE_PROPERTY #undef HANDLE_PROPERTY
xcb_get_property_cookie_t
property_get_wm_transient_for(client_t *c)
{
return xcb_get_wm_transient_for_unchecked(globalconf.connection, c->window);
}
void void
property_update_wm_transient_for(client_t *c, xcb_get_property_reply_t *reply) property_update_wm_transient_for(client_t *c, xcb_get_property_cookie_t cookie)
{ {
xcb_window_t trans; xcb_window_t trans;
if(reply)
{
if(!xcb_get_wm_transient_for_from_reply(&trans, reply))
return;
}
else
{
if(!xcb_get_wm_transient_for_reply(globalconf.connection, if(!xcb_get_wm_transient_for_reply(globalconf.connection,
xcb_get_wm_transient_for_unchecked(globalconf.connection, cookie,
c->window),
&trans, NULL)) &trans, NULL))
return; return;
}
luaA_object_push(globalconf.L, c); luaA_object_push(globalconf.L, c);
client_set_type(globalconf.L, -1, WINDOW_TYPE_DIALOG); client_set_type(globalconf.L, -1, WINDOW_TYPE_DIALOG);
@ -124,76 +122,68 @@ property_update_wm_transient_for(client_t *c, xcb_get_property_reply_t *reply)
lua_pop(globalconf.L, 1); lua_pop(globalconf.L, 1);
} }
xcb_get_property_cookie_t
property_get_wm_client_leader(client_t *c)
{
return xcb_get_property_unchecked(globalconf.connection, false, c->window,
WM_CLIENT_LEADER, XCB_ATOM_WINDOW, 1, 32);
}
/** Update leader hint of a client. /** Update leader hint of a client.
* \param c The client. * \param c The client.
* \param reply (Optional) An existing reply. * \param cookie Cookie returned by property_get_wm_client_leader.
*/ */
void void
property_update_wm_client_leader(client_t *c, xcb_get_property_reply_t *reply) property_update_wm_client_leader(client_t *c, xcb_get_property_cookie_t cookie)
{ {
xcb_get_property_cookie_t client_leader_q; xcb_get_property_reply_t *reply;
void *data; void *data;
bool no_reply = !reply;
if(no_reply) reply = xcb_get_property_reply(globalconf.connection, cookie, NULL);
{
client_leader_q = xcb_get_property_unchecked(globalconf.connection, false, c->window,
WM_CLIENT_LEADER, XCB_ATOM_WINDOW, 1, 32);
reply = xcb_get_property_reply(globalconf.connection, client_leader_q, NULL);
}
if(reply && reply->value_len && (data = xcb_get_property_value(reply))) if(reply && reply->value_len && (data = xcb_get_property_value(reply)))
c->leader_window = *(xcb_window_t *) data; c->leader_window = *(xcb_window_t *) data;
/* Only free when we created a reply ourselves. */
if(no_reply)
p_delete(&reply); p_delete(&reply);
} }
xcb_get_property_cookie_t
property_get_wm_normal_hints(client_t *c)
{
return xcb_get_wm_normal_hints_unchecked(globalconf.connection, c->window);
}
/** Update the size hints of a client. /** Update the size hints of a client.
* \param c The client. * \param c The client.
* \param reply (Optional) An existing reply. * \param cookie Cookie returned by property_get_wm_normal_hints.
*/ */
void void
property_update_wm_normal_hints(client_t *c, xcb_get_property_reply_t *reply) property_update_wm_normal_hints(client_t *c, xcb_get_property_cookie_t cookie)
{ {
if(reply) xcb_get_wm_normal_hints_reply(globalconf.connection,
{ cookie,
if(!xcb_get_wm_size_hints_from_reply(&c->size_hints, reply)) &c->size_hints, NULL);
return;
} }
else
xcb_get_property_cookie_t
property_get_wm_hints(client_t *c)
{ {
if(!xcb_get_wm_normal_hints_reply(globalconf.connection, return xcb_get_wm_hints_unchecked(globalconf.connection, c->window);
xcb_get_wm_normal_hints_unchecked(globalconf.connection,
c->window),
&c->size_hints, NULL))
return;
}
} }
/** Update the WM hints of a client. /** Update the WM hints of a client.
* \param c The client. * \param c The client.
* \param reply (Optional) An existing reply. * \param cookie Cookie returned by property_get_wm_hints.
*/ */
void void
property_update_wm_hints(client_t *c, xcb_get_property_reply_t *reply) property_update_wm_hints(client_t *c, xcb_get_property_cookie_t cookie)
{ {
xcb_wm_hints_t wmh; xcb_wm_hints_t wmh;
if(reply)
{
if(!xcb_get_wm_hints_from_reply(&wmh, reply))
return;
}
else
{
if(!xcb_get_wm_hints_reply(globalconf.connection, if(!xcb_get_wm_hints_reply(globalconf.connection,
xcb_get_wm_hints_unchecked(globalconf.connection, c->window), cookie,
&wmh, NULL)) &wmh, NULL))
return; return;
}
luaA_object_push(globalconf.L, c); luaA_object_push(globalconf.L, c);
client_set_urgent(globalconf.L, -1, xcb_wm_hints_get_urgency(&wmh)); client_set_urgent(globalconf.L, -1, xcb_wm_hints_get_urgency(&wmh));
@ -207,34 +197,30 @@ property_update_wm_hints(client_t *c, xcb_get_property_reply_t *reply)
lua_pop(globalconf.L, 1); lua_pop(globalconf.L, 1);
} }
xcb_get_property_cookie_t
property_get_wm_class(client_t *c)
{
return xcb_get_wm_class_unchecked(globalconf.connection, c->window);
}
/** Update WM_CLASS of a client. /** Update WM_CLASS of a client.
* \param c The client. * \param c The client.
* \param reply The reply to get property request, or NULL if none. * \param cookie Cookie returned by property_get_wm_class.
*/ */
void void
property_update_wm_class(client_t *c, xcb_get_property_reply_t *reply) property_update_wm_class(client_t *c, xcb_get_property_cookie_t cookie)
{ {
xcb_get_wm_class_reply_t hint; xcb_get_wm_class_reply_t hint;
if(reply)
{
if(!xcb_get_wm_class_from_reply(&hint, reply))
return;
}
else
{
if(!xcb_get_wm_class_reply(globalconf.connection, if(!xcb_get_wm_class_reply(globalconf.connection,
xcb_get_wm_class_unchecked(globalconf.connection, c->window), cookie,
&hint, NULL)) &hint, NULL))
return; return;
}
luaA_object_push(globalconf.L, c); luaA_object_push(globalconf.L, c);
client_set_class_instance(globalconf.L, -1, hint.class_name, hint.instance_name); client_set_class_instance(globalconf.L, -1, hint.class_name, hint.instance_name);
lua_pop(globalconf.L, 1); lua_pop(globalconf.L, 1);
/* only delete reply if we get it ourselves */
if(!reply)
xcb_get_wm_class_reply_wipe(&hint); xcb_get_wm_class_reply_wipe(&hint);
} }
@ -252,37 +238,37 @@ property_handle_net_wm_strut_partial(uint8_t state,
return 0; return 0;
} }
xcb_get_property_cookie_t
property_get_net_wm_icon(client_t *c)
{
return ewmh_window_icon_get_unchecked(c->window);
}
void void
property_update_net_wm_icon(client_t *c, property_update_net_wm_icon(client_t *c, xcb_get_property_cookie_t cookie)
xcb_get_property_reply_t *reply)
{ {
luaA_object_push(globalconf.L, c); luaA_object_push(globalconf.L, c);
if(reply) if(ewmh_window_icon_get_reply(cookie))
{
if(ewmh_window_icon_from_reply(reply))
client_set_icon(globalconf.L, -2, -1);
}
else if(ewmh_window_icon_get_reply(ewmh_window_icon_get_unchecked(c->window)))
client_set_icon(globalconf.L, -2, -1); client_set_icon(globalconf.L, -2, -1);
/* remove client */ /* remove client */
lua_pop(globalconf.L, 1); lua_pop(globalconf.L, 1);
} }
void xcb_get_property_cookie_t
property_update_net_wm_pid(client_t *c, property_get_net_wm_pid(client_t *c)
xcb_get_property_reply_t *reply)
{ {
bool no_reply = !reply; return xcb_get_property_unchecked(globalconf.connection, false, c->window, _NET_WM_PID, XCB_ATOM_CARDINAL, 0L, 1L);
if(no_reply)
{
xcb_get_property_cookie_t prop_c =
xcb_get_property_unchecked(globalconf.connection, false, c->window, _NET_WM_PID, XCB_ATOM_CARDINAL, 0L, 1L);
reply = xcb_get_property_reply(globalconf.connection, prop_c, NULL);
} }
void
property_update_net_wm_pid(client_t *c, xcb_get_property_cookie_t cookie)
{
xcb_get_property_reply_t *reply;
reply = xcb_get_property_reply(globalconf.connection, cookie, NULL);
if(reply && reply->value_len) if(reply && reply->value_len)
{ {
uint32_t *rdata = xcb_get_property_value(reply); uint32_t *rdata = xcb_get_property_value(reply);
@ -294,39 +280,29 @@ property_update_net_wm_pid(client_t *c,
} }
} }
if(no_reply)
p_delete(&reply); p_delete(&reply);
} }
xcb_get_property_cookie_t
property_get_wm_protocols(client_t *c)
{
return xcb_get_wm_protocols_unchecked(globalconf.connection, c->window, WM_PROTOCOLS);
}
/** Update the list of supported protocols for a client. /** Update the list of supported protocols for a client.
* \param c The client. * \param c The client.
* \param reply The xcb property reply. * \param cookie Cookie from property_get_wm_protocols.
*/ */
void void
property_update_wm_protocols(client_t *c, xcb_get_property_reply_t *reply) property_update_wm_protocols(client_t *c, xcb_get_property_cookie_t cookie)
{ {
xcb_get_wm_protocols_reply_t protocols; xcb_get_wm_protocols_reply_t protocols;
xcb_get_property_reply_t *reply_copy;
if(reply)
{
reply_copy = p_dup(reply, 1);
if(!xcb_get_wm_protocols_from_reply(reply_copy, &protocols))
{
p_delete(&reply_copy);
return;
}
}
else
{
/* If this fails for any reason, we still got the old value */ /* If this fails for any reason, we still got the old value */
if(!xcb_get_wm_protocols_reply(globalconf.connection, if(!xcb_get_wm_protocols_reply(globalconf.connection,
xcb_get_wm_protocols_unchecked(globalconf.connection, cookie,
c->window, WM_PROTOCOLS),
&protocols, NULL)) &protocols, NULL))
return; return;
}
xcb_get_wm_protocols_reply_wipe(&c->protocols); xcb_get_wm_protocols_reply_wipe(&c->protocols);
memcpy(&c->protocols, &protocols, sizeof(protocols)); memcpy(&c->protocols, &protocols, sizeof(protocols));

View File

@ -24,20 +24,26 @@
#include "globalconf.h" #include "globalconf.h"
void property_update_wm_transient_for(client_t *, xcb_get_property_reply_t *); #define PROPERTY(funcname) \
void property_update_wm_client_leader(client_t *c, xcb_get_property_reply_t *); xcb_get_property_cookie_t property_get_##funcname(client_t *c); \
void property_update_wm_normal_hints(client_t *, xcb_get_property_reply_t *); void property_update_##funcname(client_t *c, xcb_get_property_cookie_t cookie)
void property_update_wm_hints(client_t *, xcb_get_property_reply_t *);
void property_update_wm_class(client_t *, xcb_get_property_reply_t *); PROPERTY(wm_name);
void property_update_wm_name(client_t *, xcb_get_property_reply_t *); PROPERTY(net_wm_name);
void property_update_net_wm_name(client_t *, xcb_get_property_reply_t *); PROPERTY(wm_icon_name);
void property_update_wm_icon_name(client_t *, xcb_get_property_reply_t *); PROPERTY(net_wm_icon_name);
void property_update_net_wm_icon_name(client_t *, xcb_get_property_reply_t *); PROPERTY(wm_client_machine);
void property_update_wm_protocols(client_t *, xcb_get_property_reply_t *); PROPERTY(wm_window_role);
void property_update_wm_client_machine(client_t *, xcb_get_property_reply_t *); PROPERTY(wm_transient_for);
void property_update_wm_window_role(client_t *, xcb_get_property_reply_t *); PROPERTY(wm_client_leader);
void property_update_net_wm_pid(client_t *, xcb_get_property_reply_t *); PROPERTY(wm_normal_hints);
void property_update_net_wm_icon(client_t *, xcb_get_property_reply_t *); PROPERTY(wm_hints);
PROPERTY(wm_class);
PROPERTY(wm_protocols);
PROPERTY(net_wm_pid);
PROPERTY(net_wm_icon);
#undef PROPERTY
void property_handle_propertynotify(xcb_property_notify_event_t *ev); void property_handle_propertynotify(xcb_property_notify_event_t *ev);