X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fmanage.c;h=06f4e664338f736dceca5034a1486c64cea13951;hb=6e5e2fe5ee7ea92c93207b8f5ff5f8b674d7a72e;hp=93ae48659ff8b525895fc436c95af5a25a728758;hpb=d08ec003294481f5b2299099779fef623240bcfa;p=i3%2Fi3 diff --git a/src/manage.c b/src/manage.c index 93ae4865..06f4e664 100644 --- a/src/manage.c +++ b/src/manage.c @@ -3,7 +3,7 @@ * * i3 - an improved dynamic tiling window manager * - * © 2009 Michael Stapelberg and contributors + * © 2009-2010 Michael Stapelberg and contributors * * See file LICENSE for license information. * @@ -63,6 +63,28 @@ void manage_existing_windows(xcb_connection_t *conn, xcb_property_handlers_t *pr free(cookies); } +/* + * Restores the geometry of each window by reparenting it to the root window + * at the position of its frame. + * + * This is to be called *only* before exiting/restarting i3 because of evil + * side-effects which are to be expected when continuing to run i3. + * + */ +void restore_geometry(xcb_connection_t *conn) { + Workspace *ws; + Client *client; + DLOG("Restoring geometry\n"); + + TAILQ_FOREACH(ws, workspaces, workspaces) + SLIST_FOREACH(client, &(ws->focus_stack), focus_clients) + xcb_reparent_window(conn, client->child, root, + client->rect.x, client->rect.y); + + /* Make sure our changes reach the X server, we restart/exit now */ + xcb_flush(conn); +} + /* * Do some sanity checks and then reparent the window. * @@ -250,12 +272,20 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child, for (int i = 0; i < xcb_get_property_value_length(preply); i++) if (atom[i] == atoms[_NET_WM_WINDOW_TYPE_DOCK]) { DLOG("Window is a dock.\n"); + Output *t_out = get_output_containing(x, y); + if (t_out == NULL) + t_out = c_ws->output; + if (t_out != c_ws->output) { + DLOG("Dock client requested to be on output %s by geometry (%d, %d)\n", + t_out->name, x, y); + new->workspace = t_out->current_workspace; + } new->dock = true; new->borderless = true; new->titlebar_position = TITLEBAR_OFF; new->force_reconfigure = true; new->container = NULL; - SLIST_INSERT_HEAD(&(c_ws->output->dock_clients), new, dock_clients); + SLIST_INSERT_HEAD(&(t_out->dock_clients), new, dock_clients); /* If it’s a dock we can’t make it float, so we break */ new->floating = FLOATING_AUTO_OFF; break; @@ -318,6 +348,29 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child, preply = xcb_get_property_reply(conn, leader_cookie, NULL); handle_clientleader_change(NULL, conn, 0, new->child, atoms[WM_CLIENT_LEADER], preply); + /* if WM_CLIENT_LEADER is set, we put the new window on the + * same window as its leader. This might be overwritten by + * assignments afterwards. */ + if (new->leader != XCB_NONE) { + DLOG("client->leader is set (to 0x%08x)\n", new->leader); + Client *parent = table_get(&by_child, new->leader); + if (parent != NULL && parent->container != NULL) { + Workspace *t_ws = parent->workspace; + new->container = t_ws->table[parent->container->col][parent->container->row]; + new->workspace = t_ws; + old_focused = new->container->currently_focused; + map_frame = workspace_is_visible(t_ws); + new->urgent = true; + /* This is a little tricky: we cannot use + * workspace_update_urgent_flag() because the + * new window was not yet inserted into the + * focus stack on t_ws. */ + t_ws->urgent = true; + } else { + DLOG("parent is not usable\n"); + } + } + struct Assignment *assign; TAILQ_FOREACH(assign, &assignments, assignments) { if (get_matching_client(conn, assign->windowclass_title, new) == NULL) @@ -355,9 +408,15 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child, if (new->workspace->fullscreen_client != NULL) { DLOG("Setting below fullscreen window\n"); - /* If we are in fullscreen, we should lower the window to not be annoying */ - uint32_t values[] = { XCB_STACK_MODE_BELOW }; - xcb_configure_window(conn, new->frame, XCB_CONFIG_WINDOW_STACK_MODE, values); + /* If we are in fullscreen, we should place the window below + * the fullscreen window to not be annoying */ + uint32_t values[] = { + new->workspace->fullscreen_client->frame, + XCB_STACK_MODE_BELOW + }; + xcb_configure_window(conn, new->frame, + XCB_CONFIG_WINDOW_SIBLING | + XCB_CONFIG_WINDOW_STACK_MODE, values); } /* Insert into the currently active container, if it’s not a dock window */