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, } } +static void render_tab(struct sway_output *output, pixman_region32_t *damage, + struct sway_container *parent, int child_index, + struct border_colors *colors, struct wlr_texture *title_texture) { + struct sway_container *con = parent->children->items[child_index]; + float output_scale = output->wlr_output->scale; + float color[4]; + struct wlr_box box; + + int tab_width = parent->width / parent->children->length; + int x = parent->x + tab_width * child_index; + // Make last tab use the remaining width of the parent + if (child_index == parent->children->length - 1) { + tab_width = parent->width - tab_width * child_index; + } + + // Single pixel bar above title + memcpy(&color, colors->border, sizeof(float) * 4); + premultiply_alpha(color, con->alpha); + box.x = x; + box.y = parent->y; + box.width = tab_width; + box.height = 1; + scale_box(&box, output_scale); + render_rect(output->wlr_output, damage, &box, color); + + // Single pixel bar below title + box.y = (parent->y + config->border_thickness * 2 + config->font_height - 1) + * output_scale; + render_rect(output->wlr_output, damage, &box, color); + + // Single pixel bar on left + box.x = x; + box.y = parent->y + 1; + box.width = 1; + box.height = config->border_thickness * 2 + config->font_height - 2; + scale_box(&box, output_scale); + render_rect(output->wlr_output, damage, &box, color); + + // Single pixel bar on right + box.x = (x + tab_width - 1) * output_scale; + render_rect(output->wlr_output, damage, &box, color); + + // Title text + size_t title_width = 0; + if (title_texture) { + struct wlr_box texture_box; + wlr_texture_get_size(title_texture, + &texture_box.width, &texture_box.height); + texture_box.x = (x + 1 + config->border_thickness) * output_scale; + texture_box.y = (parent->y + config->border_thickness) * output_scale; + + float matrix[9]; + wlr_matrix_project_box(matrix, &texture_box, + WL_OUTPUT_TRANSFORM_NORMAL, + 0.0, output->wlr_output->transform_matrix); + + int available = (tab_width - config->border_thickness * 2 - 2) + * output_scale; + if (texture_box.width > available) { + texture_box.width = available; + } + render_texture(output->wlr_output, damage, title_texture, + &texture_box, matrix, 1.0); + title_width = texture_box.width; + } + + // Title background - above the text + memcpy(&color, colors->background, sizeof(float) * 4); + premultiply_alpha(color, con->alpha); + box.x = x + 1; + box.y = parent->y + 1; + box.width = tab_width - 2; + box.height = config->border_thickness - 1; + scale_box(&box, output_scale); + render_rect(output->wlr_output, damage, &box, color); + + // Title background - below the text + box.y = (parent->y + config->border_thickness + config->font_height) + * output_scale; + render_rect(output->wlr_output, damage, &box, color); + + // Title background - left of text + box.x = x + 1; + box.y = parent->y + config->border_thickness; + box.width = config->border_thickness; + box.height = config->font_height; + scale_box(&box, output_scale); + render_rect(output->wlr_output, damage, &box, color); + + // Title background - right of text + box.x = (x + 1 + config->border_thickness) * output_scale + title_width; + box.y = (parent->y + config->border_thickness) * output_scale; + box.width = (tab_width - config->border_thickness - 2) * output_scale + - title_width; + box.height = config->font_height * output_scale; + render_rect(output->wlr_output, damage, &box, color); +} + +static void render_tab_content(struct sway_output *output, + pixman_region32_t *damage, struct sway_container *con, + struct border_colors *colors) { + struct sway_view *view = con->sway_view; + render_view(view, output, damage); + + struct wlr_box box; + float output_scale = output->wlr_output->scale; + float color[4]; + + if (view->border != B_NONE) { + if (view->border_left) { + memcpy(&color, colors->child_border, sizeof(float) * 4); + premultiply_alpha(color, con->alpha); + box.x = con->x; + box.y = con->y + config->border_thickness * 2 + config->font_height; + box.width = view->border_thickness; + box.height = view->height; + scale_box(&box, output_scale); + render_rect(output->wlr_output, damage, &box, color); + } + + if (view->border_right) { + memcpy(&color, colors->child_border, sizeof(float) * 4); + premultiply_alpha(color, con->alpha); + box.x = view->x + view->width; + box.y = con->y + config->border_thickness * 2 + config->font_height; + box.width = view->border_thickness; + box.height = view->height; + scale_box(&box, output_scale); + render_rect(output->wlr_output, damage, &box, color); + } + + if (view->border_bottom) { + memcpy(&color, colors->child_border, sizeof(float) * 4); + premultiply_alpha(color, con->alpha); + box.x = con->x; + box.y = view->y + view->height; + box.width = con->width; + box.height = view->border_thickness; + scale_box(&box, output_scale); + render_rect(output->wlr_output, damage, &box, color); + } + } +} + /** * Render a container's children using the L_TABBED layout. */ static void render_container_tabbed(struct sway_output *output, - pixman_region32_t *damage, struct sway_container *con) { - // TODO + pixman_region32_t *damage, struct sway_container *con, + bool parent_focused) { + if (!con->children->length) { + return; + } + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = seat_get_focus(seat); + struct sway_container *current = seat_get_active_child(seat, con); + struct border_colors *current_colors = NULL; + + // Render tabs + for (int i = 0; i < con->children->length; ++i) { + struct sway_container *child = con->children->items[i]; + struct border_colors *colors; + struct wlr_texture *title_texture; + + if (focus == child || parent_focused) { + colors = &config->border_colors.focused; + title_texture = child->title_focused; + } else if (child == current) { + colors = &config->border_colors.focused_inactive; + title_texture = child->title_focused_inactive; + } else { + colors = &config->border_colors.unfocused; + title_texture = child->title_unfocused; + } + + render_tab(output, damage, con, i, colors, title_texture); + + if (child == current) { + current_colors = colors; + } + } + + // Render surface and left/right/bottom borders + if (current->type == C_VIEW) { + render_tab_content(output, damage, current, current_colors); + } else { + render_container(output, damage, current, + parent_focused || current == focus); + } } /** @@ -628,7 +811,7 @@ static void render_container(struct sway_output *output, render_container_stacked(output, damage, con); break; case L_TABBED: - render_container_tabbed(output, damage, con); + render_container_tabbed(output, damage, con, parent_focused); break; case L_FLOATING: // TODO @@ -896,9 +1079,7 @@ static void output_damage_view(struct sway_output *output, return; } - struct sway_container *workspace = container_parent(view->swayc, - C_WORKSPACE); - if (workspace->sway_workspace->fullscreen && !view->is_fullscreen) { + if (!view_is_visible(view)) { return; } |