diff options
-rw-r--r-- | sway/commands/resize.c | 132 |
1 files changed, 73 insertions, 59 deletions
diff --git a/sway/commands/resize.c b/sway/commands/resize.c index c850575b..9a756e81 100644 --- a/sway/commands/resize.c +++ b/sway/commands/resize.c | |||
@@ -63,35 +63,6 @@ static bool resize_floating(int amount, bool use_width) { | |||
63 | } | 63 | } |
64 | 64 | ||
65 | /** | 65 | /** |
66 | * returns the index of the container's child that is first in a group. | ||
67 | * This index is > to the <after> argument. | ||
68 | * This makes the function usable to walk through the groups in a container. | ||
69 | */ | ||
70 | static int next_group_index(swayc_t *container, int after) { | ||
71 | if (after < 0) { | ||
72 | return 0; | ||
73 | } else if (is_auto_layout(container->layout)) { | ||
74 | if ((uint_fast32_t) after < container->nb_master) { | ||
75 | return container->nb_master; | ||
76 | } else { | ||
77 | uint_fast32_t grp_idx = 0; | ||
78 | for (int i = container->nb_master; i < container->children->length; ) { | ||
79 | uint_fast32_t grp_sz = (container->children->length - i) / | ||
80 | (container->nb_slave_groups - grp_idx); | ||
81 | if (after - i < (int) grp_sz) { | ||
82 | return i + grp_sz; | ||
83 | } | ||
84 | i += grp_sz; | ||
85 | } | ||
86 | return container->children->length; | ||
87 | } | ||
88 | } else { | ||
89 | // return after + 1; | ||
90 | return container->children->length; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | /** | ||
95 | * 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 |
96 | * that are not members of the master group. | 67 | * that are not members of the master group. |
97 | */ | 68 | */ |
@@ -105,36 +76,46 @@ static inline uint_fast32_t slave_count(swayc_t *container) { | |||
105 | * which index is a member of. | 76 | * which index is a member of. |
106 | */ | 77 | */ |
107 | static int group_start_index(swayc_t *container, int index) { | 78 | static int group_start_index(swayc_t *container, int index) { |
108 | if (index < 0 || ! is_auto_layout(container->layout) || (uint_fast32_t) index < container->nb_master) { | 79 | if ((index < 0) || (! is_auto_layout(container->layout)) || |
80 | ((uint_fast32_t) index < container->nb_master)) { | ||
109 | return 0; | 81 | return 0; |
110 | } else { | 82 | } else { |
111 | uint_fast32_t grp_sz = slave_count(container) / container->nb_slave_groups; | 83 | uint_fast32_t grp_sz = slave_count(container) / container->nb_slave_groups; |
112 | uint_fast32_t remainder = slave_count(container) % container->nb_slave_groups; | 84 | uint_fast32_t remainder = slave_count(container) % container->nb_slave_groups; |
113 | if ((index - container->nb_master) / grp_sz < container->nb_slave_groups - remainder) { | 85 | int start_idx; |
114 | return ((index - container->nb_master) / grp_sz) * grp_sz + container->nb_master; | 86 | int idx2 = (container->nb_slave_groups - remainder) * grp_sz + container->nb_master; |
87 | if (index < idx2) { | ||
88 | start_idx = ((index - container->nb_master) / grp_sz) * grp_sz + container->nb_master; | ||
115 | } else { | 89 | } else { |
116 | int idx2 = (container->nb_slave_groups - remainder) * grp_sz + container->nb_master; | 90 | start_idx = idx2 + ((index - idx2) / (grp_sz + 1)) * (grp_sz + 1); |
117 | return idx2 + ((idx2 - index) / (grp_sz + 1)) * (grp_sz + 1); | ||
118 | } | 91 | } |
92 | return MIN(start_idx, container->children->length); | ||
119 | } | 93 | } |
120 | } | 94 | } |
121 | 95 | ||
122 | /** | 96 | /** |
123 | * given the index of a container's child, return the index of the first child of the group | 97 | * given the index of a container's child, return the index of the first child of the group |
124 | * 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. | ||
125 | */ | 100 | */ |
126 | static int group_end_index(swayc_t *container, int index) { | 101 | static int group_end_index(swayc_t *container, int index) { |
127 | if (index < 0 || ! is_auto_layout(container->layout)) { | 102 | if (index < 0 || ! is_auto_layout(container->layout)) { |
128 | return container->children->length; | 103 | return container->children->length; |
129 | } else { | 104 | } else { |
130 | uint_fast32_t grp_sz = slave_count(container) / container->nb_slave_groups; | 105 | int nxt_idx; |
131 | uint_fast32_t remainder = slave_count(container) % container->nb_slave_groups; | 106 | if ((uint_fast32_t)index < container->nb_master) { |
132 | if ((index - container->nb_master) / grp_sz < container->nb_slave_groups - remainder) { | 107 | nxt_idx = container->nb_master; |
133 | return ((index - container->nb_master) / grp_sz + 1) * grp_sz + container->nb_master; | ||
134 | } else { | 108 | } else { |
109 | uint_fast32_t grp_sz = slave_count(container) / container->nb_slave_groups; | ||
110 | uint_fast32_t remainder = slave_count(container) % container->nb_slave_groups; | ||
135 | 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; |
136 | return idx2 + ((idx2 - index) / (grp_sz + 1) + 1) * (grp_sz + 1); | 112 | if (index < idx2) { |
113 | nxt_idx = ((index - container->nb_master) / grp_sz + 1) * grp_sz + container->nb_master; | ||
114 | } else { | ||
115 | nxt_idx = idx2 + ((index - idx2) / (grp_sz + 1) + 1) * (grp_sz + 1); | ||
116 | } | ||
137 | } | 117 | } |
118 | return MIN(nxt_idx, container->children->length); | ||
138 | } | 119 | } |
139 | } | 120 | } |
140 | 121 | ||
@@ -150,22 +131,26 @@ static inline uint_fast32_t group_count(swayc_t *container) { | |||
150 | * 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). |
151 | */ | 132 | */ |
152 | static uint_fast32_t group_index(swayc_t *container, int index) { | 133 | static uint_fast32_t group_index(swayc_t *container, int index) { |
134 | if (index < 0) { | ||
135 | return 0; | ||
136 | } | ||
153 | 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); |
154 | int nb_slaves = slave_count(container); | 138 | int nb_slaves = slave_count(container); |
155 | if (index < (int) container->nb_master) { | 139 | if ((uint_fast32_t) index < container->nb_master) { |
156 | if (master_first || nb_slaves <= 0) { | 140 | if (master_first || nb_slaves <= 0) { |
157 | return 0; | 141 | return 0; |
158 | } else { | 142 | } else { |
159 | return MIN(container->nb_slave_groups, nb_slaves); | 143 | return MIN(container->nb_slave_groups, nb_slaves); |
160 | } | 144 | } |
161 | } else { | 145 | } else { |
162 | uint_fast32_t grp_idx = 0; | 146 | uint_fast32_t grp_sz = slave_count(container) / container->nb_slave_groups; |
163 | for (int i = container->nb_master; i < container->children->length; ) { | 147 | uint_fast32_t remainder = slave_count(container) % container->nb_slave_groups; |
164 | uint_fast32_t grp_sz = (container->children->length - i) / | 148 | uint_fast32_t grp_idx; |
165 | (container->nb_slave_groups - grp_idx); | 149 | int idx2 = (container->nb_slave_groups - remainder) * grp_sz + container->nb_master; |
166 | if (index - i < (int) grp_sz) { | 150 | if (index < idx2) { |
167 | break; | 151 | grp_idx = (index - container->nb_master) / grp_sz; |
168 | } | 152 | } else { |
153 | grp_idx = (container->nb_slave_groups - remainder) + (index - idx2) / (grp_sz + 1) ; | ||
169 | } | 154 | } |
170 | return grp_idx + (master_first ? 1 : 0); | 155 | return grp_idx + (master_first ? 1 : 0); |
171 | } | 156 | } |
@@ -204,7 +189,13 @@ static bool resize_tiled(int amount, bool use_width) { | |||
204 | nb_after = group_count(parent) - nb_before - 1; | 189 | nb_after = group_count(parent) - nb_before - 1; |
205 | } else { | 190 | } else { |
206 | nb_before = idx_focused - group_start_index(parent, idx_focused); | 191 | nb_before = idx_focused - group_start_index(parent, idx_focused); |
207 | nb_after = next_group_index(parent, idx_focused) - idx_focused - 1; | 192 | nb_after = group_end_index(parent, idx_focused) - idx_focused - 1; |
193 | sway_log(L_DEBUG, "+++ focused: %d, start: %d, end: %d, before: %d, after: %d", | ||
194 | idx_focused, | ||
195 | (int)group_start_index(parent, idx_focused), | ||
196 | (int)group_end_index(parent, idx_focused), | ||
197 | (int)nb_before, (int)nb_after); | ||
198 | |||
208 | } | 199 | } |
209 | if (nb_before || nb_after) { | 200 | if (nb_before || nb_after) { |
210 | break; | 201 | break; |
@@ -223,6 +214,7 @@ static bool resize_tiled(int amount, bool use_width) { | |||
223 | swayc_t *focused = parent->children->items[idx_focused]; | 214 | swayc_t *focused = parent->children->items[idx_focused]; |
224 | int start = use_major ? 0 : group_start_index(parent, idx_focused); | 215 | int start = use_major ? 0 : group_start_index(parent, idx_focused); |
225 | int end = use_major ? parent->children->length : group_end_index(parent, idx_focused); | 216 | int end = use_major ? parent->children->length : group_end_index(parent, idx_focused); |
217 | sway_log(L_DEBUG, "Check children of container %p [%d,%d[", container, start, end); | ||
226 | for (int i = start; i < end; ) { | 218 | for (int i = start; i < end; ) { |
227 | swayc_t *sibling = parent->children->items[i]; | 219 | swayc_t *sibling = parent->children->items[i]; |
228 | double pixels = amount; | 220 | double pixels = amount; |
@@ -235,17 +227,21 @@ static bool resize_tiled(int amount, bool use_width) { | |||
235 | pixels /= 2; | 227 | pixels /= 2; |
236 | } | 228 | } |
237 | } | 229 | } |
230 | sway_log(L_DEBUG, "Check container %p: width %g vs %d, height %g vs %d", sibling, sibling->width + pixels, min_sane_w, sibling->height + pixels, min_sane_h); | ||
238 | if (use_width ? | 231 | if (use_width ? |
239 | sibling->width + pixels < min_sane_w : | 232 | sibling->width + pixels < min_sane_w : |
240 | sibling->height + pixels < min_sane_h) { | 233 | sibling->height + pixels < min_sane_h) { |
241 | valid = false; | 234 | valid = false; |
235 | sway_log(L_DEBUG, "Container size no longer sane"); | ||
242 | break; | 236 | break; |
243 | } | 237 | } |
244 | i = use_major ? next_group_index(parent, i) : (i + 1); | 238 | i = use_major ? group_end_index(parent, i) : (i + 1); |
239 | sway_log(L_DEBUG, "+++++ check %i", i); | ||
245 | } | 240 | } |
246 | // 3. Apply the size change | 241 | // 3. Apply the size change |
247 | if (valid) { | 242 | if (valid) { |
248 | for (int i = 0; i < parent->children->length; ++i) { | 243 | for (int i = start; i < end; ) { |
244 | int next_i = use_major ? group_end_index(parent, i) : (i + 1); | ||
249 | swayc_t *sibling = parent->children->items[i]; | 245 | swayc_t *sibling = parent->children->items[i]; |
250 | double pixels = amount; | 246 | double pixels = amount; |
251 | 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; |
@@ -257,17 +253,35 @@ static bool resize_tiled(int amount, bool use_width) { | |||
257 | pixels /= 2; | 253 | pixels /= 2; |
258 | } | 254 | } |
259 | sway_log(L_DEBUG, "%p: %s", sibling, is_before ? "before" : "after"); | 255 | sway_log(L_DEBUG, "%p: %s", sibling, is_before ? "before" : "after"); |
260 | recursive_resize(sibling, pixels, | 256 | if (use_major) { |
261 | use_width ? | 257 | for (int j = i; j < next_i; ++j) { |
262 | (is_before ? WLC_RESIZE_EDGE_RIGHT : WLC_RESIZE_EDGE_LEFT) : | 258 | recursive_resize(parent->children->items[j], pixels, |
263 | (is_before ? WLC_RESIZE_EDGE_BOTTOM : WLC_RESIZE_EDGE_TOP)); | 259 | use_width ? |
260 | (is_before ? WLC_RESIZE_EDGE_RIGHT : WLC_RESIZE_EDGE_LEFT) : | ||
261 | (is_before ? WLC_RESIZE_EDGE_BOTTOM : WLC_RESIZE_EDGE_TOP)); | ||
262 | } | ||
263 | } else { | ||
264 | recursive_resize(sibling, pixels, | ||
265 | use_width ? | ||
266 | (is_before ? WLC_RESIZE_EDGE_RIGHT : WLC_RESIZE_EDGE_LEFT) : | ||
267 | (is_before ? WLC_RESIZE_EDGE_BOTTOM : WLC_RESIZE_EDGE_TOP)); | ||
268 | } | ||
264 | } else { | 269 | } else { |
265 | sway_log(L_DEBUG, "%p: same pos", sibling); | 270 | if (use_major) { |
266 | recursive_resize(sibling, pixels, | 271 | for (int j = i; j < next_i; ++j) { |
267 | use_width ? WLC_RESIZE_EDGE_LEFT : WLC_RESIZE_EDGE_TOP); | 272 | recursive_resize(parent->children->items[j], pixels, |
268 | recursive_resize(sibling, pixels, | 273 | use_width ? WLC_RESIZE_EDGE_LEFT : WLC_RESIZE_EDGE_TOP); |
269 | use_width ? WLC_RESIZE_EDGE_RIGHT : WLC_RESIZE_EDGE_BOTTOM); | 274 | recursive_resize(parent->children->items[j], pixels, |
275 | use_width ? WLC_RESIZE_EDGE_RIGHT : WLC_RESIZE_EDGE_BOTTOM); | ||
276 | } | ||
277 | } else { | ||
278 | recursive_resize(sibling, pixels, | ||
279 | use_width ? WLC_RESIZE_EDGE_LEFT : WLC_RESIZE_EDGE_TOP); | ||
280 | recursive_resize(sibling, pixels, | ||
281 | use_width ? WLC_RESIZE_EDGE_RIGHT : WLC_RESIZE_EDGE_BOTTOM); | ||
282 | } | ||
270 | } | 283 | } |
284 | i = next_i; | ||
271 | } | 285 | } |
272 | // Recursive resize does not handle positions, let arrange_windows | 286 | // Recursive resize does not handle positions, let arrange_windows |
273 | // take care of that. | 287 | // take care of that. |