void manage_window(xcb_property_handlers_t *prophs, xcb_connection_t *conn,
xcb_window_t window, xcb_get_window_attributes_cookie_t cookie,
bool needs_to_be_mapped) {
- LOG("managing window.\n");
xcb_drawable_t d = { window };
xcb_get_geometry_cookie_t geomc;
xcb_get_geometry_reply_t *geom;
return;
}
- if (needs_to_be_mapped && attr->map_state != XCB_MAP_STATE_VIEWABLE) {
- LOG("Window not mapped, not managing\n");
+ if (needs_to_be_mapped && attr->map_state != XCB_MAP_STATE_VIEWABLE)
goto out;
- }
/* Don’t manage clients with the override_redirect flag */
- if (attr->override_redirect) {
- LOG("override_redirect set, not managing\n");
+ if (attr->override_redirect)
goto out;
- }
/* Check if the window is already managed */
if (table_get(&by_child, window))
/* Reparent the window and add it to our list of managed windows */
reparent_window(conn, window, attr->visual, geom->root, geom->depth,
- geom->x, geom->y, geom->width, geom->height);
+ geom->x, geom->y, geom->width, geom->height,
+ geom->border_width);
/* Generate callback events for every property we watch */
xcb_property_changed(prophs, XCB_PROPERTY_NEW_VALUE, window, WM_CLASS);
xcb_property_changed(prophs, XCB_PROPERTY_NEW_VALUE, window, WM_NAME);
xcb_property_changed(prophs, XCB_PROPERTY_NEW_VALUE, window, WM_NORMAL_HINTS);
+ xcb_property_changed(prophs, XCB_PROPERTY_NEW_VALUE, window, WM_HINTS);
xcb_property_changed(prophs, XCB_PROPERTY_NEW_VALUE, window, WM_TRANSIENT_FOR);
xcb_property_changed(prophs, XCB_PROPERTY_NEW_VALUE, window, atoms[WM_CLIENT_LEADER]);
xcb_property_changed(prophs, XCB_PROPERTY_NEW_VALUE, window, atoms[_NET_WM_NAME]);
*/
void reparent_window(xcb_connection_t *conn, xcb_window_t child,
xcb_visualid_t visual, xcb_window_t root, uint8_t depth,
- int16_t x, int16_t y, uint16_t width, uint16_t height) {
+ int16_t x, int16_t y, uint16_t width, uint16_t height,
+ uint32_t border_width) {
xcb_get_property_cookie_t wm_type_cookie, strut_cookie, state_cookie,
utf8_title_cookie, title_cookie,
/* Events for already managed windows should already be filtered in manage_window() */
assert(new == NULL);
- LOG("reparenting new client\n");
+ LOG("Reparenting window 0x%08x\n", child);
LOG("x = %d, y = %d, width = %d, height = %d\n", x, y, width, height);
new = calloc(sizeof(Client), 1);
new->force_reconfigure = true;
new->child = child;
new->rect.width = width;
new->rect.height = height;
+ new->width_increment = 1;
+ new->height_increment = 1;
+ new->border_width = border_width;
/* Pre-initialize the values for floating */
new->floating_rect.x = -1;
new->floating_rect.width = width;
mask |= XCB_CW_EVENT_MASK;
values[1] = FRAME_EVENT_MASK;
- LOG("Reparenting 0x%08x under 0x%08x.\n", child, new->frame);
-
i3Font *font = load_font(conn, config.font);
width = min(width, c_ws->rect.x + c_ws->rect.width);
height = min(height, c_ws->rect.y + c_ws->rect.height);
/* Yo dawg, I heard you like windows, so I create a window around your window… */
new->frame = create_window(conn, framerect, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_CURSOR_LEFT_PTR, false, mask, values);
- /* Set WM_STATE_NORMAL because GTK applications don’t want to drag & drop if we don’t.
- * Also, xprop(1) needs that to work. */
- long data[] = { XCB_WM_STATE_NORMAL, XCB_NONE };
- xcb_change_property(conn, XCB_PROP_MODE_REPLACE, new->child, atoms[WM_STATE], atoms[WM_STATE], 32, 2, data);
-
/* Put the client inside the save set. Upon termination (whether killed or normal exit
does not matter) of the window manager, these clients will be correctly reparented
to their most closest living ancestor (= cleanup) */
xcb_grab_button(conn, false, child, XCB_EVENT_MASK_BUTTON_PRESS,
XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE,
- 1 /* left mouse button */, XCB_MOD_MASK_1);
+ 3 /* right mouse button */,
+ XCB_BUTTON_MASK_ANY /* don’t filter for any modifiers */);
/* Get _NET_WM_WINDOW_TYPE (to see if it’s a dock) */
xcb_atom_t *atom;
preply = xcb_get_property_reply(conn, leader_cookie, NULL);
handle_clientleader_change(NULL, conn, 0, new->child, atoms[WM_CLIENT_LEADER], preply);
- LOG("DEBUG: should have all infos now\n");
struct Assignment *assign;
TAILQ_FOREACH(assign, &assignments, assignments) {
if (get_matching_client(conn, assign->windowclass_title, new) == NULL)
}
LOG("Changing container/workspace and unmapping the client\n");
- Workspace *t_ws = &(workspaces[assign->workspace-1]);
+ Workspace *t_ws = workspace_get(assign->workspace-1);
workspace_initialize(t_ws, c_ws->screen);
new->container = t_ws->table[t_ws->current_col][t_ws->current_row];
and don’t event bother to redraw the layout – that would not change
anything anyways */
client_toggle_fullscreen(conn, new);
- return;
+ goto map;
}
render_layout(conn);
+map:
/* Map the window first to avoid flickering */
xcb_map_window(conn, child);
- if (map_frame) {
- LOG("Mapping client\n");
- xcb_map_window(conn, new->frame);
- }
- if (CUR_CELL->workspace->fullscreen_client == NULL && !new->dock) {
+ if (map_frame)
+ client_map(conn, new);
+
+ if ((CUR_CELL->workspace->fullscreen_client == NULL || new->fullscreen) && !new->dock) {
/* Focus the new window if we’re not in fullscreen mode and if it is not a dock window */
- if (new->workspace->fullscreen_client == NULL) {
+ if ((new->workspace->fullscreen_client == NULL) || new->fullscreen) {
if (!client_is_floating(new))
new->container->currently_focused = new;
if (new->container == CUR_CELL || client_is_floating(new))