diff options
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r-- | sway/desktop/output.c | 193 |
1 files changed, 187 insertions, 6 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 51c1ffbe..551e96fc 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -599,12 +599,195 @@ 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 | struct sway_container *con = parent->children->items[child_index]; | ||
606 | float output_scale = output->wlr_output->scale; | ||
607 | float color[4]; | ||
608 | struct wlr_box box; | ||
609 | |||
610 | int tab_width = parent->width / parent->children->length; | ||
611 | int x = parent->x + tab_width * child_index; | ||
612 | // Make last tab use the remaining width of the parent | ||
613 | if (child_index == parent->children->length - 1) { | ||
614 | tab_width = parent->width - tab_width * child_index; | ||
615 | } | ||
616 | |||
617 | // Single pixel bar above title | ||
618 | memcpy(&color, colors->border, sizeof(float) * 4); | ||
619 | premultiply_alpha(color, con->alpha); | ||
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 | box.y = (parent->y + config->border_thickness * 2 + config->font_height - 1) | ||
629 | * output_scale; | ||
630 | render_rect(output->wlr_output, damage, &box, color); | ||
631 | |||
632 | // Single pixel bar on left | ||
633 | box.x = x; | ||
634 | box.y = parent->y + 1; | ||
635 | box.width = 1; | ||
636 | box.height = config->border_thickness * 2 + config->font_height - 2; | ||
637 | scale_box(&box, output_scale); | ||
638 | render_rect(output->wlr_output, damage, &box, color); | ||
639 | |||
640 | // Single pixel bar on right | ||
641 | box.x = (x + tab_width - 1) * output_scale; | ||
642 | render_rect(output->wlr_output, damage, &box, color); | ||
643 | |||
644 | // Title text | ||
645 | size_t title_width = 0; | ||
646 | if (title_texture) { | ||
647 | struct wlr_box texture_box; | ||
648 | wlr_texture_get_size(title_texture, | ||
649 | &texture_box.width, &texture_box.height); | ||
650 | texture_box.x = (x + 1 + config->border_thickness) * output_scale; | ||
651 | texture_box.y = (parent->y + config->border_thickness) * output_scale; | ||
652 | |||
653 | float matrix[9]; | ||
654 | wlr_matrix_project_box(matrix, &texture_box, | ||
655 | WL_OUTPUT_TRANSFORM_NORMAL, | ||
656 | 0.0, output->wlr_output->transform_matrix); | ||
657 | |||
658 | int available = (tab_width - config->border_thickness * 2 - 2) | ||
659 | * output_scale; | ||
660 | if (texture_box.width > available) { | ||
661 | texture_box.width = available; | ||
662 | } | ||
663 | render_texture(output->wlr_output, damage, title_texture, | ||
664 | &texture_box, matrix, 1.0); | ||
665 | title_width = texture_box.width; | ||
666 | } | ||
667 | |||
668 | // Title background - above the text | ||
669 | memcpy(&color, colors->background, sizeof(float) * 4); | ||
670 | premultiply_alpha(color, con->alpha); | ||
671 | box.x = x + 1; | ||
672 | box.y = parent->y + 1; | ||
673 | box.width = tab_width - 2; | ||
674 | box.height = config->border_thickness - 1; | ||
675 | scale_box(&box, output_scale); | ||
676 | render_rect(output->wlr_output, damage, &box, color); | ||
677 | |||
678 | // Title background - below the text | ||
679 | box.y = (parent->y + config->border_thickness + config->font_height) | ||
680 | * output_scale; | ||
681 | render_rect(output->wlr_output, damage, &box, color); | ||
682 | |||
683 | // Title background - left of text | ||
684 | box.x = x + 1; | ||
685 | box.y = parent->y + config->border_thickness; | ||
686 | box.width = config->border_thickness; | ||
687 | box.height = config->font_height; | ||
688 | scale_box(&box, output_scale); | ||
689 | render_rect(output->wlr_output, damage, &box, color); | ||
690 | |||
691 | // Title background - right of text | ||
692 | box.x = (x + 1 + config->border_thickness) * output_scale + title_width; | ||
693 | box.y = (parent->y + config->border_thickness) * output_scale; | ||
694 | box.width = (tab_width - config->border_thickness - 2) * output_scale | ||
695 | - title_width; | ||
696 | box.height = config->font_height * output_scale; | ||
697 | render_rect(output->wlr_output, damage, &box, color); | ||
698 | } | ||
699 | |||
700 | static void render_tab_content(struct sway_output *output, | ||
701 | pixman_region32_t *damage, struct sway_container *con, | ||
702 | struct border_colors *colors) { | ||
703 | struct sway_view *view = con->sway_view; | ||
704 | render_view(view, output, damage); | ||
705 | |||
706 | struct wlr_box box; | ||
707 | float output_scale = output->wlr_output->scale; | ||
708 | float color[4]; | ||
709 | |||
710 | if (view->border != B_NONE) { | ||
711 | if (view->border_left) { | ||
712 | memcpy(&color, colors->child_border, sizeof(float) * 4); | ||
713 | premultiply_alpha(color, con->alpha); | ||
714 | box.x = con->x; | ||
715 | box.y = con->y + config->border_thickness * 2 + config->font_height; | ||
716 | box.width = view->border_thickness; | ||
717 | box.height = view->height; | ||
718 | scale_box(&box, output_scale); | ||
719 | render_rect(output->wlr_output, damage, &box, color); | ||
720 | } | ||
721 | |||
722 | if (view->border_right) { | ||
723 | memcpy(&color, colors->child_border, sizeof(float) * 4); | ||
724 | premultiply_alpha(color, con->alpha); | ||
725 | box.x = view->x + view->width; | ||
726 | box.y = con->y + config->border_thickness * 2 + config->font_height; | ||
727 | box.width = view->border_thickness; | ||
728 | box.height = view->height; | ||
729 | scale_box(&box, output_scale); | ||
730 | render_rect(output->wlr_output, damage, &box, color); | ||
731 | } | ||
732 | |||
733 | if (view->border_bottom) { | ||
734 | memcpy(&color, colors->child_border, sizeof(float) * 4); | ||
735 | premultiply_alpha(color, con->alpha); | ||
736 | box.x = con->x; | ||
737 | box.y = view->y + view->height; | ||
738 | box.width = con->width; | ||
739 | box.height = view->border_thickness; | ||
740 | scale_box(&box, output_scale); | ||
741 | render_rect(output->wlr_output, damage, &box, color); | ||
742 | } | ||
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_active_child(seat, con); | ||
758 | struct border_colors *current_colors = NULL; | ||
759 | |||
760 | // Render tabs | ||
761 | for (int i = 0; i < con->children->length; ++i) { | ||
762 | struct sway_container *child = con->children->items[i]; | ||
763 | struct border_colors *colors; | ||
764 | struct wlr_texture *title_texture; | ||
765 | |||
766 | if (focus == child || parent_focused) { | ||
767 | colors = &config->border_colors.focused; | ||
768 | title_texture = child->title_focused; | ||
769 | } else if (child == current) { | ||
770 | colors = &config->border_colors.focused_inactive; | ||
771 | title_texture = child->title_focused_inactive; | ||
772 | } else { | ||
773 | colors = &config->border_colors.unfocused; | ||
774 | title_texture = child->title_unfocused; | ||
775 | } | ||
776 | |||
777 | render_tab(output, damage, con, i, colors, title_texture); | ||
778 | |||
779 | if (child == current) { | ||
780 | current_colors = colors; | ||
781 | } | ||
782 | } | ||
783 | |||
784 | // Render surface and left/right/bottom borders | ||
785 | if (current->type == C_VIEW) { | ||
786 | render_tab_content(output, damage, current, current_colors); | ||
787 | } else { | ||
788 | render_container(output, damage, current, | ||
789 | parent_focused || current == focus); | ||
790 | } | ||
608 | } | 791 | } |
609 | 792 | ||
610 | /** | 793 | /** |
@@ -628,7 +811,7 @@ static void render_container(struct sway_output *output, | |||
628 | render_container_stacked(output, damage, con); | 811 | render_container_stacked(output, damage, con); |
629 | break; | 812 | break; |
630 | case L_TABBED: | 813 | case L_TABBED: |
631 | render_container_tabbed(output, damage, con); | 814 | render_container_tabbed(output, damage, con, parent_focused); |
632 | break; | 815 | break; |
633 | case L_FLOATING: | 816 | case L_FLOATING: |
634 | // TODO | 817 | // TODO |
@@ -896,9 +1079,7 @@ static void output_damage_view(struct sway_output *output, | |||
896 | return; | 1079 | return; |
897 | } | 1080 | } |
898 | 1081 | ||
899 | struct sway_container *workspace = container_parent(view->swayc, | 1082 | if (!view_is_visible(view)) { |
900 | C_WORKSPACE); | ||
901 | if (workspace->sway_workspace->fullscreen && !view->is_fullscreen) { | ||
902 | return; | 1083 | return; |
903 | } | 1084 | } |
904 | 1085 | ||