aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop
diff options
context:
space:
mode:
authorLibravatar Kenny Levinsen <kl@kl.wtf>2020-05-31 01:37:43 +0200
committerLibravatar Simon Ser <contact@emersion.fr>2020-06-03 16:41:17 +0200
commitfcd0ab8f331a6e74fde113d665d4aed21bccdfc5 (patch)
treec2f53f827372904f8d7b1356231350652bed8a8d /sway/desktop
parentxwayland: pass focus to previous unmanaged surface on unmap (diff)
downloadsway-fcd0ab8f331a6e74fde113d665d4aed21bccdfc5.tar.gz
sway-fcd0ab8f331a6e74fde113d665d4aed21bccdfc5.tar.zst
sway-fcd0ab8f331a6e74fde113d665d4aed21bccdfc5.zip
view: Save all buffers associated with view
During the execution of a resize transaction, the buffer associated with a view's surface is saved and reused until the client acknowledges the resulting configure event. However, only one the main buffer of the main surface was stored and rendered, meaning that subsurfaces disappear during resize. Iterate over all, store and render buffers from all surfaces in the view to ensure that correct rendering is preserved.
Diffstat (limited to 'sway/desktop')
-rw-r--r--sway/desktop/output.c2
-rw-r--r--sway/desktop/render.c61
-rw-r--r--sway/desktop/transaction.c23
3 files changed, 48 insertions, 38 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index a86622e1..18250ae6 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -511,7 +511,7 @@ static bool scan_out_fullscreen_view(struct sway_output *output,
511 return false; 511 return false;
512 } 512 }
513 513
514 if (view->saved_buffer) { 514 if (!wl_list_empty(&view->saved_buffers)) {
515 return false; 515 return false;
516 } 516 }
517 517
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index 14753df2..491a9bc0 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -280,37 +280,44 @@ static void render_saved_view(struct sway_view *view,
280 struct sway_output *output, pixman_region32_t *damage, float alpha) { 280 struct sway_output *output, pixman_region32_t *damage, float alpha) {
281 struct wlr_output *wlr_output = output->wlr_output; 281 struct wlr_output *wlr_output = output->wlr_output;
282 282
283 if (!view->saved_buffer || !view->saved_buffer->texture) { 283 if (wl_list_empty(&view->saved_buffers)) {
284 return; 284 return;
285 } 285 }
286 struct wlr_box box = { 286 struct sway_saved_buffer *saved_buf;
287 .x = view->container->surface_x - output->lx - 287 wl_list_for_each(saved_buf, &view->saved_buffers, link) {
288 view->saved_geometry.x, 288 if (!saved_buf->buffer->texture) {
289 .y = view->container->surface_y - output->ly - 289 continue;
290 view->saved_geometry.y, 290 }
291 .width = view->saved_buffer_width,
292 .height = view->saved_buffer_height,
293 };
294
295 struct wlr_box output_box = {
296 .width = output->width,
297 .height = output->height,
298 };
299 291
300 struct wlr_box intersection; 292 struct wlr_box box = {
301 bool intersects = wlr_box_intersection(&intersection, &output_box, &box); 293 .x = view->container->surface_x - output->lx -
302 if (!intersects) { 294 view->saved_geometry.x + saved_buf->x,
303 return; 295 .y = view->container->surface_y - output->ly -
304 } 296 view->saved_geometry.y + saved_buf->y,
297 .width = saved_buf->width,
298 .height = saved_buf->height,
299 };
300
301 struct wlr_box output_box = {
302 .width = output->width,
303 .height = output->height,
304 };
305
306 struct wlr_box intersection;
307 bool intersects = wlr_box_intersection(&intersection, &output_box, &box);
308 if (!intersects) {
309 continue;
310 }
305 311
306 scale_box(&box, wlr_output->scale); 312 scale_box(&box, wlr_output->scale);
307 313
308 float matrix[9]; 314 float matrix[9];
309 wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0, 315 wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0,
310 wlr_output->transform_matrix); 316 wlr_output->transform_matrix);
311 317
312 render_texture(wlr_output, damage, view->saved_buffer->texture, 318 render_texture(wlr_output, damage, saved_buf->buffer->texture,
313 &box, matrix, alpha); 319 &box, matrix, alpha);
320 }
314 321
315 // FIXME: we should set the surface that this saved buffer originates from 322 // FIXME: we should set the surface that this saved buffer originates from
316 // as sampled here. 323 // as sampled here.
@@ -323,7 +330,7 @@ static void render_saved_view(struct sway_view *view,
323static void render_view(struct sway_output *output, pixman_region32_t *damage, 330static void render_view(struct sway_output *output, pixman_region32_t *damage,
324 struct sway_container *con, struct border_colors *colors) { 331 struct sway_container *con, struct border_colors *colors) {
325 struct sway_view *view = con->view; 332 struct sway_view *view = con->view;
326 if (view->saved_buffer) { 333 if (!wl_list_empty(&view->saved_buffers)) {
327 render_saved_view(view, output, damage, view->container->alpha); 334 render_saved_view(view, output, damage, view->container->alpha);
328 } else if (view->surface) { 335 } else if (view->surface) {
329 render_view_toplevels(view, output, damage, view->container->alpha); 336 render_view_toplevels(view, output, damage, view->container->alpha);
@@ -1020,7 +1027,7 @@ void output_render(struct sway_output *output, struct timespec *when,
1020 } 1027 }
1021 1028
1022 if (fullscreen_con->view) { 1029 if (fullscreen_con->view) {
1023 if (fullscreen_con->view->saved_buffer) { 1030 if (!wl_list_empty(&fullscreen_con->view->saved_buffers)) {
1024 render_saved_view(fullscreen_con->view, output, damage, 1.0f); 1031 render_saved_view(fullscreen_con->view, output, damage, 1.0f);
1025 } else if (fullscreen_con->view->surface) { 1032 } else if (fullscreen_con->view->surface) {
1026 render_view_toplevels(fullscreen_con->view, 1033 render_view_toplevels(fullscreen_con->view,
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c
index ccf60514..ef656102 100644
--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -210,14 +210,17 @@ static void apply_container_state(struct sway_container *container,
210 struct sway_view *view = container->view; 210 struct sway_view *view = container->view;
211 // Damage the old location 211 // Damage the old location
212 desktop_damage_whole_container(container); 212 desktop_damage_whole_container(container);
213 if (view && view->saved_buffer) { 213 if (view && !wl_list_empty(&view->saved_buffers)) {
214 struct wlr_box box = { 214 struct sway_saved_buffer *saved_buf;
215 .x = container->current.content_x - view->saved_geometry.x, 215 wl_list_for_each(saved_buf, &view->saved_buffers, link) {
216 .y = container->current.content_y - view->saved_geometry.y, 216 struct wlr_box box = {
217 .width = view->saved_buffer_width, 217 .x = container->current.content_x - view->saved_geometry.x + saved_buf->x,
218 .height = view->saved_buffer_height, 218 .y = container->current.content_y - view->saved_geometry.y + saved_buf->y,
219 }; 219 .width = saved_buf->width,
220 desktop_damage_box(&box); 220 .height = saved_buf->height,
221 };
222 desktop_damage_box(&box);
223 }
221 } 224 }
222 225
223 // There are separate children lists for each instruction state, the 226 // There are separate children lists for each instruction state, the
@@ -229,7 +232,7 @@ static void apply_container_state(struct sway_container *container,
229 232
230 memcpy(&container->current, state, sizeof(struct sway_container_state)); 233 memcpy(&container->current, state, sizeof(struct sway_container_state));
231 234
232 if (view && view->saved_buffer) { 235 if (view && !wl_list_empty(&view->saved_buffers)) {
233 if (!container->node.destroying || container->node.ntxnrefs == 1) { 236 if (!container->node.destroying || container->node.ntxnrefs == 1) {
234 view_remove_saved_buffer(view); 237 view_remove_saved_buffer(view);
235 } 238 }
@@ -432,7 +435,7 @@ static void transaction_commit(struct sway_transaction *transaction) {
432 wlr_surface_send_frame_done( 435 wlr_surface_send_frame_done(
433 node->sway_container->view->surface, &now); 436 node->sway_container->view->surface, &now);
434 } 437 }
435 if (node_is_view(node) && !node->sway_container->view->saved_buffer) { 438 if (node_is_view(node) && wl_list_empty(&node->sway_container->view->saved_buffers)) {
436 view_save_buffer(node->sway_container->view); 439 view_save_buffer(node->sway_container->view);
437 memcpy(&node->sway_container->view->saved_geometry, 440 memcpy(&node->sway_container->view->saved_geometry,
438 &node->sway_container->view->geometry, 441 &node->sway_container->view->geometry,