From c7b3f9854fa511f879bc3b16d5728c10c8d10f1f Mon Sep 17 00:00:00 2001 From: dudemanguy Date: Thu, 3 May 2018 15:53:05 -0500 Subject: [PATCH 01/14] add tabbed windows --- sway/commands/default_orientation.c | 4 +- sway/commands/layout.c | 5 ++ sway/desktop/output.c | 73 +++++++++++++++++++++++++---- sway/tree/arrange.c | 17 +++++++ sway/tree/layout.c | 1 + 5 files changed, 89 insertions(+), 11 deletions(-) diff --git a/sway/commands/default_orientation.c b/sway/commands/default_orientation.c index a5347ce21..848b1a44e 100644 --- a/sway/commands/default_orientation.c +++ b/sway/commands/default_orientation.c @@ -11,11 +11,13 @@ struct cmd_results *cmd_default_orientation(int argc, char **argv) { config->default_orientation = L_HORIZ; } else if (strcasecmp(argv[0], "vertical") == 0) { config->default_orientation = L_VERT; + } else if (strcasecmp(argv[0], "tabbed") == 0) { + config->default_orientation = L_TABBED; } else if (strcasecmp(argv[0], "auto") == 0) { // Do nothing } else { return cmd_results_new(CMD_INVALID, "default_orientation", - "Expected 'orientation '"); + "Expected 'orientation '"); } return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/commands/layout.c b/sway/commands/layout.c index bb36bb18b..559be7c5b 100644 --- a/sway/commands/layout.c +++ b/sway/commands/layout.c @@ -25,6 +25,7 @@ struct cmd_results *cmd_layout(int argc, char **argv) { // TODO: stacks and tabs + if (strcasecmp(argv[0], "default") == 0) { parent->layout = parent->prev_layout; if (parent->layout == L_NONE) { @@ -35,6 +36,10 @@ struct cmd_results *cmd_layout(int argc, char **argv) { parent->prev_layout = parent->layout; } + if (strcasecmp(argv[0], "tabbed") == 0) { + parent->layout = L_TABBED; + } + if (strcasecmp(argv[0], "splith") == 0) { parent->layout = L_HORIZ; } else if (strcasecmp(argv[0], "splitv") == 0) { diff --git a/sway/desktop/output.c b/sway/desktop/output.c index d17a6e143..4fd8db8c9 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -228,11 +228,19 @@ static void render_view(struct sway_view *view, struct sway_output *output) { */ static void render_container_simple_border_normal(struct sway_output *output, struct sway_container *con, struct border_colors *colors, - struct wlr_texture *title_texture) { + struct wlr_texture *title_texture, int iteration) { struct wlr_renderer *renderer = wlr_backend_get_renderer(output->wlr_output->backend); struct wlr_box box; float color[4]; + size_t num_tabs; + + if (con->parent->layout == L_TABBED) { + num_tabs = con->parent->children->length; + } + else { + num_tabs = 1; + } // Child border - left edge memcpy(&color, colors->child_border, sizeof(float) * 4); @@ -278,18 +286,18 @@ static void render_container_simple_border_normal(struct sway_output *output, // Single pixel bar above title memcpy(&color, colors->border, sizeof(float) * 4); color[3] *= con->alpha; - box.x = con->x; + box.x = con->x + iteration * (con->width / num_tabs); box.y = con->y; - box.width = con->width; + 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 + con->sway_view->border_thickness; + box.x = con->x + iteration * (con->width / num_tabs); box.y = con->sway_view->y - 1; - box.width = con->width - con->sway_view->border_thickness * 2; + box.width = con->width / num_tabs; box.height = 1; scale_box(&box, output->wlr_output->scale); wlr_render_rect(renderer, &box, color, @@ -298,9 +306,9 @@ static void render_container_simple_border_normal(struct sway_output *output, // Title background memcpy(&color, colors->background, sizeof(float) * 4); color[3] *= con->alpha; - box.x = con->x + con->sway_view->border_thickness; + box.x = con->x + iteration * (con->width / num_tabs); box.y = con->y + 1; - box.width = con->width - con->sway_view->border_thickness * 2; + 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, @@ -325,7 +333,6 @@ static void render_container_simple_border_pixel(struct sway_output *output, struct wlr_box box; float color[4]; - // Child border - left edge memcpy(&color, colors->child_border, sizeof(float) * 4); color[3] *= con->alpha; box.x = con->x; @@ -410,7 +417,7 @@ static void render_container_simple(struct sway_output *output, if (child->sway_view->border == B_NORMAL) { render_container_simple_border_normal(output, child, - colors, title_texture); + colors, title_texture, 0); } else { render_container_simple_border_pixel(output, child, colors); } @@ -427,7 +434,53 @@ static void render_container_simple(struct sway_output *output, */ static void render_container_tabbed(struct sway_output *output, struct sway_container *con) { - // TODO + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = seat_get_focus(seat); + + 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; + + if (child->sway_view->border == B_NORMAL) { + render_container_simple_border_normal(output, child, + colors, title_texture, i); + } else { + render_container_simple_border_pixel(output, child, colors); + } + 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; + if (child->sway_view->border == B_NORMAL) { + render_container_simple_border_normal(output, child, + colors, title_texture, i); + } else { + render_container_simple_border_pixel(output, child, colors); + } + render_view(child->sway_view, output); + } else { + colors = &config->border_colors.unfocused; + title_texture = child->title_unfocused; + if (child->sway_view->border == B_NORMAL) { + render_container_simple_border_normal(output, child, + colors, title_texture, i); + } else { + render_container_simple_border_pixel(output, child, colors); + } + } + } + } + else { + render_container(output, child); + } + } } /** diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c index 83bb20fbe..3fe68ec5b 100644 --- a/sway/tree/arrange.c +++ b/sway/tree/arrange.c @@ -159,6 +159,20 @@ static void apply_vert_layout(struct sway_container *parent) { child->height = parent->y + parent->height - child->y; } +static void apply_tabbed_layout(struct sway_container *parent) { + size_t num_children = parent->children->length; + if (!num_children) { + return; + } + for (size_t i=0; i < num_children; ++i) { + struct sway_container *child = parent->children->items[i]; + child->x = parent->x; + child->y = parent->y; + child->width = parent->width; + child->height = parent->height; + } +} + void arrange_children_of(struct sway_container *parent) { if (config->reloading) { return; @@ -189,6 +203,9 @@ void arrange_children_of(struct sway_container *parent) { case L_VERT: apply_vert_layout(parent); break; + case L_TABBED: + apply_tabbed_layout(parent); + break; default: wlr_log(L_DEBUG, "TODO: arrange layout type %d", parent->layout); apply_horiz_layout(parent); diff --git a/sway/tree/layout.c b/sway/tree/layout.c index ec1c6fe5b..0a795b907 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -234,6 +234,7 @@ static bool is_parallel(enum sway_container_layout layout, enum movement_direction dir) { switch (layout) { case L_TABBED: + return dir == MOVE_LEFT || dir == MOVE_RIGHT; case L_STACKED: case L_HORIZ: return dir == MOVE_LEFT || dir == MOVE_RIGHT; From 505e34b6efc5767aa9383aeed7c9207696dfd125 Mon Sep 17 00:00:00 2001 From: Dudemanguy911 Date: Sat, 5 May 2018 17:15:46 +0000 Subject: [PATCH 02/14] fix merge conflict after rebasing for wlr_renderer_scissor --- sway/commands/default_orientation.c | 4 +--- sway/commands/layout.c | 9 +++------ sway/desktop/output.c | 16 ++++++---------- sway/tree/arrange.c | 2 +- 4 files changed, 11 insertions(+), 20 deletions(-) diff --git a/sway/commands/default_orientation.c b/sway/commands/default_orientation.c index 848b1a44e..a5347ce21 100644 --- a/sway/commands/default_orientation.c +++ b/sway/commands/default_orientation.c @@ -11,13 +11,11 @@ struct cmd_results *cmd_default_orientation(int argc, char **argv) { config->default_orientation = L_HORIZ; } else if (strcasecmp(argv[0], "vertical") == 0) { config->default_orientation = L_VERT; - } else if (strcasecmp(argv[0], "tabbed") == 0) { - config->default_orientation = L_TABBED; } else if (strcasecmp(argv[0], "auto") == 0) { // Do nothing } else { return cmd_results_new(CMD_INVALID, "default_orientation", - "Expected 'orientation '"); + "Expected 'orientation '"); } return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/commands/layout.c b/sway/commands/layout.c index 559be7c5b..fa59eac47 100644 --- a/sway/commands/layout.c +++ b/sway/commands/layout.c @@ -23,8 +23,7 @@ struct cmd_results *cmd_layout(int argc, char **argv) { parent = parent->parent; } - // TODO: stacks and tabs - + // TODO: stacks if (strcasecmp(argv[0], "default") == 0) { parent->layout = parent->prev_layout; @@ -36,14 +35,12 @@ struct cmd_results *cmd_layout(int argc, char **argv) { parent->prev_layout = parent->layout; } - if (strcasecmp(argv[0], "tabbed") == 0) { - parent->layout = L_TABBED; - } - if (strcasecmp(argv[0], "splith") == 0) { parent->layout = L_HORIZ; } else if (strcasecmp(argv[0], "splitv") == 0) { parent->layout = L_VERT; + } else if (strcasecmp(argv[0], "tabbed") == 0) { + parent->layout = L_TABBED; } else if (strcasecmp(argv[0], "toggle") == 0 && argc == 2 && strcasecmp(argv[1], "split") == 0) { if (parent->layout == L_HORIZ) { parent->layout = L_VERT; diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 4fd8db8c9..0fd4434f1 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -228,19 +228,16 @@ static void render_view(struct sway_view *view, struct sway_output *output) { */ static void render_container_simple_border_normal(struct sway_output *output, struct sway_container *con, struct border_colors *colors, - struct wlr_texture *title_texture, int iteration) { + 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; + size_t num_tabs = 1; if (con->parent->layout == L_TABBED) { num_tabs = con->parent->children->length; } - else { - num_tabs = 1; - } // Child border - left edge memcpy(&color, colors->child_border, sizeof(float) * 4); @@ -286,7 +283,7 @@ static void render_container_simple_border_normal(struct sway_output *output, // Single pixel bar above title memcpy(&color, colors->border, sizeof(float) * 4); color[3] *= con->alpha; - box.x = con->x + iteration * (con->width / num_tabs); + box.x = con->x + depth * (con->width / num_tabs); box.y = con->y; box.width = con->width / num_tabs; box.height = 1; @@ -295,7 +292,7 @@ static void render_container_simple_border_normal(struct sway_output *output, output->wlr_output->transform_matrix); // Single pixel bar below title - box.x = con->x + iteration * (con->width / num_tabs); + 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; @@ -306,7 +303,7 @@ static void render_container_simple_border_normal(struct sway_output *output, // Title background memcpy(&color, colors->background, sizeof(float) * 4); color[3] *= con->alpha; - box.x = con->x + iteration * (con->width / num_tabs); + 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; @@ -476,8 +473,7 @@ static void render_container_tabbed(struct sway_output *output, } } } - } - else { + } else { render_container(output, child); } } diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c index 3fe68ec5b..60d0dfb95 100644 --- a/sway/tree/arrange.c +++ b/sway/tree/arrange.c @@ -164,7 +164,7 @@ static void apply_tabbed_layout(struct sway_container *parent) { if (!num_children) { return; } - for (size_t i=0; i < num_children; ++i) { + for (size_t i = 0; i < num_children; ++i) { struct sway_container *child = parent->children->items[i]; child->x = parent->x; child->y = parent->y; From 63684cb2b085cfa7e751287cee49c7d0198a8d1f Mon Sep 17 00:00:00 2001 From: Dudemanguy911 Date: Sat, 5 May 2018 17:30:50 +0000 Subject: [PATCH 03/14] disable changing focus on click for tabbed layout --- sway/input/cursor.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sway/input/cursor.c b/sway/input/cursor.c index c0c6e827f..4a8609da0 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -222,7 +222,9 @@ void dispatch_cursor_button(struct sway_cursor *cursor, seat_set_focus(cursor->seat, cont); } } else { - seat_set_focus(cursor->seat, cont); + if (cont && cont->parent->layout != L_TABBED) { + seat_set_focus(cursor->seat, cont); + } } wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, From 7d7afbede6b6732c59a3c47f795227ab2199ad0c Mon Sep 17 00:00:00 2001 From: Dudemanguy911 Date: Fri, 4 May 2018 00:09:03 +0000 Subject: [PATCH 04/14] remove pixel borders for tabbed layout --- sway/desktop/output.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 0fd4434f1..8ab7079bb 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -445,32 +445,20 @@ static void render_container_tabbed(struct sway_output *output, colors = &config->border_colors.focused; title_texture = child->title_focused; - if (child->sway_view->border == B_NORMAL) { - render_container_simple_border_normal(output, child, - colors, title_texture, i); - } else { - render_container_simple_border_pixel(output, child, colors); - } + render_container_simple_border_normal(output, child, + colors, title_texture, i); 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; - if (child->sway_view->border == B_NORMAL) { - render_container_simple_border_normal(output, child, - colors, title_texture, i); - } else { - render_container_simple_border_pixel(output, child, colors); - } + render_container_simple_border_normal(output, child, + colors, title_texture, i); render_view(child->sway_view, output); } else { colors = &config->border_colors.unfocused; title_texture = child->title_unfocused; - if (child->sway_view->border == B_NORMAL) { - render_container_simple_border_normal(output, child, - colors, title_texture, i); - } else { - render_container_simple_border_pixel(output, child, colors); - } + render_container_simple_border_normal(output, child, + colors, title_texture, i); } } } else { From eed8625d964b4759f1490e1bf653d0dc70e7458a Mon Sep 17 00:00:00 2001 From: Dudemanguy911 Date: Sun, 6 May 2018 04:47:17 +0000 Subject: [PATCH 05/14] 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); } From 10f0f4418fc80698bcc15426c14ac46fbf1d0431 Mon Sep 17 00:00:00 2001 From: Dudemanguy911 Date: Mon, 7 May 2018 12:10:15 -0500 Subject: [PATCH 06/14] remove select_focus_color --- sway/desktop/output.c | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 249846d70..be09db983 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -223,22 +223,6 @@ static void render_view(struct sway_view *view, struct sway_output *output) { view, &data.root_geo, render_surface_iterator, &data); } -/** - * Select a color to use to render a border based on focus. - */ -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. */ @@ -335,13 +319,13 @@ static void render_container_top_tabbed_border_normal(struct sway_output *output 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 *unfocused = &config->border_colors.unfocused; struct border_colors *focus_color; if (active) { - focus_color = select_focus_color("focused"); + focus_color = &config->border_colors.focused; } else { - focus_color = select_focus_color("inactive"); + focus_color = &config->border_colors.focused_inactive; } if (index_left_of_focus >= 0) { @@ -483,7 +467,7 @@ 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"); + struct border_colors *focused_color = &config->border_colors.focused; render_container_simple_border_normal(output, con, focused_color, NULL, false); render_container_top_tabbed_border_normal(output, con, title_texture, @@ -511,13 +495,13 @@ static void render_container_simple(struct sway_output *output, struct border_colors *colors; struct wlr_texture *title_texture; if (focus == child) { - colors = select_focus_color("focused"); + colors = &config->border_colors.focused; title_texture = child->title_focused; } else if (seat_get_focus_inactive(seat, con) == child) { - colors = select_focus_color("inactive"); + colors = &config->border_colors.focused_inactive; title_texture = child->title_focused_inactive; } else { - colors = select_focus_color("unfocused"); + colors = &config->border_colors.unfocused; title_texture = child->title_unfocused; } From da0c25bc9dcb8445c26ce77378c9246eb418bf29 Mon Sep 17 00:00:00 2001 From: Dudemanguy911 Date: Tue, 8 May 2018 09:09:18 -0500 Subject: [PATCH 07/14] simplify border renderering and fix border thickness --- sway/desktop/output.c | 322 ++++++++++++++++++++++++------------------ 1 file changed, 182 insertions(+), 140 deletions(-) diff --git a/sway/desktop/output.c b/sway/desktop/output.c index be09db983..9ee9662d9 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -224,130 +224,11 @@ static void render_view(struct sway_view *view, struct sway_output *output) { } /** - * 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 = &config->border_colors.unfocused; - struct border_colors *focus_color; - - if (active) { - focus_color = &config->border_colors.focused; - } else { - focus_color = &config->border_colors.focused_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". + * Render decorations for a 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_texture *title_texture) { struct wlr_renderer *renderer = wlr_backend_get_renderer(output->wlr_output->backend); struct wlr_box box; @@ -394,8 +275,43 @@ static void render_container_simple_border_normal(struct sway_output *output, wlr_render_rect(renderer, &box, color, output->wlr_output->transform_matrix); - if (top) { - render_container_top_border_normal(output, con, colors, title_texture, 0); + // Single pixel bar above title + memcpy(&color, colors->border, sizeof(float) * 4); + color[3] *= con->alpha; + box.x = con->x; + box.y = con->y; + box.width = con->width; + 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 + con->sway_view->border_thickness; + box.y = con->sway_view->y - 1; + box.width = con->width - con->sway_view->border_thickness * 2; + 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 + con->sway_view->border_thickness; + box.y = con->y + 1; + box.width = con->width - con->sway_view->border_thickness * 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, box.y, 1); + wlr_renderer_scissor(renderer, NULL); } } @@ -409,6 +325,7 @@ static void render_container_simple_border_pixel(struct sway_output *output, struct wlr_box box; float color[4]; + // Child border - left edge memcpy(&color, colors->child_border, sizeof(float) * 4); color[3] *= con->alpha; box.x = con->x; @@ -460,19 +377,129 @@ static void render_container_simple_border_pixel(struct sway_output *output, } /** - * Render decorations for a tabbed view with "border normal". + * Render decorations for the left, right, and bottom edge of a view with "border normal". */ +static void render_container_border_outline_normal(struct sway_output *output, + struct sway_container *con, struct border_colors *colors) { + struct wlr_renderer *renderer = + wlr_backend_get_renderer(output->wlr_output->backend); + struct wlr_box box; + float color[4]; -static void render_container_tabbed_border_normal(struct sway_output *output, - struct sway_container *con, struct wlr_texture **title_texture, - int depth, bool active) { + // Child border - left edge + memcpy(&color, colors->child_border, sizeof(float) * 4); + color[3] *= con->alpha; + box.x = con->x; + box.y = con->y + (con->sway_view->y - con->y); + box.width = con->sway_view->border_thickness; + box.height = con->height; + scale_box(&box, output->wlr_output->scale); + wlr_render_rect(renderer, &box, color, + output->wlr_output->transform_matrix); - struct border_colors *focused_color = &config->border_colors.focused; - render_container_simple_border_normal(output, con, focused_color, - NULL, false); - render_container_top_tabbed_border_normal(output, con, title_texture, - depth, active); + // Child border - right edge + if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) { + memcpy(&color, colors->indicator, sizeof(float) * 4); + } else { + memcpy(&color, colors->child_border, sizeof(float) * 4); + } + color[3] *= con->alpha; + box.x = con->x + con->width - con->sway_view->border_thickness; + box.y = con->y + (con->sway_view->y - con->y); + box.width = con->sway_view->border_thickness; + box.height = con->height; + scale_box(&box, output->wlr_output->scale); + wlr_render_rect(renderer, &box, color, + output->wlr_output->transform_matrix); + + // Child border - bottom edge + if (con->parent->children->length == 1 && con->parent->layout == L_VERT) { + memcpy(&color, colors->indicator, sizeof(float) * 4); + } else { + memcpy(&color, colors->child_border, sizeof(float) * 4); + } + color[3] *= con->alpha; + box.x = con->x; + box.y = con->y + con->height - con->sway_view->border_thickness; + box.width = con->width; + box.height = con->sway_view->border_thickness; + scale_box(&box, output->wlr_output->scale); + wlr_render_rect(renderer, &box, color, + output->wlr_output->transform_matrix); } + +/** + * 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 border_colors *colors, + struct wlr_texture *title_texture, size_t depth) { + + struct wlr_renderer *renderer = + wlr_backend_get_renderer(output->wlr_output->backend); + struct wlr_box box; + float color[4]; + size_t num_tabs = con->parent->children->length; + float 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); + + // Single pixel wide vertical line tab separator on the left + box.x = con->x + depth * tab_width; + box.y = con->y + 1; + box.width = con->sway_view->border_thickness; + 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); + + // Single pixel wide verticl line tab separator on the right + box.x = con->x + (depth + 1) * tab_width - con->sway_view->border_thickness; + box.y = con->y + 1; + box.width = con->sway_view->border_thickness; + 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 background + memcpy(&color, colors->background, sizeof(float) * 4); + color[3] *= con->alpha; + box.x = con->x + con->sway_view->border_thickness + depth * tab_width; + box.y = con->y + 1; + box.width = con->width / num_tabs - con->sway_view->border_thickness * 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, box.y, 1); + wlr_renderer_scissor(renderer, NULL); + } +} + static void render_container(struct sway_output *output, struct sway_container *con); @@ -507,7 +534,7 @@ static void render_container_simple(struct sway_output *output, if (child->sway_view->border == B_NORMAL) { render_container_simple_border_normal(output, child, - colors, title_texture, true); + colors, title_texture); } else { render_container_simple_border_pixel(output, child, colors); } @@ -526,27 +553,42 @@ 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); + struct sway_container *active_child = NULL; + struct border_colors *focused_colors = &config->border_colors.focused; for (int i = 0; i < con->children->length; ++i) { struct sway_container *child = con->children->items[i]; if (child->type == C_VIEW) { + struct border_colors *colors; + struct wlr_texture *title_texture; if (child->sway_view->border != B_NONE) { if (focus == child) { - render_container_tabbed_border_normal(output, child, - title_texture, i, true); - render_view(child->sway_view, output); + colors = &config->border_colors.focused; + title_texture = child->title_focused; + active_child = child; } else if (seat_get_focus_inactive(seat, con) == child) { - render_container_tabbed_border_normal(output, child, - title_texture, i, false); - render_view(child->sway_view, output); + colors= &config->border_colors.focused_inactive; + title_texture = child->title_focused_inactive; + active_child = child; + } else { + colors = &config->border_colors.unfocused; + title_texture = child->title_unfocused; } + + render_container_top_tabbed_border_normal(output, child, colors, + title_texture, i); } } else { render_container(output, child); } } + if (active_child) { + render_container_border_outline_normal(output, active_child, focused_colors); + render_view(active_child->sway_view, output); + } else { + wlr_log(L_INFO, "tabbed layout has no active child"); + } } /** From d39c594f30ad52871d2c4c564033d189a6f548ed Mon Sep 17 00:00:00 2001 From: Dudemanguy911 Date: Tue, 8 May 2018 10:30:00 -0500 Subject: [PATCH 08/14] fix incorrect comments --- sway/desktop/output.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 9ee9662d9..f1f239a84 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -462,7 +462,7 @@ static void render_container_top_tabbed_border_normal(struct sway_output *output wlr_render_rect(renderer, &box, color, output->wlr_output->transform_matrix); - // Single pixel wide vertical line tab separator on the left + // Tab separator on the left box.x = con->x + depth * tab_width; box.y = con->y + 1; box.width = con->sway_view->border_thickness; @@ -471,7 +471,7 @@ static void render_container_top_tabbed_border_normal(struct sway_output *output wlr_render_rect(renderer, &box, color, output->wlr_output->transform_matrix); - // Single pixel wide verticl line tab separator on the right + // Tab separator on the right box.x = con->x + (depth + 1) * tab_width - con->sway_view->border_thickness; box.y = con->y + 1; box.width = con->sway_view->border_thickness; From d97d662984ca5f001317e6ac5fd15f6eecc5944f Mon Sep 17 00:00:00 2001 From: Dudemanguy911 Date: Tue, 8 May 2018 12:41:26 -0500 Subject: [PATCH 09/14] fix case where drawing border gets off by 1 pixel --- sway/desktop/output.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sway/desktop/output.c b/sway/desktop/output.c index f1f239a84..92bccd340 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -439,7 +439,7 @@ static void render_container_top_tabbed_border_normal(struct sway_output *output wlr_backend_get_renderer(output->wlr_output->backend); struct wlr_box box; float color[4]; - size_t num_tabs = con->parent->children->length; + float num_tabs = con->parent->children->length; float tab_width = con->width / num_tabs; // Single pixel bar above title @@ -447,7 +447,7 @@ static void render_container_top_tabbed_border_normal(struct sway_output *output color[3] *= con->alpha; box.x = con->x + depth * tab_width; box.y = con->y; - box.width = con->width / num_tabs; + box.width = con->width / num_tabs + 1; box.height = 1; scale_box(&box, output->wlr_output->scale); wlr_render_rect(renderer, &box, color, @@ -456,7 +456,7 @@ static void render_container_top_tabbed_border_normal(struct sway_output *output // 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.width = con->width / num_tabs + 1; box.height = 1; scale_box(&box, output->wlr_output->scale); wlr_render_rect(renderer, &box, color, @@ -485,7 +485,7 @@ static void render_container_top_tabbed_border_normal(struct sway_output *output color[3] *= con->alpha; box.x = con->x + con->sway_view->border_thickness + depth * tab_width; box.y = con->y + 1; - box.width = con->width / num_tabs - con->sway_view->border_thickness * 2; + box.width = con->width / num_tabs - con->sway_view->border_thickness * 2 + 1; box.height = con->sway_view->y - con->y - 2; scale_box(&box, output->wlr_output->scale); wlr_render_rect(renderer, &box, color, From 986358d5a2b3090c99a65fbb4fc720184fe025cd Mon Sep 17 00:00:00 2001 From: Dudemanguy911 Date: Wed, 9 May 2018 00:18:53 +0000 Subject: [PATCH 10/14] use floor and ceiling while rendering borders --- sway/desktop/output.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 92bccd340..9a1c64696 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -439,42 +439,42 @@ static void render_container_top_tabbed_border_normal(struct sway_output *output wlr_backend_get_renderer(output->wlr_output->backend); struct wlr_box box; float color[4]; - float num_tabs = con->parent->children->length; - float tab_width = con->width / num_tabs; + double num_tabs = con->parent->children->length; + double 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.x = floor(con->x + depth * tab_width); box.y = con->y; - box.width = con->width / num_tabs + 1; + box.width = ceil(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.x = floor(con->x + depth*tab_width); box.y = con->sway_view->y - 1; - box.width = con->width / num_tabs + 1; + box.width = ceil(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); // Tab separator on the left - box.x = con->x + depth * tab_width; + box.x = floor(con->x + depth * tab_width); box.y = con->y + 1; - box.width = con->sway_view->border_thickness; + box.width = ceil(con->sway_view->border_thickness); 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); // Tab separator on the right - box.x = con->x + (depth + 1) * tab_width - con->sway_view->border_thickness; + box.x = floor(con->x + (depth + 1) * tab_width - con->sway_view->border_thickness); box.y = con->y + 1; - box.width = con->sway_view->border_thickness; + box.width = ceil(con->sway_view->border_thickness); box.height = con->sway_view->y - con->y - 2; scale_box(&box, output->wlr_output->scale); wlr_render_rect(renderer, &box, color, @@ -483,9 +483,9 @@ static void render_container_top_tabbed_border_normal(struct sway_output *output // Title background memcpy(&color, colors->background, sizeof(float) * 4); color[3] *= con->alpha; - box.x = con->x + con->sway_view->border_thickness + depth * tab_width; + box.x = floor(con->x + con->sway_view->border_thickness + depth * tab_width); box.y = con->y + 1; - box.width = con->width / num_tabs - con->sway_view->border_thickness * 2 + 1; + box.width = ceil(con->width / num_tabs - con->sway_view->border_thickness * 2); box.height = con->sway_view->y - con->y - 2; scale_box(&box, output->wlr_output->scale); wlr_render_rect(renderer, &box, color, From 56102da12416a97947de2d90518442090a0c9fb4 Mon Sep 17 00:00:00 2001 From: Dudemanguy911 Date: Thu, 10 May 2018 14:29:45 -0500 Subject: [PATCH 11/14] refactor container_at to return the correct container in tabbed layout --- sway/input/cursor.c | 5 +--- sway/tree/container.c | 53 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 116899eab..c0c6e827f 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -222,10 +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); - } + seat_set_focus(cursor->seat, cont); } wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, diff --git a/sway/tree/container.c b/sway/tree/container.c index 38db29c2f..ac9e690fc 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -421,6 +421,8 @@ struct sway_container *container_at(struct sway_container *parent, list_add(queue, parent); + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = seat_get_focus_inactive(seat, parent); struct sway_container *swayc = NULL; while (queue->length) { swayc = queue->items[0]; @@ -460,21 +462,54 @@ struct sway_container *container_at(struct sway_container *parent, view_sx, view_sy, &_sx, &_sy); break; } - if (_surface) { - *sx = _sx; - *sy = _sy; - *surface = _surface; - return swayc; - } // Check the view's decorations struct wlr_box swayc_box = { .x = swayc->x, .y = swayc->y, .width = swayc->width, - .height = swayc->height, + .height = swayc->height }; - if (wlr_box_contains_point(&swayc_box, ox, oy)) { - return swayc; + // Check which tab the mouse is on + int depth; + int num_tabs = swayc->parent->children->length; + double tab_width = swayc->width / num_tabs; + struct wlr_box tab_box = { + .y = swayc->y, + .width = swayc->width / num_tabs, + .height = swayc->sway_view->y - swayc->y + }; + switch (swayc->parent->layout) { + case L_NONE: + case L_HORIZ: + case L_VERT: + if (_surface) { + *sx = _sx; + *sy = _sy; + *surface = _surface; + return swayc; + } + if (wlr_box_contains_point(&swayc_box, ox, oy)) { + return swayc; + } + break; + case L_TABBED: + for (depth = 0; depth < num_tabs; ++depth) { + tab_box.x = swayc->x + depth * tab_width; + *sx = _sx; + *sy = _sy; + *surface = _surface; + if (wlr_box_contains_point(&tab_box, ox, oy)) { + return swayc->parent->children->items[depth]; + } + } + if (focus == swayc) { + return swayc; + } + break; + case L_STACKED: + break; + case L_FLOATING: + break; } } else { list_cat(queue, swayc->children); From 77f41efd4e0d91e3a3e9c68c4ebbe9f47308808e Mon Sep 17 00:00:00 2001 From: Dudemanguy911 Date: Fri, 11 May 2018 00:11:58 +0000 Subject: [PATCH 12/14] fix tabbed layout for no borders --- sway/desktop/output.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 9a1c64696..7cb2bedb0 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -562,20 +562,20 @@ static void render_container_tabbed(struct sway_output *output, if (child->type == C_VIEW) { struct border_colors *colors; struct wlr_texture *title_texture; - if (child->sway_view->border != B_NONE) { - if (focus == child) { - colors = &config->border_colors.focused; - title_texture = child->title_focused; - active_child = child; - } else if (seat_get_focus_inactive(seat, con) == child) { - colors= &config->border_colors.focused_inactive; - title_texture = child->title_focused_inactive; - active_child = child; - } else { - colors = &config->border_colors.unfocused; - title_texture = child->title_unfocused; - } + if (focus == child) { + colors = &config->border_colors.focused; + title_texture = child->title_focused; + active_child = child; + } else if (seat_get_focus_inactive(seat, con) == child) { + colors= &config->border_colors.focused_inactive; + title_texture = child->title_focused_inactive; + active_child = child; + } else { + colors = &config->border_colors.unfocused; + title_texture = child->title_unfocused; + } + if (child->sway_view->border != B_NONE) { render_container_top_tabbed_border_normal(output, child, colors, title_texture, i); } From 47c1b0a2bc1e14aebab39de660521fdbb6f855f2 Mon Sep 17 00:00:00 2001 From: Dudemanguy911 Date: Fri, 11 May 2018 12:57:11 -0500 Subject: [PATCH 13/14] make tabbed layout share all border toggle/thickness settings --- sway/commands/border.c | 61 +++++++++++++++++++++++---------- sway/desktop/output.c | 76 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 119 insertions(+), 18 deletions(-) diff --git a/sway/commands/border.c b/sway/commands/border.c index 1eb06a218..f2194e2b8 100644 --- a/sway/commands/border.c +++ b/sway/commands/border.c @@ -18,26 +18,53 @@ struct cmd_results *cmd_border(int argc, char **argv) { return cmd_results_new(CMD_INVALID, "border", "Only views can have borders"); } - struct sway_view *view = container->sway_view; - if (strcmp(argv[0], "none") == 0) { - view->border = B_NONE; - } else if (strcmp(argv[0], "normal") == 0) { - view->border = B_NORMAL; - } else if (strcmp(argv[0], "pixel") == 0) { - view->border = B_PIXEL; - if (argc == 2) { - view->border_thickness = atoi(argv[1]); + if (container->parent->layout != L_TABBED) { + struct sway_view *view = container->sway_view; + if (strcmp(argv[0], "none") == 0) { + view->border = B_NONE; + } else if (strcmp(argv[0], "normal") == 0) { + view->border = B_NORMAL; + } else if (strcmp(argv[0], "pixel") == 0) { + view->border = B_PIXEL; + if (argc == 2) { + view->border_thickness = atoi(argv[1]); + } + } else if (strcmp(argv[0], "toggle") == 0) { + view->border = (view->border + 1) % 3; + } else { + return cmd_results_new(CMD_INVALID, "border", + "Expected 'border ' " + "or 'border pixel '"); } - } else if (strcmp(argv[0], "toggle") == 0) { - view->border = (view->border + 1) % 3; - } else { - return cmd_results_new(CMD_INVALID, "border", - "Expected 'border ' " - "or 'border pixel '"); - } - view_autoconfigure(view); + view_autoconfigure(view); + } else { + int depth; + int num_tabs = container->parent->children->length; + + for (depth = 0; depth < num_tabs; ++depth) { + struct sway_container *child = container->parent->children->items[depth]; + if (strcmp(argv[0], "none") == 0) { + child->sway_view->border = B_NONE; + } else if (strcmp(argv[0], "normal") == 0) { + child->sway_view->border = B_NORMAL; + } else if (strcmp(argv[0], "pixel") == 0) { + child->sway_view->border = B_PIXEL; + if (argc == 2) { + child->sway_view->border_thickness = atoi(argv[1]); + } + } else if (strcmp(argv[0], "toggle") == 0) { + child->sway_view->border = (child->sway_view->border + 1) % 3; + } else { + return cmd_results_new(CMD_INVALID, "border", + "Expected 'border ' " + "or 'border pixel '"); + } + + view_autoconfigure(child->sway_view); + } + } struct sway_seat *seat = input_manager_current_seat(input_manager); if (seat->cursor) { diff --git a/sway/desktop/output.c b/sway/desktop/output.c index ac44803dc..f28ae02d9 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -571,6 +571,60 @@ static void render_container_top_tabbed_border_normal(struct sway_output *output } } +/** + * Render decorations for a tabbed view with "border pixel". + */ +static void render_container_tabbed_border_pixel(struct sway_output *output, + pixman_region32_t *output_damage, struct sway_container *con, + struct border_colors *colors, size_t depth) { + struct wlr_box box; + float color[4]; + double num_tabs = con->parent->children->length; + double tab_width = con->width / num_tabs; + + // Child border - left edge + memcpy(&color, colors->child_border, sizeof(float) * 4); + color[3] *= con->alpha; + box.x = con->x; + box.y = con->y + (con->sway_view->y - con->y); + box.width = con->sway_view->border_thickness; + box.height = con->height; + render_rect(output->wlr_output, output_damage, &box, color); + + // Child border - right edge + if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) { + memcpy(&color, colors->indicator, sizeof(float) * 4); + } else { + memcpy(&color, colors->child_border, sizeof(float) * 4); + } + color[3] *= con->alpha; + box.x = con->x + con->width - con->sway_view->border_thickness; + box.y = con->y + (con->sway_view->y - con->y); + box.width = con->sway_view->border_thickness; + box.height = con->height; + render_rect(output->wlr_output, output_damage, &box, color); + + // Child border - top edge + box.x = con->x + depth * tab_width; + box.y = con->y; + box.width = con->width / num_tabs; + box.height = con->sway_view->border_thickness; + render_rect(output->wlr_output, output_damage, &box, color); + + // Child border - bottom edge + if (con->parent->children->length == 1 && con->parent->layout == L_VERT) { + memcpy(&color, colors->indicator, sizeof(float) * 4); + } else { + memcpy(&color, colors->child_border, sizeof(float) * 4); + } + color[3] *= con->alpha; + box.x = con->x; + box.y = con->y + con->height - con->sway_view->border_thickness; + box.width = con->width; + box.height = con->sway_view->border_thickness; + render_rect(output->wlr_output, output_damage, &box, color); +} + static void render_container(struct sway_output *output, pixman_region32_t *damage, struct sway_container *con, bool parent_focused); @@ -633,6 +687,8 @@ static void render_container_tabbed(struct sway_output *output, struct border_colors *focused_colors = &config->border_colors.focused; for (int i = 0; i < con->children->length; ++i) { struct sway_container *child = con->children->items[i]; + enum sway_container_border border_type; + int border_thickness; if (child->type == C_VIEW) { struct border_colors *colors; @@ -650,9 +706,27 @@ static void render_container_tabbed(struct sway_output *output, title_texture = child->title_unfocused; } - if (child->sway_view->border != B_NONE) { + if (i == 0) { + border_type = child->sway_view->border; + border_thickness = child->sway_view->border_thickness; + } + + if (border_type == B_NORMAL) { render_container_top_tabbed_border_normal(output, damage, child, colors, title_texture, i); + child->sway_view->border = border_type; + child->sway_view->border_thickness = border_thickness; + view_autoconfigure(child->sway_view); + } else if (border_type == B_PIXEL) { + render_container_tabbed_border_pixel(output, damage, + child, colors, i); + child->sway_view->border = border_type; + child->sway_view->border_thickness = border_thickness; + view_autoconfigure(child->sway_view); + } else { + child->sway_view->border = border_type; + child->sway_view->border_thickness = border_thickness; + view_autoconfigure(child->sway_view); } } else { render_container(output, damage, child, From 95258cf442d69f737cc30710c0c8f6d8ef559a71 Mon Sep 17 00:00:00 2001 From: Dudemanguy911 Date: Sat, 12 May 2018 14:04:49 -0500 Subject: [PATCH 14/14] use arrange_children_of instead of view_autoconfigure --- sway/desktop/output.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sway/desktop/output.c b/sway/desktop/output.c index f28ae02d9..c67fb0c02 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -716,23 +716,23 @@ static void render_container_tabbed(struct sway_output *output, child, colors, title_texture, i); child->sway_view->border = border_type; child->sway_view->border_thickness = border_thickness; - view_autoconfigure(child->sway_view); } else if (border_type == B_PIXEL) { render_container_tabbed_border_pixel(output, damage, child, colors, i); child->sway_view->border = border_type; child->sway_view->border_thickness = border_thickness; - view_autoconfigure(child->sway_view); } else { child->sway_view->border = border_type; child->sway_view->border_thickness = border_thickness; - view_autoconfigure(child->sway_view); } } else { render_container(output, damage, child, parent_focused || focus == child); } } + + arrange_children_of(con); + if (active_child) { render_container_border_outline_normal(output, damage, active_child, focused_colors);