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
);
66 if(c
&& !client_isfloating(c
))
67 property_update_wm_transient_for(c
, reply
);
72 /** Update the size hints of a client.
73 * \param c The client.
76 property_update_wm_normal_hints(client_t
*c
, xcb_get_property_reply_t
*reply
)
80 if(!xcb_get_wm_size_hints_from_reply(&c
->size_hints
, reply
))
85 if(!xcb_get_wm_normal_hints_reply(globalconf
.connection
,
86 xcb_get_wm_normal_hints_unchecked(globalconf
.connection
,
88 &c
->size_hints
, NULL
))
92 if((c
->size_hints
.flags
& XCB_SIZE_HINT_P_SIZE
))
94 c
->basew
= c
->size_hints
.base_width
;
95 c
->baseh
= c
->size_hints
.base_height
;
97 else if((c
->size_hints
.flags
& XCB_SIZE_HINT_P_MIN_SIZE
))
99 c
->basew
= c
->size_hints
.min_width
;
100 c
->baseh
= c
->size_hints
.min_height
;
103 c
->basew
= c
->baseh
= 0;
105 if((c
->size_hints
.flags
& XCB_SIZE_HINT_P_RESIZE_INC
))
107 c
->incw
= c
->size_hints
.width_inc
;
108 c
->inch
= c
->size_hints
.height_inc
;
111 c
->incw
= c
->inch
= 0;
113 if((c
->size_hints
.flags
& XCB_SIZE_HINT_P_MAX_SIZE
))
115 c
->maxw
= c
->size_hints
.max_width
;
116 c
->maxh
= c
->size_hints
.max_height
;
119 c
->maxw
= c
->maxh
= 0;
121 if((c
->size_hints
.flags
& XCB_SIZE_HINT_P_MIN_SIZE
))
123 c
->minw
= c
->size_hints
.min_width
;
124 c
->minh
= c
->size_hints
.min_height
;
126 else if((c
->size_hints
.flags
& XCB_SIZE_HINT_BASE_SIZE
))
128 c
->minw
= c
->size_hints
.base_width
;
129 c
->minh
= c
->size_hints
.base_height
;
132 c
->minw
= c
->minh
= 0;
134 if((c
->size_hints
.flags
& XCB_SIZE_HINT_P_ASPECT
))
136 c
->minax
= c
->size_hints
.min_aspect_num
;
137 c
->minay
= c
->size_hints
.min_aspect_den
;
138 c
->maxax
= c
->size_hints
.max_aspect_num
;
139 c
->maxay
= c
->size_hints
.max_aspect_den
;
142 c
->minax
= c
->maxax
= c
->minay
= c
->maxay
= 0;
144 c
->hassizehints
= !(!c
->basew
&& !c
->baseh
&& !c
->incw
&& !c
->inch
145 && !c
->maxw
&& !c
->maxh
&& !c
->minw
&& !c
->minh
146 && !c
->minax
&& !c
->maxax
&& !c
->minax
&& !c
->minay
);
150 property_handle_wm_normal_hints(void *data
,
151 xcb_connection_t
*connection
,
155 xcb_get_property_reply_t
*reply
)
157 client_t
*c
= client_getbywin(window
);
160 property_update_wm_normal_hints(c
, reply
);
165 /** Update the WM hints of a client.
166 * \param c The client.
169 property_update_wm_hints(client_t
*c
, xcb_get_property_reply_t
*reply
)
175 if(!xcb_get_wm_hints_from_reply(&wmh
, reply
))
180 if(!xcb_get_wm_hints_reply(globalconf
.connection
,
181 xcb_get_wm_hints_unchecked(globalconf
.connection
, c
->win
),
186 bool isurgent
= xcb_wm_hints_get_urgency(&wmh
);
187 if(isurgent
!= c
->isurgent
)
189 c
->isurgent
= isurgent
;
192 hooks_property(c
, "urgent");
194 widget_invalidate_cache(c
->screen
, WIDGET_CACHE_CLIENTS
);
196 if(wmh
.flags
& XCB_WM_HINT_STATE
&&
197 wmh
.initial_state
== XCB_WM_STATE_WITHDRAWN
)
198 client_setborder(c
, 0);
200 if(wmh
.flags
& XCB_WM_HINT_INPUT
)
201 c
->nofocus
= !wmh
.input
;
205 property_handle_wm_hints(void *data
,
206 xcb_connection_t
*connection
,
210 xcb_get_property_reply_t
*reply
)
212 client_t
*c
= client_getbywin(window
);
215 property_update_wm_hints(c
, reply
);
220 /** Update client name attribute with its new title.
221 * \param c The client.
222 * \param Return true if it has been updated.
225 property_update_wm_name(client_t
*c
)
230 if(!xutil_text_prop_get(globalconf
.connection
, c
->win
, _NET_WM_NAME
, &name
, &len
))
231 if(!xutil_text_prop_get(globalconf
.connection
, c
->win
, WM_NAME
, &name
, &len
))
236 if((utf8
= draw_iso2utf8(name
, len
)))
242 hooks_property(c
, "name");
244 widget_invalidate_cache(c
->screen
, WIDGET_CACHE_CLIENTS
);
248 property_handle_wm_name(void *data
,
249 xcb_connection_t
*connection
,
253 xcb_get_property_reply_t
*reply
)
255 client_t
*c
= client_getbywin(window
);
258 property_update_wm_name(c
);
264 property_handle_net_wm_strut_partial(void *data
,
265 xcb_connection_t
*connection
,
269 xcb_get_property_reply_t
*reply
)
271 client_t
*c
= client_getbywin(window
);
274 ewmh_client_strut_update(c
, reply
);
280 property_handle_net_wm_icon(void *data
,
281 xcb_connection_t
*connection
,
285 xcb_get_property_reply_t
*reply
)
287 client_t
*c
= client_getbywin(window
);
292 image_unref(&c
->icon
);
293 widget_invalidate_cache(c
->screen
, WIDGET_CACHE_CLIENTS
);
294 icon
= ewmh_window_icon_from_reply(reply
);
295 c
->icon
= icon
? image_ref(&icon
) : NULL
;
298 hooks_property(c
, "icon");
304 /** The property notify event handler.
305 * \param data currently unused.
306 * \param connection The connection to the X server.
307 * \param ev The event.
310 property_handle_xembed_info(void *data
__attribute__ ((unused
)),
311 xcb_connection_t
*connection
,
315 xcb_get_property_reply_t
*reply
)
317 xembed_window_t
*emwin
= xembed_getbywin(globalconf
.embedded
, window
);
320 xembed_property_update(connection
, emwin
, reply
);
326 property_handle_xrootpmap_id(void *data
__attribute__ ((unused
)),
327 xcb_connection_t
*connection
,
331 xcb_get_property_reply_t
*reply
)
333 if(globalconf
.xinerama_is_active
)
334 for(int screen
= 0; screen
< globalconf
.nscreen
; screen
++)
336 wibox_array_t
*w
= &globalconf
.screens
[screen
].wiboxes
;
337 for(int i
= 0; i
< w
->len
; i
++)
338 w
->tab
[i
]->need_update
= true;
342 int screen
= xutil_root2screen(connection
, window
);
343 wibox_array_t
*w
= &globalconf
.screens
[screen
].wiboxes
;
344 for(int i
= 0; i
< w
->len
; i
++)
345 w
->tab
[i
]->need_update
= true;
351 void a_xcb_set_property_handlers(void)
354 xcb_property_handlers_init(&globalconf
.prophs
, &globalconf
.evenths
);
357 xcb_property_set_handler(&globalconf
.prophs
, _XEMBED_INFO
, UINT_MAX
,
358 property_handle_xembed_info
, NULL
);
361 xcb_property_set_handler(&globalconf
.prophs
, WM_TRANSIENT_FOR
, UINT_MAX
,
362 property_handle_wm_transient_for
, NULL
);
363 xcb_property_set_handler(&globalconf
.prophs
, WM_NORMAL_HINTS
, UINT_MAX
,
364 property_handle_wm_normal_hints
, NULL
);
365 xcb_property_set_handler(&globalconf
.prophs
, WM_HINTS
, UINT_MAX
,
366 property_handle_wm_hints
, NULL
);
367 xcb_property_set_handler(&globalconf
.prophs
, WM_NAME
, UINT_MAX
,
368 property_handle_wm_name
, NULL
);
371 xcb_property_set_handler(&globalconf
.prophs
, _NET_WM_NAME
, UINT_MAX
,
372 property_handle_wm_name
, NULL
);
373 xcb_property_set_handler(&globalconf
.prophs
, _NET_WM_STRUT_PARTIAL
, UINT_MAX
,
374 property_handle_net_wm_strut_partial
, NULL
);
375 xcb_property_set_handler(&globalconf
.prophs
, _NET_WM_ICON
, UINT_MAX
,
376 property_handle_net_wm_icon
, NULL
);
378 /* background change */
379 xcb_property_set_handler(&globalconf
.prophs
, _XROOTPMAP_ID
, 1,
380 property_handle_xrootpmap_id
, NULL
);
383 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80