2 * property.c - property handlers
4 * Copyright © 2008 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include <xcb/xcb_atom.h>
28 #include "common/atoms.h"
30 extern awesome_t globalconf
;
34 property_update_wm_transient_for(client_t
*c
, xcb_get_property_reply_t
*reply
)
40 if(!xcb_get_wm_transient_for_from_reply(&trans
, reply
))
45 if(!xcb_get_wm_transient_for_reply(globalconf
.connection
,
46 xcb_get_wm_transient_for_unchecked(globalconf
.connection
,
52 c
->type
= WINDOW_TYPE_DIALOG
;
53 c
->transient_for
= client_getbywin(trans
);
57 property_handle_wm_transient_for(void *data
,
58 xcb_connection_t
*connection
,
62 xcb_get_property_reply_t
*reply
)
64 client_t
*c
= client_getbywin(window
);
67 property_update_wm_transient_for(c
, reply
);
73 /** Update leader hint of a client.
74 * \param c The client.
75 * \param reply (Optional) An existing reply.
78 property_update_wm_client_leader(client_t
*c
, xcb_get_property_reply_t
*reply
)
80 xcb_get_property_cookie_t client_leader_q
;
82 bool no_reply
= !reply
;
86 client_leader_q
= xcb_get_property_unchecked(globalconf
.connection
, false, c
->win
,
87 WM_CLIENT_LEADER
, WINDOW
, 0, 32);
89 reply
= xcb_get_property_reply(globalconf
.connection
, client_leader_q
, NULL
);
92 if(reply
&& reply
->value_len
&& (data
= xcb_get_property_value(reply
)))
93 c
->leader_win
= *(xcb_window_t
*) data
;
95 /* Only free when we created a reply ourselves. */
101 property_handle_wm_client_leader(void *data
,
102 xcb_connection_t
*connection
,
106 xcb_get_property_reply_t
*reply
)
108 client_t
*c
= client_getbywin(window
);
111 property_update_wm_client_leader(c
, reply
);
116 /** Update the size hints of a client.
117 * \param c The client.
120 property_update_wm_normal_hints(client_t
*c
, xcb_get_property_reply_t
*reply
)
124 if(!xcb_get_wm_size_hints_from_reply(&c
->size_hints
, reply
))
129 if(!xcb_get_wm_normal_hints_reply(globalconf
.connection
,
130 xcb_get_wm_normal_hints_unchecked(globalconf
.connection
,
132 &c
->size_hints
, NULL
))
138 property_handle_wm_normal_hints(void *data
,
139 xcb_connection_t
*connection
,
143 xcb_get_property_reply_t
*reply
)
145 client_t
*c
= client_getbywin(window
);
148 property_update_wm_normal_hints(c
, reply
);
153 /** Update the WM hints of a client.
154 * \param c The client.
157 property_update_wm_hints(client_t
*c
, xcb_get_property_reply_t
*reply
)
163 if(!xcb_get_wm_hints_from_reply(&wmh
, reply
))
168 if(!xcb_get_wm_hints_reply(globalconf
.connection
,
169 xcb_get_wm_hints_unchecked(globalconf
.connection
, c
->win
),
174 bool isurgent
= xcb_wm_hints_get_urgency(&wmh
);
175 if(isurgent
!= c
->isurgent
)
177 c
->isurgent
= isurgent
;
179 hooks_property(c
, "urgent");
181 if(wmh
.flags
& XCB_WM_HINT_STATE
&&
182 wmh
.initial_state
== XCB_WM_STATE_WITHDRAWN
)
183 client_setborder(c
, 0);
185 if(wmh
.flags
& XCB_WM_HINT_INPUT
)
186 c
->nofocus
= !wmh
.input
;
188 if(wmh
.flags
& XCB_WM_HINT_WINDOW_GROUP
)
189 c
->group_win
= wmh
.window_group
;
193 property_handle_wm_hints(void *data
,
194 xcb_connection_t
*connection
,
198 xcb_get_property_reply_t
*reply
)
200 client_t
*c
= client_getbywin(window
);
203 property_update_wm_hints(c
, reply
);
208 /** Update client name attribute with its new title.
209 * \param c The client.
210 * \param Return true if it has been updated.
213 property_update_wm_name(client_t
*c
)
218 if(!xutil_text_prop_get(globalconf
.connection
, c
->win
, _NET_WM_NAME
, &name
, &len
))
219 if(!xutil_text_prop_get(globalconf
.connection
, c
->win
, WM_NAME
, &name
, &len
))
224 /* if no conversion needed, just point to name */
225 if(draw_iso2utf8(name
, len
, &utf8
, NULL
))
231 hooks_property(c
, "name");
234 /** Update client icon name attribute with its new title.
235 * \param c The client.
236 * \param Return true if it has been updated.
239 property_update_wm_icon_name(client_t
*c
)
244 if(!xutil_text_prop_get(globalconf
.connection
, c
->win
, _NET_WM_ICON_NAME
, &name
, &len
))
245 if(!xutil_text_prop_get(globalconf
.connection
, c
->win
, WM_ICON_NAME
, &name
, &len
))
248 p_delete(&c
->icon_name
);
250 if(draw_iso2utf8(name
, len
, &utf8
, NULL
))
256 hooks_property(c
, "icon_name");
260 property_handle_wm_name(void *data
,
261 xcb_connection_t
*connection
,
265 xcb_get_property_reply_t
*reply
)
267 client_t
*c
= client_getbywin(window
);
270 property_update_wm_name(c
);
276 property_handle_wm_icon_name(void *data
,
277 xcb_connection_t
*connection
,
281 xcb_get_property_reply_t
*reply
)
283 client_t
*c
= client_getbywin(window
);
286 property_update_wm_icon_name(c
);
292 property_handle_net_wm_strut_partial(void *data
,
293 xcb_connection_t
*connection
,
297 xcb_get_property_reply_t
*reply
)
299 client_t
*c
= client_getbywin(window
);
302 ewmh_client_strut_update(c
, reply
);
308 property_handle_net_wm_icon(void *data
,
309 xcb_connection_t
*connection
,
313 xcb_get_property_reply_t
*reply
)
315 client_t
*c
= client_getbywin(window
);
320 image_unref(&c
->icon
);
321 icon
= ewmh_window_icon_from_reply(reply
);
322 c
->icon
= icon
? image_ref(&icon
) : NULL
;
325 hooks_property(c
, "icon");
331 /** The property notify event handler.
332 * \param data currently unused.
333 * \param connection The connection to the X server.
334 * \param ev The event.
337 property_handle_xembed_info(void *data
__attribute__ ((unused
)),
338 xcb_connection_t
*connection
,
342 xcb_get_property_reply_t
*reply
)
344 xembed_window_t
*emwin
= xembed_getbywin(&globalconf
.embedded
, window
);
347 xembed_property_update(connection
, emwin
, reply
);
353 property_handle_xrootpmap_id(void *data
__attribute__ ((unused
)),
354 xcb_connection_t
*connection
,
358 xcb_get_property_reply_t
*reply
)
360 if(globalconf
.xinerama_is_active
)
361 for(int screen
= 0; screen
< globalconf
.nscreen
; screen
++)
363 wibox_array_t
*w
= &globalconf
.screens
[screen
].wiboxes
;
364 for(int i
= 0; i
< w
->len
; i
++)
365 w
->tab
[i
]->need_update
= true;
369 int screen
= xutil_root2screen(connection
, window
);
370 wibox_array_t
*w
= &globalconf
.screens
[screen
].wiboxes
;
371 for(int i
= 0; i
< w
->len
; i
++)
372 w
->tab
[i
]->need_update
= true;
378 void a_xcb_set_property_handlers(void)
381 xcb_property_handlers_init(&globalconf
.prophs
, &globalconf
.evenths
);
384 xcb_property_set_handler(&globalconf
.prophs
, _XEMBED_INFO
, UINT_MAX
,
385 property_handle_xembed_info
, NULL
);
388 xcb_property_set_handler(&globalconf
.prophs
, WM_TRANSIENT_FOR
, UINT_MAX
,
389 property_handle_wm_transient_for
, NULL
);
390 xcb_property_set_handler(&globalconf
.prophs
, WM_CLIENT_LEADER
, UINT_MAX
,
391 property_handle_wm_client_leader
, NULL
);
392 xcb_property_set_handler(&globalconf
.prophs
, WM_NORMAL_HINTS
, UINT_MAX
,
393 property_handle_wm_normal_hints
, NULL
);
394 xcb_property_set_handler(&globalconf
.prophs
, WM_HINTS
, UINT_MAX
,
395 property_handle_wm_hints
, NULL
);
396 xcb_property_set_handler(&globalconf
.prophs
, WM_NAME
, UINT_MAX
,
397 property_handle_wm_name
, NULL
);
398 xcb_property_set_handler(&globalconf
.prophs
, WM_ICON_NAME
, UINT_MAX
,
399 property_handle_wm_icon_name
, NULL
);
402 xcb_property_set_handler(&globalconf
.prophs
, _NET_WM_NAME
, UINT_MAX
,
403 property_handle_wm_name
, NULL
);
404 xcb_property_set_handler(&globalconf
.prophs
, _NET_WM_ICON_NAME
, UINT_MAX
,
405 property_handle_wm_icon_name
, NULL
);
406 xcb_property_set_handler(&globalconf
.prophs
, _NET_WM_STRUT_PARTIAL
, UINT_MAX
,
407 property_handle_net_wm_strut_partial
, NULL
);
408 xcb_property_set_handler(&globalconf
.prophs
, _NET_WM_ICON
, UINT_MAX
,
409 property_handle_net_wm_icon
, NULL
);
411 /* background change */
412 xcb_property_set_handler(&globalconf
.prophs
, _XROOTPMAP_ID
, 1,
413 property_handle_xrootpmap_id
, NULL
);
416 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80