diff options
Diffstat (limited to 'sway/desktop/render.c')
-rw-r--r-- | sway/desktop/render.c | 211 |
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 @@ | |||
32 | struct render_data { | 31 | struct 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 | ||
53 | static void scissor_output(struct wlr_output *wlr_output, | 53 | static 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 | ||
136 | static void render_surface_iterator(struct sway_output *output, struct sway_view *view, | 132 | static 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 | ||
765 | static bool container_is_focused(struct sway_container *con, void *data) { | ||
766 | return con->current.focused; | ||
767 | } | ||
768 | |||
769 | static 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, | |||
979 | void output_render(struct sway_output *output, struct timespec *when, | 1027 | void 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 | } |