diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-05-19 22:54:50 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-05-21 20:16:56 +1000 |
commit | c08f9bf257c38c92a75988d89fba2d4de6bb2aea (patch) | |
tree | 76ea44c5548301ff4892c44838b783eeeb569c62 /sway/desktop/output.c | |
parent | Merge pull request #2011 from RyanDwyer/fix-hide-edge-border-bottom (diff) | |
download | sway-c08f9bf257c38c92a75988d89fba2d4de6bb2aea.tar.gz sway-c08f9bf257c38c92a75988d89fba2d4de6bb2aea.tar.zst sway-c08f9bf257c38c92a75988d89fba2d4de6bb2aea.zip |
Implement tabbed layout
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r-- | sway/desktop/output.c | 192 |
1 files changed, 189 insertions, 3 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 51c1ffbe..e39ef8db 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -599,12 +599,198 @@ static void render_container_simple(struct sway_output *output, | |||
599 | } | 599 | } |
600 | } | 600 | } |
601 | 601 | ||
602 | static void render_tab(struct sway_output *output, pixman_region32_t *damage, | ||
603 | struct sway_container *parent, int child_index, | ||
604 | struct border_colors *colors, struct wlr_texture *title_texture) { | ||
605 | float output_scale = output->wlr_output->scale; | ||
606 | float color[4]; | ||
607 | struct wlr_box box; | ||
608 | bool is_first = (child_index == 0); | ||
609 | bool is_last = (child_index == parent->children->length - 1); | ||
610 | |||
611 | int tab_width = parent->width / parent->children->length; | ||
612 | int x = parent->x + tab_width * child_index; | ||
613 | // Make last tab use the remaining width of the parent | ||
614 | if (is_last) { | ||
615 | tab_width = parent->width - tab_width * child_index; | ||
616 | } | ||
617 | |||
618 | // Single pixel bar above title | ||
619 | memcpy(&color, colors->border, sizeof(float) * 4); | ||
620 | box.x = x; | ||
621 | box.y = parent->y; | ||
622 | box.width = tab_width; | ||
623 | box.height = 1; | ||
624 | scale_box(&box, output_scale); | ||
625 | render_rect(output->wlr_output, damage, &box, color); | ||
626 | |||
627 | // Single pixel bar below title | ||
628 | memcpy(&color, colors->border, sizeof(float) * 4); | ||
629 | box.x = x + config->border_thickness * is_first; | ||
630 | box.y = parent->y + config->border_thickness * 2 + config->font_height - 1; | ||
631 | box.width = tab_width - config->border_thickness * is_first | ||
632 | - config->border_thickness * is_last; | ||
633 | box.height = 1; | ||
634 | scale_box(&box, output_scale); | ||
635 | render_rect(output->wlr_output, damage, &box, color); | ||
636 | |||
637 | // Title text | ||
638 | size_t title_width = 0; | ||
639 | if (title_texture) { | ||
640 | struct wlr_box texture_box; | ||
641 | wlr_texture_get_size(title_texture, | ||
642 | &texture_box.width, &texture_box.height); | ||
643 | texture_box.x = (x + config->border_thickness) * output_scale; | ||
644 | texture_box.y = (parent->y + config->border_thickness) * output_scale; | ||
645 | |||
646 | float matrix[9]; | ||
647 | wlr_matrix_project_box(matrix, &texture_box, | ||
648 | WL_OUTPUT_TRANSFORM_NORMAL, | ||
649 | 0.0, output->wlr_output->transform_matrix); | ||
650 | |||
651 | int available = (tab_width - config->border_thickness * 2) | ||
652 | * output_scale; | ||
653 | if (texture_box.width > available) { | ||
654 | texture_box.width = available; | ||
655 | } | ||
656 | render_texture(output->wlr_output, damage, title_texture, | ||
657 | &texture_box, matrix, 1.0); | ||
658 | title_width = texture_box.width; | ||
659 | } | ||
660 | |||
661 | // Title background - above the text | ||
662 | memcpy(&color, colors->background, sizeof(float) * 4); | ||
663 | box.x = x + config->border_thickness; | ||
664 | box.y = parent->y + 1; | ||
665 | box.width = tab_width - config->border_thickness * 2; | ||
666 | box.height = config->border_thickness - 1; | ||
667 | scale_box(&box, output_scale); | ||
668 | render_rect(output->wlr_output, damage, &box, color); | ||
669 | |||
670 | // Title background - below the text | ||
671 | box.y = (parent->y + config->border_thickness + config->font_height) | ||
672 | * output_scale; | ||
673 | render_rect(output->wlr_output, damage, &box, color); | ||
674 | |||
675 | // Title background - left border | ||
676 | box.x = x; | ||
677 | box.y = parent->y + 1; | ||
678 | box.width = config->border_thickness; | ||
679 | box.height = config->border_thickness * 2 | ||
680 | + config->font_height - 1 - !is_first; | ||
681 | scale_box(&box, output_scale); | ||
682 | render_rect(output->wlr_output, damage, &box, color); | ||
683 | |||
684 | // Title background - right border | ||
685 | box.x = x + tab_width - config->border_thickness; | ||
686 | box.y = parent->y + 1; | ||
687 | box.width = config->border_thickness; | ||
688 | box.height = config->border_thickness * 2 | ||
689 | + config->font_height - 1 - !is_last; | ||
690 | scale_box(&box, output_scale); | ||
691 | render_rect(output->wlr_output, damage, &box, color); | ||
692 | |||
693 | // Title background - right of text | ||
694 | box.x = (x + config->border_thickness) * output_scale + title_width; | ||
695 | box.y = (parent->y + config->border_thickness) * output_scale; | ||
696 | box.width = (tab_width - config->border_thickness * 2) * output_scale | ||
697 | - title_width; | ||
698 | box.height = config->font_height * output_scale; | ||
699 | render_rect(output->wlr_output, damage, &box, color); | ||
700 | } | ||
701 | |||
702 | static void render_tab_content(struct sway_output *output, | ||
703 | pixman_region32_t *damage, struct sway_container *con, | ||
704 | struct border_colors *colors) { | ||
705 | struct sway_view *view = con->sway_view; | ||
706 | render_view(view, output, damage); | ||
707 | |||
708 | struct wlr_box box; | ||
709 | float output_scale = output->wlr_output->scale; | ||
710 | float color[4]; | ||
711 | |||
712 | if (view->border_left) { | ||
713 | memcpy(&color, colors->child_border, sizeof(float) * 4); | ||
714 | color[3] *= con->alpha; | ||
715 | box.x = con->x; | ||
716 | box.y = con->y + config->border_thickness * 2 + config->font_height; | ||
717 | box.width = view->border_thickness; | ||
718 | box.height = view->height; | ||
719 | scale_box(&box, output_scale); | ||
720 | render_rect(output->wlr_output, damage, &box, color); | ||
721 | } | ||
722 | |||
723 | if (view->border_right) { | ||
724 | memcpy(&color, colors->child_border, sizeof(float) * 4); | ||
725 | color[3] *= con->alpha; | ||
726 | box.x = view->x + view->width; | ||
727 | box.y = con->y + config->border_thickness * 2 + config->font_height; | ||
728 | box.width = view->border_thickness; | ||
729 | box.height = view->height; | ||
730 | scale_box(&box, output_scale); | ||
731 | render_rect(output->wlr_output, damage, &box, color); | ||
732 | } | ||
733 | |||
734 | if (view->border_bottom) { | ||
735 | memcpy(&color, colors->child_border, sizeof(float) * 4); | ||
736 | color[3] *= con->alpha; | ||
737 | box.x = con->x; | ||
738 | box.y = view->y + view->height; | ||
739 | box.width = con->width; | ||
740 | box.height = view->border_thickness; | ||
741 | scale_box(&box, output_scale); | ||
742 | render_rect(output->wlr_output, damage, &box, color); | ||
743 | } | ||
744 | } | ||
745 | |||
602 | /** | 746 | /** |
603 | * Render a container's children using the L_TABBED layout. | 747 | * Render a container's children using the L_TABBED layout. |
604 | */ | 748 | */ |
605 | static void render_container_tabbed(struct sway_output *output, | 749 | static void render_container_tabbed(struct sway_output *output, |
606 | pixman_region32_t *damage, struct sway_container *con) { | 750 | pixman_region32_t *damage, struct sway_container *con, |
607 | // TODO | 751 | bool parent_focused) { |
752 | if (!con->children->length) { | ||
753 | return; | ||
754 | } | ||
755 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
756 | struct sway_container *focus = seat_get_focus(seat); | ||
757 | struct sway_container *current = seat_get_focus_inactive(seat, con); | ||
758 | while (current->parent != con) { | ||
759 | current = current->parent; | ||
760 | } | ||
761 | struct border_colors *current_colors = NULL; | ||
762 | |||
763 | // Render tabs | ||
764 | for (int i = 0; i < con->children->length; ++i) { | ||
765 | struct sway_container *child = con->children->items[i]; | ||
766 | struct border_colors *colors; | ||
767 | struct wlr_texture *title_texture; | ||
768 | |||
769 | if (focus == child || parent_focused) { | ||
770 | colors = &config->border_colors.focused; | ||
771 | title_texture = child->title_focused; | ||
772 | } else if (child == current) { | ||
773 | colors = &config->border_colors.focused_inactive; | ||
774 | title_texture = child->title_focused_inactive; | ||
775 | } else { | ||
776 | colors = &config->border_colors.unfocused; | ||
777 | title_texture = child->title_unfocused; | ||
778 | } | ||
779 | |||
780 | render_tab(output, damage, con, i, colors, title_texture); | ||
781 | |||
782 | if (child == current) { | ||
783 | current_colors = colors; | ||
784 | } | ||
785 | } | ||
786 | |||
787 | // Render surface and left/right/bottom borders | ||
788 | if (current->type == C_VIEW) { | ||
789 | render_tab_content(output, damage, current, current_colors); | ||
790 | } else { | ||
791 | render_container(output, damage, current, | ||
792 | parent_focused || current == focus); | ||
793 | } | ||
608 | } | 794 | } |
609 | 795 | ||
610 | /** | 796 | /** |
@@ -628,7 +814,7 @@ static void render_container(struct sway_output *output, | |||
628 | render_container_stacked(output, damage, con); | 814 | render_container_stacked(output, damage, con); |
629 | break; | 815 | break; |
630 | case L_TABBED: | 816 | case L_TABBED: |
631 | render_container_tabbed(output, damage, con); | 817 | render_container_tabbed(output, damage, con, parent_focused); |
632 | break; | 818 | break; |
633 | case L_FLOATING: | 819 | case L_FLOATING: |
634 | // TODO | 820 | // TODO |