From 97f7d47413967e2b6f405c4fa303850b7c56f57a Mon Sep 17 00:00:00 2001 From: wil Date: Sat, 10 Dec 2016 16:44:43 +0100 Subject: Added Awesome/Monad type "auto" layouts --- sway/container.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sway/container.c') diff --git a/sway/container.c b/sway/container.c index e557f450..d034115f 100644 --- a/sway/container.c +++ b/sway/container.c @@ -32,6 +32,8 @@ static swayc_t *new_swayc(enum swayc_types type) { c->layout = L_NONE; c->workspace_layout = L_NONE; c->type = type; + c->nb_master = 1; + c->nb_slave_groups = 1; if (type != C_VIEW) { c->children = create_list(); } -- cgit v1.2.3 From a0aa8d9780c6c8b0138800e3b2c2c0053174a2c5 Mon Sep 17 00:00:00 2001 From: wil Date: Thu, 29 Dec 2016 20:26:35 +0100 Subject: cleanup in auto layouts - added L_AUTO_FIRST/LAST instead of using explicit layouts. - when switching between auto layout that don't share the same major axis, invert the width/height of their child views to preserve their relative proportions. --- include/sway/container.h | 3 +++ include/sway/layout.h | 2 +- sway/commands/layout.c | 48 ++++++++++++++++++++++++++++++---------- sway/commands/workspace_layout.c | 10 ++++++++- sway/container.c | 23 ++++++++++++++++--- sway/sway.5.txt | 2 +- 6 files changed, 70 insertions(+), 18 deletions(-) (limited to 'sway/container.c') diff --git a/include/sway/container.h b/include/sway/container.h index 1d0fb265..f0574b1b 100644 --- a/include/sway/container.h +++ b/include/sway/container.h @@ -44,6 +44,9 @@ enum swayc_layouts { L_AUTO_TOP, L_AUTO_BOTTOM, + L_AUTO_FIRST = L_AUTO_LEFT, + L_AUTO_LAST = L_AUTO_BOTTOM, + // Keep last L_LAYOUTS, }; diff --git a/include/sway/layout.h b/include/sway/layout.h index 38096947..a771a72e 100644 --- a/include/sway/layout.h +++ b/include/sway/layout.h @@ -76,6 +76,6 @@ void swayc_log(log_importance_t verbosity, swayc_t *cont, const char* format, .. enum swayc_layouts default_layout(swayc_t *output); inline bool is_auto_layout(enum swayc_layouts layout) { - return (layout >= L_AUTO_LEFT) && (layout <= L_AUTO_BOTTOM); + return (layout >= L_AUTO_FIRST) && (layout <= L_AUTO_LAST); } #endif diff --git a/sway/commands/layout.c b/sway/commands/layout.c index 9e468c21..5426186e 100644 --- a/sway/commands/layout.c +++ b/sway/commands/layout.c @@ -56,24 +56,12 @@ struct cmd_results *cmd_layout(int argc, char **argv) { swayc_change_layout(parent, L_HORIZ); } } else if (strcasecmp(argv[0], "auto_left") == 0) { - if (parent->type != C_CONTAINER && !swayc_is_empty_workspace(parent)){ - parent = new_container(parent, L_AUTO_LEFT); - } swayc_change_layout(parent, L_AUTO_LEFT); } else if (strcasecmp(argv[0], "auto_right") == 0) { - if (parent->type != C_CONTAINER && !swayc_is_empty_workspace(parent)){ - parent = new_container(parent, L_AUTO_RIGHT); - } swayc_change_layout(parent, L_AUTO_RIGHT); } else if (strcasecmp(argv[0], "auto_top") == 0) { - if (parent->type != C_CONTAINER && !swayc_is_empty_workspace(parent)){ - parent = new_container(parent, L_AUTO_TOP); - } swayc_change_layout(parent, L_AUTO_TOP); } else if (strcasecmp(argv[0], "auto_bot") == 0) { - if (parent->type != C_CONTAINER && !swayc_is_empty_workspace(parent)){ - parent = new_container(parent, L_AUTO_BOTTOM); - } swayc_change_layout(parent, L_AUTO_BOTTOM); } else if (strcasecmp(argv[0], "incnmaster") == 0) { if ((error = checkarg(argc, "layout incnmaster", @@ -105,6 +93,42 @@ struct cmd_results *cmd_layout(int argc, char **argv) { ((int)container->parent->nb_slave_groups + inc >= 1)) { container->parent->nb_slave_groups += inc; } + } else if (strcasecmp(argv[0], "auto") == 0) { + if ((error = checkarg(argc, "auto", EXPECTED_EQUAL_TO, 2))) { + 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_FIRST; + } + } else { + return cmd_results_new(CMD_FAILURE, "layout auto", + "Must be one of ."); + } + swayc_change_layout(parent, layout); + } else if (strcasecmp(argv[0], "promote") == 0) { + // swap first child in auto layout with currently focused child + swayc_t *container = get_focused_view(swayc_active_workspace()); + swayc_t *parent = container->parent; + if (is_auto_layout(parent->layout)) { + int focused_idx = index_child(container); + swayc_t *first = parent->children->items[0]; + if (focused_idx > 0) { + list_swap(parent->children, 0, focused_idx); + swap_geometry(first, container); + } + } } } diff --git a/sway/commands/workspace_layout.c b/sway/commands/workspace_layout.c index b7b4b033..3e0a12ce 100644 --- a/sway/commands/workspace_layout.c +++ b/sway/commands/workspace_layout.c @@ -13,8 +13,16 @@ struct cmd_results *cmd_workspace_layout(int argc, char **argv) { config->default_layout = L_STACKED; } else if (strcasecmp(argv[0], "tabbed") == 0) { config->default_layout = L_TABBED; + } else if (strcasecmp(argv[0], "auto_left") == 0) { + config->default_layout = L_AUTO_LEFT; + } else if (strcasecmp(argv[0], "auto_right") == 0) { + config->default_layout = L_AUTO_RIGHT; + } else if (strcasecmp(argv[0], "auto_top") == 0) { + config->default_layout = L_AUTO_TOP; + } else if (strcasecmp(argv[0], "auto_bottom") == 0) { + config->default_layout = L_AUTO_BOTTOM; } else { - return cmd_results_new(CMD_INVALID, "workspace_layout", "Expected 'workspace_layout '"); + return cmd_results_new(CMD_INVALID, "workspace_layout", "Expected 'workspace_layout '"); } return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/container.c b/sway/container.c index d034115f..3bdc8b6c 100644 --- a/sway/container.c +++ b/sway/container.c @@ -962,11 +962,28 @@ swayc_t *swayc_tabbed_stacked_parent(swayc_t *con) { } swayc_t *swayc_change_layout(swayc_t *container, enum swayc_layouts layout) { + // if layout change modifies the auto layout's major axis, swap width and height + // to preserve current ratios. + if (is_auto_layout(layout) && is_auto_layout(container->layout)) { + enum swayc_layouts prev_major = (container->layout == L_AUTO_LEFT || + container->layout == L_AUTO_RIGHT) + ? L_HORIZ : L_VERT; + enum swayc_layouts new_major = (layout == L_AUTO_LEFT || layout == L_AUTO_RIGHT) + ? L_HORIZ : L_VERT; + if (new_major != prev_major) { + for (int i = 0; i < container->children->length; ++i) { + swayc_t *child = container->children->items[i]; + double h = child->height; + child->height = child->width; + child->width = h; + } + } + } if (container->type == C_WORKSPACE) { container->workspace_layout = layout; - if (layout == L_HORIZ || layout == L_VERT) { - container->layout = layout; - } + if (layout == L_HORIZ || layout == L_VERT || is_auto_layout(layout)) { + container->layout = layout; + } } else { container->layout = layout; } diff --git a/sway/sway.5.txt b/sway/sway.5.txt index 8f8302f0..c0c4bfb2 100644 --- a/sway/sway.5.txt +++ b/sway/sway.5.txt @@ -371,7 +371,7 @@ The default colors are: switch to workspace 2, then invoke the "workspace 2" command again, you will be returned to workspace 1. Defaults to _no_. -**workspace_layout** :: +**workspace_layout** :: Specifies the start layout for new workspaces. **include** :: -- cgit v1.2.3 From 063c79874a0d55ffa69f48947381607978e128d7 Mon Sep 17 00:00:00 2001 From: wil Date: Sun, 8 Jan 2017 14:49:47 +0100 Subject: Indent cleanups --- sway/commands/layout.c | 24 ++++++++++++------------ sway/container.c | 7 ++++--- sway/layout.c | 36 ++++++++++++++++++------------------ 3 files changed, 34 insertions(+), 33 deletions(-) (limited to 'sway/container.c') diff --git a/sway/commands/layout.c b/sway/commands/layout.c index 0cdac1b4..c13a2ef7 100644 --- a/sway/commands/layout.c +++ b/sway/commands/layout.c @@ -49,8 +49,8 @@ struct cmd_results *cmd_layout(int argc, char **argv) { } else if (strcasecmp(argv[0], "splitv") == 0) { swayc_change_layout(parent, L_VERT); } else if (strcasecmp(argv[0], "toggle") == 0 && argc == 2 && strcasecmp(argv[1], "split") == 0) { - if (parent->layout == L_HORIZ && (parent->workspace_layout == L_NONE || - parent->workspace_layout == L_HORIZ)) { + if (parent->layout == L_HORIZ && (parent->workspace_layout == L_NONE + || parent->workspace_layout == L_HORIZ)) { swayc_change_layout(parent, L_VERT); } else { swayc_change_layout(parent, L_HORIZ); @@ -66,23 +66,23 @@ struct cmd_results *cmd_layout(int argc, char **argv) { } else if (strcasecmp(argv[0], "incnmaster") == 0) { const char *name = "layout incnmaster"; if ((error = checkarg(argc, name, - EXPECTED_EQUAL_TO, 2))) { + 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); + "(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)) { + 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;) { + 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; @@ -92,19 +92,19 @@ struct cmd_results *cmd_layout(int argc, char **argv) { } else if ((strcasecmp(argv[0], "incncol") == 0) && argc ==2) { const char *name = "layout incncol"; if ((error = checkarg(argc, name, - EXPECTED_EQUAL_TO, 2))) { + 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); + "(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)) { + ((int)container->parent->nb_slave_groups + inc >= 1)) { container->parent->nb_slave_groups += inc; } } else if (strcasecmp(argv[0], "auto") == 0) { @@ -128,7 +128,7 @@ struct cmd_results *cmd_layout(int argc, char **argv) { } } else { return cmd_results_new(CMD_FAILURE, "layout auto", - "Must be one of ."); + "Must be one of ."); } swayc_change_layout(parent, layout); } diff --git a/sway/container.c b/sway/container.c index 3bdc8b6c..cf7d7dda 100644 --- a/sway/container.c +++ b/sway/container.c @@ -965,10 +965,11 @@ swayc_t *swayc_change_layout(swayc_t *container, enum swayc_layouts layout) { // if layout change modifies the auto layout's major axis, swap width and height // to preserve current ratios. if (is_auto_layout(layout) && is_auto_layout(container->layout)) { - enum swayc_layouts prev_major = (container->layout == L_AUTO_LEFT || - container->layout == L_AUTO_RIGHT) + enum swayc_layouts prev_major = + container->layout == L_AUTO_LEFT || container->layout == L_AUTO_RIGHT ? L_HORIZ : L_VERT; - enum swayc_layouts new_major = (layout == L_AUTO_LEFT || layout == L_AUTO_RIGHT) + enum swayc_layouts new_major = + layout == L_AUTO_LEFT || layout == L_AUTO_RIGHT ? L_HORIZ : L_VERT; if (new_major != prev_major) { for (int i = 0; i < container->children->length; ++i) { diff --git a/sway/layout.c b/sway/layout.c index 3e467169..869a3bcb 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -296,7 +296,7 @@ void move_container(swayc_t *container, enum movement_direction dir) { sway_log(L_DEBUG, "container:%p, parent:%p, child %p,", container,parent,child); if (parent->layout == layout - || layout == L_NONE /* accept any layout for next/prev direction */ + || (layout == L_NONE && parent->type == C_CONTAINER) /* accept any layout for next/prev direction */ || (parent->layout == L_TABBED && layout == L_HORIZ) || (parent->layout == L_STACKED && layout == L_VERT) || is_auto_layout(parent->layout)) { @@ -321,16 +321,16 @@ void move_container(swayc_t *container, enum movement_direction dir) { } // if move command makes container change from master to slave // (or the contrary), reset its geometry an the one of the replaced item. - if (parent->nb_master && - (size_t) parent->children->length > parent->nb_master) { + if (parent->nb_master + && (size_t) parent->children->length > parent->nb_master) { swayc_t *swap_geom = NULL; // if child is being promoted/demoted, it will swap geometry // with the sibling being demoted/promoted. if ((dir == MOVE_NEXT && desired == 0) - || (dir == MOVE_PREV && (size_t) desired == parent->nb_master - 1)) { + || (dir == MOVE_PREV && (size_t) desired == parent->nb_master - 1)) { swap_geom = parent->children->items[parent->nb_master - 1]; } else if ((dir == MOVE_NEXT && (size_t) desired == parent->nb_master) - || (dir == MOVE_PREV && desired == parent->children->length - 1)) { + || (dir == MOVE_PREV && desired == parent->children->length - 1)) { swap_geom = parent->children->items[parent->nb_master]; } if (swap_geom) { @@ -837,9 +837,9 @@ static void apply_tabbed_or_stacked_layout(swayc_t *container, double x, double height); static void apply_auto_layout(swayc_t *container, const double x, const double y, - const double width, const double height, - enum swayc_layouts group_layout, - bool master_first); + const double width, const double height, + enum swayc_layouts group_layout, + bool master_first); static void arrange_windows_r(swayc_t *container, double width, double height) { int i; @@ -972,11 +972,11 @@ static void arrange_windows_r(swayc_t *container, double width, double height) { case L_HORIZ: default: apply_horiz_layout(container, x, y, width, height, 0, - container->children->length); + container->children->length); break; case L_VERT: apply_vert_layout(container, x, y, width, height, 0, - container->children->length); + container->children->length); break; case L_TABBED: case L_STACKED: @@ -1007,7 +1007,7 @@ static void arrange_windows_r(swayc_t *container, double width, double height) { if (swayc_is_fullscreen(view)) { wlc_view_bring_to_front(view->handle); } else if (!container->focused || - !swayc_is_fullscreen(container->focused)) { + !swayc_is_fullscreen(container->focused)) { wlc_view_bring_to_front(view->handle); } } @@ -1068,8 +1068,8 @@ void apply_horiz_layout(swayc_t *container, const double x, const double y, } void apply_vert_layout(swayc_t *container, const double x, const double y, - const double width, const double height, const int start, - const int end) { + const double width, const double height, const int start, + const int end) { int i; double scale = 0; // Calculate total height @@ -1121,7 +1121,7 @@ void apply_vert_layout(swayc_t *container, const double x, const double y, } void apply_tabbed_or_stacked_layout(swayc_t *container, double x, double y, - double width, double height) { + double width, double height) { int i; swayc_t *focused = NULL; for (i = 0; i < container->children->length; ++i) { @@ -1141,9 +1141,9 @@ void apply_tabbed_or_stacked_layout(swayc_t *container, double x, double y, } void apply_auto_layout(swayc_t *container, const double x, const double y, - const double width, const double height, - enum swayc_layouts group_layout, - bool master_first) { + const double width, const double height, + enum swayc_layouts group_layout, + bool master_first) { // Auto layout "container" in width x height @ x, y // using "group_layout" for each of the groups in the container. // There is one "master" group, plus container->nb_slave_groups. @@ -1342,7 +1342,7 @@ swayc_t *get_swayc_in_direction_under(swayc_t *container, enum movement_directio return NULL; } else { int desired = (focused_idx + (dir == MOVE_NEXT ? 1 : -1)) % - parent->children->length; + parent->children->length; if (desired < 0) { desired += parent->children->length; } -- cgit v1.2.3