summaryrefslogtreecommitdiffstats
path: root/sway/tree/layout.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree/layout.c')
-rw-r--r--sway/tree/layout.c204
1 files changed, 104 insertions, 100 deletions
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index 9580d3a7..343f349a 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -24,10 +24,10 @@ static void output_layout_handle_change(struct wl_listener *listener,
24 root_container.sway_root->output_layout; 24 root_container.sway_root->output_layout;
25 const struct wlr_box *layout_box = 25 const struct wlr_box *layout_box =
26 wlr_output_layout_get_box(output_layout, NULL); 26 wlr_output_layout_get_box(output_layout, NULL);
27 root_container.box.x = layout_box->x; 27 root_container.x = layout_box->x;
28 root_container.box.y = layout_box->y; 28 root_container.y = layout_box->y;
29 root_container.box.width = layout_box->width; 29 root_container.width = layout_box->width;
30 root_container.box.height = layout_box->height; 30 root_container.height = layout_box->height;
31 31
32 for (int i = 0 ; i < root_container.children->length; ++i) { 32 for (int i = 0 ; i < root_container.children->length; ++i) {
33 struct sway_container *output_container = 33 struct sway_container *output_container =
@@ -42,10 +42,10 @@ static void output_layout_handle_change(struct wl_listener *listener,
42 if (!output_box) { 42 if (!output_box) {
43 continue; 43 continue;
44 } 44 }
45 output_container->box.x = output_box->x; 45 output_container->x = output_box->x;
46 output_container->box.y = output_box->y; 46 output_container->y = output_box->y;
47 output_container->box.width = output_box->width; 47 output_container->width = output_box->width;
48 output_container->box.height = output_box->height; 48 output_container->height = output_box->height;
49 } 49 }
50 50
51 arrange_windows(&root_container, -1, -1); 51 arrange_windows(&root_container, -1, -1);
@@ -112,9 +112,9 @@ struct sway_container *container_add_sibling(struct sway_container *fixed,
112 112
113void container_add_child(struct sway_container *parent, 113void container_add_child(struct sway_container *parent,
114 struct sway_container *child) { 114 struct sway_container *child) {
115 wlr_log(L_DEBUG, "Adding id:%zd (%d, %dx%d) to id:%zd (%d, %dx%d)", 115 wlr_log(L_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)",
116 child->id, child->type, child->box.width, child->box.height, 116 child, child->type, child->width, child->height,
117 parent->id, parent->type, parent->box.width, parent->box.height); 117 parent, parent->type, parent->width, parent->height);
118 list_add(parent->children, child); 118 list_add(parent->children, child);
119 child->parent = parent; 119 child->parent = parent;
120} 120}
@@ -138,7 +138,7 @@ void container_move_to(struct sway_container *container,
138 return; 138 return;
139 } 139 }
140 struct sway_container *old_parent = container_remove_child(container); 140 struct sway_container *old_parent = container_remove_child(container);
141 container->box.width = container->box.height = 0; 141 container->width = container->height = 0;
142 struct sway_container *new_parent; 142 struct sway_container *new_parent;
143 if (destination->type == C_VIEW) { 143 if (destination->type == C_VIEW) {
144 new_parent = container_add_sibling(destination, container); 144 new_parent = container_add_sibling(destination, container);
@@ -187,10 +187,11 @@ enum sway_container_layout container_get_default_layout(
187 return config->default_layout; 187 return config->default_layout;
188 } else if (config->default_orientation != L_NONE) { 188 } else if (config->default_orientation != L_NONE) {
189 return config->default_orientation; 189 return config->default_orientation;
190 } else if (con->box.width >= con->box.height) { 190 } else if (con->width >= con->height) {
191 return L_HORIZ; 191 return L_HORIZ;
192 } else {
193 return L_VERT;
192 } 194 }
193 return L_VERT;
194} 195}
195 196
196static int sort_workspace_cmp_qsort(const void *_a, const void *_b) { 197static int sort_workspace_cmp_qsort(const void *_a, const void *_b) {
@@ -215,23 +216,25 @@ void container_sort_workspaces(struct sway_container *output) {
215 list_stable_sort(output->children, sort_workspace_cmp_qsort); 216 list_stable_sort(output->children, sort_workspace_cmp_qsort);
216} 217}
217 218
218static void apply_horiz_layout(struct sway_container *container, 219static void apply_horiz_layout(struct sway_container *container, const double x,
219 const int x, const int y, const int width, 220 const double y, const double width,
220 const int height, const int start, const int end); 221 const double height, const int start,
222 const int end);
221 223
222static void apply_vert_layout(struct sway_container *container, 224static void apply_vert_layout(struct sway_container *container, const double x,
223 const int x, const int y, const int width, 225 const double y, const double width,
224 const int height, const int start, const int end); 226 const double height, const int start,
227 const int end);
225 228
226void arrange_windows(struct sway_container *container, 229void arrange_windows(struct sway_container *container,
227 int width, int height) { 230 double width, double height) {
228 if (config->reloading) { 231 if (config->reloading) {
229 return; 232 return;
230 } 233 }
231 int i; 234 int i;
232 if (width == -1 || height == -1) { 235 if (width == -1 || height == -1) {
233 width = container->box.width; 236 width = container->width;
234 height = container->box.height; 237 height = container->height;
235 } 238 }
236 // pixels are indivisible. if we don't round the pixels, then the view 239 // pixels are indivisible. if we don't round the pixels, then the view
237 // calculations will be off (e.g. 50.5 + 50.5 = 101, but in reality it's 240 // calculations will be off (e.g. 50.5 + 50.5 = 101, but in reality it's
@@ -239,17 +242,17 @@ void arrange_windows(struct sway_container *container,
239 width = floor(width); 242 width = floor(width);
240 height = floor(height); 243 height = floor(height);
241 244
242 wlr_log(L_DEBUG, "Arranging layout for %p %s %dx%d+%d,%d", container, 245 wlr_log(L_DEBUG, "Arranging layout for %p %s %fx%f+%f,%f", container,
243 container->name, container->box.width, container->box.height, 246 container->name, container->width, container->height, container->x,
244 container->box.x, container->box.y); 247 container->y);
245 248
246 int x = 0, y = 0; 249 double x = 0, y = 0;
247 switch (container->type) { 250 switch (container->type) {
248 case C_ROOT: 251 case C_ROOT:
249 for (i = 0; i < container->children->length; ++i) { 252 for (i = 0; i < container->children->length; ++i) {
250 struct sway_container *output = container->children->items[i]; 253 struct sway_container *output = container->children->items[i];
251 wlr_log(L_DEBUG, "Arranging output '%s' at %d,%d", 254 wlr_log(L_DEBUG, "Arranging output '%s' at %f,%f",
252 output->name, output->box.x, output->box.y); 255 output->name, output->x, output->y);
253 arrange_windows(output, -1, -1); 256 arrange_windows(output, -1, -1);
254 } 257 }
255 return; 258 return;
@@ -258,8 +261,8 @@ void arrange_windows(struct sway_container *container,
258 int _width, _height; 261 int _width, _height;
259 wlr_output_effective_resolution( 262 wlr_output_effective_resolution(
260 container->sway_output->wlr_output, &_width, &_height); 263 container->sway_output->wlr_output, &_width, &_height);
261 width = container->box.width = _width; 264 width = container->width = _width;
262 height = container->box.height = _height; 265 height = container->height = _height;
263 } 266 }
264 // arrange all workspaces: 267 // arrange all workspaces:
265 for (i = 0; i < container->children->length; ++i) { 268 for (i = 0; i < container->children->length; ++i) {
@@ -274,32 +277,31 @@ void arrange_windows(struct sway_container *container,
274 struct wlr_box *area = &output->sway_output->usable_area; 277 struct wlr_box *area = &output->sway_output->usable_area;
275 wlr_log(L_DEBUG, "Usable area for ws: %dx%d@%d,%d", 278 wlr_log(L_DEBUG, "Usable area for ws: %dx%d@%d,%d",
276 area->width, area->height, area->x, area->y); 279 area->width, area->height, area->x, area->y);
277 container->box.width = width = area->width; 280 container->width = width = area->width;
278 container->box.height = height = area->height; 281 container->height = height = area->height;
279 container->box.x = x = area->x; 282 container->x = x = area->x;
280 container->box.y = y = area->y; 283 container->y = y = area->y;
281 wlr_log(L_DEBUG, "Arranging workspace '%s' at %d,%d", 284 wlr_log(L_DEBUG, "Arranging workspace '%s' at %f, %f",
282 container->name, container->box.x, container->box.y); 285 container->name, container->x, container->y);
283 } 286 }
284 // children are properly handled below 287 // children are properly handled below
285 break; 288 break;
286 case C_VIEW: 289 case C_VIEW:
287 { 290 {
288 container->box.width = width; 291 container->width = width;
289 container->box.height = height; 292 container->height = height;
290 view_configure(container->sway_view, 293 view_configure(container->sway_view, container->x, container->y,
291 container->box.x, container->box.y, 294 container->width, container->height);
292 container->box.width, container->box.height); 295 wlr_log(L_DEBUG, "Set view to %.f x %.f @ %.f, %.f",
293 wlr_log(L_DEBUG, "Set view to %d x %d @ %d, %d", 296 container->width, container->height,
294 container->box.width, container->box.height, 297 container->x, container->y);
295 container->box.x, container->box.y);
296 } 298 }
297 return; 299 return;
298 default: 300 default:
299 container->box.width = width; 301 container->width = width;
300 container->box.height = height; 302 container->height = height;
301 x = container->box.x; 303 x = container->x;
302 y = container->box.y; 304 y = container->y;
303 break; 305 break;
304 } 306 }
305 307
@@ -321,49 +323,50 @@ void arrange_windows(struct sway_container *container,
321} 323}
322 324
323static void apply_horiz_layout(struct sway_container *container, 325static void apply_horiz_layout(struct sway_container *container,
324 const int x, const int y, const int width, const int height, 326 const double x, const double y,
327 const double width, const double height,
325 const int start, const int end) { 328 const int start, const int end) {
326 double scale = 0; 329 double scale = 0;
327 // Calculate total width 330 // Calculate total width
328 for (int i = start; i < end; ++i) { 331 for (int i = start; i < end; ++i) {
329 struct sway_container *child = container->children->items[i]; 332 double *old_width =
330 int old_width = child->box.width; 333 &((struct sway_container *)container->children->items[i])->width;
331 if (old_width <= 0) { 334 if (*old_width <= 0) {
332 if (end - start > 1) { 335 if (end - start > 1) {
333 old_width = width / (end - start - 1); 336 *old_width = width / (end - start - 1);
334 } else { 337 } else {
335 old_width = width; 338 *old_width = width;
336 } 339 }
337 } 340 }
338 scale += old_width; 341 scale += *old_width;
339 } 342 }
340 scale = width / scale; 343 scale = width / scale;
341 344
342 // Resize windows 345 // Resize windows
343 int child_x = x; 346 double child_x = x;
344 if (scale > 0.1) { 347 if (scale > 0.1) {
345 wlr_log(L_DEBUG, "Arranging %p horizontally", container); 348 wlr_log(L_DEBUG, "Arranging %p horizontally", container);
346 for (int i = start; i < end; ++i) { 349 for (int i = start; i < end; ++i) {
347 struct sway_container *child = container->children->items[i]; 350 struct sway_container *child = container->children->items[i];
348 wlr_log(L_DEBUG, 351 wlr_log(L_DEBUG,
349 "Calculating arrangement for %p:%d (will scale %d by %f)", 352 "Calculating arrangement for %p:%d (will scale %f by %f)",
350 child, child->type, width, scale); 353 child, child->type, width, scale);
351 354
352 if (child->type == C_VIEW) { 355 if (child->type == C_VIEW) {
353 view_configure(child->sway_view, child_x, y, 356 view_configure(child->sway_view, child_x, y, child->width,
354 child->box.width, child->box.height); 357 child->height);
355 } else { 358 } else {
356 child->box.x = child_x; 359 child->x = child_x;
357 child->box.y = y; 360 child->y = y;
358 } 361 }
359 362
360 if (i == end - 1) { 363 if (i == end - 1) {
361 int remaining_width = x + width - child_x; 364 double remaining_width = x + width - child_x;
362 arrange_windows(child, remaining_width, height); 365 arrange_windows(child, remaining_width, height);
363 } else { 366 } else {
364 arrange_windows(child, child->box.width * scale, height); 367 arrange_windows(child, child->width * scale, height);
365 } 368 }
366 child_x += child->box.width; 369 child_x += child->width;
367 } 370 }
368 371
369 // update focused view border last because it may 372 // update focused view border last because it may
@@ -377,49 +380,50 @@ static void apply_horiz_layout(struct sway_container *container,
377} 380}
378 381
379void apply_vert_layout(struct sway_container *container, 382void apply_vert_layout(struct sway_container *container,
380 const int x, const int y, const int width, const int height, 383 const double x, const double y,
381 const int start, const int end) { 384 const double width, const double height, const int start,
385 const int end) {
382 int i; 386 int i;
383 double scale = 0; 387 double scale = 0;
384 // Calculate total height 388 // Calculate total height
385 for (i = start; i < end; ++i) { 389 for (i = start; i < end; ++i) {
386 struct sway_container *child = container->children->items[i]; 390 double *old_height =
387 int old_height = child->box.height; 391 &((struct sway_container *)container->children->items[i])->height;
388 if (old_height <= 0) { 392 if (*old_height <= 0) {
389 if (end - start > 1) { 393 if (end - start > 1) {
390 old_height = height / (end - start - 1); 394 *old_height = height / (end - start - 1);
391 } else { 395 } else {
392 old_height = height; 396 *old_height = height;
393 } 397 }
394 } 398 }
395 scale += old_height; 399 scale += *old_height;
396 } 400 }
397 scale = height / scale; 401 scale = height / scale;
398 402
399 // Resize 403 // Resize
400 int child_y = y; 404 double child_y = y;
401 if (scale > 0.1) { 405 if (scale > 0.1) {
402 wlr_log(L_DEBUG, "Arranging %p vertically", container); 406 wlr_log(L_DEBUG, "Arranging %p vertically", container);
403 for (i = start; i < end; ++i) { 407 for (i = start; i < end; ++i) {
404 struct sway_container *child = container->children->items[i]; 408 struct sway_container *child = container->children->items[i];
405 wlr_log(L_DEBUG, 409 wlr_log(L_DEBUG,
406 "Calculating arrangement for %p:%d (will scale %d by %f)", 410 "Calculating arrangement for %p:%d (will scale %f by %f)",
407 child, child->type, height, scale); 411 child, child->type, height, scale);
408 if (child->type == C_VIEW) { 412 if (child->type == C_VIEW) {
409 view_configure(child->sway_view, x, child_y, 413 view_configure(child->sway_view, x, child_y, child->width,
410 child->box.width, child->box.height); 414 child->height);
411 } else { 415 } else {
412 child->box.x = x; 416 child->x = x;
413 child->box.y = child_y; 417 child->y = child_y;
414 } 418 }
415 419
416 if (i == end - 1) { 420 if (i == end - 1) {
417 int remaining_height = y + height - child_y; 421 double remaining_height = y + height - child_y;
418 arrange_windows(child, width, remaining_height); 422 arrange_windows(child, width, remaining_height);
419 } else { 423 } else {
420 arrange_windows(child, width, child->box.height * scale); 424 arrange_windows(child, width, child->height * scale);
421 } 425 }
422 child_y += child->box.height; 426 child_y += child->height;
423 } 427 }
424 428
425 // update focused view border last because it may 429 // update focused view border last because it may
@@ -492,18 +496,18 @@ static void get_layout_center_position(struct sway_container *container,
492 int *x, int *y) { 496 int *x, int *y) {
493 // FIXME view coords are inconsistently referred to in layout/output systems 497 // FIXME view coords are inconsistently referred to in layout/output systems
494 if (container->type == C_OUTPUT) { 498 if (container->type == C_OUTPUT) {
495 *x = container->box.x + container->box.width / 2; 499 *x = container->x + container->width/2;
496 *y = container->box.y + container->box.height / 2; 500 *y = container->y + container->height/2;
497 } else { 501 } else {
498 struct sway_container *output = container_parent(container, C_OUTPUT); 502 struct sway_container *output = container_parent(container, C_OUTPUT);
499 if (container->type == C_WORKSPACE) { 503 if (container->type == C_WORKSPACE) {
500 // Workspace coordinates are actually wrong/arbitrary, but should 504 // Workspace coordinates are actually wrong/arbitrary, but should
501 // be same as output. 505 // be same as output.
502 *x = output->box.x; 506 *x = output->x;
503 *y = output->box.y; 507 *y = output->y;
504 } else { 508 } else {
505 *x = output->box.x + container->box.x; 509 *x = output->x + container->x;
506 *y = output->box.y + container->box.y; 510 *y = output->y + container->y;
507 } 511 }
508 } 512 }
509} 513}
@@ -674,14 +678,14 @@ struct sway_container *container_replace_child(struct sway_container *child,
674 child->parent = NULL; 678 child->parent = NULL;
675 679
676 // Set geometry for new child 680 // Set geometry for new child
677 new_child->box.x = child->box.x; 681 new_child->x = child->x;
678 new_child->box.y = child->box.y; 682 new_child->y = child->y;
679 new_child->box.width = child->box.width; 683 new_child->width = child->width;
680 new_child->box.height = child->box.height; 684 new_child->height = child->height;
681 685
682 // reset geometry for child 686 // reset geometry for child
683 child->box.width = 0; 687 child->width = 0;
684 child->box.height = 0; 688 child->height = 0;
685 689
686 return parent; 690 return parent;
687} 691}
@@ -697,10 +701,10 @@ struct sway_container *container_split(struct sway_container *child,
697 wlr_log(L_DEBUG, "creating container %p around %p", cont, child); 701 wlr_log(L_DEBUG, "creating container %p around %p", cont, child);
698 702
699 cont->prev_layout = L_NONE; 703 cont->prev_layout = L_NONE;
700 cont->box.width = child->box.width; 704 cont->width = child->width;
701 cont->box.height = child->box.height; 705 cont->height = child->height;
702 cont->box.x = child->box.x; 706 cont->x = child->x;
703 cont->box.y = child->box.y; 707 cont->y = child->y;
704 708
705 if (child->type == C_WORKSPACE) { 709 if (child->type == C_WORKSPACE) {
706 struct sway_seat *seat = input_manager_get_default_seat(input_manager); 710 struct sway_seat *seat = input_manager_get_default_seat(input_manager);
@@ -733,10 +737,10 @@ void container_recursive_resize(struct sway_container *container,
733 bool layout_match = true; 737 bool layout_match = true;
734 wlr_log(L_DEBUG, "Resizing %p with amount: %f", container, amount); 738 wlr_log(L_DEBUG, "Resizing %p with amount: %f", container, amount);
735 if (edge == RESIZE_EDGE_LEFT || edge == RESIZE_EDGE_RIGHT) { 739 if (edge == RESIZE_EDGE_LEFT || edge == RESIZE_EDGE_RIGHT) {
736 container->box.width += amount; 740 container->width += amount;
737 layout_match = container->layout == L_HORIZ; 741 layout_match = container->layout == L_HORIZ;
738 } else if (edge == RESIZE_EDGE_TOP || edge == RESIZE_EDGE_BOTTOM) { 742 } else if (edge == RESIZE_EDGE_TOP || edge == RESIZE_EDGE_BOTTOM) {
739 container->box.height += amount; 743 container->height += amount;
740 layout_match = container->layout == L_VERT; 744 layout_match = container->layout == L_VERT;
741 } 745 }
742 if (container->children) { 746 if (container->children) {