diff options
-rw-r--r-- | README.md | 5 | ||||
-rw-r--r-- | include/sway/container.h | 4 | ||||
-rw-r--r-- | include/sway/focus.h | 3 | ||||
-rw-r--r-- | sway/commands/layout.c | 34 | ||||
-rw-r--r-- | sway/commands/move.c | 4 | ||||
-rw-r--r-- | sway/commands/resize.c | 70 | ||||
-rw-r--r-- | sway/layout.c | 56 | ||||
-rw-r--r-- | sway/sway.5.txt | 9 |
8 files changed, 99 insertions, 86 deletions
@@ -1,4 +1,3 @@ | |||
1 | |||
2 | # sway [![](https://api.travis-ci.org/SirCmpwn/sway.svg)](https://travis-ci.org/SirCmpwn/sway) [![Donate with fosspay](https://drewdevault.com/donate/static/donate-with-fosspay.png)](https://drewdevault.com/donate?project=4) | 1 | # sway [![](https://api.travis-ci.org/SirCmpwn/sway.svg)](https://travis-ci.org/SirCmpwn/sway) [![Donate with fosspay](https://drewdevault.com/donate/static/donate-with-fosspay.png)](https://drewdevault.com/donate?project=4) |
3 | 2 | ||
4 | "**S**irCmpwn's **Way**land compositor" is a **work in progress** | 3 | "**S**irCmpwn's **Way**land compositor" is a **work in progress** |
@@ -11,10 +10,6 @@ irc.freenode.net). | |||
11 | 10 | ||
12 | [More screenshots](https://github.com/SirCmpwn/sway/wiki/Screenshots-of-Sway) | 11 | [More screenshots](https://github.com/SirCmpwn/sway/wiki/Screenshots-of-Sway) |
13 | 12 | ||
14 | This fork attempts to add | ||
15 | [Awesome](http://awesomewm.org)/[Monad](http://xmonad.org) style auto layouts | ||
16 | to Sway. For us lazies that just want things to happen automatically! | ||
17 | |||
18 | ## Release Signatures | 13 | ## Release Signatures |
19 | 14 | ||
20 | Releases are signed with [B22DA89A](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x52CB6609B22DA89A) | 15 | Releases are signed with [B22DA89A](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x52CB6609B22DA89A) |
diff --git a/include/sway/container.h b/include/sway/container.h index f0574b1b..ff65628c 100644 --- a/include/sway/container.h +++ b/include/sway/container.h | |||
@@ -158,12 +158,12 @@ struct sway_container { | |||
158 | /** | 158 | /** |
159 | * Number of master views in auto layouts. | 159 | * Number of master views in auto layouts. |
160 | */ | 160 | */ |
161 | uint32_t nb_master; | 161 | size_t nb_master; |
162 | 162 | ||
163 | /** | 163 | /** |
164 | * Number of slave groups (e.g. columns) in auto layouts. | 164 | * Number of slave groups (e.g. columns) in auto layouts. |
165 | */ | 165 | */ |
166 | uint32_t nb_slave_groups; | 166 | size_t nb_slave_groups; |
167 | }; | 167 | }; |
168 | 168 | ||
169 | enum visibility_mask { | 169 | enum visibility_mask { |
diff --git a/include/sway/focus.h b/include/sway/focus.h index 30c9e108..652cdccc 100644 --- a/include/sway/focus.h +++ b/include/sway/focus.h | |||
@@ -8,7 +8,8 @@ enum movement_direction { | |||
8 | MOVE_PARENT, | 8 | MOVE_PARENT, |
9 | MOVE_CHILD, | 9 | MOVE_CHILD, |
10 | MOVE_NEXT, | 10 | MOVE_NEXT, |
11 | MOVE_PREV | 11 | MOVE_PREV, |
12 | MOVE_FIRST | ||
12 | }; | 13 | }; |
13 | 14 | ||
14 | #include "container.h" | 15 | #include "container.h" |
diff --git a/sway/commands/layout.c b/sway/commands/layout.c index d908b95c..0cdac1b4 100644 --- a/sway/commands/layout.c +++ b/sway/commands/layout.c | |||
@@ -64,11 +64,18 @@ struct cmd_results *cmd_layout(int argc, char **argv) { | |||
64 | } else if (strcasecmp(argv[0], "auto_bot") == 0) { | 64 | } else if (strcasecmp(argv[0], "auto_bot") == 0) { |
65 | swayc_change_layout(parent, L_AUTO_BOTTOM); | 65 | swayc_change_layout(parent, L_AUTO_BOTTOM); |
66 | } else if (strcasecmp(argv[0], "incnmaster") == 0) { | 66 | } else if (strcasecmp(argv[0], "incnmaster") == 0) { |
67 | if ((error = checkarg(argc, "layout incnmaster", | 67 | const char *name = "layout incnmaster"; |
68 | if ((error = checkarg(argc, name, | ||
68 | EXPECTED_EQUAL_TO, 2))) { | 69 | EXPECTED_EQUAL_TO, 2))) { |
69 | return error; | 70 | return error; |
70 | } | 71 | } |
71 | int inc = (int) strtol(argv[1], NULL, 10); | 72 | char *end; |
73 | int inc = (int) strtol(argv[1], &end, 10); | ||
74 | if (*end) { | ||
75 | return cmd_results_new(CMD_INVALID, name, "Invalid %s command " | ||
76 | "(argument must be an integer)", name); | ||
77 | |||
78 | } | ||
72 | swayc_t *container = get_focused_view(swayc_active_workspace()); | 79 | swayc_t *container = get_focused_view(swayc_active_workspace()); |
73 | if (container && inc && | 80 | if (container && inc && |
74 | is_auto_layout(container->parent->layout) && | 81 | is_auto_layout(container->parent->layout) && |
@@ -83,11 +90,18 @@ struct cmd_results *cmd_layout(int argc, char **argv) { | |||
83 | container->parent->nb_master += inc; | 90 | container->parent->nb_master += inc; |
84 | } | 91 | } |
85 | } else if ((strcasecmp(argv[0], "incncol") == 0) && argc ==2) { | 92 | } else if ((strcasecmp(argv[0], "incncol") == 0) && argc ==2) { |
86 | if ((error = checkarg(argc, "layout incncol", | 93 | const char *name = "layout incncol"; |
94 | if ((error = checkarg(argc, name, | ||
87 | EXPECTED_EQUAL_TO, 2))) { | 95 | EXPECTED_EQUAL_TO, 2))) { |
88 | return error; | 96 | return error; |
89 | } | 97 | } |
90 | int inc = (int) strtol(argv[1], NULL, 10); | 98 | char *end; |
99 | int inc = (int) strtol(argv[1], &end, 10); | ||
100 | if (*end) { | ||
101 | return cmd_results_new(CMD_INVALID, name, "Invalid %s command " | ||
102 | "(argument must be an integer)", name); | ||
103 | |||
104 | } | ||
91 | swayc_t *container = get_focused_view(swayc_active_workspace()); | 105 | swayc_t *container = get_focused_view(swayc_active_workspace()); |
92 | if (container && inc && is_auto_layout(container->parent->layout) && | 106 | if (container && inc && is_auto_layout(container->parent->layout) && |
93 | ((int)container->parent->nb_slave_groups + inc >= 1)) { | 107 | ((int)container->parent->nb_slave_groups + inc >= 1)) { |
@@ -117,18 +131,6 @@ struct cmd_results *cmd_layout(int argc, char **argv) { | |||
117 | "Must be one of <prev|next>."); | 131 | "Must be one of <prev|next>."); |
118 | } | 132 | } |
119 | swayc_change_layout(parent, layout); | 133 | swayc_change_layout(parent, layout); |
120 | } else if (strcasecmp(argv[0], "promote") == 0) { | ||
121 | // swap first child in auto layout with currently focused child | ||
122 | swayc_t *container = get_focused_view(swayc_active_workspace()); | ||
123 | swayc_t *parent = container->parent; | ||
124 | if (is_auto_layout(parent->layout)) { | ||
125 | int focused_idx = index_child(container); | ||
126 | swayc_t *first = parent->children->items[0]; | ||
127 | if (focused_idx > 0) { | ||
128 | list_swap(parent->children, 0, focused_idx); | ||
129 | swap_geometry(first, container); | ||
130 | } | ||
131 | } | ||
132 | } | 134 | } |
133 | } | 135 | } |
134 | 136 | ||
diff --git a/sway/commands/move.c b/sway/commands/move.c index 4f6bc76f..0b134494 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c | |||
@@ -13,7 +13,7 @@ struct cmd_results *cmd_move(int argc, char **argv) { | |||
13 | if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) { | 13 | if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) { |
14 | return error; | 14 | return error; |
15 | } | 15 | } |
16 | const char* expected_syntax = "Expected 'move <left|right|up|down|next|prev>' or " | 16 | const char* expected_syntax = "Expected 'move <left|right|up|down|next|prev|first>' or " |
17 | "'move <container|window> to workspace <name>' or " | 17 | "'move <container|window> to workspace <name>' or " |
18 | "'move <container|window|workspace> to output <name|direction>' or " | 18 | "'move <container|window|workspace> to output <name|direction>' or " |
19 | "'move position mouse'"; | 19 | "'move position mouse'"; |
@@ -31,6 +31,8 @@ struct cmd_results *cmd_move(int argc, char **argv) { | |||
31 | move_container(view, MOVE_NEXT); | 31 | move_container(view, MOVE_NEXT); |
32 | } else if (strcasecmp(argv[0], "prev") == 0) { | 32 | } else if (strcasecmp(argv[0], "prev") == 0) { |
33 | move_container(view, MOVE_PREV); | 33 | move_container(view, MOVE_PREV); |
34 | } else if (strcasecmp(argv[0], "first") == 0) { | ||
35 | move_container(view, MOVE_FIRST); | ||
34 | } else if (strcasecmp(argv[0], "container") == 0 || strcasecmp(argv[0], "window") == 0) { | 36 | } else if (strcasecmp(argv[0], "container") == 0 || strcasecmp(argv[0], "window") == 0) { |
35 | // "move container ... | 37 | // "move container ... |
36 | if ((error = checkarg(argc, "move container/window", EXPECTED_AT_LEAST, 4))) { | 38 | if ((error = checkarg(argc, "move container/window", EXPECTED_AT_LEAST, 4))) { |
diff --git a/sway/commands/resize.c b/sway/commands/resize.c index 9a756e81..1c052286 100644 --- a/sway/commands/resize.c +++ b/sway/commands/resize.c | |||
@@ -66,7 +66,7 @@ static bool resize_floating(int amount, bool use_width) { | |||
66 | * Return the number of children in the slave groups. This corresponds to the children | 66 | * Return the number of children in the slave groups. This corresponds to the children |
67 | * that are not members of the master group. | 67 | * that are not members of the master group. |
68 | */ | 68 | */ |
69 | static inline uint_fast32_t slave_count(swayc_t *container) { | 69 | static inline size_t auto_slave_count(swayc_t *container) { |
70 | return container->children->length - container->nb_master; | 70 | return container->children->length - container->nb_master; |
71 | 71 | ||
72 | } | 72 | } |
@@ -75,13 +75,13 @@ static inline uint_fast32_t slave_count(swayc_t *container) { | |||
75 | * given the index of a container's child, return the index of the first child of the group | 75 | * given the index of a container's child, return the index of the first child of the group |
76 | * which index is a member of. | 76 | * which index is a member of. |
77 | */ | 77 | */ |
78 | static int group_start_index(swayc_t *container, int index) { | 78 | static int auto_group_start_index(swayc_t *container, int index) { |
79 | if ((index < 0) || (! is_auto_layout(container->layout)) || | 79 | if (index < 0 || ! is_auto_layout(container->layout) |
80 | ((uint_fast32_t) index < container->nb_master)) { | 80 | || (size_t) index < container->nb_master) { |
81 | return 0; | 81 | return 0; |
82 | } else { | 82 | } else { |
83 | uint_fast32_t grp_sz = slave_count(container) / container->nb_slave_groups; | 83 | size_t grp_sz = auto_slave_count(container) / container->nb_slave_groups; |
84 | uint_fast32_t remainder = slave_count(container) % container->nb_slave_groups; | 84 | size_t remainder = auto_slave_count(container) % container->nb_slave_groups; |
85 | int start_idx; | 85 | int start_idx; |
86 | int idx2 = (container->nb_slave_groups - remainder) * grp_sz + container->nb_master; | 86 | int idx2 = (container->nb_slave_groups - remainder) * grp_sz + container->nb_master; |
87 | if (index < idx2) { | 87 | if (index < idx2) { |
@@ -98,16 +98,16 @@ static int group_start_index(swayc_t *container, int index) { | |||
98 | * that follows the one which index is a member of. | 98 | * that follows the one which index is a member of. |
99 | * This makes the function usable to walk through the groups in a container. | 99 | * This makes the function usable to walk through the groups in a container. |
100 | */ | 100 | */ |
101 | static int group_end_index(swayc_t *container, int index) { | 101 | static int auto_group_end_index(swayc_t *container, int index) { |
102 | if (index < 0 || ! is_auto_layout(container->layout)) { | 102 | if (index < 0 || ! is_auto_layout(container->layout)) { |
103 | return container->children->length; | 103 | return container->children->length; |
104 | } else { | 104 | } else { |
105 | int nxt_idx; | 105 | int nxt_idx; |
106 | if ((uint_fast32_t)index < container->nb_master) { | 106 | if ((size_t)index < container->nb_master) { |
107 | nxt_idx = container->nb_master; | 107 | nxt_idx = container->nb_master; |
108 | } else { | 108 | } else { |
109 | uint_fast32_t grp_sz = slave_count(container) / container->nb_slave_groups; | 109 | size_t grp_sz = auto_slave_count(container) / container->nb_slave_groups; |
110 | uint_fast32_t remainder = slave_count(container) % container->nb_slave_groups; | 110 | size_t remainder = auto_slave_count(container) % container->nb_slave_groups; |
111 | int idx2 = (container->nb_slave_groups - remainder) * grp_sz + container->nb_master; | 111 | int idx2 = (container->nb_slave_groups - remainder) * grp_sz + container->nb_master; |
112 | if (index < idx2) { | 112 | if (index < idx2) { |
113 | nxt_idx = ((index - container->nb_master) / grp_sz + 1) * grp_sz + container->nb_master; | 113 | nxt_idx = ((index - container->nb_master) / grp_sz + 1) * grp_sz + container->nb_master; |
@@ -122,30 +122,30 @@ static int group_end_index(swayc_t *container, int index) { | |||
122 | /** | 122 | /** |
123 | * Return the combined number of master and slave groups in the container. | 123 | * Return the combined number of master and slave groups in the container. |
124 | */ | 124 | */ |
125 | static inline uint_fast32_t group_count(swayc_t *container) { | 125 | static inline size_t auto_group_count(swayc_t *container) { |
126 | return MIN(container->nb_slave_groups, slave_count(container)) + (container->nb_master ? 1 : 0); | 126 | return MIN(container->nb_slave_groups, auto_slave_count(container)) + (container->nb_master ? 1 : 0); |
127 | } | 127 | } |
128 | 128 | ||
129 | /** | 129 | /** |
130 | * return the index of the Group containing <index>th child of <container>. | 130 | * return the index of the Group containing <index>th child of <container>. |
131 | * The index is the order of the group along the container's major axis (starting at 0). | 131 | * The index is the order of the group along the container's major axis (starting at 0). |
132 | */ | 132 | */ |
133 | static uint_fast32_t group_index(swayc_t *container, int index) { | 133 | static size_t auto_group_index(swayc_t *container, int index) { |
134 | if (index < 0) { | 134 | if (index < 0) { |
135 | return 0; | 135 | return 0; |
136 | } | 136 | } |
137 | bool master_first = (container->layout == L_AUTO_LEFT || container->layout == L_AUTO_TOP); | 137 | bool master_first = (container->layout == L_AUTO_LEFT || container->layout == L_AUTO_TOP); |
138 | int nb_slaves = slave_count(container); | 138 | int nb_slaves = auto_slave_count(container); |
139 | if ((uint_fast32_t) index < container->nb_master) { | 139 | if ((size_t) index < container->nb_master) { |
140 | if (master_first || nb_slaves <= 0) { | 140 | if (master_first || nb_slaves <= 0) { |
141 | return 0; | 141 | return 0; |
142 | } else { | 142 | } else { |
143 | return MIN(container->nb_slave_groups, nb_slaves); | 143 | return MIN(container->nb_slave_groups, nb_slaves); |
144 | } | 144 | } |
145 | } else { | 145 | } else { |
146 | uint_fast32_t grp_sz = slave_count(container) / container->nb_slave_groups; | 146 | size_t grp_sz = auto_slave_count(container) / container->nb_slave_groups; |
147 | uint_fast32_t remainder = slave_count(container) % container->nb_slave_groups; | 147 | size_t remainder = auto_slave_count(container) % container->nb_slave_groups; |
148 | uint_fast32_t grp_idx; | 148 | size_t grp_idx; |
149 | int idx2 = (container->nb_slave_groups - remainder) * grp_sz + container->nb_master; | 149 | int idx2 = (container->nb_slave_groups - remainder) * grp_sz + container->nb_master; |
150 | if (index < idx2) { | 150 | if (index < idx2) { |
151 | grp_idx = (index - container->nb_master) / grp_sz; | 151 | grp_idx = (index - container->nb_master) / grp_sz; |
@@ -161,16 +161,16 @@ static bool resize_tiled(int amount, bool use_width) { | |||
161 | swayc_t *parent = container->parent; | 161 | swayc_t *parent = container->parent; |
162 | int idx_focused = 0; | 162 | int idx_focused = 0; |
163 | bool use_major = false; | 163 | bool use_major = false; |
164 | uint_fast32_t nb_before = 0; | 164 | size_t nb_before = 0; |
165 | uint_fast32_t nb_after = 0; | 165 | size_t nb_after = 0; |
166 | 166 | ||
167 | // 1. Identify a container ancestor that will allow the focused child to grow in the requested | 167 | // 1. Identify a container ancestor that will allow the focused child to grow in the requested |
168 | // direction. | 168 | // direction. |
169 | while (container->parent) { | 169 | while (container->parent) { |
170 | parent = container->parent; | 170 | parent = container->parent; |
171 | if ((parent->children && parent->children->length > 1) && | 171 | if ((parent->children && parent->children->length > 1) |
172 | (is_auto_layout(parent->layout) || (use_width ? parent->layout == L_HORIZ : | 172 | && (is_auto_layout(parent->layout) |
173 | parent->layout == L_VERT))) { | 173 | || (use_width ? parent->layout == L_HORIZ : parent->layout == L_VERT))) { |
174 | // check if container has siblings that can provide/absorb the space needed for | 174 | // check if container has siblings that can provide/absorb the space needed for |
175 | // the resize operation. | 175 | // the resize operation. |
176 | use_major = use_width | 176 | use_major = use_width |
@@ -185,15 +185,15 @@ static bool resize_tiled(int amount, bool use_width) { | |||
185 | continue; | 185 | continue; |
186 | } | 186 | } |
187 | if (use_major) { | 187 | if (use_major) { |
188 | nb_before = group_index(parent, idx_focused); | 188 | nb_before = auto_group_index(parent, idx_focused); |
189 | nb_after = group_count(parent) - nb_before - 1; | 189 | nb_after = auto_group_count(parent) - nb_before - 1; |
190 | } else { | 190 | } else { |
191 | nb_before = idx_focused - group_start_index(parent, idx_focused); | 191 | nb_before = idx_focused - auto_group_start_index(parent, idx_focused); |
192 | nb_after = group_end_index(parent, idx_focused) - idx_focused - 1; | 192 | nb_after = auto_group_end_index(parent, idx_focused) - idx_focused - 1; |
193 | sway_log(L_DEBUG, "+++ focused: %d, start: %d, end: %d, before: %d, after: %d", | 193 | sway_log(L_DEBUG, "+++ focused: %d, start: %d, end: %d, before: %d, after: %d", |
194 | idx_focused, | 194 | idx_focused, |
195 | (int)group_start_index(parent, idx_focused), | 195 | (int)auto_group_start_index(parent, idx_focused), |
196 | (int)group_end_index(parent, idx_focused), | 196 | (int)auto_group_end_index(parent, idx_focused), |
197 | (int)nb_before, (int)nb_after); | 197 | (int)nb_before, (int)nb_after); |
198 | 198 | ||
199 | } | 199 | } |
@@ -206,14 +206,14 @@ static bool resize_tiled(int amount, bool use_width) { | |||
206 | if (parent == &root_container) { | 206 | if (parent == &root_container) { |
207 | return true; | 207 | return true; |
208 | } | 208 | } |
209 | sway_log(L_DEBUG, "Found the proper parent: %p. It has %" PRIuFAST32 " before conts, and %" | 209 | sway_log(L_DEBUG, "Found the proper parent: %p. It has %zu before conts, " |
210 | PRIuFAST32 " after conts", parent, nb_before, nb_after); | 210 | "and %zu after conts", parent, nb_before, nb_after); |
211 | // 2. Ensure that the resize operation will not make one of the resized containers drop | 211 | // 2. Ensure that the resize operation will not make one of the resized containers drop |
212 | // below the "sane" size threshold. | 212 | // below the "sane" size threshold. |
213 | bool valid = true; | 213 | bool valid = true; |
214 | swayc_t *focused = parent->children->items[idx_focused]; | 214 | swayc_t *focused = parent->children->items[idx_focused]; |
215 | int start = use_major ? 0 : group_start_index(parent, idx_focused); | 215 | int start = use_major ? 0 : auto_group_start_index(parent, idx_focused); |
216 | int end = use_major ? parent->children->length : group_end_index(parent, idx_focused); | 216 | int end = use_major ? parent->children->length : auto_group_end_index(parent, idx_focused); |
217 | sway_log(L_DEBUG, "Check children of container %p [%d,%d[", container, start, end); | 217 | sway_log(L_DEBUG, "Check children of container %p [%d,%d[", container, start, end); |
218 | for (int i = start; i < end; ) { | 218 | for (int i = start; i < end; ) { |
219 | swayc_t *sibling = parent->children->items[i]; | 219 | swayc_t *sibling = parent->children->items[i]; |
@@ -235,13 +235,13 @@ static bool resize_tiled(int amount, bool use_width) { | |||
235 | sway_log(L_DEBUG, "Container size no longer sane"); | 235 | sway_log(L_DEBUG, "Container size no longer sane"); |
236 | break; | 236 | break; |
237 | } | 237 | } |
238 | i = use_major ? group_end_index(parent, i) : (i + 1); | 238 | i = use_major ? auto_group_end_index(parent, i) : (i + 1); |
239 | sway_log(L_DEBUG, "+++++ check %i", i); | 239 | sway_log(L_DEBUG, "+++++ check %i", i); |
240 | } | 240 | } |
241 | // 3. Apply the size change | 241 | // 3. Apply the size change |
242 | if (valid) { | 242 | if (valid) { |
243 | for (int i = start; i < end; ) { | 243 | for (int i = start; i < end; ) { |
244 | int next_i = use_major ? group_end_index(parent, i) : (i + 1); | 244 | int next_i = use_major ? auto_group_end_index(parent, i) : (i + 1); |
245 | swayc_t *sibling = parent->children->items[i]; | 245 | swayc_t *sibling = parent->children->items[i]; |
246 | double pixels = amount; | 246 | double pixels = amount; |
247 | bool is_before = use_width ? sibling->x < focused->x : sibling->y < focused->y; | 247 | bool is_before = use_width ? sibling->x < focused->x : sibling->y < focused->y; |
diff --git a/sway/layout.c b/sway/layout.c index 2195863e..377dad47 100644 --- a/sway/layout.c +++ b/sway/layout.c | |||
@@ -252,18 +252,31 @@ void swap_geometry(swayc_t *a, swayc_t *b) { | |||
252 | 252 | ||
253 | void move_container(swayc_t *container, enum movement_direction dir) { | 253 | void move_container(swayc_t *container, enum movement_direction dir) { |
254 | enum swayc_layouts layout = L_NONE; | 254 | enum swayc_layouts layout = L_NONE; |
255 | if (container->is_floating | 255 | swayc_t *parent = container->parent; |
256 | || (container->type != C_VIEW && container->type != C_CONTAINER)) { | 256 | if (container->is_floating || (container->type != C_VIEW && container->type != C_CONTAINER)) { |
257 | return; | 257 | return; |
258 | } | 258 | } |
259 | if (dir == MOVE_UP || dir == MOVE_DOWN) { | 259 | if (dir == MOVE_UP || dir == MOVE_DOWN) { |
260 | layout = L_VERT; | 260 | layout = L_VERT; |
261 | } else if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { | 261 | } else if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { |
262 | layout = L_HORIZ; | 262 | layout = L_HORIZ; |
263 | } else if (dir == MOVE_FIRST) { | ||
264 | // swap first child in auto layout with currently focused child | ||
265 | if (is_auto_layout(parent->layout)) { | ||
266 | int focused_idx = index_child(container); | ||
267 | swayc_t *first = parent->children->items[0]; | ||
268 | if (focused_idx > 0) { | ||
269 | list_swap(parent->children, 0, focused_idx); | ||
270 | swap_geometry(first, container); | ||
271 | } | ||
272 | arrange_windows(parent->parent, -1, -1); | ||
273 | ipc_event_window(container, "move"); | ||
274 | set_focused_container_for(parent->parent, container); | ||
275 | } | ||
276 | return; | ||
263 | } else if (! (dir == MOVE_NEXT || dir == MOVE_PREV)) { | 277 | } else if (! (dir == MOVE_NEXT || dir == MOVE_PREV)) { |
264 | return; | 278 | return; |
265 | } | 279 | } |
266 | swayc_t *parent = container->parent; | ||
267 | swayc_t *child = container; | 280 | swayc_t *child = container; |
268 | bool ascended = false; | 281 | bool ascended = false; |
269 | 282 | ||
@@ -309,14 +322,14 @@ void move_container(swayc_t *container, enum movement_direction dir) { | |||
309 | // if move command makes container change from master to slave | 322 | // if move command makes container change from master to slave |
310 | // (or the contrary), reset its geometry an the one of the replaced item. | 323 | // (or the contrary), reset its geometry an the one of the replaced item. |
311 | if (parent->nb_master && | 324 | if (parent->nb_master && |
312 | (uint_fast32_t) parent->children->length > parent->nb_master) { | 325 | (size_t) parent->children->length > parent->nb_master) { |
313 | swayc_t *swap_geom = NULL; | 326 | swayc_t *swap_geom = NULL; |
314 | // if child is being promoted/demoted, it will swap geometry | 327 | // if child is being promoted/demoted, it will swap geometry |
315 | // with the sibling being demoted/promoted. | 328 | // with the sibling being demoted/promoted. |
316 | if ((dir == MOVE_NEXT && desired == 0) | 329 | if ((dir == MOVE_NEXT && desired == 0) |
317 | || (dir == MOVE_PREV && (uint_fast32_t) desired == parent->nb_master - 1)) { | 330 | || (dir == MOVE_PREV && (size_t) desired == parent->nb_master - 1)) { |
318 | swap_geom = parent->children->items[parent->nb_master - 1]; | 331 | swap_geom = parent->children->items[parent->nb_master - 1]; |
319 | } else if ((dir == MOVE_NEXT && (uint_fast32_t) desired == parent->nb_master) | 332 | } else if ((dir == MOVE_NEXT && (size_t) desired == parent->nb_master) |
320 | || (dir == MOVE_PREV && desired == parent->children->length - 1)) { | 333 | || (dir == MOVE_PREV && desired == parent->children->length - 1)) { |
321 | swap_geom = parent->children->items[parent->nb_master]; | 334 | swap_geom = parent->children->items[parent->nb_master]; |
322 | } | 335 | } |
@@ -812,16 +825,16 @@ void update_geometry(swayc_t *container) { | |||
812 | * Layout application prototypes | 825 | * Layout application prototypes |
813 | */ | 826 | */ |
814 | static void apply_horiz_layout(swayc_t *container, const double x, | 827 | static void apply_horiz_layout(swayc_t *container, const double x, |
815 | const double y, const double width, | 828 | const double y, const double width, |
816 | const double height, const int start, | 829 | const double height, const int start, |
817 | const int end); | 830 | const int end); |
818 | static void apply_vert_layout(swayc_t *container, const double x, | 831 | static void apply_vert_layout(swayc_t *container, const double x, |
819 | const double y, const double width, | 832 | const double y, const double width, |
820 | const double height, const int start, | 833 | const double height, const int start, |
821 | const int end); | 834 | const int end); |
822 | static void apply_tabbed_or_stacked_layout(swayc_t *container, double x, | 835 | static void apply_tabbed_or_stacked_layout(swayc_t *container, double x, |
823 | double y, double width, | 836 | double y, double width, |
824 | double height); | 837 | double height); |
825 | 838 | ||
826 | static void apply_auto_layout(swayc_t *container, const double x, const double y, | 839 | static void apply_auto_layout(swayc_t *container, const double x, const double y, |
827 | const double width, const double height, | 840 | const double width, const double height, |
@@ -1150,8 +1163,8 @@ void apply_auto_layout(swayc_t *container, const double x, const double y, | |||
1150 | // a single slave group (containing slave 1 and 2). The master | 1163 | // a single slave group (containing slave 1 and 2). The master |
1151 | // group and slave group are layed out using L_VERT. | 1164 | // group and slave group are layed out using L_VERT. |
1152 | 1165 | ||
1153 | uint_fast32_t nb_slaves = container->children->length - container->nb_master; | 1166 | size_t nb_slaves = container->children->length - container->nb_master; |
1154 | uint_fast32_t nb_groups = (container->nb_master > 0 ? 1 : 0) + | 1167 | size_t nb_groups = (container->nb_master > 0 ? 1 : 0) + |
1155 | MIN(container->nb_slave_groups, nb_slaves); | 1168 | MIN(container->nb_slave_groups, nb_slaves); |
1156 | 1169 | ||
1157 | // the target dimension of the container along the "major" axis, each | 1170 | // the target dimension of the container along the "major" axis, each |
@@ -1172,9 +1185,9 @@ void apply_auto_layout(swayc_t *container, const double x, const double y, | |||
1172 | // height and width of next group to be laid out. | 1185 | // height and width of next group to be laid out. |
1173 | const double *group_h, *group_w; | 1186 | const double *group_h, *group_w; |
1174 | 1187 | ||
1175 | switch(group_layout) { | 1188 | switch (group_layout) { |
1176 | default: | 1189 | default: |
1177 | sway_log(L_ERROR, "Unknown layout type (%d) used in %s()", | 1190 | sway_log(L_DEBUG, "Unknown layout type (%d) used in %s()", |
1178 | group_layout, __func__); | 1191 | group_layout, __func__); |
1179 | /* fall through */ | 1192 | /* fall through */ |
1180 | case L_VERT: | 1193 | case L_VERT: |
@@ -1202,7 +1215,7 @@ void apply_auto_layout(swayc_t *container, const double x, const double y, | |||
1202 | * layout. */ | 1215 | * layout. */ |
1203 | double old_group_dim[nb_groups]; | 1216 | double old_group_dim[nb_groups]; |
1204 | double old_dim = 0; | 1217 | double old_dim = 0; |
1205 | uint_fast32_t group = 0; | 1218 | size_t group = 0; |
1206 | for (int i = 0; i < container->children->length;) { | 1219 | for (int i = 0; i < container->children->length;) { |
1207 | swayc_t *child = container->children->items[i]; | 1220 | swayc_t *child = container->children->items[i]; |
1208 | double *dim = group_layout == L_HORIZ ? &child->height : &child->width; | 1221 | double *dim = group_layout == L_HORIZ ? &child->height : &child->width; |
@@ -1238,7 +1251,7 @@ void apply_auto_layout(swayc_t *container, const double x, const double y, | |||
1238 | 1251 | ||
1239 | for (group = 0; group < nb_groups; ++group) { | 1252 | for (group = 0; group < nb_groups; ++group) { |
1240 | // column to include next by increasing position. | 1253 | // column to include next by increasing position. |
1241 | uint_fast32_t layout_group = master_first ? group : (group + 1) % nb_groups; | 1254 | size_t layout_group = master_first ? group : (group + 1) % nb_groups; |
1242 | 1255 | ||
1243 | // adjusted size of the group | 1256 | // adjusted size of the group |
1244 | group_dim = old_group_dim[layout_group] * scale; | 1257 | group_dim = old_group_dim[layout_group] * scale; |
@@ -1256,8 +1269,7 @@ void apply_auto_layout(swayc_t *container, const double x, const double y, | |||
1256 | if (group == nb_groups - 1) { | 1269 | if (group == nb_groups - 1) { |
1257 | group_dim = pos_maj + dim_maj - pos; // remaining width | 1270 | group_dim = pos_maj + dim_maj - pos; // remaining width |
1258 | } | 1271 | } |
1259 | sway_log(L_DEBUG, "Arranging container %p column %" PRIuFAST32 | 1272 | sway_log(L_DEBUG, "Arranging container %p column %zu, children [%d,%d[ (%fx%f+%f,%f)", |
1260 | ", children [%d,%d[ (%fx%f+%f,%f)", | ||
1261 | container, group, start, end, *group_w, *group_h, *group_x, *group_y); | 1273 | container, group, start, end, *group_w, *group_h, *group_x, *group_y); |
1262 | switch (group_layout) { | 1274 | switch (group_layout) { |
1263 | default: | 1275 | default: |
diff --git a/sway/sway.5.txt b/sway/sway.5.txt index 87b02f9f..cbff6cef 100644 --- a/sway/sway.5.txt +++ b/sway/sway.5.txt | |||
@@ -101,10 +101,11 @@ They are expected to be used with **bindsym** or at runtime through **swaymsg**( | |||
101 | **layout** promote:: | 101 | **layout** promote:: |
102 | Swap the focused element with the first in the one of the auto layouts. | 102 | Swap the focused element with the first in the one of the auto layouts. |
103 | 103 | ||
104 | **move** <left|right|up|down|next|prev>:: | 104 | **move** <left|right|up|down|next|prev|first>:: |
105 | Moves the focused container _left_, _right_, _up_, or _down_. Moving | 105 | Moves the focused container _left_, _right_, _up_, or _down_. Moving to _prev_ |
106 | to _prev_ or _next_ swaps the container with its sibling in the same | 106 | or _next_ swaps the container with its sibling in the same container. Move |
107 | container. | 107 | _first_ exchanges the focused element in an auto layout with the first |
108 | element, i.e. promotes the focused element to master position. | ||
108 | 109 | ||
109 | **move** <container|window> to workspace <name>:: | 110 | **move** <container|window> to workspace <name>:: |
110 | Moves the focused container to the workspace identified by _name_. | 111 | Moves the focused container to the workspace identified by _name_. |