commands: complete layout implementation

This commit is contained in:
Ian Fan 2018-07-29 12:27:34 +01:00
parent 11ac66d6fe
commit be64c46624
2 changed files with 70 additions and 18 deletions

View file

@ -1,3 +1,4 @@
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include "sway/commands.h"
@ -5,6 +6,26 @@
#include "sway/tree/container.h"
#include "log.h"
static bool parse_layout_string(char *s, enum sway_container_layout *ptr) {
if (strcasecmp(s, "splith") == 0) {
*ptr = L_HORIZ;
} else if (strcasecmp(s, "splitv") == 0) {
*ptr = L_VERT;
} else if (strcasecmp(s, "tabbed") == 0) {
*ptr = L_TABBED;
} else if (strcasecmp(s, "stacking") == 0) {
*ptr = L_STACKED;
} else {
return false;
}
return true;
}
static const char* expected_syntax =
"Expected 'layout default|tabbed|stacking|splitv|splith' or "
"'layout toggle [split|all]' or "
"'layout toggle [split|tabbed|stacking|splitv|splith] [split|tabbed|stacking|splitv|splith]...'";
struct cmd_results *cmd_layout(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "layout", EXPECTED_MORE_THAN, 0))) {
@ -23,30 +44,55 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
if (strcasecmp(argv[0], "default") == 0) {
parent->layout = parent->prev_layout;
if (parent->layout == L_NONE) {
parent->layout = container_get_default_layout(parent);
}
} else {
if (parent->layout != L_TABBED && parent->layout != L_STACKED) {
parent->prev_layout = parent->layout;
}
if (strcasecmp(argv[0], "splith") == 0) {
parent->layout = L_HORIZ;
} else if (strcasecmp(argv[0], "splitv") == 0) {
parent->layout = L_VERT;
} else if (strcasecmp(argv[0], "tabbed") == 0) {
parent->layout = L_TABBED;
} else if (strcasecmp(argv[0], "stacking") == 0) {
parent->layout = L_STACKED;
} else if (strcasecmp(argv[0], "toggle") == 0 && argc == 2 && strcasecmp(argv[1], "split") == 0) {
if (parent->layout == L_HORIZ) {
parent->layout = L_VERT;
bool assigned_directly = parse_layout_string(argv[0], &parent->layout);
if (!assigned_directly && strcasecmp(argv[0], "toggle") == 0) {
if (argc == 1) {
parent->layout =
parent->layout == L_STACKED ? L_TABBED :
parent->layout == L_TABBED ? parent->prev_layout : L_STACKED;
} else if (argc == 2) {
if (strcasecmp(argv[1], "all") == 0) {
parent->layout =
parent->layout == L_HORIZ ? L_VERT :
parent->layout == L_VERT ? L_STACKED :
parent->layout == L_STACKED ? L_TABBED : L_HORIZ;
} else if (strcasecmp(argv[1], "split") == 0) {
parent->layout = parent->layout == L_VERT ? L_HORIZ : L_VERT;
} else {
return cmd_results_new(CMD_INVALID, "layout", expected_syntax);
}
} else {
parent->layout = L_HORIZ;
bool valid;
enum sway_container_layout parsed_layout;
int curr = 1;
for (; curr < argc; curr++) {
valid = parse_layout_string(argv[curr], &parsed_layout);
if (valid && parsed_layout == parent->layout) {
break;
}
}
for (int i = curr + 1; i != curr; ++i) {
// cycle round to find next valid layout
if (i >= argc) {
i = 1;
}
if (parse_layout_string(argv[i], &parent->layout)) {
break;
} // invalid layout strings are silently ignored
}
}
} else {
return cmd_results_new(CMD_INVALID, "layout", expected_syntax);
}
}
if (parent->layout == L_NONE) {
parent->layout = container_get_default_layout(parent);
}
container_notify_subtree_changed(parent);
arrange_windows(parent);

View file

@ -111,11 +111,17 @@ They are expected to be used with *bindsym* or at runtime through *swaymsg*(1).
*fullscreen*
Toggles fullscreen for the focused view.
*layout* splith|splitv|stacking|tabbed
*layout* default|splith|splitv|stacking|tabbed
Sets the layout mode of the focused container.
*layout* toggle split
Switches the focused container between the splitv and splith layouts.
*layout* toggle [split|all]
Cycles the layout mode of the focused container though a preset list of
layouts. If no argument is given, then it cycles through stacking, tabbed
and the last split layout. If "split" is given, then it cycles through
splith and splitv. If "all" is given, then it cycles through every layout.
*layout* toggle [split|tabbed|stacking|splitv|splith] [split|tabbed|stacking|splitv|splith]...
Cycles the layout mode of the focused container through a list of layouts.
*move* left|right|up|down [<px>]
Moves the focused container in the direction specified. If the container,