From: Michael Stapelberg Date: Fri, 26 Nov 2010 22:08:12 +0000 (+0100) Subject: look and feel: create split container when switching workspace layout X-Git-Tag: tree-pr1~58 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=77d0d42ed2d7ac8cafe267c92b35a81c1b9491eb;p=i3%2Fi3 look and feel: create split container when switching workspace layout Quote from the source: When the container type is CT_WORKSPACE, the user wants to change the whole workspace into stacked/tabbed mode. To do this and still allow intuitive operations (like level-up and then opening a new window), we need to create a new split container. */ --- diff --git a/include/con.h b/include/con.h index bdf0b2a2..9194b0e0 100644 --- a/include/con.h +++ b/include/con.h @@ -153,4 +153,12 @@ Rect con_border_style_rect(Con *con); */ int con_border_style(Con *con); +/** + * This function changes the layout of a given container. Use it to handle + * special cases like changing a whole workspace to stacked/tabbed (creates a + * new split container before). + * + */ +void con_set_layout(Con *con, int layout); + #endif diff --git a/src/cmdparse.y b/src/cmdparse.y index c2f0222e..931729d8 100644 --- a/src/cmdparse.y +++ b/src/cmdparse.y @@ -574,11 +574,11 @@ layout: /* check if the match is empty, not if the result is empty */ if (match_is_empty(¤t_match)) - focused->parent->layout = $3; + con_set_layout(focused->parent, $3); else { TAILQ_FOREACH(current, &owindows, owindows) { printf("matching: %p / %s\n", current->con, current->con->name); - current->con->layout = $3; + con_set_layout(current->con, $3); } } diff --git a/src/con.c b/src/con.c index 3d1441f6..2454684e 100644 --- a/src/con.c +++ b/src/con.c @@ -544,3 +544,47 @@ int con_border_style(Con *con) { return con->border_style; } + +/* + * This function changes the layout of a given container. Use it to handle + * special cases like changing a whole workspace to stacked/tabbed (creates a + * new split container before). + * + */ +void con_set_layout(Con *con, int layout) { + /* When the container type is CT_WORKSPACE, the user wants to change the + * whole workspace into stacked/tabbed mode. To do this and still allow + * intuitive operations (like level-up and then opening a new window), we + * need to create a new split container. */ + if (con->type == CT_WORKSPACE) { + DLOG("Creating new split container\n"); + /* 1: create a new split container */ + Con *new = con_new(NULL); + new->parent = con; + + /* 2: set the requested layout on the split con */ + new->layout = layout; + + /* 3: While the layout is irrelevant in stacked/tabbed mode, it needs + * to be set. Otherwise, this con will not be interpreted as a split + * container. */ + new->orientation = HORIZ; + + /* 4: move the existing cons of this workspace below the new con */ + DLOG("Moving cons\n"); + Con *child; + while (!TAILQ_EMPTY(&(con->nodes_head))) { + child = TAILQ_FIRST(&(con->nodes_head)); + con_detach(child); + con_attach(child, new); + } + + /* 4: attach the new split container to the workspace */ + DLOG("Attaching new split to ws\n"); + con_attach(new, con); + + return; + } + + con->layout = layout; +}