Line | Branch | Exec | Source |
---|---|---|---|
1 | #include "frame.h" | ||
2 | #include "editor.h" | ||
3 | #include "util/xmalloc.h" | ||
4 | #include "window.h" | ||
5 | |||
6 | enum { | ||
7 | WINDOW_MIN_WIDTH = 8, | ||
8 | WINDOW_MIN_HEIGHT = 3, | ||
9 | }; | ||
10 | |||
11 | // Recursion is bounded by the number of descendant frames, which is | ||
12 | // typically not more than 5 or so | ||
13 | // NOLINTBEGIN(misc-no-recursion) | ||
14 | |||
15 | 11 | static void sanity_check_frame(const Frame *frame) | |
16 | { | ||
17 | 11 | bool has_window = !!frame->window; | |
18 | 11 | bool has_frames = frame->frames.count > 0; | |
19 |
1/2✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→4) taken 11 times.
|
11 | if (has_window == has_frames) { |
20 | − | BUG("frames must contain a window or subframe(s), but never both"); | |
21 | } | ||
22 | 11 | BUG_ON(has_window && frame != frame->window->frame); | |
23 | 11 | } | |
24 | |||
25 | 46 | static int get_min_w(const Frame *frame) | |
26 | { | ||
27 |
2/2✓ Branch 0 (2→3) taken 3 times.
✓ Branch 1 (2→11) taken 43 times.
|
46 | if (frame->window) { |
28 | return WINDOW_MIN_WIDTH; | ||
29 | } | ||
30 | |||
31 | 3 | void **subframes = frame->frames.ptrs; | |
32 | 3 | size_t count = frame->frames.count; | |
33 |
1/2✓ Branch 0 (3→4) taken 3 times.
✗ Branch 1 (3→10) not taken.
|
3 | if (!frame->vertical) { |
34 | 3 | int w = count - 1; // Separators | |
35 |
2/2✓ Branch 0 (7→5) taken 6 times.
✓ Branch 1 (7→11) taken 3 times.
|
9 | for (size_t i = 0; i < count; i++) { |
36 | 6 | w += get_min_w(subframes[i]); | |
37 | } | ||
38 | return w; | ||
39 | } | ||
40 | |||
41 | int max = 0; | ||
42 | ✗ | for (size_t i = 0; i < count; i++) { | |
43 | ✗ | int w = get_min_w(subframes[i]); | |
44 | ✗ | max = MAX(w, max); | |
45 | } | ||
46 | return max; | ||
47 | } | ||
48 | |||
49 | 30 | static int get_min_h(const Frame *frame) | |
50 | { | ||
51 |
2/2✓ Branch 0 (2→3) taken 3 times.
✓ Branch 1 (2→10) taken 27 times.
|
30 | if (frame->window) { |
52 | return WINDOW_MIN_HEIGHT; | ||
53 | } | ||
54 | |||
55 | 3 | void **subframes = frame->frames.ptrs; | |
56 | 3 | size_t count = frame->frames.count; | |
57 |
1/2✗ Branch 0 (3→6) not taken.
✓ Branch 1 (3→9) taken 3 times.
|
3 | if (frame->vertical) { |
58 | int h = 0; | ||
59 | ✗ | for (size_t i = 0; i < count; i++) { | |
60 | ✗ | h += get_min_h(subframes[i]); | |
61 | } | ||
62 | return h; | ||
63 | } | ||
64 | |||
65 | int max = 0; | ||
66 |
2/2✓ Branch 0 (9→7) taken 6 times.
✓ Branch 1 (9→10) taken 3 times.
|
9 | for (size_t i = 0; i < count; i++) { |
67 | 6 | int h = get_min_h(subframes[i]); | |
68 | 6 | max = MAX(h, max); | |
69 | } | ||
70 | return max; | ||
71 | } | ||
72 | |||
73 | // Get parent frame and assert non-NULL, for use in contexts where | ||
74 | // `frame` may not be the root frame | ||
75 | 62 | static Frame *frame_must_get_parent(const Frame *frame) | |
76 | { | ||
77 | 62 | Frame *parent = frame->parent; | |
78 | 62 | BUG_ON(!parent); | |
79 | 62 | return parent; | |
80 | } | ||
81 | |||
82 | 16 | static int get_min(const Frame *frame) | |
83 | { | ||
84 | 16 | const Frame *parent = frame_must_get_parent(frame); | |
85 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 16 times.
|
16 | return parent->vertical ? get_min_h(frame) : get_min_w(frame); |
86 | } | ||
87 | |||
88 | 13 | static int get_size(const Frame *frame) | |
89 | { | ||
90 | 13 | const Frame *parent = frame_must_get_parent(frame); | |
91 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 13 times.
|
13 | return parent->vertical ? frame->h : frame->w; |
92 | } | ||
93 | |||
94 | 4 | static int get_container_size(const Frame *frame) | |
95 | { | ||
96 |
1/2✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→4) taken 4 times.
|
4 | return frame->vertical ? frame->h : frame->w; |
97 | } | ||
98 | |||
99 | 18 | static void set_size(Frame *frame, int size) | |
100 | { | ||
101 | 18 | const Frame *parent = frame_must_get_parent(frame); | |
102 | 18 | bool vertical = parent->vertical; | |
103 |
1/2✓ Branch 0 (3→4) taken 18 times.
✗ Branch 1 (3→5) not taken.
|
18 | int w = vertical ? parent->w : size; |
104 | 18 | int h = vertical ? size : parent->h; | |
105 | 18 | frame_set_size(frame, w, h); | |
106 | 18 | } | |
107 | |||
108 | 4 | static void divide_equally(const Frame *frame) | |
109 | { | ||
110 | 4 | void **ptrs = frame->frames.ptrs; | |
111 | 4 | size_t count = frame->frames.count; | |
112 | 4 | BUG_ON(count == 0); | |
113 | 4 | BUG_ON(!ptrs); | |
114 | |||
115 | 4 | int *min = xmallocarray(count, sizeof(int)); | |
116 |
2/2✓ Branch 0 (10→8) taken 8 times.
✓ Branch 1 (10→11) taken 4 times.
|
12 | for (size_t i = 0; i < count; i++) { |
117 | 8 | min[i] = get_min(ptrs[i]); | |
118 | } | ||
119 | |||
120 | 4 | int *size = xcalloc(count, sizeof(int)); | |
121 | 4 | int s = get_container_size(frame); | |
122 | 4 | int q, r, used; | |
123 | 4 | size_t n = count; | |
124 | |||
125 | // Consume q and r as equally as possible | ||
126 | 4 | do { | |
127 | 4 | used = 0; | |
128 | 4 | q = s / n; | |
129 | 4 | r = s % n; | |
130 |
2/2✓ Branch 0 (18→14) taken 8 times.
✓ Branch 1 (18→19) taken 4 times.
|
12 | for (size_t i = 0; i < count; i++) { |
131 |
2/4✓ Branch 0 (14→15) taken 8 times.
✗ Branch 1 (14→17) not taken.
✗ Branch 2 (15→16) not taken.
✓ Branch 3 (15→17) taken 8 times.
|
8 | if (size[i] == 0 && min[i] > q) { |
132 | ✗ | size[i] = min[i]; | |
133 | ✗ | used += min[i]; | |
134 | ✗ | n--; | |
135 | } | ||
136 | } | ||
137 | 4 | s -= used; | |
138 |
1/2✗ Branch 0 (19→13) not taken.
✓ Branch 1 (19→24) taken 4 times.
|
4 | } while (used && n > 0); |
139 | |||
140 |
2/2✓ Branch 0 (24→20) taken 8 times.
✓ Branch 1 (24→25) taken 4 times.
|
12 | for (size_t i = 0; i < count; i++) { |
141 | 8 | Frame *c = ptrs[i]; | |
142 |
1/2✓ Branch 0 (20→21) taken 8 times.
✗ Branch 1 (20→22) not taken.
|
8 | if (size[i] == 0) { |
143 | 8 | size[i] = q + (r-- > 0); | |
144 | } | ||
145 | 8 | set_size(c, size[i]); | |
146 | } | ||
147 | |||
148 | 4 | free(size); | |
149 | 4 | free(min); | |
150 | 4 | } | |
151 | |||
152 | ✗ | static void fix_size(const Frame *frame) | |
153 | { | ||
154 | ✗ | void **ptrs = frame->frames.ptrs; | |
155 | ✗ | size_t count = frame->frames.count; | |
156 | ✗ | int *size = xmallocarray(count, sizeof(int)); | |
157 | ✗ | int *min = xmallocarray(count, sizeof(int)); | |
158 | ✗ | int total = 0; | |
159 | |||
160 | ✗ | for (size_t i = 0; i < count; i++) { | |
161 | ✗ | const Frame *c = ptrs[i]; | |
162 | ✗ | min[i] = get_min(c); | |
163 | ✗ | size[i] = MAX(get_size(c), min[i]); | |
164 | ✗ | total += size[i]; | |
165 | } | ||
166 | |||
167 | ✗ | int s = get_container_size(frame); | |
168 | ✗ | if (total > s) { | |
169 | ✗ | int n = total - s; | |
170 | ✗ | for (ssize_t i = count - 1; n > 0 && i >= 0; i--) { | |
171 | ✗ | int new_size = MAX(size[i] - n, min[i]); | |
172 | ✗ | n -= size[i] - new_size; | |
173 | ✗ | size[i] = new_size; | |
174 | } | ||
175 | } else { | ||
176 | ✗ | size[count - 1] += s - total; | |
177 | } | ||
178 | |||
179 | ✗ | for (size_t i = 0; i < count; i++) { | |
180 | ✗ | set_size(ptrs[i], size[i]); | |
181 | } | ||
182 | |||
183 | ✗ | free(size); | |
184 | ✗ | free(min); | |
185 | ✗ | } | |
186 | |||
187 | 2 | static void add_to_sibling_size(Frame *frame, int count) | |
188 | { | ||
189 | 2 | const Frame *parent = frame_must_get_parent(frame); | |
190 | 2 | const PointerArray *pframes = &parent->frames; | |
191 | 2 | size_t idx = ptr_array_xindex(pframes, frame); | |
192 | 2 | bool last = (idx == pframes->count - 1); | |
193 |
1/2✓ Branch 0 (4→5) taken 2 times.
✗ Branch 1 (4→6) not taken.
|
2 | frame = pframes->ptrs[last ? idx - 1 : idx + 1]; |
194 | 2 | set_size(frame, get_size(frame) + count); | |
195 | 2 | } | |
196 | |||
197 | 3 | static int sub(Frame *frame, int count) | |
198 | { | ||
199 | 3 | int min = get_min(frame); | |
200 | 3 | int old = get_size(frame); | |
201 | 3 | int new = MAX(min, old - count); | |
202 |
1/2✓ Branch 0 (4→5) taken 3 times.
✗ Branch 1 (4→6) not taken.
|
3 | if (new != old) { |
203 | 3 | set_size(frame, new); | |
204 | } | ||
205 | 3 | return count - (old - new); | |
206 | } | ||
207 | |||
208 | 3 | static void subtract_from_sibling_size(const Frame *frame, int count) | |
209 | { | ||
210 | 3 | const Frame *parent = frame_must_get_parent(frame); | |
211 | 3 | const PointerArray *pframes = &parent->frames; | |
212 | 3 | size_t idx = ptr_array_xindex(pframes, frame); | |
213 | 3 | void **ptrs = pframes->ptrs; | |
214 | |||
215 |
1/2✗ Branch 0 (8→5) not taken.
✓ Branch 1 (8→11) taken 3 times.
|
3 | for (size_t i = idx + 1, n = pframes->count; i < n; i++) { |
216 | ✗ | count = sub(ptrs[i], count); | |
217 | ✗ | if (count == 0) { | |
218 | return; | ||
219 | } | ||
220 | } | ||
221 | |||
222 |
1/2✓ Branch 0 (11→9) taken 3 times.
✗ Branch 1 (11→12) not taken.
|
3 | for (size_t i = idx; i > 0; i--) { |
223 | 3 | count = sub(ptrs[i - 1], count); | |
224 |
1/2✗ Branch 0 (10→11) not taken.
✓ Branch 1 (10→12) taken 3 times.
|
3 | if (count == 0) { |
225 | return; | ||
226 | } | ||
227 | } | ||
228 | } | ||
229 | |||
230 | 5 | static void resize_to(Frame *frame, int size) | |
231 | { | ||
232 | 5 | const Frame *parent = frame_must_get_parent(frame); | |
233 | 5 | size_t count = parent->frames.count; | |
234 | 5 | BUG_ON(count == 0); | |
235 | |||
236 |
1/2✗ Branch 0 (5→6) not taken.
✓ Branch 1 (5→7) taken 5 times.
|
5 | int total = parent->vertical ? parent->h : parent->w; |
237 | 5 | int min = get_min(frame); | |
238 | 5 | int max = total - ((count - 1) * min); | |
239 | 5 | max = MAX(min, max); | |
240 | 5 | size = CLAMP(size, min, max); | |
241 | |||
242 | 5 | int change = size - get_size(frame); | |
243 |
1/2✓ Branch 0 (10→11) taken 5 times.
✗ Branch 1 (10→15) not taken.
|
5 | if (change == 0) { |
244 | return; | ||
245 | } | ||
246 | |||
247 | 5 | set_size(frame, size); | |
248 |
2/2✓ Branch 0 (12→13) taken 2 times.
✓ Branch 1 (12→14) taken 3 times.
|
5 | if (change < 0) { |
249 | 2 | add_to_sibling_size(frame, -change); | |
250 | } else { | ||
251 | 3 | subtract_from_sibling_size(frame, change); | |
252 | } | ||
253 | } | ||
254 | |||
255 | 30 | static bool rightmost_frame(const Frame *frame) | |
256 | { | ||
257 | 30 | const Frame *parent = frame->parent; | |
258 |
2/2✓ Branch 0 (2→3) taken 18 times.
✓ Branch 1 (2→6) taken 12 times.
|
30 | if (!parent) { |
259 | return true; | ||
260 | } | ||
261 |
1/2✓ Branch 0 (3→4) taken 18 times.
✗ Branch 1 (3→5) not taken.
|
18 | if (!parent->vertical) { |
262 |
2/2✓ Branch 0 (4→5) taken 9 times.
✓ Branch 1 (4→6) taken 9 times.
|
18 | if (frame != parent->frames.ptrs[parent->frames.count - 1]) { |
263 | return false; | ||
264 | } | ||
265 | } | ||
266 | 9 | return rightmost_frame(parent); | |
267 | } | ||
268 | |||
269 | 14 | static Frame *new_frame(void) | |
270 | { | ||
271 | 14 | Frame *frame = xcalloc(1, sizeof(*frame)); | |
272 | 14 | frame->equal_size = true; | |
273 | 14 | return frame; | |
274 | } | ||
275 | |||
276 | 13 | static Frame *add_frame(Frame *parent, Window *window, size_t idx) | |
277 | { | ||
278 | 13 | Frame *frame = new_frame(); | |
279 | 13 | frame->parent = parent; | |
280 | 13 | frame->window = window; | |
281 | 13 | window->frame = frame; | |
282 |
2/2✓ Branch 0 (3→4) taken 5 times.
✓ Branch 1 (3→8) taken 8 times.
|
13 | if (parent) { |
283 | 5 | BUG_ON(idx > parent->frames.count); | |
284 | 5 | ptr_array_insert(&parent->frames, frame, idx); | |
285 | 5 | parent->window = NULL; | |
286 | } | ||
287 | 13 | return frame; | |
288 | } | ||
289 | |||
290 | 8 | Frame *new_root_frame(Window *window) | |
291 | { | ||
292 | 8 | return add_frame(NULL, window, 0); | |
293 | } | ||
294 | |||
295 | 6 | static Frame *find_resizable(Frame *frame, ResizeDirection dir) | |
296 | { | ||
297 |
2/2✓ Branch 0 (2→8) taken 2 times.
✓ Branch 1 (2→9) taken 4 times.
|
6 | if (dir == RESIZE_DIRECTION_AUTO) { |
298 | return frame; | ||
299 | } | ||
300 | |||
301 |
2/2✓ Branch 0 (8→3) taken 2 times.
✓ Branch 1 (8→9) taken 1 times.
|
3 | while (frame->parent) { |
302 |
3/4✓ Branch 0 (3→4) taken 1 times.
✓ Branch 1 (3→5) taken 1 times.
✓ Branch 2 (4→5) taken 1 times.
✗ Branch 3 (4→9) not taken.
|
2 | if (dir == RESIZE_DIRECTION_VERTICAL && frame->parent->vertical) { |
303 | return frame; | ||
304 | } | ||
305 |
3/4✓ Branch 0 (5→6) taken 1 times.
✓ Branch 1 (5→7) taken 1 times.
✗ Branch 2 (6→7) not taken.
✓ Branch 3 (6→9) taken 1 times.
|
2 | if (dir == RESIZE_DIRECTION_HORIZONTAL && !frame->parent->vertical) { |
306 | return frame; | ||
307 | } | ||
308 | frame = frame->parent; | ||
309 | } | ||
310 | return NULL; | ||
311 | } | ||
312 | |||
313 | 24 | void frame_set_size(Frame *frame, int w, int h) | |
314 | { | ||
315 | 24 | int min_w = get_min_w(frame); | |
316 | 24 | int min_h = get_min_h(frame); | |
317 | 24 | w = MAX(w, min_w); | |
318 | 24 | h = MAX(h, min_h); | |
319 | 24 | frame->w = w; | |
320 | 24 | frame->h = h; | |
321 | |||
322 |
2/2✓ Branch 0 (4→5) taken 21 times.
✓ Branch 1 (4→8) taken 3 times.
|
24 | if (frame->window) { |
323 | 21 | w -= rightmost_frame(frame) ? 0 : 1; // Separator | |
324 | 21 | window_set_size(frame->window, w, h); | |
325 | 21 | return; | |
326 | } | ||
327 | |||
328 |
1/2✓ Branch 0 (8→9) taken 3 times.
✗ Branch 1 (8→10) not taken.
|
3 | if (frame->equal_size) { |
329 | 3 | divide_equally(frame); | |
330 | } else { | ||
331 | ✗ | fix_size(frame); | |
332 | } | ||
333 | } | ||
334 | |||
335 | 1 | void frame_equalize_sizes(Frame *parent) | |
336 | { | ||
337 | 1 | parent->equal_size = true; | |
338 | 1 | divide_equally(parent); | |
339 | 1 | update_window_coordinates(parent); | |
340 | 1 | } | |
341 | |||
342 | 6 | void frame_resize(Frame *frame, ResizeDirection dir, int size) | |
343 | { | ||
344 | 6 | frame = find_resizable(frame, dir); | |
345 |
2/2✓ Branch 0 (3→4) taken 5 times.
✓ Branch 1 (3→7) taken 1 times.
|
6 | if (!frame) { |
346 | return; | ||
347 | } | ||
348 | |||
349 | 5 | Frame *parent = frame_must_get_parent(frame); | |
350 | 5 | parent->equal_size = false; | |
351 | 5 | resize_to(frame, size); | |
352 | 5 | update_window_coordinates(parent); | |
353 | } | ||
354 | |||
355 | 3 | void frame_add_to_size(Frame *frame, ResizeDirection dir, int amount) | |
356 | { | ||
357 | 3 | frame_resize(frame, dir, get_size(frame) + amount); | |
358 | 3 | } | |
359 | |||
360 | 29 | static void update_frame_coordinates(const Frame *frame, int x, int y) | |
361 | { | ||
362 |
2/2✓ Branch 0 (2→3) taken 20 times.
✓ Branch 1 (2→5) taken 9 times.
|
29 | if (frame->window) { |
363 | 20 | window_set_coordinates(frame->window, x, y); | |
364 | 20 | return; | |
365 | } | ||
366 | |||
367 | 9 | void **ptrs = frame->frames.ptrs; | |
368 |
2/2✓ Branch 0 (11→6) taken 18 times.
✓ Branch 1 (11→12) taken 9 times.
|
27 | for (size_t i = 0, n = frame->frames.count; i < n; i++) { |
369 | 18 | const Frame *c = ptrs[i]; | |
370 | 18 | update_frame_coordinates(c, x, y); | |
371 |
1/2✗ Branch 0 (7→8) not taken.
✓ Branch 1 (7→9) taken 18 times.
|
18 | if (frame->vertical) { |
372 | ✗ | y += c->h; | |
373 | } else { | ||
374 | 18 | x += c->w; | |
375 | } | ||
376 | } | ||
377 | } | ||
378 | |||
379 | 11 | static Frame *get_root_frame(Frame *frame) | |
380 | { | ||
381 | 11 | BUG_ON(!frame); | |
382 |
1/2✗ Branch 0 (4→4) not taken.
✓ Branch 1 (4→5) taken 11 times.
|
11 | while (frame->parent) { |
383 | frame = frame->parent; | ||
384 | } | ||
385 | 11 | return frame; | |
386 | } | ||
387 | |||
388 | 11 | void update_window_coordinates(Frame *frame) | |
389 | { | ||
390 | 11 | update_frame_coordinates(get_root_frame(frame), 0, 0); | |
391 | 11 | } | |
392 | |||
393 | 2 | Frame *frame_split(Window *window, bool vertical, bool before) | |
394 | { | ||
395 | 2 | Frame *frame = window->frame; | |
396 | 2 | Frame *parent = frame->parent; | |
397 |
1/4✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→4) taken 2 times.
✗ Branch 2 (3→4) not taken.
✗ Branch 3 (3→5) not taken.
|
2 | if (!parent || parent->vertical != vertical) { |
398 | // Reparent window | ||
399 | 2 | frame->vertical = vertical; | |
400 | 2 | add_frame(frame, window, 0); | |
401 | 2 | parent = frame; | |
402 | } | ||
403 | |||
404 | 2 | size_t idx = ptr_array_xindex(&parent->frames, window->frame); | |
405 | 2 | idx += before ? 0 : 1; | |
406 | 2 | frame = add_frame(parent, new_window(window->editor), idx); | |
407 | 2 | parent->equal_size = true; | |
408 | |||
409 | // Recalculate | ||
410 | 2 | frame_set_size(parent, parent->w, parent->h); | |
411 | 2 | update_window_coordinates(parent); | |
412 | 2 | return frame; | |
413 | } | ||
414 | |||
415 | // Doesn't really split root but adds new frame between root and its contents | ||
416 | 1 | Frame *frame_split_root(EditorState *e, bool vertical, bool before) | |
417 | { | ||
418 | 1 | Frame *old_root = e->root_frame; | |
419 | 1 | Frame *new_root = new_frame(); | |
420 | 1 | ptr_array_append(&new_root->frames, old_root); | |
421 | 1 | old_root->parent = new_root; | |
422 | 1 | new_root->vertical = vertical; | |
423 | 1 | e->root_frame = new_root; | |
424 | |||
425 | 1 | Frame *frame = add_frame(new_root, new_window(e), before ? 0 : 1); | |
426 | 1 | frame_set_size(new_root, old_root->w, old_root->h); | |
427 | 1 | update_window_coordinates(new_root); | |
428 | 1 | return frame; | |
429 | } | ||
430 | |||
431 | // NOTE: does not remove frame from frame->parent->frames | ||
432 | 12 | static void free_frame(Frame *frame) | |
433 | { | ||
434 | 12 | frame->parent = NULL; | |
435 | 12 | ptr_array_free_cb(&frame->frames, FREE_FUNC(free_frame)); | |
436 | |||
437 |
2/2✓ Branch 0 (3→4) taken 11 times.
✓ Branch 1 (3→6) taken 1 times.
|
12 | if (frame->window) { |
438 | 11 | window_free(frame->window); | |
439 | 11 | frame->window = NULL; | |
440 | } | ||
441 | |||
442 | 12 | free(frame); | |
443 | 12 | } | |
444 | |||
445 | 10 | void frame_remove(EditorState *e, Frame *frame) | |
446 | { | ||
447 | 10 | Frame *parent = frame->parent; | |
448 |
2/2✓ Branch 0 (2→3) taken 8 times.
✓ Branch 1 (2→5) taken 2 times.
|
10 | if (!parent) { |
449 | 8 | free_frame(frame); | |
450 | 8 | return; | |
451 | } | ||
452 | |||
453 | 2 | ptr_array_remove(&parent->frames, frame); | |
454 | 2 | free_frame(frame); | |
455 | |||
456 |
1/2✓ Branch 0 (7→8) taken 2 times.
✗ Branch 1 (7→14) not taken.
|
2 | if (parent->frames.count == 1) { |
457 | // Replace parent with the only child frame | ||
458 | 2 | Frame *gp = parent->parent; | |
459 | 2 | Frame *c = parent->frames.ptrs[0]; | |
460 | 2 | c->parent = gp; | |
461 | 2 | c->w = parent->w; | |
462 | 2 | c->h = parent->h; | |
463 |
1/2✗ Branch 0 (8→9) not taken.
✓ Branch 1 (8→11) taken 2 times.
|
2 | if (gp) { |
464 | ✗ | size_t idx = ptr_array_xindex(&gp->frames, parent); | |
465 | ✗ | gp->frames.ptrs[idx] = c; | |
466 | } else { | ||
467 | 2 | e->root_frame = c; | |
468 | } | ||
469 | 2 | ptr_array_free_array(&parent->frames); | |
470 | 2 | free(parent); | |
471 | 2 | parent = c; | |
472 | } | ||
473 | |||
474 | // Recalculate | ||
475 | 2 | frame_set_size(parent, parent->w, parent->h); | |
476 | 2 | update_window_coordinates(parent); | |
477 | } | ||
478 | |||
479 | 1 | void dump_frame(const Frame *frame, size_t level, String *str) | |
480 | { | ||
481 | 1 | sanity_check_frame(frame); | |
482 | 1 | string_append_memset(str, ' ', level * 4); | |
483 | 1 | string_sprintf(str, "%dx%d", frame->w, frame->h); | |
484 | |||
485 | 1 | const Window *w = frame->window; | |
486 |
1/2✓ Branch 0 (5→6) taken 1 times.
✗ Branch 1 (5→11) not taken.
|
1 | if (w) { |
487 | 1 | const char *name = buffer_filename(w->view->buffer); | |
488 | 1 | string_append_byte(str, '\n'); | |
489 | 1 | string_append_memset(str, ' ', (level + 1) * 4); | |
490 | 1 | string_sprintf(str, "%d,%d %dx%d %s\n", w->x, w->y, w->w, w->h, name); | |
491 | 1 | return; | |
492 | } | ||
493 | |||
494 | ✗ | string_append_cstring(str, frame->vertical ? " V" : " H"); | |
495 | ✗ | string_append_cstring(str, frame->equal_size ? "\n" : " !\n"); | |
496 | |||
497 | ✗ | for (size_t i = 0, n = frame->frames.count; i < n; i++) { | |
498 | ✗ | const Frame *c = frame->frames.ptrs[i]; | |
499 | ✗ | dump_frame(c, level + 1, str); | |
500 | } | ||
501 | } | ||
502 | |||
503 | #if DEBUG_ASSERTIONS_ENABLED | ||
504 | 10 | void frame_debug(const Frame *frame) | |
505 | { | ||
506 | 10 | sanity_check_frame(frame); | |
507 |
2/2✓ Branch 0 (8→4) taken 4 times.
✓ Branch 1 (8→9) taken 10 times.
|
14 | for (size_t i = 0, n = frame->frames.count; i < n; i++) { |
508 | 4 | const Frame *c = frame->frames.ptrs[i]; | |
509 | 4 | BUG_ON(c->parent != frame); | |
510 | 4 | frame_debug(c); | |
511 | } | ||
512 | 10 | } | |
513 | #endif | ||
514 | |||
515 | // NOLINTEND(misc-no-recursion) | ||
516 |