diff options
Diffstat (limited to 'sway/layout.c')
-rw-r--r-- | sway/layout.c | 344 |
1 files changed, 276 insertions, 68 deletions
diff --git a/sway/layout.c b/sway/layout.c index 0b498937..3e550927 100644 --- a/sway/layout.c +++ b/sway/layout.c | |||
@@ -3,7 +3,6 @@ | |||
3 | #include <math.h> | 3 | #include <math.h> |
4 | #include <wlc/wlc.h> | 4 | #include <wlc/wlc.h> |
5 | #include "extensions.h" | 5 | #include "extensions.h" |
6 | #include "layout.h" | ||
7 | #include "log.h" | 6 | #include "log.h" |
8 | #include "list.h" | 7 | #include "list.h" |
9 | #include "config.h" | 8 | #include "config.h" |
@@ -13,6 +12,7 @@ | |||
13 | #include "output.h" | 12 | #include "output.h" |
14 | #include "ipc-server.h" | 13 | #include "ipc-server.h" |
15 | #include "border.h" | 14 | #include "border.h" |
15 | #include "layout.h" | ||
16 | 16 | ||
17 | swayc_t root_container; | 17 | swayc_t root_container; |
18 | list_t *scratchpad; | 18 | list_t *scratchpad; |
@@ -244,7 +244,9 @@ void move_container(swayc_t *container, enum movement_direction dir) { | |||
244 | while (true) { | 244 | while (true) { |
245 | sway_log(L_DEBUG, "container:%p, parent:%p, child %p,", | 245 | sway_log(L_DEBUG, "container:%p, parent:%p, child %p,", |
246 | container,parent,child); | 246 | container,parent,child); |
247 | if (parent->layout == layout) { | 247 | if (parent->layout == layout |
248 | || (parent->layout == L_TABBED && layout == L_HORIZ) | ||
249 | || (parent->layout == L_STACKED && layout == L_VERT)) { | ||
248 | int diff; | 250 | int diff; |
249 | // If it has ascended (parent has moved up), no container is removed | 251 | // If it has ascended (parent has moved up), no container is removed |
250 | // so insert it at index, or index+1. | 252 | // so insert it at index, or index+1. |
@@ -264,9 +266,11 @@ void move_container(swayc_t *container, enum movement_direction dir) { | |||
264 | // Move container into sibling container | 266 | // Move container into sibling container |
265 | if (child->type == C_CONTAINER) { | 267 | if (child->type == C_CONTAINER) { |
266 | parent = child; | 268 | parent = child; |
267 | // Insert it in first/last if matching layout,otherwise | 269 | // Insert it in first/last if matching layout, otherwise |
268 | // inesrt it next to focused container | 270 | // inesrt it next to focused container |
269 | if (parent->layout == layout) { | 271 | if (parent->layout == layout |
272 | || (parent->layout == L_TABBED && layout == L_HORIZ) | ||
273 | || (parent->layout == L_STACKED && layout == L_VERT)) { | ||
270 | desired = (diff < 0) * parent->children->length; | 274 | desired = (diff < 0) * parent->children->length; |
271 | } else { | 275 | } else { |
272 | desired = index_child(child->focused); | 276 | desired = index_child(child->focused); |
@@ -299,8 +303,6 @@ void move_container(swayc_t *container, enum movement_direction dir) { | |||
299 | child = parent; | 303 | child = parent; |
300 | parent = child->parent; | 304 | parent = child->parent; |
301 | } | 305 | } |
302 | // Dirty hack to fix a certain case | ||
303 | arrange_windows(parent, -1, -1); | ||
304 | arrange_windows(parent->parent, -1, -1); | 306 | arrange_windows(parent->parent, -1, -1); |
305 | set_focused_container_for(parent->parent, container); | 307 | set_focused_container_for(parent->parent, container); |
306 | } | 308 | } |
@@ -380,16 +382,14 @@ static void adjust_border_geometry(swayc_t *c, struct wlc_geometry *g, | |||
380 | g->size.w += left + right; | 382 | g->size.w += left + right; |
381 | if (g->origin.x - left < 0) { | 383 | if (g->origin.x - left < 0) { |
382 | g->size.w += g->origin.x - left; | 384 | g->size.w += g->origin.x - left; |
383 | } | 385 | } else if (g->origin.x + g->size.w - right > res->w) { |
384 | else if (g->origin.x + g->size.w - right > res->w) { | ||
385 | g->size.w = res->w - g->origin.x + right; | 386 | g->size.w = res->w - g->origin.x + right; |
386 | } | 387 | } |
387 | 388 | ||
388 | g->size.h += top + bottom; | 389 | g->size.h += top + bottom; |
389 | if (g->origin.y - top < 0) { | 390 | if (g->origin.y - top < 0) { |
390 | g->size.h += g->origin.y - top; | 391 | g->size.h += g->origin.y - top; |
391 | } | 392 | } else if (g->origin.y + g->size.h - top > res->h) { |
392 | else if (g->origin.y + g->size.h - top > res->h) { | ||
393 | g->size.h = res->h - g->origin.y + top; | 393 | g->size.h = res->h - g->origin.y + top; |
394 | } | 394 | } |
395 | 395 | ||
@@ -421,11 +421,11 @@ static void update_border_geometry_floating(swayc_t *c, struct wlc_geometry *geo | |||
421 | 421 | ||
422 | struct wlc_geometry title_bar = { | 422 | struct wlc_geometry title_bar = { |
423 | .origin = { | 423 | .origin = { |
424 | .x = g.origin.x, | 424 | .x = c->actual_geometry.origin.x - c->border_thickness, |
425 | .y = g.origin.y | 425 | .y = c->actual_geometry.origin.y - title_bar_height |
426 | }, | 426 | }, |
427 | .size = { | 427 | .size = { |
428 | .w = g.size.w, | 428 | .w = c->actual_geometry.size.w + (2 * c->border_thickness), |
429 | .h = title_bar_height | 429 | .h = title_bar_height |
430 | } | 430 | } |
431 | }; | 431 | }; |
@@ -440,10 +440,42 @@ static void update_border_geometry_floating(swayc_t *c, struct wlc_geometry *geo | |||
440 | update_view_border(c); | 440 | update_view_border(c); |
441 | } | 441 | } |
442 | 442 | ||
443 | void update_geometry(swayc_t *container) { | 443 | void update_layout_geometry(swayc_t *parent, enum swayc_layouts prev_layout) { |
444 | if (container->type != C_VIEW) { | 444 | switch (parent->layout) { |
445 | return; | 445 | case L_TABBED: |
446 | case L_STACKED: | ||
447 | if (prev_layout != L_TABBED && prev_layout != L_STACKED) { | ||
448 | // cache current geometry for all non-float children | ||
449 | int i; | ||
450 | for (i = 0; i < parent->children->length; ++i) { | ||
451 | swayc_t *child = parent->children->items[i]; | ||
452 | child->cached_geometry.origin.x = child->x; | ||
453 | child->cached_geometry.origin.y = child->y; | ||
454 | child->cached_geometry.size.w = child->width; | ||
455 | child->cached_geometry.size.h = child->height; | ||
456 | } | ||
457 | } | ||
458 | break; | ||
459 | default: | ||
460 | if (prev_layout == L_TABBED || prev_layout == L_STACKED) { | ||
461 | // recover cached geometry for all non-float children | ||
462 | int i; | ||
463 | for (i = 0; i < parent->children->length; ++i) { | ||
464 | swayc_t *child = parent->children->items[i]; | ||
465 | // only recoverer cached geometry if non-zero | ||
466 | if (!wlc_geometry_equals(&child->cached_geometry, &wlc_geometry_zero)) { | ||
467 | child->x = child->cached_geometry.origin.x; | ||
468 | child->y = child->cached_geometry.origin.y; | ||
469 | child->width = child->cached_geometry.size.w; | ||
470 | child->height = child->cached_geometry.size.h; | ||
471 | } | ||
472 | } | ||
473 | } | ||
474 | break; | ||
446 | } | 475 | } |
476 | } | ||
477 | |||
478 | static int update_gap_geometry(swayc_t *container, struct wlc_geometry *g) { | ||
447 | swayc_t *ws = swayc_parent_by_type(container, C_WORKSPACE); | 479 | swayc_t *ws = swayc_parent_by_type(container, C_WORKSPACE); |
448 | swayc_t *op = ws->parent; | 480 | swayc_t *op = ws->parent; |
449 | int gap = container->is_floating ? 0 : swayc_gap(container); | 481 | int gap = container->is_floating ? 0 : swayc_gap(container); |
@@ -453,16 +485,63 @@ void update_geometry(swayc_t *container) { | |||
453 | gap -= 1; | 485 | gap -= 1; |
454 | } | 486 | } |
455 | 487 | ||
488 | g->origin.x = container->x + gap/2 < op->width ? container->x + gap/2 : op->width-1; | ||
489 | g->origin.y = container->y + gap/2 < op->height ? container->y + gap/2 : op->height-1; | ||
490 | g->size.w = container->width > gap ? container->width - gap : 1; | ||
491 | g->size.h = container->height > gap ? container->height - gap : 1; | ||
492 | |||
493 | if ((!config->edge_gaps && gap > 0) || (config->smart_gaps && ws->children->length == 1)) { | ||
494 | // Remove gap against the workspace edges. Because a pixel is not | ||
495 | // divisable, depending on gap size and the number of siblings our view | ||
496 | // might be at the workspace edge without being exactly so (thus test | ||
497 | // with gap, and align correctly). | ||
498 | if (container->x - gap <= ws->x) { | ||
499 | g->origin.x = ws->x; | ||
500 | g->size.w = container->width - gap/2; | ||
501 | } | ||
502 | if (container->y - gap <= ws->y) { | ||
503 | g->origin.y = ws->y; | ||
504 | g->size.h = container->height - gap/2; | ||
505 | } | ||
506 | if (container->x + container->width + gap >= ws->x + ws->width) { | ||
507 | g->size.w = ws->x + ws->width - g->origin.x; | ||
508 | } | ||
509 | if (container->y + container->height + gap >= ws->y + ws->height) { | ||
510 | g->size.h = ws->y + ws->height - g->origin.y; | ||
511 | } | ||
512 | } | ||
513 | |||
514 | return gap; | ||
515 | } | ||
516 | |||
517 | void update_geometry(swayc_t *container) { | ||
518 | if (container->type != C_VIEW && container->type != C_CONTAINER) { | ||
519 | return; | ||
520 | } | ||
521 | |||
522 | swayc_t *ws = swayc_parent_by_type(container, C_WORKSPACE); | ||
523 | swayc_t *op = ws->parent; | ||
524 | swayc_t *parent = container->parent; | ||
525 | |||
456 | struct wlc_geometry geometry = { | 526 | struct wlc_geometry geometry = { |
457 | .origin = { | 527 | .origin = { |
458 | .x = container->x + gap/2 < op->width ? container->x + gap/2 : op->width-1, | 528 | .x = container->x < op->width ? container->x : op->width-1, |
459 | .y = container->y + gap/2 < op->height ? container->y + gap/2 : op->height-1 | 529 | .y = container->y < op->height ? container->y : op->height-1 |
460 | }, | 530 | }, |
461 | .size = { | 531 | .size = { |
462 | .w = container->width > gap ? container->width - gap : 1, | 532 | .w = container->width, |
463 | .h = container->height > gap ? container->height - gap : 1, | 533 | .h = container->height, |
464 | } | 534 | } |
465 | }; | 535 | }; |
536 | |||
537 | int gap = 0; | ||
538 | |||
539 | // apply inner gaps to non-tabbed/stacked containers | ||
540 | swayc_t *p = swayc_tabbed_stacked_parent(container); | ||
541 | if (p == NULL) { | ||
542 | gap = update_gap_geometry(container, &geometry); | ||
543 | } | ||
544 | |||
466 | if (swayc_is_fullscreen(container)) { | 545 | if (swayc_is_fullscreen(container)) { |
467 | swayc_t *output = swayc_parent_by_type(container, C_OUTPUT); | 546 | swayc_t *output = swayc_parent_by_type(container, C_OUTPUT); |
468 | const struct wlc_size *size = wlc_output_get_resolution(output->handle); | 547 | const struct wlc_size *size = wlc_output_get_resolution(output->handle); |
@@ -473,28 +552,7 @@ void update_geometry(swayc_t *container) { | |||
473 | if (op->focused == ws) { | 552 | if (op->focused == ws) { |
474 | wlc_view_bring_to_front(container->handle); | 553 | wlc_view_bring_to_front(container->handle); |
475 | } | 554 | } |
476 | } else if ((!config->edge_gaps && gap > 0) || (config->smart_gaps && ws->children->length == 1)) { | ||
477 | // Remove gap against the workspace edges. Because a pixel is not | ||
478 | // divisable, depending on gap size and the number of siblings our view | ||
479 | // might be at the workspace edge without being exactly so (thus test | ||
480 | // with gap, and align correctly). | ||
481 | if (container->x - gap <= ws->x) { | ||
482 | geometry.origin.x = ws->x; | ||
483 | geometry.size.w = container->width - gap/2; | ||
484 | } | ||
485 | if (container->y - gap <= ws->y) { | ||
486 | geometry.origin.y = ws->y; | ||
487 | geometry.size.h = container->height - gap/2; | ||
488 | } | ||
489 | if (container->x + container->width + gap >= ws->x + ws->width) { | ||
490 | geometry.size.w = ws->x + ws->width - geometry.origin.x; | ||
491 | } | ||
492 | if (container->y + container->height + gap >= ws->y + ws->height) { | ||
493 | geometry.size.h = ws->y + ws->height - geometry.origin.y; | ||
494 | } | ||
495 | } | ||
496 | 555 | ||
497 | if (swayc_is_fullscreen(container)) { | ||
498 | container->border_geometry = wlc_geometry_zero; | 556 | container->border_geometry = wlc_geometry_zero; |
499 | container->title_bar_geometry = wlc_geometry_zero; | 557 | container->title_bar_geometry = wlc_geometry_zero; |
500 | } else if (container->is_floating) { // allocate border for floating window | 558 | } else if (container->is_floating) { // allocate border for floating window |
@@ -533,42 +591,106 @@ void update_geometry(swayc_t *container) { | |||
533 | } | 591 | } |
534 | } | 592 | } |
535 | 593 | ||
536 | switch (container->border_type) { | 594 | int title_bar_height = config->font_height + 4; //borders + padding |
537 | case B_NONE: | 595 | |
538 | break; | 596 | if (parent->layout == L_TABBED) { |
539 | case B_PIXEL: | 597 | int i, x = 0, w, l, r; |
598 | l = parent->children->length; | ||
599 | w = geometry.size.w / l; | ||
600 | r = geometry.size.w % l; | ||
601 | for (i = 0; i < parent->children->length; ++i) { | ||
602 | swayc_t *view = parent->children->items[i]; | ||
603 | if (view == container) { | ||
604 | x = w * i; | ||
605 | if (i == l - 1) { | ||
606 | w += r; | ||
607 | } | ||
608 | break; | ||
609 | } | ||
610 | } | ||
611 | |||
612 | struct wlc_geometry title_bar = { | ||
613 | .origin = { | ||
614 | .x = container->border_geometry.origin.x + x, | ||
615 | .y = container->border_geometry.origin.y | ||
616 | }, | ||
617 | .size = { | ||
618 | .w = w, | ||
619 | .h = title_bar_height | ||
620 | } | ||
621 | }; | ||
540 | geometry.origin.x += border_left; | 622 | geometry.origin.x += border_left; |
541 | geometry.origin.y += border_top; | 623 | geometry.origin.y += title_bar.size.h; |
542 | geometry.size.w -= (border_left + border_right); | 624 | geometry.size.w -= (border_left + border_right); |
543 | geometry.size.h -= (border_top + border_bottom); | 625 | geometry.size.h -= (border_bottom + title_bar.size.h); |
544 | break; | 626 | container->title_bar_geometry = title_bar; |
545 | case B_NORMAL: | 627 | } else if (parent->layout == L_STACKED) { |
546 | { | 628 | int i, y; |
547 | struct wlc_geometry title_bar = { | 629 | for (i = 0; i < parent->children->length; ++i) { |
548 | .origin = { | 630 | swayc_t *view = parent->children->items[i]; |
549 | .x = container->border_geometry.origin.x, | 631 | if (view == container) { |
550 | .y = container->border_geometry.origin.y | 632 | y = title_bar_height * i; |
551 | }, | 633 | } |
552 | .size = { | 634 | } |
553 | .w = container->border_geometry.size.w, | 635 | |
554 | .h = config->font_height + 4 // borders + padding | 636 | struct wlc_geometry title_bar = { |
555 | } | 637 | .origin = { |
556 | }; | 638 | .x = container->border_geometry.origin.x, |
639 | .y = container->border_geometry.origin.y + y | ||
640 | }, | ||
641 | .size = { | ||
642 | .w = container->border_geometry.size.w, | ||
643 | .h = title_bar_height | ||
644 | } | ||
645 | }; | ||
646 | title_bar_height = title_bar_height * parent->children->length; | ||
647 | geometry.origin.x += border_left; | ||
648 | geometry.origin.y += title_bar_height; | ||
649 | geometry.size.w -= (border_left + border_right); | ||
650 | geometry.size.h -= (border_bottom + title_bar_height); | ||
651 | container->title_bar_geometry = title_bar; | ||
652 | } else { | ||
653 | switch (container->border_type) { | ||
654 | case B_NONE: | ||
655 | break; | ||
656 | case B_PIXEL: | ||
557 | geometry.origin.x += border_left; | 657 | geometry.origin.x += border_left; |
558 | geometry.origin.y += title_bar.size.h; | 658 | geometry.origin.y += border_top; |
559 | geometry.size.w -= (border_left + border_right); | 659 | geometry.size.w -= (border_left + border_right); |
560 | geometry.size.h -= (border_bottom + title_bar.size.h); | 660 | geometry.size.h -= (border_top + border_bottom); |
561 | container->title_bar_geometry = title_bar; | ||
562 | break; | 661 | break; |
662 | case B_NORMAL: | ||
663 | { | ||
664 | struct wlc_geometry title_bar = { | ||
665 | .origin = { | ||
666 | .x = container->border_geometry.origin.x, | ||
667 | .y = container->border_geometry.origin.y | ||
668 | }, | ||
669 | .size = { | ||
670 | .w = container->border_geometry.size.w, | ||
671 | .h = title_bar_height | ||
672 | } | ||
673 | }; | ||
674 | geometry.origin.x += border_left; | ||
675 | geometry.origin.y += title_bar.size.h; | ||
676 | geometry.size.w -= (border_left + border_right); | ||
677 | geometry.size.h -= (border_bottom + title_bar.size.h); | ||
678 | container->title_bar_geometry = title_bar; | ||
679 | break; | ||
680 | } | ||
563 | } | 681 | } |
564 | } | 682 | } |
565 | 683 | ||
566 | container->actual_geometry = geometry; | 684 | container->actual_geometry = geometry; |
567 | 685 | ||
568 | update_view_border(container); | 686 | if (container->type == C_VIEW) { |
687 | update_view_border(container); | ||
688 | } | ||
569 | } | 689 | } |
570 | 690 | ||
571 | wlc_view_set_geometry(container->handle, 0, &geometry); | 691 | if (container->type == C_VIEW) { |
692 | wlc_view_set_geometry(container->handle, 0, &geometry); | ||
693 | } | ||
572 | } | 694 | } |
573 | 695 | ||
574 | static void arrange_windows_r(swayc_t *container, double width, double height) { | 696 | static void arrange_windows_r(swayc_t *container, double width, double height) { |
@@ -648,7 +770,7 @@ static void arrange_windows_r(swayc_t *container, double width, double height) { | |||
648 | height = container->height = height - gap * 2; | 770 | height = container->height = height - gap * 2; |
649 | sway_log(L_DEBUG, "Arranging workspace '%s' at %f, %f", container->name, container->x, container->y); | 771 | sway_log(L_DEBUG, "Arranging workspace '%s' at %f, %f", container->name, container->x, container->y); |
650 | } | 772 | } |
651 | // children are properly handled below | 773 | // children are properly handled below |
652 | break; | 774 | break; |
653 | case C_VIEW: | 775 | case C_VIEW: |
654 | { | 776 | { |
@@ -664,6 +786,33 @@ static void arrange_windows_r(swayc_t *container, double width, double height) { | |||
664 | container->height = height; | 786 | container->height = height; |
665 | x = container->x; | 787 | x = container->x; |
666 | y = container->y; | 788 | y = container->y; |
789 | |||
790 | // add gaps to top level tapped/stacked container | ||
791 | if (container->parent->type == C_WORKSPACE && | ||
792 | (container->layout == L_TABBED || container->layout == L_STACKED)) { | ||
793 | update_geometry(container); | ||
794 | width = container->border_geometry.size.w; | ||
795 | height = container->border_geometry.size.h; | ||
796 | x = container->border_geometry.origin.x; | ||
797 | y = container->border_geometry.origin.y; | ||
798 | } | ||
799 | |||
800 | // update container size if it's a child in a tabbed/stacked layout | ||
801 | if (swayc_tabbed_stacked_parent(container) != NULL) { | ||
802 | // Use parent actual_geometry as a base for calculating | ||
803 | // container geometry | ||
804 | container->width = container->parent->actual_geometry.size.w; | ||
805 | container->height = container->parent->actual_geometry.size.h; | ||
806 | container->x = container->parent->actual_geometry.origin.x; | ||
807 | container->y = container->parent->actual_geometry.origin.y; | ||
808 | |||
809 | update_geometry(container); | ||
810 | width = container->width = container->actual_geometry.size.w; | ||
811 | height = container->height = container->actual_geometry.size.h; | ||
812 | x = container->x = container->actual_geometry.origin.x; | ||
813 | y = container->y = container->actual_geometry.origin.y; | ||
814 | } | ||
815 | |||
667 | break; | 816 | break; |
668 | } | 817 | } |
669 | 818 | ||
@@ -683,15 +832,22 @@ static void arrange_windows_r(swayc_t *container, double width, double height) { | |||
683 | } | 832 | } |
684 | scale += *old_width; | 833 | scale += *old_width; |
685 | } | 834 | } |
835 | |||
686 | // Resize windows | 836 | // Resize windows |
687 | if (scale > 0.1) { | 837 | if (scale > 0.1) { |
688 | scale = width / scale; | 838 | scale = width / scale; |
689 | sway_log(L_DEBUG, "Arranging %p horizontally", container); | 839 | sway_log(L_DEBUG, "Arranging %p horizontally", container); |
840 | swayc_t *focused = NULL; | ||
690 | for (i = 0; i < container->children->length; ++i) { | 841 | for (i = 0; i < container->children->length; ++i) { |
691 | swayc_t *child = container->children->items[i]; | 842 | swayc_t *child = container->children->items[i]; |
692 | sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, width, scale); | 843 | sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, width, scale); |
693 | child->x = x; | 844 | child->x = x; |
694 | child->y = y; | 845 | child->y = y; |
846 | |||
847 | if (child == container->focused) { | ||
848 | focused = child; | ||
849 | } | ||
850 | |||
695 | if (i == container->children->length - 1) { | 851 | if (i == container->children->length - 1) { |
696 | double remaining_width = container->x + width - x; | 852 | double remaining_width = container->x + width - x; |
697 | arrange_windows_r(child, remaining_width, height); | 853 | arrange_windows_r(child, remaining_width, height); |
@@ -700,6 +856,12 @@ static void arrange_windows_r(swayc_t *container, double width, double height) { | |||
700 | } | 856 | } |
701 | x += child->width; | 857 | x += child->width; |
702 | } | 858 | } |
859 | |||
860 | // update focused view border last because it may | ||
861 | // depend on the title bar geometry of its siblings. | ||
862 | if (focused && container->children->length > 1) { | ||
863 | update_view_border(focused); | ||
864 | } | ||
703 | } | 865 | } |
704 | break; | 866 | break; |
705 | case L_VERT: | 867 | case L_VERT: |
@@ -719,11 +881,17 @@ static void arrange_windows_r(swayc_t *container, double width, double height) { | |||
719 | if (scale > 0.1) { | 881 | if (scale > 0.1) { |
720 | scale = height / scale; | 882 | scale = height / scale; |
721 | sway_log(L_DEBUG, "Arranging %p vertically", container); | 883 | sway_log(L_DEBUG, "Arranging %p vertically", container); |
884 | swayc_t *focused = NULL; | ||
722 | for (i = 0; i < container->children->length; ++i) { | 885 | for (i = 0; i < container->children->length; ++i) { |
723 | swayc_t *child = container->children->items[i]; | 886 | swayc_t *child = container->children->items[i]; |
724 | sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, height, scale); | 887 | sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, height, scale); |
725 | child->x = x; | 888 | child->x = x; |
726 | child->y = y; | 889 | child->y = y; |
890 | |||
891 | if (child == container->focused) { | ||
892 | focused = child; | ||
893 | } | ||
894 | |||
727 | if (i == container->children->length - 1) { | 895 | if (i == container->children->length - 1) { |
728 | double remaining_height = container->y + height - y; | 896 | double remaining_height = container->y + height - y; |
729 | arrange_windows_r(child, width, remaining_height); | 897 | arrange_windows_r(child, width, remaining_height); |
@@ -732,8 +900,34 @@ static void arrange_windows_r(swayc_t *container, double width, double height) { | |||
732 | } | 900 | } |
733 | y += child->height; | 901 | y += child->height; |
734 | } | 902 | } |
903 | |||
904 | // update focused view border last because it may | ||
905 | // depend on the title bar geometry of its siblings. | ||
906 | if (focused && container->children->length > 1) { | ||
907 | update_view_border(focused); | ||
908 | } | ||
735 | } | 909 | } |
736 | break; | 910 | break; |
911 | case L_TABBED: | ||
912 | case L_STACKED: | ||
913 | { | ||
914 | swayc_t *focused = NULL; | ||
915 | for (i = 0; i < container->children->length; ++i) { | ||
916 | swayc_t *child = container->children->items[i]; | ||
917 | child->x = x; | ||
918 | child->y = y; | ||
919 | if (child == container->focused) { | ||
920 | focused = child; | ||
921 | } else { | ||
922 | arrange_windows_r(child, width, height); | ||
923 | } | ||
924 | } | ||
925 | |||
926 | if (focused) { | ||
927 | arrange_windows_r(focused, width, height); | ||
928 | } | ||
929 | break; | ||
930 | } | ||
737 | } | 931 | } |
738 | 932 | ||
739 | // Arrage floating layouts for workspaces last | 933 | // Arrage floating layouts for workspaces last |
@@ -742,6 +936,8 @@ static void arrange_windows_r(swayc_t *container, double width, double height) { | |||
742 | swayc_t *view = container->floating->items[i]; | 936 | swayc_t *view = container->floating->items[i]; |
743 | if (view->type == C_VIEW) { | 937 | if (view->type == C_VIEW) { |
744 | update_geometry(view); | 938 | update_geometry(view); |
939 | sway_log(L_DEBUG, "Set floating view to %.f x %.f @ %.f, %.f", view->width, | ||
940 | view->height, view->x, view->y); | ||
745 | if (swayc_is_fullscreen(view)) { | 941 | if (swayc_is_fullscreen(view)) { |
746 | wlc_view_bring_to_front(view->handle); | 942 | wlc_view_bring_to_front(view->handle); |
747 | } else if (!container->focused | 943 | } else if (!container->focused |
@@ -840,12 +1036,12 @@ swayc_t *get_swayc_in_direction_under(swayc_t *container, enum movement_directio | |||
840 | return get_swayc_in_output_direction(output, dir); | 1036 | return get_swayc_in_output_direction(output, dir); |
841 | } else { | 1037 | } else { |
842 | if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { | 1038 | if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { |
843 | if (parent->layout == L_HORIZ) { | 1039 | if (parent->layout == L_HORIZ || parent->layout == L_TABBED) { |
844 | can_move = true; | 1040 | can_move = true; |
845 | diff = dir == MOVE_LEFT ? -1 : 1; | 1041 | diff = dir == MOVE_LEFT ? -1 : 1; |
846 | } | 1042 | } |
847 | } else { | 1043 | } else { |
848 | if (parent->layout == L_VERT) { | 1044 | if (parent->layout == L_VERT || parent->layout == L_STACKED) { |
849 | can_move = true; | 1045 | can_move = true; |
850 | diff = dir == MOVE_UP ? -1 : 1; | 1046 | diff = dir == MOVE_UP ? -1 : 1; |
851 | } | 1047 | } |
@@ -900,3 +1096,15 @@ void recursive_resize(swayc_t *container, double amount, enum wlc_resize_edge ed | |||
900 | } | 1096 | } |
901 | } | 1097 | } |
902 | } | 1098 | } |
1099 | |||
1100 | enum swayc_layouts default_layout(swayc_t *output) { | ||
1101 | if (config->default_layout != L_NONE) { | ||
1102 | return config->default_layout; | ||
1103 | } else if (config->default_orientation != L_NONE) { | ||
1104 | return config->default_orientation; | ||
1105 | } else if (output->width >= output->height) { | ||
1106 | return L_HORIZ; | ||
1107 | } else { | ||
1108 | return L_VERT; | ||
1109 | } | ||
1110 | } | ||