void event_on_configure(XEvent event) { XConfigureRequestEvent* cre = &event.xconfigurerequest; HSClient* client = get_client_from_window(cre->window); if (client) { bool changes = false; Rectangle newRect = client->float_size; if (client->sizehints_floating && (is_client_floated(client) || client->pseudotile)) { bool width_requested = 0 != (cre->value_mask & CWWidth); bool height_requested = 0 != (cre->value_mask & CWHeight); bool x_requested = 0 != (cre->value_mask & CWX); bool y_requested = 0 != (cre->value_mask & CWY); cre->width += 2*cre->border_width; cre->height += 2*cre->border_width; if (width_requested && newRect.width != cre->width) changes = true; if (height_requested && newRect.height != cre->height) changes = true; if (x_requested || y_requested) changes = true; if (x_requested) newRect.x = cre->x; if (y_requested) newRect.y = cre->y; if (width_requested) newRect.width = cre->width; if (height_requested) newRect.height = cre->height; } if (changes && is_client_floated(client)) { client->float_size = newRect; client_resize_floating(client, find_monitor_with_tag(client->tag)); } else if (changes && client->pseudotile) { client->float_size = newRect; monitor_apply_layout(find_monitor_with_tag(client->tag)); } else { // FIXME: why send event and not XConfigureWindow or XMoveResizeWindow?? client_send_configure(client); } } else { // if client not known.. then allow configure. // its probably a nice conky or dzen2 bar :) XWindowChanges wc; wc.x = cre->x; wc.y = cre->y; wc.width = cre->width; wc.height = cre->height; wc.border_width = cre->border_width; wc.sibling = cre->above; wc.stack_mode = cre->detail; XConfigureWindow(g_display, cre->window, cre->value_mask, &wc); } }
/** The configure event handler. * \param ev The event. */ static void event_handle_configurerequest(xcb_configure_request_event_t *ev) { client_t *c; if((c = client_getbywin(ev->window))) { area_t geometry = c->geometry; uint16_t bw = c->border_width; uint16_t tb_left = c->titlebar[CLIENT_TITLEBAR_LEFT].size; uint16_t tb_right = c->titlebar[CLIENT_TITLEBAR_RIGHT].size; uint16_t tb_top = c->titlebar[CLIENT_TITLEBAR_TOP].size; uint16_t tb_bottom = c->titlebar[CLIENT_TITLEBAR_BOTTOM].size; uint16_t deco_left = bw + tb_left; uint16_t deco_right = bw + tb_right; uint16_t deco_top = bw + tb_top; uint16_t deco_bottom = bw + tb_bottom; int16_t diff_w = 0, diff_h = 0, diff_border = 0; if(ev->value_mask & XCB_CONFIG_WINDOW_X) { int16_t diff = 0; geometry.x = ev->x; xwindow_translate_for_gravity(c->size_hints.win_gravity, deco_left, 0, deco_right, 0, &diff, NULL); geometry.x += diff; } if(ev->value_mask & XCB_CONFIG_WINDOW_Y) { int16_t diff = 0; geometry.y = ev->y; xwindow_translate_for_gravity(c->size_hints.win_gravity, 0, deco_top, 0, deco_bottom, NULL, &diff); geometry.y += diff; } if(ev->value_mask & XCB_CONFIG_WINDOW_WIDTH) { uint16_t old_w = geometry.width; geometry.width = ev->width; /* The ConfigureRequest specifies the size of the client window, we want the frame */ geometry.width += tb_left + tb_right; diff_w = geometry.width - old_w; } if(ev->value_mask & XCB_CONFIG_WINDOW_HEIGHT) { uint16_t old_h = geometry.height; geometry.height = ev->height; /* The ConfigureRequest specifies the size of the client window, we want the frame */ geometry.height += tb_top + tb_bottom; diff_h = geometry.height - old_h; } if(ev->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) { lua_State *L = globalconf_get_lua_State(); diff_border = ev->border_width - bw; diff_h += diff_border; diff_w += diff_border; luaA_object_push(L, c); window_set_border_width(L, -1, ev->border_width); lua_pop(L, 1); } /* If the client resizes without moving itself, apply window gravity */ if(c->size_hints.flags & XCB_ICCCM_SIZE_HINT_P_WIN_GRAVITY) { int16_t diff_x = 0, diff_y = 0; xwindow_translate_for_gravity(c->size_hints.win_gravity, diff_border, diff_border, diff_w, diff_h, &diff_x, &diff_y); if(!(ev->value_mask & XCB_CONFIG_WINDOW_X)) geometry.x += diff_x; if(!(ev->value_mask & XCB_CONFIG_WINDOW_Y)) geometry.y += diff_y; } if(!client_resize(c, geometry, false)) /* ICCCM 4.1.5 / 4.2.3, if nothing was changed, send an event saying so */ client_send_configure(c); } else if (xembed_getbywin(&globalconf.embedded, ev->window)) { /* Ignore this so that systray icons cannot resize themselves. * We decide their size! */ } else event_handle_configurerequest_configure_window(ev); }
/** The configure event handler. * \param ev The event. */ static void event_handle_configurerequest(xcb_configure_request_event_t *ev) { client_t *c; if((c = client_getbywin(ev->window))) { area_t geometry = c->geometry; uint16_t bw = c->border_width; uint16_t tb_left = c->titlebar[CLIENT_TITLEBAR_LEFT].size; uint16_t tb_right = c->titlebar[CLIENT_TITLEBAR_RIGHT].size; uint16_t tb_top = c->titlebar[CLIENT_TITLEBAR_TOP].size; uint16_t tb_bottom = c->titlebar[CLIENT_TITLEBAR_BOTTOM].size; uint16_t deco_left = bw + tb_left; uint16_t deco_right = bw + tb_right; uint16_t deco_top = bw + tb_top; uint16_t deco_bottom = bw + tb_bottom; int16_t diff_w = 0, diff_h = 0, diff_border = 0; if(ev->value_mask & XCB_CONFIG_WINDOW_X) { int16_t diff = 0; geometry.x = ev->x; xwindow_translate_for_gravity(c->size_hints.win_gravity, deco_left, 0, deco_right, 0, &diff, NULL); geometry.x += diff; } if(ev->value_mask & XCB_CONFIG_WINDOW_Y) { int16_t diff = 0; geometry.y = ev->y; xwindow_translate_for_gravity(c->size_hints.win_gravity, 0, deco_top, 0, deco_bottom, NULL, &diff); geometry.y += diff; } if(ev->value_mask & XCB_CONFIG_WINDOW_WIDTH) { uint16_t old_w = geometry.width; geometry.width = ev->width; /* The ConfigureRequest specifies the size of the client window, we want the frame */ geometry.width += tb_left + tb_right; diff_w = geometry.width - old_w; } if(ev->value_mask & XCB_CONFIG_WINDOW_HEIGHT) { uint16_t old_h = geometry.height; geometry.height = ev->height; /* The ConfigureRequest specifies the size of the client window, we want the frame */ geometry.height += tb_top + tb_bottom; diff_h = geometry.height - old_h; } if(ev->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) { lua_State *L = globalconf_get_lua_State(); diff_border = ev->border_width - bw; diff_h += diff_border; diff_w += diff_border; luaA_object_push(L, c); window_set_border_width(L, -1, ev->border_width); lua_pop(L, 1); } /* If the client resizes without moving itself, apply window gravity */ if(c->size_hints.flags & XCB_ICCCM_SIZE_HINT_P_WIN_GRAVITY) { int16_t diff_x = 0, diff_y = 0; xwindow_translate_for_gravity(c->size_hints.win_gravity, diff_border, diff_border, diff_w, diff_h, &diff_x, &diff_y); if(!(ev->value_mask & XCB_CONFIG_WINDOW_X)) geometry.x += diff_x; if(!(ev->value_mask & XCB_CONFIG_WINDOW_Y)) geometry.y += diff_y; } if(!client_resize(c, geometry, false)) /* ICCCM 4.1.5 / 4.2.3, if nothing was changed, send an event saying so */ client_send_configure(c); } else if (xembed_getbywin(&globalconf.embedded, ev->window)) { /* Ignore this so that systray icons cannot resize themselves. * We decide their size! * However, Xembed says that we act like a WM to the embedded window and * thus we have to send a synthetic configure notify informing the * window that its configure request was denied. */ xcb_get_geometry_cookie_t geom_cookie = xcb_get_geometry_unchecked(globalconf.connection, ev->window); xcb_translate_coordinates_cookie_t coords_cookie = xcb_translate_coordinates_unchecked(globalconf.connection, ev->window, globalconf.screen->root, 0, 0); xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(globalconf.connection, geom_cookie, NULL); xcb_translate_coordinates_reply_t *coords = xcb_translate_coordinates_reply(globalconf.connection, coords_cookie, NULL); if (geom && coords) { xwindow_configure(ev->window, (area_t) { .x = coords->dst_x, .y = coords->dst_y, .width = geom->width, .height = geom->height }, 0);