layout toggle: take any combination of layouts as arguments (#2649)
With this PR the 'layout toggle' command can be passed any combination of valid layout keywords as arguments. They will be activated one after another each time you issue the command, advancing from left to right always selecting the layout after the currently active layout or the leftmost layout if the active layout is not in the argument list. This PR also incorporates the feature request from #2476.
This commit is contained in:
64
src/con.c
64
src/con.c
@ -1719,28 +1719,64 @@ void con_toggle_layout(Con *con, const char *toggle_mode) {
|
||||
parent = con->parent;
|
||||
DLOG("con_toggle_layout(%p, %s), parent = %p\n", con, toggle_mode, parent);
|
||||
|
||||
if (strcmp(toggle_mode, "split") == 0) {
|
||||
/* Toggle between splits. When the current layout is not a split
|
||||
* layout, we just switch back to last_split_layout. Otherwise, we
|
||||
* change to the opposite split layout. */
|
||||
if (parent->layout != L_SPLITH && parent->layout != L_SPLITV)
|
||||
con_set_layout(con, parent->last_split_layout);
|
||||
else {
|
||||
if (parent->layout == L_SPLITH)
|
||||
con_set_layout(con, L_SPLITV);
|
||||
else
|
||||
con_set_layout(con, L_SPLITH);
|
||||
const char delim[] = " ";
|
||||
|
||||
if (strcasecmp(toggle_mode, "split") == 0 || strstr(toggle_mode, delim)) {
|
||||
/* L_DEFAULT is used as a placeholder value to distinguish if
|
||||
* the first layout has already been saved. (it can never be L_DEFAULT) */
|
||||
layout_t new_layout = L_DEFAULT;
|
||||
bool current_layout_found = false;
|
||||
char *tm_dup = sstrdup(toggle_mode);
|
||||
char *cur_tok = strtok(tm_dup, delim);
|
||||
|
||||
for (layout_t layout; cur_tok != NULL; cur_tok = strtok(NULL, delim)) {
|
||||
if (strcasecmp(cur_tok, "split") == 0) {
|
||||
/* Toggle between splits. When the current layout is not a split
|
||||
* layout, we just switch back to last_split_layout. Otherwise, we
|
||||
* change to the opposite split layout. */
|
||||
if (parent->layout != L_SPLITH && parent->layout != L_SPLITV) {
|
||||
layout = parent->last_split_layout;
|
||||
} else {
|
||||
layout = (parent->layout == L_SPLITH) ? L_SPLITV : L_SPLITH;
|
||||
}
|
||||
} else {
|
||||
bool success = layout_from_name(cur_tok, &layout);
|
||||
if (!success || layout == L_DEFAULT) {
|
||||
ELOG("The token '%s' was not recognized and has been skipped.\n", cur_tok);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* If none of the specified layouts match the current,
|
||||
* fall back to the first layout in the list */
|
||||
if (new_layout == L_DEFAULT) {
|
||||
new_layout = layout;
|
||||
}
|
||||
|
||||
/* We found the active layout in the last iteration, so
|
||||
* now let's activate the current layout (next in list) */
|
||||
if (current_layout_found) {
|
||||
new_layout = layout;
|
||||
free(tm_dup);
|
||||
break;
|
||||
}
|
||||
|
||||
if (parent->layout == layout) {
|
||||
current_layout_found = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
con_set_layout(con, new_layout);
|
||||
} else if (strcasecmp(toggle_mode, "all") == 0 || strcasecmp(toggle_mode, "default") == 0) {
|
||||
if (parent->layout == L_STACKED)
|
||||
con_set_layout(con, L_TABBED);
|
||||
else if (parent->layout == L_TABBED) {
|
||||
if (strcmp(toggle_mode, "all") == 0)
|
||||
if (strcasecmp(toggle_mode, "all") == 0)
|
||||
con_set_layout(con, L_SPLITH);
|
||||
else
|
||||
con_set_layout(con, parent->last_split_layout);
|
||||
} else if (parent->layout == L_SPLITH || parent->layout == L_SPLITV) {
|
||||
if (strcmp(toggle_mode, "all") == 0) {
|
||||
if (strcasecmp(toggle_mode, "all") == 0) {
|
||||
/* When toggling through all modes, we toggle between
|
||||
* splith/splitv, whereas normally we just directly jump to
|
||||
* stacked. */
|
||||
|
Reference in New Issue
Block a user