From e67f3543332349e63b5099a241fdd85ce28ea54b Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Mon, 30 Apr 2018 21:24:13 +1000 Subject: Implement borders Implements rendering of borders. Title text is still to do. Implements the following configuration directives: * client.focused * client.focused_inactive * client.unfocused * client.urgent * border * default_border --- sway/desktop/output.c | 205 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 190 insertions(+), 15 deletions(-) (limited to 'sway/desktop/output.c') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index d9ae890f..2511c610 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -116,8 +116,8 @@ static void surface_for_each_surface(struct wlr_surface *surface, static void output_view_for_each_surface(struct sway_view *view, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data) { - geo->x = view->swayc->x; - geo->y = view->swayc->y; + geo->x = view->x; + geo->y = view->y; geo->width = view->surface->current->width; geo->height = view->surface->current->height; geo->rotation = 0; // TODO @@ -217,23 +217,198 @@ static void render_unmanaged(struct sway_output *output, render_surface_iterator, &data); } -static void render_container_iterator(struct sway_container *con, - void *_data) { - struct sway_output *output = _data; - if (!sway_assert(con->type == C_VIEW, "expected a view")) { - return; +static void render_view(struct sway_view *view, struct sway_output *output) { + struct render_data data = { .output = output, .alpha = view->swayc->alpha }; + output_view_for_each_surface( + view, &data.root_geo, render_surface_iterator, &data); +} + +/** + * 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_renderer *renderer = + wlr_backend_get_renderer(output->wlr_output->backend); + struct wlr_box box; + float color[4]; + color[3] = con->alpha; + + // Child border - left edge + memcpy(&color, colors->child_border, sizeof(float) * 3); + box.x = con->x; + box.y = con->y + 1; + box.width = con->sway_view->border_thickness; + box.height = con->height - 1; + wlr_render_rect(renderer, &box, color, + output->wlr_output->transform_matrix); + + // Child border - right edge + box.x = con->x + con->width - con->sway_view->border_thickness; + box.y = con->y + 1; + box.width = con->sway_view->border_thickness; + box.height = con->height - 1; + wlr_render_rect(renderer, &box, color, + output->wlr_output->transform_matrix); + + // Child border - bottom edge + 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; + wlr_render_rect(renderer, &box, color, + output->wlr_output->transform_matrix); + + // Single pixel bar above title + memcpy(&color, colors->border, sizeof(float) * 3); + box.x = con->x; + box.y = con->y; + box.width = con->width; + box.height = 1; + 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; + wlr_render_rect(renderer, &box, color, + output->wlr_output->transform_matrix); + + // Title background + memcpy(&color, colors->background, sizeof(float) * 3); + 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; + wlr_render_rect(renderer, &box, color, + output->wlr_output->transform_matrix); + + // Title text + // TODO +} + +/** + * Render decorations for a view with "border pixel". + */ +static void render_container_simple_border_pixel(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]; + color[3] = con->alpha; + + // Child border - left edge + memcpy(&color, colors->child_border, sizeof(float) * 3); + box.x = con->x; + box.y = con->y; + box.width = con->sway_view->border_thickness; + box.height = con->height; + wlr_render_rect(renderer, &box, color, + output->wlr_output->transform_matrix); + + // Child border - right edge + box.x = con->x + con->width - con->sway_view->border_thickness; + box.y = con->y; + box.width = con->sway_view->border_thickness; + box.height = con->height; + wlr_render_rect(renderer, &box, color, + output->wlr_output->transform_matrix); + + // Child border - top edge + box.x = con->x; + box.y = con->y; + box.width = con->width; + box.height = con->sway_view->border_thickness; + wlr_render_rect(renderer, &box, color, + output->wlr_output->transform_matrix); + + // Child border - bottom edge + 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; + wlr_render_rect(renderer, &box, color, + output->wlr_output->transform_matrix); +} + +static void render_container(struct sway_output *output, + struct sway_container *con); + +/** + * Render a container's children using a L_HORIZ or L_VERT layout. + * + * Wrap child views in borders and leave child containers borderless because + * they'll apply their own borders to their children. + */ +static void render_container_simple(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); + + 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; + if (focus == child) { + colors = &config->border_colors.focused; + } else if (seat_get_focus_inactive(seat, con) == child) { + colors = &config->border_colors.focused_inactive; + } else { + colors = &config->border_colors.unfocused; + } + + if (child->sway_view->border == B_NORMAL) { + render_container_simple_border_normal(output, child, + colors); + } else { + render_container_simple_border_pixel(output, child, colors); + } + } + render_view(child->sway_view, output); + } else { + render_container(output, child); + } } - struct render_data data = { .output = output, .alpha = con->alpha }; - output_view_for_each_surface(con->sway_view, &data.root_geo, - render_surface_iterator, &data); +} + +/** + * Render a container's children using the L_TABBED layout. + */ +static void render_container_tabbed(struct sway_output *output, + struct sway_container *con) { + // TODO +} + +/** + * Render a container's children using the L_STACKED layout. + */ +static void render_container_stacked(struct sway_output *output, + struct sway_container *con) { + // TODO } static void render_container(struct sway_output *output, struct sway_container *con) { - if (con->type == C_VIEW) { // Happens if a view is fullscreened - render_container_iterator(con, output); - } else { - container_descendants(con, C_VIEW, render_container_iterator, output); + switch (con->layout) { + case L_NONE: + case L_HORIZ: + case L_VERT: + render_container_simple(output, con); + break; + case L_STACKED: + render_container_stacked(output, con); + break; + case L_TABBED: + render_container_tabbed(output, con); + break; + case L_FLOATING: + // TODO + break; } } @@ -282,7 +457,7 @@ static void render_output(struct sway_output *output, struct timespec *when, float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; wlr_renderer_clear(renderer, clear_color); // TODO: handle views smaller than the output - render_container(output, workspace->sway_workspace->fullscreen->swayc); + render_view(workspace->sway_workspace->fullscreen, output); if (workspace->sway_workspace->fullscreen->type == SWAY_VIEW_XWAYLAND) { render_unmanaged(output, -- cgit v1.2.3 From d847ac1120b87bfe0ac5747964a1299cabd3bc19 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Tue, 1 May 2018 18:35:58 +1000 Subject: Scale borders according to output scale --- sway/desktop/output.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'sway/desktop/output.c') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 2511c610..498a3a2e 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -240,6 +240,7 @@ static void render_container_simple_border_normal(struct sway_output *output, box.y = con->y + 1; box.width = con->sway_view->border_thickness; box.height = con->height - 1; + scale_box(&box, output->wlr_output->scale); wlr_render_rect(renderer, &box, color, output->wlr_output->transform_matrix); @@ -248,6 +249,7 @@ static void render_container_simple_border_normal(struct sway_output *output, box.y = con->y + 1; box.width = con->sway_view->border_thickness; box.height = con->height - 1; + scale_box(&box, output->wlr_output->scale); wlr_render_rect(renderer, &box, color, output->wlr_output->transform_matrix); @@ -256,6 +258,7 @@ static void render_container_simple_border_normal(struct sway_output *output, 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); @@ -265,6 +268,7 @@ static void render_container_simple_border_normal(struct sway_output *output, 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); @@ -273,6 +277,7 @@ static void render_container_simple_border_normal(struct sway_output *output, 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); @@ -282,6 +287,7 @@ static void render_container_simple_border_normal(struct sway_output *output, 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); @@ -306,6 +312,7 @@ static void render_container_simple_border_pixel(struct sway_output *output, box.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); @@ -314,6 +321,7 @@ static void render_container_simple_border_pixel(struct sway_output *output, box.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); @@ -322,6 +330,7 @@ static void render_container_simple_border_pixel(struct sway_output *output, box.y = con->y; 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); @@ -330,6 +339,7 @@ static void render_container_simple_border_pixel(struct sway_output *output, 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); } -- cgit v1.2.3 From a19a511b90d214f200bfca1cffad0376b855caac Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Tue, 1 May 2018 19:21:29 +1000 Subject: Implement indicator border --- sway/desktop/output.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'sway/desktop/output.c') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 498a3a2e..e0a211d1 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -245,6 +245,11 @@ static void render_container_simple_border_normal(struct sway_output *output, output->wlr_output->transform_matrix); // Child border - right edge + if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) { + memcpy(&color, colors->indicator, sizeof(float) * 3); + } else { + memcpy(&color, colors->child_border, sizeof(float) * 3); + } box.x = con->x + con->width - con->sway_view->border_thickness; box.y = con->y + 1; box.width = con->sway_view->border_thickness; @@ -254,6 +259,11 @@ static void render_container_simple_border_normal(struct sway_output *output, 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) * 3); + } else { + memcpy(&color, colors->child_border, sizeof(float) * 3); + } box.x = con->x; box.y = con->y + con->height - con->sway_view->border_thickness; box.width = con->width; @@ -317,6 +327,11 @@ static void render_container_simple_border_pixel(struct sway_output *output, output->wlr_output->transform_matrix); // Child border - right edge + if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) { + memcpy(&color, colors->indicator, sizeof(float) * 3); + } else { + memcpy(&color, colors->child_border, sizeof(float) * 3); + } box.x = con->x + con->width - con->sway_view->border_thickness; box.y = con->y; box.width = con->sway_view->border_thickness; @@ -335,6 +350,11 @@ static void render_container_simple_border_pixel(struct sway_output *output, 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) * 3); + } else { + memcpy(&color, colors->child_border, sizeof(float) * 3); + } box.x = con->x; box.y = con->y + con->height - con->sway_view->border_thickness; box.width = con->width; -- cgit v1.2.3