aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/output.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-05-19 22:54:50 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-05-21 20:16:56 +1000
commitc08f9bf257c38c92a75988d89fba2d4de6bb2aea (patch)
tree76ea44c5548301ff4892c44838b783eeeb569c62 /sway/desktop/output.c
parentMerge pull request #2011 from RyanDwyer/fix-hide-edge-border-bottom (diff)
downloadsway-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.c192
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
602static 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
702static 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 */
605static void render_container_tabbed(struct sway_output *output, 749static 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