diff options
author | wil <william.barsse@gmail.com> | 2016-12-10 16:44:43 +0100 |
---|---|---|
committer | wil <william.barsse@gmail.com> | 2016-12-29 20:31:30 +0100 |
commit | 97f7d47413967e2b6f405c4fa303850b7c56f57a (patch) | |
tree | 5237aea545fd2665b5e4a3967df5d6688d81858d | |
parent | Fix user-set LD_LIBRARY_PATH (diff) | |
download | sway-97f7d47413967e2b6f405c4fa303850b7c56f57a.tar.gz sway-97f7d47413967e2b6f405c4fa303850b7c56f57a.tar.zst sway-97f7d47413967e2b6f405c4fa303850b7c56f57a.zip |
Added Awesome/Monad type "auto" layouts
-rw-r--r-- | include/sway/container.h | 17 | ||||
-rw-r--r-- | include/sway/layout.h | 3 | ||||
-rw-r--r-- | sway/commands/layout.c | 20 | ||||
-rw-r--r-- | sway/container.c | 2 | ||||
-rw-r--r-- | sway/debug_log.c | 4 | ||||
-rw-r--r-- | sway/layout.c | 426 | ||||
-rw-r--r-- | sway/sway.5.txt | 3 |
7 files changed, 367 insertions, 108 deletions
diff --git a/include/sway/container.h b/include/sway/container.h index 2bedd136..1d0fb265 100644 --- a/include/sway/container.h +++ b/include/sway/container.h | |||
@@ -37,6 +37,13 @@ enum swayc_layouts { | |||
37 | L_STACKED, | 37 | L_STACKED, |
38 | L_TABBED, | 38 | L_TABBED, |
39 | L_FLOATING, /**< A psuedo-container, removed from the tree, to hold floating windows */ | 39 | L_FLOATING, /**< A psuedo-container, removed from the tree, to hold floating windows */ |
40 | |||
41 | /* Awesome/Monad style auto layouts */ | ||
42 | L_AUTO_LEFT, | ||
43 | L_AUTO_RIGHT, | ||
44 | L_AUTO_TOP, | ||
45 | L_AUTO_BOTTOM, | ||
46 | |||
40 | // Keep last | 47 | // Keep last |
41 | L_LAYOUTS, | 48 | L_LAYOUTS, |
42 | }; | 49 | }; |
@@ -144,6 +151,16 @@ struct sway_container { | |||
144 | struct wlc_geometry title_bar_geometry; | 151 | struct wlc_geometry title_bar_geometry; |
145 | struct wlc_geometry actual_geometry; | 152 | struct wlc_geometry actual_geometry; |
146 | int border_thickness; | 153 | int border_thickness; |
154 | |||
155 | /** | ||
156 | * Number of master views in auto layouts. | ||
157 | */ | ||
158 | uint32_t nb_master; | ||
159 | |||
160 | /** | ||
161 | * Number of slave groups (e.g. columns) in auto layouts. | ||
162 | */ | ||
163 | uint32_t nb_slave_groups; | ||
147 | }; | 164 | }; |
148 | 165 | ||
149 | enum visibility_mask { | 166 | enum visibility_mask { |
diff --git a/include/sway/layout.h b/include/sway/layout.h index b982365c..38096947 100644 --- a/include/sway/layout.h +++ b/include/sway/layout.h | |||
@@ -75,4 +75,7 @@ void swayc_log(log_importance_t verbosity, swayc_t *cont, const char* format, .. | |||
75 | */ | 75 | */ |
76 | enum swayc_layouts default_layout(swayc_t *output); | 76 | enum swayc_layouts default_layout(swayc_t *output); |
77 | 77 | ||
78 | inline bool is_auto_layout(enum swayc_layouts layout) { | ||
79 | return (layout >= L_AUTO_LEFT) && (layout <= L_AUTO_BOTTOM); | ||
80 | } | ||
78 | #endif | 81 | #endif |
diff --git a/sway/commands/layout.c b/sway/commands/layout.c index 08336150..e6fa7ef1 100644 --- a/sway/commands/layout.c +++ b/sway/commands/layout.c | |||
@@ -54,6 +54,26 @@ struct cmd_results *cmd_layout(int argc, char **argv) { | |||
54 | } else { | 54 | } else { |
55 | swayc_change_layout(parent, L_HORIZ); | 55 | swayc_change_layout(parent, L_HORIZ); |
56 | } | 56 | } |
57 | } else if (strcasecmp(argv[0], "auto_left") == 0) { | ||
58 | if (parent->type != C_CONTAINER && !swayc_is_empty_workspace(parent)){ | ||
59 | parent = new_container(parent, L_AUTO_LEFT); | ||
60 | } | ||
61 | swayc_change_layout(parent, L_AUTO_LEFT); | ||
62 | } else if (strcasecmp(argv[0], "auto_right") == 0) { | ||
63 | if (parent->type != C_CONTAINER && !swayc_is_empty_workspace(parent)){ | ||
64 | parent = new_container(parent, L_AUTO_RIGHT); | ||
65 | } | ||
66 | swayc_change_layout(parent, L_AUTO_RIGHT); | ||
67 | } else if (strcasecmp(argv[0], "auto_top") == 0) { | ||
68 | if (parent->type != C_CONTAINER && !swayc_is_empty_workspace(parent)){ | ||
69 | parent = new_container(parent, L_AUTO_TOP); | ||
70 | } | ||
71 | swayc_change_layout(parent, L_AUTO_TOP); | ||
72 | } else if (strcasecmp(argv[0], "auto_bot") == 0) { | ||
73 | if (parent->type != C_CONTAINER && !swayc_is_empty_workspace(parent)){ | ||
74 | parent = new_container(parent, L_AUTO_BOTTOM); | ||
75 | } | ||
76 | swayc_change_layout(parent, L_AUTO_BOTTOM); | ||
57 | } | 77 | } |
58 | } | 78 | } |
59 | 79 | ||
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) { | |||
32 | c->layout = L_NONE; | 32 | c->layout = L_NONE; |
33 | c->workspace_layout = L_NONE; | 33 | c->workspace_layout = L_NONE; |
34 | c->type = type; | 34 | c->type = type; |
35 | c->nb_master = 1; | ||
36 | c->nb_slave_groups = 1; | ||
35 | if (type != C_VIEW) { | 37 | if (type != C_VIEW) { |
36 | c->children = create_list(); | 38 | c->children = create_list(); |
37 | } | 39 | } |
diff --git a/sway/debug_log.c b/sway/debug_log.c index 8d891a44..d1eafae8 100644 --- a/sway/debug_log.c +++ b/sway/debug_log.c | |||
@@ -38,6 +38,10 @@ static void container_log(const swayc_t *c, int depth) { | |||
38 | c->layout == L_STACKED ? "Stack": | 38 | c->layout == L_STACKED ? "Stack": |
39 | c->layout == L_TABBED ? "Tab": | 39 | c->layout == L_TABBED ? "Tab": |
40 | c->layout == L_FLOATING ? "Float": | 40 | c->layout == L_FLOATING ? "Float": |
41 | c->layout == L_AUTO_LEFT ? "A_lft": | ||
42 | c->layout == L_AUTO_RIGHT ? "A_rgt": | ||
43 | c->layout == L_AUTO_TOP ? "A_top": | ||
44 | c->layout == L_AUTO_BOTTOM ? "A_bot": | ||
41 | "Unknown"); | 45 | "Unknown"); |
42 | fprintf(stderr, "w:%4.f|h:%4.f|", c->width, c->height); | 46 | fprintf(stderr, "w:%4.f|h:%4.f|", c->width, c->height); |
43 | fprintf(stderr, "x:%4.f|y:%4.f|", c->x, c->y); | 47 | fprintf(stderr, "x:%4.f|y:%4.f|", c->x, c->y); |
diff --git a/sway/layout.c b/sway/layout.c index ea4a680d..52473d0d 100644 --- a/sway/layout.c +++ b/sway/layout.c | |||
@@ -118,7 +118,11 @@ swayc_t *add_sibling(swayc_t *fixed, swayc_t *active) { | |||
118 | list_add(parent->floating, active); | 118 | list_add(parent->floating, active); |
119 | } else { | 119 | } else { |
120 | int i = index_child(fixed); | 120 | int i = index_child(fixed); |
121 | list_insert(parent->children, i + 1, active); | 121 | if (is_auto_layout(parent->layout)) { |
122 | list_add(parent->children, active); | ||
123 | } else { | ||
124 | list_insert(parent->children, i + 1, active); | ||
125 | } | ||
122 | } | 126 | } |
123 | } | 127 | } |
124 | active->parent = parent; | 128 | active->parent = parent; |
@@ -769,6 +773,26 @@ void update_geometry(swayc_t *container) { | |||
769 | } | 773 | } |
770 | } | 774 | } |
771 | 775 | ||
776 | /** | ||
777 | * Layout application prototypes | ||
778 | */ | ||
779 | static void apply_horiz_layout(swayc_t *container, const double x, | ||
780 | const double y, const double width, | ||
781 | const double height, const int start, | ||
782 | const int end); | ||
783 | static void apply_vert_layout(swayc_t *container, const double x, | ||
784 | const double y, const double width, | ||
785 | const double height, const int start, | ||
786 | const int end); | ||
787 | static void apply_tabbed_or_stacked_layout(swayc_t *container, double x, | ||
788 | double y, double width, | ||
789 | double height); | ||
790 | |||
791 | static void apply_auto_layout(swayc_t *container, const double x, const double y, | ||
792 | const double width, const double height, | ||
793 | enum swayc_layouts group_layout, | ||
794 | bool master_first); | ||
795 | |||
772 | static void arrange_windows_r(swayc_t *container, double width, double height) { | 796 | static void arrange_windows_r(swayc_t *container, double width, double height) { |
773 | int i; | 797 | int i; |
774 | if (width == -1 || height == -1) { | 798 | if (width == -1 || height == -1) { |
@@ -776,14 +800,15 @@ static void arrange_windows_r(swayc_t *container, double width, double height) { | |||
776 | width = container->width; | 800 | width = container->width; |
777 | height = container->height; | 801 | height = container->height; |
778 | } | 802 | } |
779 | // pixels are indivisable. if we don't round the pixels, then the view | 803 | // pixels are indivisible. if we don't round the pixels, then the view |
780 | // calculations will be off (e.g. 50.5 + 50.5 = 101, but in reality it's | 804 | // calculations will be off (e.g. 50.5 + 50.5 = 101, but in reality it's |
781 | // 50 + 50 = 100). doing it here cascades properly to all width/height/x/y. | 805 | // 50 + 50 = 100). doing it here cascades properly to all width/height/x/y. |
782 | width = floor(width); | 806 | width = floor(width); |
783 | height = floor(height); | 807 | height = floor(height); |
784 | 808 | ||
785 | sway_log(L_DEBUG, "Arranging layout for %p %s %fx%f+%f,%f", container, | 809 | sway_log(L_DEBUG, "Arranging layout for %p %s %fx%f+%f,%f", container, |
786 | container->name, container->width, container->height, container->x, container->y); | 810 | container->name, container->width, container->height, container->x, |
811 | container->y); | ||
787 | 812 | ||
788 | double x = 0, y = 0; | 813 | double x = 0, y = 0; |
789 | switch (container->type) { | 814 | switch (container->type) { |
@@ -895,136 +920,323 @@ static void arrange_windows_r(swayc_t *container, double width, double height) { | |||
895 | break; | 920 | break; |
896 | } | 921 | } |
897 | 922 | ||
898 | double scale = 0; | ||
899 | switch (container->layout) { | 923 | switch (container->layout) { |
900 | case L_HORIZ: | 924 | case L_HORIZ: |
901 | default: | 925 | default: |
902 | // Calculate total width | 926 | apply_horiz_layout(container, x, y, width, height, 0, |
903 | for (i = 0; i < container->children->length; ++i) { | 927 | container->children->length); |
904 | double *old_width = &((swayc_t *)container->children->items[i])->width; | 928 | break; |
905 | if (*old_width <= 0) { | 929 | case L_VERT: |
906 | if (container->children->length > 1) { | 930 | apply_vert_layout(container, x, y, width, height, 0, |
907 | *old_width = width / (container->children->length - 1); | 931 | container->children->length); |
908 | } else { | 932 | break; |
909 | *old_width = width; | 933 | case L_TABBED: |
934 | case L_STACKED: | ||
935 | apply_tabbed_or_stacked_layout(container, x, y, width, height); | ||
936 | break; | ||
937 | case L_AUTO_LEFT: | ||
938 | apply_auto_layout(container, x, y, width, height, L_VERT, true); | ||
939 | break; | ||
940 | case L_AUTO_RIGHT: | ||
941 | apply_auto_layout(container, x, y, width, height, L_VERT, false); | ||
942 | break; | ||
943 | case L_AUTO_TOP: | ||
944 | apply_auto_layout(container, x, y, width, height, L_HORIZ, true); | ||
945 | break; | ||
946 | case L_AUTO_BOTTOM: | ||
947 | apply_auto_layout(container, x, y, width, height, L_HORIZ, false); | ||
948 | break; | ||
949 | } | ||
950 | |||
951 | // Arrage floating layouts for workspaces last | ||
952 | if (container->type == C_WORKSPACE) { | ||
953 | for (int i = 0; i < container->floating->length; ++i) { | ||
954 | swayc_t *view = container->floating->items[i]; | ||
955 | if (view->type == C_VIEW) { | ||
956 | update_geometry(view); | ||
957 | sway_log(L_DEBUG, "Set floating view to %.f x %.f @ %.f, %.f", | ||
958 | view->width, view->height, view->x, view->y); | ||
959 | if (swayc_is_fullscreen(view)) { | ||
960 | wlc_view_bring_to_front(view->handle); | ||
961 | } else if (!container->focused || | ||
962 | !swayc_is_fullscreen(container->focused)) { | ||
963 | wlc_view_bring_to_front(view->handle); | ||
910 | } | 964 | } |
911 | } | 965 | } |
912 | scale += *old_width; | ||
913 | } | 966 | } |
967 | } | ||
968 | } | ||
914 | 969 | ||
915 | // Resize windows | 970 | void apply_horiz_layout(swayc_t *container, const double x, const double y, |
916 | if (scale > 0.1) { | 971 | const double width, const double height, |
917 | scale = width / scale; | 972 | const int start, const int end) { |
918 | sway_log(L_DEBUG, "Arranging %p horizontally", container); | 973 | double scale = 0; |
919 | swayc_t *focused = NULL; | 974 | // Calculate total width |
920 | for (i = 0; i < container->children->length; ++i) { | 975 | for (int i = start; i < end; ++i) { |
921 | swayc_t *child = container->children->items[i]; | 976 | double *old_width = &((swayc_t *)container->children->items[i])->width; |
922 | sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, width, scale); | 977 | if (*old_width <= 0) { |
923 | child->x = x; | 978 | if (end - start > 1) { |
924 | child->y = y; | 979 | *old_width = width / (end - start - 1); |
925 | 980 | } else { | |
926 | if (child == container->focused) { | 981 | *old_width = width; |
927 | focused = child; | 982 | } |
928 | } | 983 | } |
984 | scale += *old_width; | ||
985 | } | ||
929 | 986 | ||
930 | if (i == container->children->length - 1) { | 987 | // Resize windows |
931 | double remaining_width = container->x + width - x; | 988 | double child_x = x; |
932 | arrange_windows_r(child, remaining_width, height); | 989 | if (scale > 0.1) { |
933 | } else { | 990 | scale = width / scale; |
934 | arrange_windows_r(child, child->width * scale, height); | 991 | sway_log(L_DEBUG, "Arranging %p horizontally", container); |
935 | } | 992 | swayc_t *focused = NULL; |
936 | x += child->width; | 993 | for (int i = start; i < end; ++i) { |
994 | swayc_t *child = container->children->items[i]; | ||
995 | sway_log(L_DEBUG, | ||
996 | "Calculating arrangement for %p:%d (will scale %f by %f)", child, | ||
997 | child->type, width, scale); | ||
998 | child->x = child_x; | ||
999 | child->y = y; | ||
1000 | |||
1001 | if (child == container->focused) { | ||
1002 | focused = child; | ||
937 | } | 1003 | } |
938 | 1004 | ||
939 | // update focused view border last because it may | 1005 | if (i == end - 1) { |
940 | // depend on the title bar geometry of its siblings. | 1006 | double remaining_width = x + width - child_x; |
941 | if (focused && container->children->length > 1) { | 1007 | arrange_windows_r(child, remaining_width, height); |
942 | update_container_border(focused); | 1008 | } else { |
1009 | arrange_windows_r(child, child->width * scale, height); | ||
943 | } | 1010 | } |
1011 | child_x += child->width; | ||
944 | } | 1012 | } |
945 | break; | 1013 | |
946 | case L_VERT: | 1014 | // update focused view border last because it may |
947 | // Calculate total height | 1015 | // depend on the title bar geometry of its siblings. |
948 | for (i = 0; i < container->children->length; ++i) { | 1016 | if (focused && container->children->length > 1) { |
949 | double *old_height = &((swayc_t *)container->children->items[i])->height; | 1017 | update_container_border(focused); |
950 | if (*old_height <= 0) { | ||
951 | if (container->children->length > 1) { | ||
952 | *old_height = height / (container->children->length - 1); | ||
953 | } else { | ||
954 | *old_height = height; | ||
955 | } | ||
956 | } | ||
957 | scale += *old_height; | ||
958 | } | 1018 | } |
959 | // Resize | 1019 | } |
960 | if (scale > 0.1) { | 1020 | } |
961 | scale = height / scale; | ||
962 | sway_log(L_DEBUG, "Arranging %p vertically", container); | ||
963 | swayc_t *focused = NULL; | ||
964 | for (i = 0; i < container->children->length; ++i) { | ||
965 | swayc_t *child = container->children->items[i]; | ||
966 | sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, height, scale); | ||
967 | child->x = x; | ||
968 | child->y = y; | ||
969 | |||
970 | if (child == container->focused) { | ||
971 | focused = child; | ||
972 | } | ||
973 | 1021 | ||
974 | if (i == container->children->length - 1) { | 1022 | void apply_vert_layout(swayc_t *container, const double x, const double y, |
975 | double remaining_height = container->y + height - y; | 1023 | const double width, const double height, const int start, |
976 | arrange_windows_r(child, width, remaining_height); | 1024 | const int end) { |
977 | } else { | 1025 | int i; |
978 | arrange_windows_r(child, width, child->height * scale); | 1026 | double scale = 0; |
979 | } | 1027 | // Calculate total height |
980 | y += child->height; | 1028 | for (i = start; i < end; ++i) { |
1029 | double *old_height = &((swayc_t *)container->children->items[i])->height; | ||
1030 | if (*old_height <= 0) { | ||
1031 | if (end - start > 1) { | ||
1032 | *old_height = height / (end - start - 1); | ||
1033 | } else { | ||
1034 | *old_height = height; | ||
1035 | } | ||
1036 | } | ||
1037 | scale += *old_height; | ||
1038 | } | ||
1039 | // Resize | ||
1040 | double child_y = y; | ||
1041 | if (scale > 0.1) { | ||
1042 | scale = height / scale; | ||
1043 | sway_log(L_DEBUG, "Arranging %p vertically", container); | ||
1044 | swayc_t *focused = NULL; | ||
1045 | for (i = start; i < end; ++i) { | ||
1046 | swayc_t *child = container->children->items[i]; | ||
1047 | sway_log(L_DEBUG, | ||
1048 | "Calculating arrangement for %p:%d (will scale %f by %f)", child, | ||
1049 | child->type, height, scale); | ||
1050 | child->x = x; | ||
1051 | child->y = child_y; | ||
1052 | |||
1053 | if (child == container->focused) { | ||
1054 | focused = child; | ||
981 | } | 1055 | } |
982 | 1056 | ||
983 | // update focused view border last because it may | 1057 | if (i == end - 1) { |
984 | // depend on the title bar geometry of its siblings. | 1058 | double remaining_height = y + height - child_y; |
985 | if (focused && container->children->length > 1) { | 1059 | arrange_windows_r(child, width, remaining_height); |
986 | update_container_border(focused); | 1060 | } else { |
1061 | arrange_windows_r(child, width, child->height * scale); | ||
987 | } | 1062 | } |
1063 | child_y += child->height; | ||
1064 | } | ||
1065 | |||
1066 | // update focused view border last because it may | ||
1067 | // depend on the title bar geometry of its siblings. | ||
1068 | if (focused && container->children->length > 1) { | ||
1069 | update_container_border(focused); | ||
1070 | } | ||
1071 | } | ||
1072 | } | ||
1073 | |||
1074 | void apply_tabbed_or_stacked_layout(swayc_t *container, double x, double y, | ||
1075 | double width, double height) { | ||
1076 | int i; | ||
1077 | swayc_t *focused = NULL; | ||
1078 | for (i = 0; i < container->children->length; ++i) { | ||
1079 | swayc_t *child = container->children->items[i]; | ||
1080 | child->x = x; | ||
1081 | child->y = y; | ||
1082 | if (child == container->focused) { | ||
1083 | focused = child; | ||
1084 | } else { | ||
1085 | arrange_windows_r(child, width, height); | ||
988 | } | 1086 | } |
1087 | } | ||
1088 | |||
1089 | if (focused) { | ||
1090 | arrange_windows_r(focused, width, height); | ||
1091 | } | ||
1092 | } | ||
1093 | |||
1094 | void apply_auto_layout(swayc_t *container, const double x, const double y, | ||
1095 | const double width, const double height, | ||
1096 | enum swayc_layouts group_layout, | ||
1097 | bool master_first) { | ||
1098 | // Auto layout "container" in width x height @ x, y | ||
1099 | // using "group_layout" for each of the groups in the container. | ||
1100 | // There is one "master" group, plus container->nb_slave_groups. | ||
1101 | // Each group is layed out side by side following the "major" axis. | ||
1102 | // The direction of the layout used for groups is the "minor" axis. | ||
1103 | // Example: | ||
1104 | // | ||
1105 | // ---- major axis --> | ||
1106 | // +---------+-----------+ | ||
1107 | // | | | | | ||
1108 | // | master | slave 1 | | | ||
1109 | // | +-----------+ | minor axis (direction of group_layout) | ||
1110 | // | | | | | ||
1111 | // | | slave 2 | V | ||
1112 | // +---------+-----------+ | ||
1113 | // | ||
1114 | // container with three children (one master and two slaves) and | ||
1115 | // a single slave group (containing slave 1 and 2). The master | ||
1116 | // group and slave group are layed out using L_VERT. | ||
1117 | |||
1118 | uint_fast32_t nb_slaves = container->children->length - container->nb_master; | ||
1119 | uint_fast32_t nb_groups = (container->nb_master > 0 ? 1 : 0) + | ||
1120 | MIN(container->nb_slave_groups, nb_slaves); | ||
1121 | |||
1122 | // the target dimension of the container along the "major" axis, each | ||
1123 | // group in the container will be layed out using "group_layout" along | ||
1124 | // the "minor" axis. | ||
1125 | double dim_maj; | ||
1126 | double pos_maj; | ||
1127 | |||
1128 | // x and y coords for the next group to be laid out. | ||
1129 | const double *group_x, *group_y; | ||
1130 | |||
1131 | // pos of the next group to layout along the major axis | ||
1132 | double pos; | ||
1133 | |||
1134 | // size of the next group along the major axis. | ||
1135 | double group_dim; | ||
1136 | |||
1137 | // height and width of next group to be laid out. | ||
1138 | const double *group_h, *group_w; | ||
1139 | |||
1140 | switch(group_layout) { | ||
1141 | default: | ||
1142 | sway_log(L_ERROR, "Unknown layout type (%d) used in %s()", | ||
1143 | group_layout, __func__); | ||
1144 | /* fall through */ | ||
1145 | case L_VERT: | ||
1146 | dim_maj = width; | ||
1147 | pos_maj = x; | ||
1148 | |||
1149 | group_x = &pos; | ||
1150 | group_y = &y; | ||
1151 | group_w = &group_dim; | ||
1152 | group_h = &height; | ||
989 | break; | 1153 | break; |
990 | case L_TABBED: | 1154 | case L_HORIZ: |
991 | case L_STACKED: | 1155 | dim_maj = height; |
992 | { | 1156 | pos_maj = y; |
993 | swayc_t *focused = NULL; | ||
994 | for (i = 0; i < container->children->length; ++i) { | ||
995 | swayc_t *child = container->children->items[i]; | ||
996 | child->x = x; | ||
997 | child->y = y; | ||
998 | if (child == container->focused) { | ||
999 | focused = child; | ||
1000 | } else { | ||
1001 | arrange_windows_r(child, width, height); | ||
1002 | } | ||
1003 | } | ||
1004 | 1157 | ||
1005 | if (focused) { | 1158 | group_x = &x; |
1006 | arrange_windows_r(focused, width, height); | 1159 | group_y = &pos; |
1160 | group_w = &width; | ||
1161 | group_h = &group_dim; | ||
1162 | break; | ||
1163 | } | ||
1164 | |||
1165 | /* Determine the dimension of each of the groups in the layout. | ||
1166 | * Dimension will be width for a VERT layout and height for a HORIZ | ||
1167 | * layout. */ | ||
1168 | double old_group_dim[nb_groups]; | ||
1169 | double old_dim = 0; | ||
1170 | uint_fast32_t group = 0; | ||
1171 | for (int i = 0; i < container->children->length;) { | ||
1172 | swayc_t *child = container->children->items[i]; | ||
1173 | double *dim = group_layout == L_HORIZ ? &child->height : &child->width; | ||
1174 | if (*dim <= 0) { | ||
1175 | // New child with uninitialized dimension | ||
1176 | *dim = dim_maj; | ||
1177 | if (nb_groups > 1) { | ||
1178 | // child gets a dimension proportional to existing groups, | ||
1179 | // it will be later scaled based on to the available size | ||
1180 | // in the major axis. | ||
1181 | *dim /= (nb_groups - 1); | ||
1007 | } | 1182 | } |
1008 | break; | ||
1009 | } | 1183 | } |
1184 | if (i == 0 && container->nb_master > 0) { | ||
1185 | i += container->nb_master; | ||
1186 | } else { | ||
1187 | i += (nb_slaves - i + container->nb_master) / (nb_groups - group); | ||
1188 | } | ||
1189 | old_dim += *dim; | ||
1190 | old_group_dim[group++] = *dim; | ||
1010 | } | 1191 | } |
1011 | 1192 | ||
1012 | // Arrage floating layouts for workspaces last | 1193 | double scale = dim_maj / old_dim; |
1013 | if (container->type == C_WORKSPACE) { | 1194 | |
1014 | for (i = 0; i < container->floating->length; ++i) { | 1195 | /* Apply layout to each group */ |
1015 | swayc_t *view = container->floating->items[i]; | 1196 | pos = pos_maj; |
1016 | if (view->type == C_VIEW) { | 1197 | |
1017 | update_geometry(view); | 1198 | // first child in the current group |
1018 | sway_log(L_DEBUG, "Set floating view to %.f x %.f @ %.f, %.f", view->width, | 1199 | int start; |
1019 | view->height, view->x, view->y); | 1200 | |
1020 | if (swayc_is_fullscreen(view)) { | 1201 | // index immediately after the last child in the current group |
1021 | wlc_view_bring_to_front(view->handle); | 1202 | int end = 0; |
1022 | } else if (!container->focused | 1203 | |
1023 | || !swayc_is_fullscreen(container->focused)) { | 1204 | for (group = 0; group < nb_groups; ++group) { |
1024 | wlc_view_bring_to_front(view->handle); | 1205 | // column to include next by increasing position. |
1025 | } | 1206 | uint_fast32_t layout_group = master_first ? group : (group + 1) % nb_groups; |
1207 | |||
1208 | // adjusted size of the group | ||
1209 | group_dim = old_group_dim[layout_group] * scale; | ||
1210 | if (container->nb_master > 0 && layout_group == 0) { | ||
1211 | start = 0; | ||
1212 | end = container->nb_master; | ||
1213 | } else { | ||
1214 | if (group == 0) { | ||
1215 | start = container->nb_master; | ||
1216 | } else { | ||
1217 | start = end; | ||
1026 | } | 1218 | } |
1219 | end = start + | ||
1220 | (nb_slaves - start + container->nb_master) / (nb_groups - layout_group); | ||
1027 | } | 1221 | } |
1222 | if (group == nb_groups - 1) { | ||
1223 | group_dim = pos_maj + dim_maj - pos; // remaining width | ||
1224 | } | ||
1225 | sway_log(L_DEBUG, "Arranging container %p column %" PRIuFAST32 | ||
1226 | ", children [%d,%d[ (%fx%f+%f,%f)", | ||
1227 | container, group, start, end, *group_w, *group_h, *group_x, *group_y); | ||
1228 | switch (group_layout) { | ||
1229 | default: | ||
1230 | case L_VERT: | ||
1231 | apply_vert_layout(container, *group_x, *group_y, *group_w, *group_h, start, end); | ||
1232 | break; | ||
1233 | case L_HORIZ: | ||
1234 | apply_horiz_layout(container, *group_x, *group_y, *group_w, *group_h, start, end); | ||
1235 | break; | ||
1236 | } | ||
1237 | |||
1238 | /* update position for next group */ | ||
1239 | pos += group_dim; | ||
1028 | } | 1240 | } |
1029 | } | 1241 | } |
1030 | 1242 | ||
diff --git a/sway/sway.5.txt b/sway/sway.5.txt index 7980ba82..1f25ce14 100644 --- a/sway/sway.5.txt +++ b/sway/sway.5.txt | |||
@@ -81,7 +81,8 @@ They are expected to be used with **bindsym** or at runtime through **swaymsg**( | |||
81 | 81 | ||
82 | **layout** <mode>:: | 82 | **layout** <mode>:: |
83 | Sets the layout mode of the focused container. _mode_ can be one of _splith_, | 83 | Sets the layout mode of the focused container. _mode_ can be one of _splith_, |
84 | _splitv_, _toggle split_, _stacking_ or _tabbed_. | 84 | _splitv_, _toggle split_, _stacking_, _tabbed_, _auto_left_, _auto_right_, |
85 | _auto_top, _auto_bottom_. | ||
85 | 86 | ||
86 | **move** <left|right|up|down>:: | 87 | **move** <left|right|up|down>:: |
87 | Moves the focused container _left_, _right_, _up_, or _down_. | 88 | Moves the focused container _left_, _right_, _up_, or _down_. |