30 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
31 DLOG(
"WM_CLASS not set.\n");
39 const size_t prop_length = xcb_get_property_value_length(prop);
40 char *new_class = xcb_get_property_value(prop);
41 const size_t class_class_index = strnlen(new_class, prop_length) + 1;
47 if (class_class_index < prop_length)
48 win->
class_class =
sstrndup(new_class + class_class_index, prop_length - class_class_index);
51 LOG(
"WM_CLASS changed to %s (instance), %s (class)\n",
63 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
64 DLOG(
"_NET_WM_NAME not specified, not changing\n");
72 const int len = xcb_get_property_value_length(prop);
73 char *name =
sstrndup(xcb_get_property_value(prop), len);
99 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
100 DLOG(
"WM_NAME not set (_NET_WM_NAME is what you want anyways).\n");
112 const int len = xcb_get_property_value_length(prop);
113 char *name =
sstrndup(xcb_get_property_value(prop), len);
125 LOG(
"Using legacy window title. Note that in order to get Unicode window "
126 "titles in i3, the application has to set _NET_WM_NAME (UTF-8)\n");
138 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
139 DLOG(
"CLIENT_LEADER not set on window 0x%08x.\n", win->
id);
145 xcb_window_t *leader = xcb_get_property_value(prop);
146 if (leader == NULL) {
151 DLOG(
"Client leader changed to %08x\n", *leader);
163 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
164 DLOG(
"TRANSIENT_FOR not set on window 0x%08x.\n", win->
id);
170 xcb_window_t transient_for;
171 if (!xcb_icccm_get_wm_transient_for_from_reply(&transient_for, prop)) {
176 DLOG(
"Transient for changed to 0x%08x (window 0x%08x)\n", transient_for, win->
id);
188 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
189 DLOG(
"_NET_WM_STRUT_PARTIAL not set.\n");
195 if (!(strut = xcb_get_property_value(prop))) {
200 DLOG(
"Reserved pixels changed to: left = %d, right = %d, top = %d, bottom = %d\n",
201 strut[0], strut[1], strut[2], strut[3]);
213 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
214 DLOG(
"WM_WINDOW_ROLE not set.\n");
220 sasprintf(&new_role,
"%.*s", xcb_get_property_value_length(prop),
221 (
char *)xcb_get_property_value(prop));
223 win->
role = new_role;
224 LOG(
"WM_WINDOW_ROLE changed to \"%s\"\n", win->
role);
236 if (new_type == XCB_NONE) {
237 DLOG(
"cannot read _NET_WM_WINDOW_TYPE from window.\n");
252 bool changed =
false;
253 xcb_size_hints_t size_hints;
258 success = xcb_icccm_get_wm_size_hints_from_reply(&size_hints, reply);
260 success = xcb_icccm_get_wm_normal_hints_reply(
conn, xcb_icccm_get_wm_normal_hints_unchecked(
conn, win->
id), &size_hints, NULL);
263 DLOG(
"Could not get WM_NORMAL_HINTS\n");
267 #define ASSIGN_IF_CHANGED(original, new) \
269 if (original != new) { \
275 if ((size_hints.flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE)) {
276 DLOG(
"Minimum size: %d (width) x %d (height)\n", size_hints.min_width, size_hints.min_height);
282 if ((size_hints.flags & XCB_ICCCM_SIZE_HINT_P_MAX_SIZE)) {
283 DLOG(
"Maximum size: %d (width) x %d (height)\n", size_hints.max_width, size_hints.max_height);
285 int max_width =
max(0, size_hints.max_width);
286 int max_height =
max(0, size_hints.max_height);
291 DLOG(
"Clearing maximum size \n");
297 if ((size_hints.flags & XCB_ICCCM_SIZE_HINT_P_RESIZE_INC)) {
298 DLOG(
"Size increments: %d (width) x %d (height)\n", size_hints.width_inc, size_hints.height_inc);
300 if (size_hints.width_inc > 0 && size_hints.width_inc < 0xFFFF) {
306 if (size_hints.height_inc > 0 && size_hints.height_inc < 0xFFFF) {
312 DLOG(
"Clearing size increments\n");
319 if (size_hints.flags & XCB_ICCCM_SIZE_HINT_BASE_SIZE &&
321 DLOG(
"Base size: %d (width) x %d (height)\n", size_hints.base_width, size_hints.base_height);
326 DLOG(
"Clearing base size\n");
333 (size_hints.flags & XCB_ICCCM_SIZE_HINT_US_POSITION || size_hints.flags & XCB_ICCCM_SIZE_HINT_P_POSITION) &&
334 (size_hints.flags & XCB_ICCCM_SIZE_HINT_US_SIZE || size_hints.flags & XCB_ICCCM_SIZE_HINT_P_SIZE)) {
335 DLOG(
"Setting geometry x=%d y=%d w=%d h=%d\n", size_hints.x, size_hints.y, size_hints.width, size_hints.height);
336 geom->x = size_hints.x;
337 geom->y = size_hints.y;
338 geom->width = size_hints.width;
339 geom->height = size_hints.height;
343 if (size_hints.flags & XCB_ICCCM_SIZE_HINT_P_ASPECT &&
344 (size_hints.min_aspect_num >= 0) && (size_hints.min_aspect_den > 0) &&
345 (size_hints.max_aspect_num >= 0) && (size_hints.max_aspect_den > 0)) {
347 double min_aspect = (double)size_hints.min_aspect_num / size_hints.min_aspect_den;
348 double max_aspect = (
double)size_hints.max_aspect_num / size_hints.max_aspect_den;
349 DLOG(
"Aspect ratio set: minimum %f, maximum %f\n", min_aspect, max_aspect);
359 DLOG(
"Clearing aspect ratios\n");
373 if (urgency_hint != NULL)
374 *urgency_hint =
false;
376 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
377 DLOG(
"WM_HINTS not set.\n");
382 xcb_icccm_wm_hints_t hints;
384 if (!xcb_icccm_get_wm_hints_from_reply(&hints, prop)) {
385 DLOG(
"Could not get WM_HINTS\n");
390 if (hints.flags & XCB_ICCCM_WM_HINT_INPUT) {
392 LOG(
"WM_HINTS.input changed to \"%d\"\n", hints.input);
395 if (urgency_hint != NULL)
396 *urgency_hint = (xcb_icccm_wm_hints_get_urgency(&hints) != 0);
420 #define MWM_HINTS_FLAGS_FIELD 0
421 #define MWM_HINTS_DECORATIONS_FIELD 2
423 #define MWM_HINTS_DECORATIONS (1 << 1)
424 #define MWM_DECOR_ALL (1 << 0)
425 #define MWM_DECOR_BORDER (1 << 1)
426 #define MWM_DECOR_TITLE (1 << 3)
428 if (motif_border_style != NULL)
431 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
445 uint32_t *motif_hints = (uint32_t *)xcb_get_property_value(prop);
447 if (motif_border_style != NULL &&
460 #undef MWM_HINTS_FLAGS_FIELD
461 #undef MWM_HINTS_DECORATIONS_FIELD
462 #undef MWM_HINTS_DECORATIONS
464 #undef MWM_DECOR_BORDER
465 #undef MWM_DECOR_TITLE