aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/render.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/desktop/render.c')
-rw-r--r--sway/desktop/render.c211
1 files changed, 145 insertions, 66 deletions
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index bd85282c..ed9ad490 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -7,13 +7,12 @@
7#include <wayland-server-core.h> 7#include <wayland-server-core.h>
8#include <wlr/render/gles2.h> 8#include <wlr/render/gles2.h>
9#include <wlr/render/wlr_renderer.h> 9#include <wlr/render/wlr_renderer.h>
10#include <wlr/types/wlr_box.h>
11#include <wlr/types/wlr_buffer.h> 10#include <wlr/types/wlr_buffer.h>
12#include <wlr/types/wlr_matrix.h> 11#include <wlr/types/wlr_matrix.h>
13#include <wlr/types/wlr_output_damage.h> 12#include <wlr/types/wlr_output_damage.h>
14#include <wlr/types/wlr_output_layout.h> 13#include <wlr/types/wlr_output_layout.h>
15#include <wlr/types/wlr_output.h> 14#include <wlr/types/wlr_output.h>
16#include <wlr/types/wlr_surface.h> 15#include <wlr/types/wlr_compositor.h>
17#include <wlr/util/region.h> 16#include <wlr/util/region.h>
18#include "log.h" 17#include "log.h"
19#include "config.h" 18#include "config.h"
@@ -32,6 +31,7 @@
32struct render_data { 31struct render_data {
33 pixman_region32_t *damage; 32 pixman_region32_t *damage;
34 float alpha; 33 float alpha;
34 struct wlr_box *clip_box;
35}; 35};
36 36
37/** 37/**
@@ -52,7 +52,7 @@ static int scale_length(int length, int offset, float scale) {
52 52
53static void scissor_output(struct wlr_output *wlr_output, 53static void scissor_output(struct wlr_output *wlr_output,
54 pixman_box32_t *rect) { 54 pixman_box32_t *rect) {
55 struct wlr_renderer *renderer = wlr_backend_get_renderer(wlr_output->backend); 55 struct wlr_renderer *renderer = wlr_output->renderer;
56 assert(renderer); 56 assert(renderer);
57 57
58 struct wlr_box box = { 58 struct wlr_box box = {
@@ -100,13 +100,9 @@ static void render_texture(struct wlr_output *wlr_output,
100 pixman_region32_t *output_damage, struct wlr_texture *texture, 100 pixman_region32_t *output_damage, struct wlr_texture *texture,
101 const struct wlr_fbox *src_box, const struct wlr_box *dst_box, 101 const struct wlr_fbox *src_box, const struct wlr_box *dst_box,
102 const float matrix[static 9], float alpha) { 102 const float matrix[static 9], float alpha) {
103 struct wlr_renderer *renderer = 103 struct wlr_renderer *renderer = wlr_output->renderer;
104 wlr_backend_get_renderer(wlr_output->backend);
105 struct sway_output *output = wlr_output->data; 104 struct sway_output *output = wlr_output->data;
106 105
107 struct wlr_gles2_texture_attribs attribs;
108 wlr_gles2_texture_get_attribs(texture, &attribs);
109
110 pixman_region32_t damage; 106 pixman_region32_t damage;
111 pixman_region32_init(&damage); 107 pixman_region32_init(&damage);
112 pixman_region32_union_rect(&damage, &damage, dst_box->x, dst_box->y, 108 pixman_region32_union_rect(&damage, &damage, dst_box->x, dst_box->y,
@@ -133,9 +129,9 @@ damage_finish:
133 pixman_region32_fini(&damage); 129 pixman_region32_fini(&damage);
134} 130}
135 131
136static void render_surface_iterator(struct sway_output *output, struct sway_view *view, 132static void render_surface_iterator(struct sway_output *output,
137 struct wlr_surface *surface, struct wlr_box *_box, float rotation, 133 struct sway_view *view, struct wlr_surface *surface,
138 void *_data) { 134 struct wlr_box *_box, void *_data) {
139 struct render_data *data = _data; 135 struct render_data *data = _data;
140 struct wlr_output *wlr_output = output->wlr_output; 136 struct wlr_output *wlr_output = output->wlr_output;
141 pixman_region32_t *output_damage = data->damage; 137 pixman_region32_t *output_damage = data->damage;
@@ -149,15 +145,23 @@ static void render_surface_iterator(struct sway_output *output, struct sway_view
149 struct wlr_fbox src_box; 145 struct wlr_fbox src_box;
150 wlr_surface_get_buffer_source_box(surface, &src_box); 146 wlr_surface_get_buffer_source_box(surface, &src_box);
151 147
152 struct wlr_box dst_box = *_box; 148 struct wlr_box proj_box = *_box;
153 scale_box(&dst_box, wlr_output->scale); 149 scale_box(&proj_box, wlr_output->scale);
154 150
155 float matrix[9]; 151 float matrix[9];
156 enum wl_output_transform transform = 152 enum wl_output_transform transform =
157 wlr_output_transform_invert(surface->current.transform); 153 wlr_output_transform_invert(surface->current.transform);
158 wlr_matrix_project_box(matrix, &dst_box, transform, rotation, 154 wlr_matrix_project_box(matrix, &proj_box, transform, 0.0,
159 wlr_output->transform_matrix); 155 wlr_output->transform_matrix);
160 156
157 struct wlr_box dst_box = *_box;
158 struct wlr_box *clip_box = data->clip_box;
159 if (clip_box != NULL) {
160 dst_box.width = fmin(dst_box.width, clip_box->width);
161 dst_box.height = fmin(dst_box.height, clip_box->height);
162 }
163 scale_box(&dst_box, wlr_output->scale);
164
161 render_texture(wlr_output, output_damage, texture, 165 render_texture(wlr_output, output_damage, texture,
162 &src_box, &dst_box, matrix, alpha); 166 &src_box, &dst_box, matrix, alpha);
163 167
@@ -213,8 +217,7 @@ void render_rect(struct sway_output *output,
213 pixman_region32_t *output_damage, const struct wlr_box *_box, 217 pixman_region32_t *output_damage, const struct wlr_box *_box,
214 float color[static 4]) { 218 float color[static 4]) {
215 struct wlr_output *wlr_output = output->wlr_output; 219 struct wlr_output *wlr_output = output->wlr_output;
216 struct wlr_renderer *renderer = 220 struct wlr_renderer *renderer = wlr_output->renderer;
217 wlr_backend_get_renderer(wlr_output->backend);
218 221
219 struct wlr_box box; 222 struct wlr_box box;
220 memcpy(&box, _box, sizeof(struct wlr_box)); 223 memcpy(&box, _box, sizeof(struct wlr_box));
@@ -256,6 +259,14 @@ static void render_view_toplevels(struct sway_view *view,
256 .damage = damage, 259 .damage = damage,
257 .alpha = alpha, 260 .alpha = alpha,
258 }; 261 };
262 struct wlr_box clip_box;
263 if (!container_is_current_floating(view->container)) {
264 // As we pass the geometry offsets to the surface iterator, we will
265 // need to account for the offsets in the clip dimensions.
266 clip_box.width = view->container->current.content_width + view->geometry.x;
267 clip_box.height = view->container->current.content_height + view->geometry.y;
268 data.clip_box = &clip_box;
269 }
259 // Render all toplevels without descending into popups 270 // Render all toplevels without descending into popups
260 double ox = view->container->surface_x - 271 double ox = view->container->surface_x -
261 output->lx - view->geometry.x; 272 output->lx - view->geometry.x;
@@ -282,17 +293,18 @@ static void render_saved_view(struct sway_view *view,
282 if (wl_list_empty(&view->saved_buffers)) { 293 if (wl_list_empty(&view->saved_buffers)) {
283 return; 294 return;
284 } 295 }
296
297 bool floating = container_is_current_floating(view->container);
298
285 struct sway_saved_buffer *saved_buf; 299 struct sway_saved_buffer *saved_buf;
286 wl_list_for_each(saved_buf, &view->saved_buffers, link) { 300 wl_list_for_each(saved_buf, &view->saved_buffers, link) {
287 if (!saved_buf->buffer->texture) { 301 if (!saved_buf->buffer->texture) {
288 continue; 302 continue;
289 } 303 }
290 304
291 struct wlr_box box = { 305 struct wlr_box proj_box = {
292 .x = view->container->surface_x - output->lx - 306 .x = saved_buf->x - view->saved_geometry.x - output->lx,
293 view->saved_geometry.x + saved_buf->x, 307 .y = saved_buf->y - view->saved_geometry.y - output->ly,
294 .y = view->container->surface_y - output->ly -
295 view->saved_geometry.y + saved_buf->y,
296 .width = saved_buf->width, 308 .width = saved_buf->width,
297 .height = saved_buf->height, 309 .height = saved_buf->height,
298 }; 310 };
@@ -303,20 +315,31 @@ static void render_saved_view(struct sway_view *view,
303 }; 315 };
304 316
305 struct wlr_box intersection; 317 struct wlr_box intersection;
306 bool intersects = wlr_box_intersection(&intersection, &output_box, &box); 318 bool intersects = wlr_box_intersection(&intersection, &output_box, &proj_box);
307 if (!intersects) { 319 if (!intersects) {
308 continue; 320 continue;
309 } 321 }
310 322
311 scale_box(&box, wlr_output->scale); 323 struct wlr_box dst_box = proj_box;
324 scale_box(&proj_box, wlr_output->scale);
312 325
313 float matrix[9]; 326 float matrix[9];
314 enum wl_output_transform transform = wlr_output_transform_invert(saved_buf->transform); 327 enum wl_output_transform transform = wlr_output_transform_invert(saved_buf->transform);
315 wlr_matrix_project_box(matrix, &box, transform, 0, 328 wlr_matrix_project_box(matrix, &proj_box, transform, 0,
316 wlr_output->transform_matrix); 329 wlr_output->transform_matrix);
317 330
331 if (!floating) {
332 dst_box.width = fmin(dst_box.width,
333 view->container->current.content_width -
334 (saved_buf->x - view->container->current.content_x) + view->saved_geometry.x);
335 dst_box.height = fmin(dst_box.height,
336 view->container->current.content_height -
337 (saved_buf->y - view->container->current.content_y) + view->saved_geometry.y);
338 }
339 scale_box(&dst_box, wlr_output->scale);
340
318 render_texture(wlr_output, damage, saved_buf->buffer->texture, 341 render_texture(wlr_output, damage, saved_buf->buffer->texture,
319 &saved_buf->source_box, &box, matrix, alpha); 342 &saved_buf->source_box, &dst_box, matrix, alpha);
320 } 343 }
321 344
322 // FIXME: we should set the surface that this saved buffer originates from 345 // FIXME: we should set the surface that this saved buffer originates from
@@ -348,8 +371,8 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage,
348 if (state->border_left) { 371 if (state->border_left) {
349 memcpy(&color, colors->child_border, sizeof(float) * 4); 372 memcpy(&color, colors->child_border, sizeof(float) * 4);
350 premultiply_alpha(color, con->alpha); 373 premultiply_alpha(color, con->alpha);
351 box.x = state->x; 374 box.x = floor(state->x);
352 box.y = state->content_y; 375 box.y = floor(state->content_y);
353 box.width = state->border_thickness; 376 box.width = state->border_thickness;
354 box.height = state->content_height; 377 box.height = state->content_height;
355 scale_box(&box, output_scale); 378 scale_box(&box, output_scale);
@@ -361,14 +384,14 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage,
361 container_current_parent_layout(con); 384 container_current_parent_layout(con);
362 385
363 if (state->border_right) { 386 if (state->border_right) {
364 if (!container_is_floating(con) && siblings->length == 1 && layout == L_HORIZ) { 387 if (!container_is_current_floating(con) && siblings->length == 1 && layout == L_HORIZ) {
365 memcpy(&color, colors->indicator, sizeof(float) * 4); 388 memcpy(&color, colors->indicator, sizeof(float) * 4);
366 } else { 389 } else {
367 memcpy(&color, colors->child_border, sizeof(float) * 4); 390 memcpy(&color, colors->child_border, sizeof(float) * 4);
368 } 391 }
369 premultiply_alpha(color, con->alpha); 392 premultiply_alpha(color, con->alpha);
370 box.x = state->content_x + state->content_width; 393 box.x = floor(state->content_x + state->content_width);
371 box.y = state->content_y; 394 box.y = floor(state->content_y);
372 box.width = state->border_thickness; 395 box.width = state->border_thickness;
373 box.height = state->content_height; 396 box.height = state->content_height;
374 scale_box(&box, output_scale); 397 scale_box(&box, output_scale);
@@ -376,14 +399,14 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage,
376 } 399 }
377 400
378 if (state->border_bottom) { 401 if (state->border_bottom) {
379 if (!container_is_floating(con) && siblings->length == 1 && layout == L_VERT) { 402 if (!container_is_current_floating(con) && siblings->length == 1 && layout == L_VERT) {
380 memcpy(&color, colors->indicator, sizeof(float) * 4); 403 memcpy(&color, colors->indicator, sizeof(float) * 4);
381 } else { 404 } else {
382 memcpy(&color, colors->child_border, sizeof(float) * 4); 405 memcpy(&color, colors->child_border, sizeof(float) * 4);
383 } 406 }
384 premultiply_alpha(color, con->alpha); 407 premultiply_alpha(color, con->alpha);
385 box.x = state->x; 408 box.x = floor(state->x);
386 box.y = state->content_y + state->content_height; 409 box.y = floor(state->content_y + state->content_height);
387 box.width = state->width; 410 box.width = state->width;
388 box.height = state->border_thickness; 411 box.height = state->border_thickness;
389 scale_box(&box, output_scale); 412 scale_box(&box, output_scale);
@@ -464,9 +487,10 @@ static void render_titlebar(struct sway_output *output,
464 int ob_marks_x = 0; // output-buffer-local 487 int ob_marks_x = 0; // output-buffer-local
465 int ob_marks_width = 0; // output-buffer-local 488 int ob_marks_width = 0; // output-buffer-local
466 if (config->show_marks && marks_texture) { 489 if (config->show_marks && marks_texture) {
467 struct wlr_box texture_box; 490 struct wlr_box texture_box = {
468 wlr_texture_get_size(marks_texture, 491 .width = marks_texture->width,
469 &texture_box.width, &texture_box.height); 492 .height = marks_texture->height,
493 };
470 ob_marks_width = texture_box.width; 494 ob_marks_width = texture_box.width;
471 495
472 // The marks texture might be shorter than the config->font_height, in 496 // The marks texture might be shorter than the config->font_height, in
@@ -517,15 +541,23 @@ static void render_titlebar(struct sway_output *output,
517 int ob_title_x = 0; // output-buffer-local 541 int ob_title_x = 0; // output-buffer-local
518 int ob_title_width = 0; // output-buffer-local 542 int ob_title_width = 0; // output-buffer-local
519 if (title_texture) { 543 if (title_texture) {
520 struct wlr_box texture_box; 544 struct wlr_box texture_box = {
521 wlr_texture_get_size(title_texture, 545 .width = title_texture->width,
522 &texture_box.width, &texture_box.height); 546 .height = title_texture->height,
547 };
548
549 // The effective output may be NULL when con is not on any output.
550 // This can happen because we render all children of containers,
551 // even those that are out of the bounds of any output.
552 struct sway_output *effective = container_get_effective_output(con);
553 float title_scale = effective ? effective->wlr_output->scale : output_scale;
554 texture_box.width = texture_box.width * output_scale / title_scale;
555 texture_box.height = texture_box.height * output_scale / title_scale;
523 ob_title_width = texture_box.width; 556 ob_title_width = texture_box.width;
524 557
525 // The title texture might be shorter than the config->font_height, 558 // The title texture might be shorter than the config->font_height,
526 // in which case we need to pad it above and below. 559 // in which case we need to pad it above and below.
527 int ob_padding_above = round((config->font_baseline - 560 int ob_padding_above = round((titlebar_v_padding -
528 con->title_baseline + titlebar_v_padding -
529 titlebar_border_thickness) * output_scale); 561 titlebar_border_thickness) * output_scale);
530 int ob_padding_below = ob_bg_height - ob_padding_above - 562 int ob_padding_below = ob_bg_height - ob_padding_above -
531 texture_box.height; 563 texture_box.height;
@@ -660,8 +692,8 @@ static void render_top_border(struct sway_output *output,
660 // Child border - top edge 692 // Child border - top edge
661 memcpy(&color, colors->child_border, sizeof(float) * 4); 693 memcpy(&color, colors->child_border, sizeof(float) * 4);
662 premultiply_alpha(color, con->alpha); 694 premultiply_alpha(color, con->alpha);
663 box.x = state->x; 695 box.x = floor(state->x);
664 box.y = state->y; 696 box.y = floor(state->y);
665 box.width = state->width; 697 box.width = state->width;
666 box.height = state->border_thickness; 698 box.height = state->border_thickness;
667 scale_box(&box, output_scale); 699 scale_box(&box, output_scale);
@@ -716,8 +748,8 @@ static void render_containers_linear(struct sway_output *output,
716 } 748 }
717 749
718 if (state->border == B_NORMAL) { 750 if (state->border == B_NORMAL) {
719 render_titlebar(output, damage, child, state->x, 751 render_titlebar(output, damage, child, floor(state->x),
720 state->y, state->width, colors, 752 floor(state->y), state->width, colors,
721 title_texture, marks_texture); 753 title_texture, marks_texture);
722 } else if (state->border == B_PIXEL) { 754 } else if (state->border == B_PIXEL) {
723 render_top_border(output, damage, child, colors); 755 render_top_border(output, damage, child, colors);
@@ -730,6 +762,14 @@ static void render_containers_linear(struct sway_output *output,
730 } 762 }
731} 763}
732 764
765static bool container_is_focused(struct sway_container *con, void *data) {
766 return con->current.focused;
767}
768
769static bool container_has_focused_child(struct sway_container *con) {
770 return container_find_child(con, container_is_focused, NULL);
771}
772
733/** 773/**
734 * Render a container's children using the L_TABBED layout. 774 * Render a container's children using the L_TABBED layout.
735 */ 775 */
@@ -761,6 +801,10 @@ static void render_containers_tabbed(struct sway_output *output,
761 colors = &config->border_colors.focused; 801 colors = &config->border_colors.focused;
762 title_texture = child->title_focused; 802 title_texture = child->title_focused;
763 marks_texture = child->marks_focused; 803 marks_texture = child->marks_focused;
804 } else if (config->has_focused_tab_title && container_has_focused_child(child)) {
805 colors = &config->border_colors.focused_tab_title;
806 title_texture = child->title_focused_tab_title;
807 marks_texture = child->marks_focused_tab_title;
764 } else if (child == parent->active_child) { 808 } else if (child == parent->active_child) {
765 colors = &config->border_colors.focused_inactive; 809 colors = &config->border_colors.focused_inactive;
766 title_texture = child->title_focused_inactive; 810 title_texture = child->title_focused_inactive;
@@ -771,7 +815,7 @@ static void render_containers_tabbed(struct sway_output *output,
771 marks_texture = child->marks_unfocused; 815 marks_texture = child->marks_unfocused;
772 } 816 }
773 817
774 int x = cstate->x + tab_width * i; 818 int x = floor(cstate->x + tab_width * i);
775 819
776 // Make last tab use the remaining width of the parent 820 // Make last tab use the remaining width of the parent
777 if (i == parent->children->length - 1) { 821 if (i == parent->children->length - 1) {
@@ -826,7 +870,11 @@ static void render_containers_stacked(struct sway_output *output,
826 colors = &config->border_colors.focused; 870 colors = &config->border_colors.focused;
827 title_texture = child->title_focused; 871 title_texture = child->title_focused;
828 marks_texture = child->marks_focused; 872 marks_texture = child->marks_focused;
829 } else if (child == parent->active_child) { 873 } else if (config->has_focused_tab_title && container_has_focused_child(child)) {
874 colors = &config->border_colors.focused_tab_title;
875 title_texture = child->title_focused_tab_title;
876 marks_texture = child->marks_focused_tab_title;
877 } else if (child == parent->active_child) {
830 colors = &config->border_colors.focused_inactive; 878 colors = &config->border_colors.focused_inactive;
831 title_texture = child->title_focused_inactive; 879 title_texture = child->title_focused_inactive;
832 marks_texture = child->marks_focused_inactive; 880 marks_texture = child->marks_focused_inactive;
@@ -884,8 +932,8 @@ static void render_container(struct sway_output *output,
884 struct parent_data data = { 932 struct parent_data data = {
885 .layout = con->current.layout, 933 .layout = con->current.layout,
886 .box = { 934 .box = {
887 .x = con->current.x, 935 .x = floor(con->current.x),
888 .y = con->current.y, 936 .y = floor(con->current.y),
889 .width = con->current.width, 937 .width = con->current.width,
890 .height = con->current.height, 938 .height = con->current.height,
891 }, 939 },
@@ -901,8 +949,8 @@ static void render_workspace(struct sway_output *output,
901 struct parent_data data = { 949 struct parent_data data = {
902 .layout = ws->current.layout, 950 .layout = ws->current.layout,
903 .box = { 951 .box = {
904 .x = ws->current.x, 952 .x = floor(ws->current.x),
905 .y = ws->current.y, 953 .y = floor(ws->current.y),
906 .width = ws->current.width, 954 .width = ws->current.width,
907 .height = ws->current.height, 955 .height = ws->current.height,
908 }, 956 },
@@ -936,8 +984,8 @@ static void render_floating_container(struct sway_output *soutput,
936 } 984 }
937 985
938 if (con->current.border == B_NORMAL) { 986 if (con->current.border == B_NORMAL) {
939 render_titlebar(soutput, damage, con, con->current.x, 987 render_titlebar(soutput, damage, con, floor(con->current.x),
940 con->current.y, con->current.width, colors, 988 floor(con->current.y), con->current.width, colors,
941 title_texture, marks_texture); 989 title_texture, marks_texture);
942 } else if (con->current.border == B_PIXEL) { 990 } else if (con->current.border == B_PIXEL) {
943 render_top_border(soutput, damage, con, colors); 991 render_top_border(soutput, damage, con, colors);
@@ -959,7 +1007,7 @@ static void render_floating(struct sway_output *soutput,
959 } 1007 }
960 for (int k = 0; k < ws->current.floating->length; ++k) { 1008 for (int k = 0; k < ws->current.floating->length; ++k) {
961 struct sway_container *floater = ws->current.floating->items[k]; 1009 struct sway_container *floater = ws->current.floating->items[k];
962 if (floater->fullscreen_mode != FULLSCREEN_NONE) { 1010 if (floater->current.fullscreen_mode != FULLSCREEN_NONE) {
963 continue; 1011 continue;
964 } 1012 }
965 render_floating_container(soutput, damage, floater); 1013 render_floating_container(soutput, damage, floater);
@@ -979,13 +1027,7 @@ static void render_seatops(struct sway_output *output,
979void output_render(struct sway_output *output, struct timespec *when, 1027void output_render(struct sway_output *output, struct timespec *when,
980 pixman_region32_t *damage) { 1028 pixman_region32_t *damage) {
981 struct wlr_output *wlr_output = output->wlr_output; 1029 struct wlr_output *wlr_output = output->wlr_output;
982 1030 struct wlr_renderer *renderer = output->server->renderer;
983 struct wlr_renderer *renderer =
984 wlr_backend_get_renderer(wlr_output->backend);
985 if (!sway_assert(renderer != NULL,
986 "expected the output backend to have a renderer")) {
987 return;
988 }
989 1031
990 struct sway_workspace *workspace = output->current.active_workspace; 1032 struct sway_workspace *workspace = output->current.active_workspace;
991 if (workspace == NULL) { 1033 if (workspace == NULL) {
@@ -999,6 +1041,12 @@ void output_render(struct sway_output *output, struct timespec *when,
999 1041
1000 wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); 1042 wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
1001 1043
1044 if (debug.damage == DAMAGE_RERENDER) {
1045 int width, height;
1046 wlr_output_transformed_resolution(wlr_output, &width, &height);
1047 pixman_region32_union_rect(damage, damage, 0, 0, width, height);
1048 }
1049
1002 if (!pixman_region32_not_empty(damage)) { 1050 if (!pixman_region32_not_empty(damage)) {
1003 // Output isn't damaged but needs buffer swap 1051 // Output isn't damaged but needs buffer swap
1004 goto renderer_end; 1052 goto renderer_end;
@@ -1006,10 +1054,41 @@ void output_render(struct sway_output *output, struct timespec *when,
1006 1054
1007 if (debug.damage == DAMAGE_HIGHLIGHT) { 1055 if (debug.damage == DAMAGE_HIGHLIGHT) {
1008 wlr_renderer_clear(renderer, (float[]){1, 1, 0, 1}); 1056 wlr_renderer_clear(renderer, (float[]){1, 1, 0, 1});
1009 } else if (debug.damage == DAMAGE_RERENDER) { 1057 }
1010 int width, height; 1058
1011 wlr_output_transformed_resolution(wlr_output, &width, &height); 1059 if (server.session_lock.locked) {
1012 pixman_region32_union_rect(damage, damage, 0, 0, width, height); 1060 float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
1061 if (server.session_lock.lock == NULL) {
1062 // abandoned lock -> red BG
1063 clear_color[0] = 1.f;
1064 }
1065 int nrects;
1066 pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects);
1067 for (int i = 0; i < nrects; ++i) {
1068 scissor_output(wlr_output, &rects[i]);
1069 wlr_renderer_clear(renderer, clear_color);
1070 }
1071
1072 if (server.session_lock.lock != NULL) {
1073 struct render_data data = {
1074 .damage = damage,
1075 .alpha = 1.0f,
1076 };
1077
1078 struct wlr_session_lock_surface_v1 *lock_surface;
1079 wl_list_for_each(lock_surface, &server.session_lock.lock->surfaces, link) {
1080 if (lock_surface->output != wlr_output) {
1081 continue;
1082 }
1083 if (!lock_surface->mapped) {
1084 continue;
1085 }
1086
1087 output_surface_for_each_surface(output, lock_surface->surface,
1088 0.0, 0.0, render_surface_iterator, &data);
1089 }
1090 }
1091 goto renderer_end;
1013 } 1092 }
1014 1093
1015 if (output_has_opaque_overlay_layer_surface(output)) { 1094 if (output_has_opaque_overlay_layer_surface(output)) {
@@ -1110,7 +1189,7 @@ renderer_end:
1110 wlr_region_transform(&frame_damage, &output->damage->current, 1189 wlr_region_transform(&frame_damage, &output->damage->current,
1111 transform, width, height); 1190 transform, width, height);
1112 1191
1113 if (debug.damage == DAMAGE_HIGHLIGHT) { 1192 if (debug.damage != DAMAGE_DEFAULT) {
1114 pixman_region32_union_rect(&frame_damage, &frame_damage, 1193 pixman_region32_union_rect(&frame_damage, &frame_damage,
1115 0, 0, wlr_output->width, wlr_output->height); 1194 0, 0, wlr_output->width, wlr_output->height);
1116 } 1195 }