X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Ftree.c;h=3378857666bc10a1485c20c4bce5c83e8bdada52;hb=a415d56048a18720bfdab8144652b87cb39ce626;hp=29b857309f00d593bb90e665678dfe1b8ae4cef3;hpb=66480d372596a489629de6aac19d704f70dae321;p=i3%2Fi3 diff --git a/src/tree.c b/src/tree.c index 29b85730..33788576 100644 --- a/src/tree.c +++ b/src/tree.c @@ -10,7 +10,7 @@ struct Con *focused; struct all_cons_head all_cons = TAILQ_HEAD_INITIALIZER(all_cons); /* - * Loads tree from ~/.i3/_restart.json + * Loads tree from ~/.i3/_restart.json (used for in-place restarts). * */ bool tree_restore() { @@ -59,6 +59,7 @@ void tree_init() { croot->type = CT_ROOT; Con *ws; + int c = 1; /* add the outputs */ TAILQ_FOREACH(output, &outputs, outputs) { if (!output->active) @@ -72,7 +73,8 @@ void tree_init() { /* add a workspace to this output */ ws = con_new(oc); ws->type = CT_WORKSPACE; - ws->name = strdup("1"); + asprintf(&(ws->name), "%d", c); + c++; ws->fullscreen_mode = CF_OUTPUT; ws->orientation = HORIZ; } @@ -132,24 +134,13 @@ static void fix_floating_parent(Con *con, Con *vanishing) { * */ void tree_close(Con *con, bool kill_window) { + Con *parent = con->parent; + /* check floating clients and adjust old_parent if necessary */ fix_floating_parent(croot, con); /* Get the container which is next focused */ - Con *next; - if (con->type == CT_FLOATING_CON) { - next = TAILQ_NEXT(con, floating_windows); - if (next == TAILQ_END(&(con->parent->floating_head))) - next = con_get_workspace(con); - } else { - next = TAILQ_NEXT(con, focused); - if (next == TAILQ_END(&(con->parent->nodes_head))) { - next = con->parent; - while (!TAILQ_EMPTY(&(next->focus_head)) && - TAILQ_FIRST(&(next->focus_head)) != con) - next = TAILQ_FIRST(&(next->focus_head)); - } - } + Con *next = con_next_focused(con); DLOG("closing %p, kill_window = %d\n", con, kill_window); Con *child; @@ -176,14 +167,14 @@ void tree_close(Con *con, bool kill_window) { x_con_kill(con); con_detach(con); - con_fix_percent(con->parent, WINDOW_REMOVE); + con_fix_percent(parent, WINDOW_REMOVE); if (con_is_floating(con)) { DLOG("Container was floating, killing floating container\n"); - TAILQ_REMOVE(&(con->parent->parent->floating_head), con->parent, floating_windows); - TAILQ_REMOVE(&(con->parent->parent->focus_head), con->parent, focused); - tree_close(con->parent, false); + TAILQ_REMOVE(&(parent->parent->floating_head), parent, floating_windows); + TAILQ_REMOVE(&(parent->parent->focus_head), parent, focused); + tree_close(parent, false); next = NULL; } @@ -199,8 +190,21 @@ void tree_close(Con *con, bool kill_window) { DLOG("focusing %p / %s\n", next, next->name); /* TODO: check if the container (or one of its children) was focused */ con_focus(next); + + /* check if the parent container is empty now and close it */ + if (parent->type != CT_WORKSPACE && + TAILQ_EMPTY(&(parent->nodes_head))) { + DLOG("Closing empty parent container\n"); + /* TODO: check if this container would swallow any other client and + * don’t close it automatically. */ + tree_close(parent, false); + } } +/* + * Closes the current container using tree_close(). + * + */ void tree_close_con() { assert(focused != NULL); if (focused->type == CT_WORKSPACE) { @@ -229,7 +233,7 @@ void tree_split(Con *con, orientation_t orientation) { /* if we are in a container whose parent contains only one * child and has the same orientation like we are trying to * set, this operation is a no-op to not confuse the user */ - if (parent->orientation == orientation && + if (con_orientation(parent) == orientation && TAILQ_NEXT(con, nodes) == TAILQ_END(&(parent->nodes_head))) { DLOG("Not splitting the same way again\n"); return; @@ -248,6 +252,10 @@ void tree_split(Con *con, orientation_t orientation) { con_attach(con, new); } +/* + * Moves focus one level up. + * + */ void level_up() { /* We can focus up to the workspace, but not any higher in the tree */ if (focused->parent->type != CT_CON && @@ -258,6 +266,10 @@ void level_up() { con_focus(focused->parent); } +/* + * Moves focus one level down. + * + */ void level_down() { /* Go down the focus stack of the current node */ Con *next = TAILQ_FIRST(&(focused->focus_head)); @@ -276,6 +288,11 @@ static void mark_unmapped(Con *con) { mark_unmapped(current); } +/* + * Renders the tree, that is rendering all outputs using render_con() and + * pushing the changes to X11 using x_push_changes(). + * + */ void tree_render() { if (croot == NULL) return; @@ -296,10 +313,16 @@ void tree_render() { printf("-- END RENDERING --\n"); } +/* + * Changes focus in the given way (next/previous) and given orientation + * (horizontal/vertical). + * + */ void tree_next(char way, orientation_t orientation) { /* 1: get the first parent with the same orientation */ Con *parent = focused->parent; - while (parent->orientation != orientation) { + while (focused->type != CT_WORKSPACE && + con_orientation(parent) != orientation) { LOG("need to go one level further up\n"); /* if the current parent is an output, we are at a workspace * and the orientation still does not match */ @@ -330,16 +353,23 @@ void tree_next(char way, orientation_t orientation) { while (!TAILQ_EMPTY(&(next->focus_head))) next = TAILQ_FIRST(&(next->focus_head)); + DLOG("focusing %p\n", next); con_focus(next); } +/* + * Moves the current container in the given way (next/previous) and given + * orientation (horizontal/vertical). + * + */ void tree_move(char way, orientation_t orientation) { /* 1: get the first parent with the same orientation */ Con *parent = focused->parent; + Con *old_parent = parent; if (focused->type == CT_WORKSPACE) return; bool level_changed = false; - while (parent->orientation != orientation) { + while (con_orientation(parent) != orientation) { LOG("need to go one level further up\n"); /* if the current parent is an output, we are at a workspace * and the orientation still does not match */ @@ -403,4 +433,9 @@ void tree_move(char way, orientation_t orientation) { TAILQ_INSERT_HEAD(&(next->parent->focus_head), focused, focused); /* TODO: don’t influence focus handling? */ } + + if (con_num_children(old_parent) == 0) { + DLOG("Old container empty after moving. Let's close it\n"); + tree_close(old_parent, false); + } }