reworked "layout auto*" star commands

- "layout auto_left|auto_xxx" are now "layout auto xxx"
- "layout incmaster <n>" is now "layout auto master [set|inc] <n>"
- "layout incncol <n>" is now "layout auto ncol [set|inc] <n>"
This commit is contained in:
wil 2017-01-08 17:57:38 +01:00
parent 063c79874a
commit 07474a4fa7
2 changed files with 129 additions and 81 deletions

View File

@ -3,6 +3,11 @@
#include "sway/container.h" #include "sway/container.h"
#include "sway/layout.h" #include "sway/layout.h"
/**
* handle "layout auto" command group
*/
static struct cmd_results *cmd_layout_auto(swayc_t *container, int argc, char **argv);
struct cmd_results *cmd_layout(int argc, char **argv) { struct cmd_results *cmd_layout(int argc, char **argv) {
struct cmd_results *error = NULL; struct cmd_results *error = NULL;
if (config->reading) return cmd_results_new(CMD_FAILURE, "layout", "Can't be used in config file."); if (config->reading) return cmd_results_new(CMD_FAILURE, "layout", "Can't be used in config file.");
@ -55,82 +60,8 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
} else { } else {
swayc_change_layout(parent, L_HORIZ); swayc_change_layout(parent, L_HORIZ);
} }
} else if (strcasecmp(argv[0], "auto_left") == 0) {
swayc_change_layout(parent, L_AUTO_LEFT);
} else if (strcasecmp(argv[0], "auto_right") == 0) {
swayc_change_layout(parent, L_AUTO_RIGHT);
} else if (strcasecmp(argv[0], "auto_top") == 0) {
swayc_change_layout(parent, L_AUTO_TOP);
} else if (strcasecmp(argv[0], "auto_bot") == 0) {
swayc_change_layout(parent, L_AUTO_BOTTOM);
} else if (strcasecmp(argv[0], "incnmaster") == 0) {
const char *name = "layout incnmaster";
if ((error = checkarg(argc, name,
EXPECTED_EQUAL_TO, 2))) {
return error;
}
char *end;
int inc = (int) strtol(argv[1], &end, 10);
if (*end) {
return cmd_results_new(CMD_INVALID, name, "Invalid %s command "
"(argument must be an integer)", name);
}
swayc_t *container = get_focused_view(swayc_active_workspace());
if (container && inc &&
is_auto_layout(container->parent->layout) &&
((int)container->parent->nb_master + inc >= 0)) {
for (int i = container->parent->nb_master;
i >= 0 && i < container->parent->children->length
&& i != (int) container->parent->nb_master + inc;) {
((swayc_t *) container->parent->children->items[i])->height = -1;
((swayc_t *) container->parent->children->items[i])->width = -1;
i += inc > 0 ? 1 : -1;
}
container->parent->nb_master += inc;
}
} else if ((strcasecmp(argv[0], "incncol") == 0) && argc ==2) {
const char *name = "layout incncol";
if ((error = checkarg(argc, name,
EXPECTED_EQUAL_TO, 2))) {
return error;
}
char *end;
int inc = (int) strtol(argv[1], &end, 10);
if (*end) {
return cmd_results_new(CMD_INVALID, name, "Invalid %s command "
"(argument must be an integer)", name);
}
swayc_t *container = get_focused_view(swayc_active_workspace());
if (container && inc && is_auto_layout(container->parent->layout) &&
((int)container->parent->nb_slave_groups + inc >= 1)) {
container->parent->nb_slave_groups += inc;
}
} else if (strcasecmp(argv[0], "auto") == 0) { } else if (strcasecmp(argv[0], "auto") == 0) {
if ((error = checkarg(argc, "auto", EXPECTED_EQUAL_TO, 2))) { return cmd_layout_auto(parent, argc, argv);
return error;
}
swayc_t *container = get_focused_view(swayc_active_workspace());
swayc_t *parent = container->parent;
enum swayc_layouts layout;
if (strcasecmp(argv[1], "next") == 0) {
if (is_auto_layout(parent->layout) && parent->layout < L_AUTO_LAST) {
layout = parent->layout + 1;
} else {
layout = L_AUTO_FIRST;
}
} else if (strcasecmp(argv[1], "prev") == 0) {
if (is_auto_layout(parent->layout) && parent->layout > L_AUTO_FIRST) {
layout = parent->layout - 1;
} else {
layout = L_AUTO_LAST;
}
} else {
return cmd_results_new(CMD_FAILURE, "layout auto",
"Must be one of <prev|next>.");
}
swayc_change_layout(parent, layout);
} }
} }
@ -141,3 +72,120 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }
static struct cmd_results *cmd_layout_auto(swayc_t *container, int argc, char **argv) {
// called after checking that argv[0] is auto, so just continue parsing from there
struct cmd_results *error = NULL;
const char *cmd_name = "layout auto";
const char *set_inc_cmd_name = "layout auto [master|ncol] [set|inc]";
const char *err_msg = "Allowed arguments are <right|left|top|bot|next|prev|master|ncol>";
bool need_layout_update = false;
enum swayc_layouts old_layout = container->layout;
enum swayc_layouts layout = old_layout;
if (strcasecmp(argv[1], "left") == 0) {
layout = L_AUTO_LEFT;
} else if (strcasecmp(argv[1], "right") == 0) {
layout = L_AUTO_RIGHT;
} else if (strcasecmp(argv[1], "top") == 0) {
layout = L_AUTO_TOP;
} else if (strcasecmp(argv[1], "bot") == 0) {
layout = L_AUTO_BOTTOM;
} else if (strcasecmp(argv[1], "next") == 0) {
if (is_auto_layout(container->layout) && container->layout < L_AUTO_LAST) {
layout = container->layout + 1;
} else {
layout = L_AUTO_FIRST;
}
} else if (strcasecmp(argv[1], "prev") == 0) {
if (is_auto_layout(container->layout) && container->layout > L_AUTO_FIRST) {
layout = container->layout - 1;
} else {
layout = L_AUTO_LAST;
}
} else {
bool is_nmaster;
bool is_set;
if (strcasecmp(argv[1], "master") == 0) {
is_nmaster = true;
} else if (strcasecmp(argv[1], "ncol") == 0) {
is_nmaster = false;
} else {
return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command. %s",
cmd_name, err_msg);
}
if ((error = checkarg(argc, "auto <master|ncol>", EXPECTED_EQUAL_TO, 4))) {
return error;
}
if (strcasecmp(argv[2], "set") == 0) {
is_set = true;
} else if (strcasecmp(argv[2], "inc") == 0) {
is_set = false;
} else {
return cmd_results_new(CMD_INVALID, set_inc_cmd_name, "Invalid %s command. %s, "
"Argument must be on of <set|inc>",
set_inc_cmd_name);
}
char *end;
int n = (int)strtol(argv[3], &end, 10);
if (*end) {
return cmd_results_new(CMD_INVALID, set_inc_cmd_name, "Invalid %s command "
"(argument must be an integer)", set_inc_cmd_name);
}
if (is_auto_layout(container->layout)) {
int inc = 0; /* difference between current master/ncol and requested value */
if (is_nmaster) {
if (is_set) {
if (n < 0) {
return cmd_results_new(CMD_INVALID, set_inc_cmd_name, "Invalid %s command "
"(master must be >= 0)", set_inc_cmd_name);
}
inc = n - (int)container->nb_master;
} else { /* inc command */
if ((int)container->nb_master + n >= 0) {
inc = n;
}
}
if (inc) {
for (int i = container->nb_master;
i >= 0 && i < container->children->length
&& i != (int)container->nb_master + inc;) {
((swayc_t *)container->children->items[i])->height = -1;
((swayc_t *)container->children->items[i])->width = -1;
i += inc > 0 ? 1 : -1;
}
container->nb_master += inc;
need_layout_update = true;
}
} else { /* ncol modification */
if (is_set) {
if (n <= 0) {
return cmd_results_new(CMD_INVALID, set_inc_cmd_name, "Invalid %s command "
"(ncol must be > 0)", set_inc_cmd_name);
}
inc = n - (int)container->nb_slave_groups;
} else { /* inc command */
if ((int)container->nb_slave_groups + n > 0) {
inc = n;
}
}
if (inc) {
container->nb_slave_groups += inc;
need_layout_update = true;
}
}
}
}
if (layout != old_layout) {
swayc_change_layout(container, layout);
update_layout_geometry(container, old_layout);
need_layout_update = true;
}
if (need_layout_update) {
update_geometry(container);
arrange_windows(container, container->width, container->height);
}
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}

View File

@ -84,13 +84,16 @@ They are expected to be used with **bindsym** or at runtime through **swaymsg**(
**layout** <mode>:: **layout** <mode>::
Sets the layout mode of the focused container. _mode_ can be one of _splith_, Sets the layout mode of the focused container. _mode_ can be one of _splith_,
_splitv_, _toggle split_, _stacking_, _tabbed_, _auto_left_, _auto_right_, _splitv_, _toggle split_, _stacking_, _tabbed_.
_auto_top, _auto_bottom_.
**layout** auto <mode>::
Sets layout to one of the auto modes, i.e. one of _left_, right_, _top_,
or _bot_.
**layout** auto <next|prev>:: **layout** auto <next|prev>::
Cycles between available auto layouts. Cycles between available auto layouts.
**layout** <incnmaster|incncol> <n>:: **layout** auto [master|ncol] [inc|set] <n>::
Modify the number of master elements, respectively slave columns, in the Modify the number of master elements, respectively slave columns, in the
focused container. <n> can be a positive or negative integer. These commands focused container. <n> can be a positive or negative integer. These commands
only have an effect if the focused container uses one of the "auto" layouts. only have an effect if the focused container uses one of the "auto" layouts.
@ -98,9 +101,6 @@ They are expected to be used with **bindsym** or at runtime through **swaymsg**(
**layout** toggle split:: **layout** toggle split::
Cycles between available split layouts. Cycles between available split layouts.
**layout** promote::
Swap the focused element with the first in the one of the auto layouts.
**move** <left|right|up|down|next|prev|first>:: **move** <left|right|up|down|next|prev|first>::
Moves the focused container _left_, _right_, _up_, or _down_. Moving to _prev_ Moves the focused container _left_, _right_, _up_, or _down_. Moving to _prev_
or _next_ swaps the container with its sibling in the same container. Move or _next_ swaps the container with its sibling in the same container. Move