X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fmanage.c;h=0dec28443906c3a209342d6e0a3cb25d8479e8ee;hb=4779e59c509c72bc7431fe2fab47c16342ef8d6b;hp=8dcc17a27cec45defa4d49b149823afff4ab6a29;hpb=00c2fe4b69a64e401019dc14555a29ac10e60ffe;p=i3%2Fi3 diff --git a/src/manage.c b/src/manage.c index 8dcc17a2..0dec2844 100644 --- a/src/manage.c +++ b/src/manage.c @@ -164,7 +164,7 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki DLOG("Managing window 0x%08x\n", window); - i3Window *cwindow = scalloc(sizeof(i3Window)); + i3Window *cwindow = scalloc(1, sizeof(i3Window)); cwindow->id = window; cwindow->depth = get_visual_depth(attr->visual); @@ -294,6 +294,7 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki if (match != NULL && match->insert_where != M_BELOW) { DLOG("Removing match %p from container %p\n", match, nc); TAILQ_REMOVE(&(nc->swallow_head), match, matches); + match_free(match); } } @@ -301,6 +302,13 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki if (nc->window != NULL && nc->window != cwindow) { if (!restore_kill_placeholder(nc->window->id)) { DLOG("Uh?! Container without a placeholder, but with a window, has swallowed this to-be-managed window?!\n"); + } else { + /* Remove remaining criteria, the first swallowed window wins. */ + while (!TAILQ_EMPTY(&(nc->swallow_head))) { + Match *first = TAILQ_FIRST(&(nc->swallow_head)); + TAILQ_REMOVE(&(nc->swallow_head), first, matches); + match_free(first); + } } } nc->window = cwindow; @@ -377,6 +385,9 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki want_floating = true; } + if (xcb_reply_contains_atom(state_reply, A__NET_WM_STATE_STICKY)) + nc->sticky = true; + FREE(state_reply); FREE(type_reply); @@ -419,6 +430,17 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki if (cwindow->dock) want_floating = false; + /* Plasma windows set their geometry in WM_SIZE_HINTS. */ + if ((wm_size_hints.flags & XCB_ICCCM_SIZE_HINT_US_POSITION || wm_size_hints.flags & XCB_ICCCM_SIZE_HINT_P_POSITION) && + (wm_size_hints.flags & XCB_ICCCM_SIZE_HINT_US_SIZE || wm_size_hints.flags & XCB_ICCCM_SIZE_HINT_P_SIZE)) { + DLOG("We are setting geometry according to wm_size_hints x=%d y=%d w=%d h=%d\n", + wm_size_hints.x, wm_size_hints.y, wm_size_hints.width, wm_size_hints.height); + geom->x = wm_size_hints.x; + geom->y = wm_size_hints.y; + geom->width = wm_size_hints.width; + geom->height = wm_size_hints.height; + } + /* Store the requested geometry. The width/height gets raised to at least * 75x50 when entering floating mode, which is the minimum size for a * window to be useful (smaller windows are usually overlays/toolbars/… @@ -503,13 +525,23 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki /* Send an event about window creation */ ipc_send_window_event("new", nc); + if (set_focus && assignment_for(cwindow, A_NO_FOCUS) != NULL) { + /* The first window on a workspace should always be focused. We have to + * compare with == 1 because the container has already been inserted at + * this point. */ + if (con_num_children(ws) == 1) { + DLOG("This is the first window on this workspace, ignoring no_focus.\n"); + } else { + DLOG("no_focus was set for con = %p, not setting focus.\n", nc); + set_focus = false; + } + } + /* Defer setting focus after the 'new' event has been sent to ensure the * proper window event sequence. */ if (set_focus && !nc->window->doesnt_accept_focus && nc->mapped) { - if (assignment_for(cwindow, A_NO_FOCUS) == NULL) { - DLOG("Now setting focus.\n"); - con_focus(nc); - } + DLOG("Now setting focus.\n"); + con_focus(nc); } tree_render();