From eed8625d964b4759f1490e1bf653d0dc70e7458a Mon Sep 17 00:00:00 2001 From: Dudemanguy911 Date: Sun, 6 May 2018 04:47:17 +0000 Subject: [PATCH] refactor render container tabbed and border rendering functions --- sway/desktop/output.c | 218 ++++++++++++++++++++++++++++++------------ sway/input/cursor.c | 1 + 2 files changed, 159 insertions(+), 60 deletions(-) diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 8ab7079bb..249846d70 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -224,21 +224,151 @@ static void render_view(struct sway_view *view, struct sway_output *output) { } /** - * Render decorations for a view with "border normal". + * Select a color to use to render a border based on focus. */ -static void render_container_simple_border_normal(struct sway_output *output, +static struct border_colors *select_focus_color(char *name) { + struct border_colors *colors; + if (strcmp(name, "focused") == 0) { + return colors = &config->border_colors.focused; + } else if (strcmp(name, "inactive") == 0) { + return colors = &config->border_colors.focused_inactive; + } else if (strcmp(name, "unfocused") == 0) { + return colors =&config->border_colors.unfocused; + } else { + return NULL; + } +} + +/** + * Get all title textures from children of a parent. + */ +static struct wlr_texture **get_title_textures(struct sway_container *con) { + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = seat_get_focus(seat); + int num_tabs = con->children->length; + struct wlr_texture **title_texture = + malloc(num_tabs * sizeof(struct wlr_texture)); + + for (int i = 0; i < con->children->length; ++i) { + struct sway_container *child = con->children->items[i]; + + if (child->type == C_VIEW) { + if (child->sway_view->border != B_NONE) { + if (focus == child) { + title_texture[i] = child->title_focused; + } else if (seat_get_focus_inactive(seat, con) == child) { + title_texture[i] = child->title_focused_inactive; + } else { + title_texture[i] = child->title_unfocused; + } + } + } + } + return title_texture; +} + +/** + * Render decorations for the top border with "border normal". + */ +static void render_container_top_border_normal(struct sway_output *output, struct sway_container *con, struct border_colors *colors, struct wlr_texture *title_texture, int depth) { + struct wlr_renderer *renderer = wlr_backend_get_renderer(output->wlr_output->backend); struct wlr_box box; float color[4]; size_t num_tabs = 1; - + size_t tab_width = 1; + if (con->parent->layout == L_TABBED) { num_tabs = con->parent->children->length; + tab_width = (con->width / num_tabs); } + // Single pixel bar above title + memcpy(&color, colors->border, sizeof(float) * 4); + color[3] *= con->alpha; + box.x = con->x + depth * tab_width; + box.y = con->y; + box.width = con->width / num_tabs; + box.height = 1; + scale_box(&box, output->wlr_output->scale); + wlr_render_rect(renderer, &box, color, + output->wlr_output->transform_matrix); + + // Single pixel bar below title + box.x = con->x + depth * tab_width; + box.y = con->sway_view->y - 1; + box.width = con->width / num_tabs; + box.height = 1; + scale_box(&box, output->wlr_output->scale); + wlr_render_rect(renderer, &box, color, + output->wlr_output->transform_matrix); + + // Title background + memcpy(&color, colors->background, sizeof(float) * 4); + color[3] *= con->alpha; + box.x = con->x + depth * tab_width; + box.y = con->y + 1; + box.width = con->width / num_tabs + 2; + box.height = con->sway_view->y - con->y - 2; + scale_box(&box, output->wlr_output->scale); + wlr_render_rect(renderer, &box, color, + output->wlr_output->transform_matrix); + + // Title text + if (title_texture) { + wlr_renderer_scissor(renderer, &box); + wlr_render_texture(renderer, title_texture, + output->wlr_output->transform_matrix, box.x + 2, box.y, 1); + wlr_renderer_scissor(renderer, NULL); + } +} + +/** + * Render decorations for the top border for tabbed view with "border normal". + */ +static void render_container_top_tabbed_border_normal(struct sway_output *output, + struct sway_container *con, struct wlr_texture **title_texture, + int focus_number, bool active) { + + int index_tabs = con->parent->children->length - 1; + int index_left_of_focus = focus_number - 1; + struct border_colors *unfocused = select_focus_color("unfocused"); + struct border_colors *focus_color; + + if (active) { + focus_color = select_focus_color("focused"); + } else { + focus_color = select_focus_color("inactive"); + } + + if (index_left_of_focus >= 0) { + for (int i = 0; i <= index_left_of_focus; ++i) { + render_container_top_border_normal(output, con, unfocused, title_texture[i], i); + } + } + render_container_top_border_normal(output, con, focus_color, title_texture[focus_number], focus_number); + if (index_tabs > index_left_of_focus) { + for (int j = focus_number + 1; j <= index_tabs; ++j) { + render_container_top_border_normal(output, con, unfocused, title_texture[j], j); + } + } +} + +/** + * Render decorations for a horizontal or vertical view with "border normal". + */ +static void render_container_simple_border_normal(struct sway_output *output, + struct sway_container *con, struct border_colors *colors, + struct wlr_texture *title_texture, bool top) { + + struct wlr_renderer *renderer = + wlr_backend_get_renderer(output->wlr_output->backend); + struct wlr_box box; + float color[4]; + // Child border - left edge memcpy(&color, colors->child_border, sizeof(float) * 4); color[3] *= con->alpha; @@ -280,43 +410,8 @@ static void render_container_simple_border_normal(struct sway_output *output, wlr_render_rect(renderer, &box, color, output->wlr_output->transform_matrix); - // Single pixel bar above title - memcpy(&color, colors->border, sizeof(float) * 4); - color[3] *= con->alpha; - box.x = con->x + depth * (con->width / num_tabs); - box.y = con->y; - box.width = con->width / num_tabs; - box.height = 1; - scale_box(&box, output->wlr_output->scale); - wlr_render_rect(renderer, &box, color, - output->wlr_output->transform_matrix); - - // Single pixel bar below title - box.x = con->x + depth * (con->width / num_tabs); - box.y = con->sway_view->y - 1; - box.width = con->width / num_tabs; - box.height = 1; - scale_box(&box, output->wlr_output->scale); - wlr_render_rect(renderer, &box, color, - output->wlr_output->transform_matrix); - - // Title background - memcpy(&color, colors->background, sizeof(float) * 4); - color[3] *= con->alpha; - box.x = con->x + depth * (con->width / num_tabs); - box.y = con->y + 1; - box.width = con->width / num_tabs; - box.height = con->sway_view->y - con->y - 2; - scale_box(&box, output->wlr_output->scale); - wlr_render_rect(renderer, &box, color, - output->wlr_output->transform_matrix); - - // Title text - if (title_texture) { - wlr_renderer_scissor(renderer, &box); - wlr_render_texture(renderer, title_texture, - output->wlr_output->transform_matrix, box.x, box.y, 1); - wlr_renderer_scissor(renderer, NULL); + if (top) { + render_container_top_border_normal(output, con, colors, title_texture, 0); } } @@ -380,6 +475,20 @@ static void render_container_simple_border_pixel(struct sway_output *output, output->wlr_output->transform_matrix); } +/** + * Render decorations for a tabbed view with "border normal". + */ + +static void render_container_tabbed_border_normal(struct sway_output *output, + struct sway_container *con, struct wlr_texture **title_texture, + int depth, bool active) { + + struct border_colors *focused_color = select_focus_color("focused"); + render_container_simple_border_normal(output, con, focused_color, + NULL, false); + render_container_top_tabbed_border_normal(output, con, title_texture, + depth, active); +} static void render_container(struct sway_output *output, struct sway_container *con); @@ -402,19 +511,19 @@ static void render_container_simple(struct sway_output *output, struct border_colors *colors; struct wlr_texture *title_texture; if (focus == child) { - colors = &config->border_colors.focused; + colors = select_focus_color("focused"); title_texture = child->title_focused; } else if (seat_get_focus_inactive(seat, con) == child) { - colors = &config->border_colors.focused_inactive; + colors = select_focus_color("inactive"); title_texture = child->title_focused_inactive; } else { - colors = &config->border_colors.unfocused; + colors = select_focus_color("unfocused"); title_texture = child->title_unfocused; } if (child->sway_view->border == B_NORMAL) { render_container_simple_border_normal(output, child, - colors, title_texture, 0); + colors, title_texture, true); } else { render_container_simple_border_pixel(output, child, colors); } @@ -433,32 +542,21 @@ static void render_container_tabbed(struct sway_output *output, struct sway_container *con) { struct sway_seat *seat = input_manager_current_seat(input_manager); struct sway_container *focus = seat_get_focus(seat); + struct wlr_texture **title_texture = get_title_textures(con); for (int i = 0; i < con->children->length; ++i) { struct sway_container *child = con->children->items[i]; if (child->type == C_VIEW) { if (child->sway_view->border != B_NONE) { - struct border_colors *colors; - struct wlr_texture *title_texture; if (focus == child) { - colors = &config->border_colors.focused; - title_texture = child->title_focused; - - render_container_simple_border_normal(output, child, - colors, title_texture, i); + render_container_tabbed_border_normal(output, child, + title_texture, i, true); render_view(child->sway_view, output); } else if (seat_get_focus_inactive(seat, con) == child) { - colors = &config->border_colors.focused_inactive; - title_texture = child->title_focused_inactive; - render_container_simple_border_normal(output, child, - colors, title_texture, i); + render_container_tabbed_border_normal(output, child, + title_texture, i, false); render_view(child->sway_view, output); - } else { - colors = &config->border_colors.unfocused; - title_texture = child->title_unfocused; - render_container_simple_border_normal(output, child, - colors, title_texture, i); } } } else { diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 4a8609da0..116899eab 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -222,6 +222,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor, seat_set_focus(cursor->seat, cont); } } else { + //TODO: set focus on top border click for tabbed view if (cont && cont->parent->layout != L_TABBED) { seat_set_focus(cursor->seat, cont); }