aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar emersion <contact@emersion.fr>2018-08-02 08:20:39 +0100
committerLibravatar GitHub <noreply@github.com>2018-08-02 08:20:39 +0100
commitfe39129b96794032c396411f96f2eb016050a545 (patch)
tree8f0085c1829ab97a920acd9d5116732779177631
parentMerge pull request #2391 from RyanDwyer/fix-popups-v2 (diff)
parentMerge branch 'master' into fix-resize-wiggle (diff)
downloadsway-fe39129b96794032c396411f96f2eb016050a545.tar.gz
sway-fe39129b96794032c396411f96f2eb016050a545.tar.zst
sway-fe39129b96794032c396411f96f2eb016050a545.zip
Merge pull request #2396 from RyanDwyer/fix-resize-wiggle
Correctly track saved surfaces during multiple transactions
-rw-r--r--include/sway/desktop/transaction.h13
-rw-r--r--include/sway/tree/view.h7
-rw-r--r--sway/desktop/render.c16
-rw-r--r--sway/desktop/transaction.c51
-rw-r--r--sway/tree/view.c20
5 files changed, 46 insertions, 61 deletions
diff --git a/include/sway/desktop/transaction.h b/include/sway/desktop/transaction.h
index cee4afed..56361d94 100644
--- a/include/sway/desktop/transaction.h
+++ b/include/sway/desktop/transaction.h
@@ -42,17 +42,4 @@ void transaction_notify_view_ready(struct sway_view *view, uint32_t serial);
42void transaction_notify_view_ready_by_size(struct sway_view *view, 42void transaction_notify_view_ready_by_size(struct sway_view *view,
43 int width, int height); 43 int width, int height);
44 44
45/**
46 * Get the saved texture that should be rendered for a view.
47 *
48 * The addresses pointed at by the width and height pointers will be populated
49 * with the surface's dimensions, which may be different to the texture's
50 * dimensions if output scaling is used.
51 *
52 * This function should only be called if it is known that the view has
53 * instructions.
54 */
55struct wlr_texture *transaction_get_saved_texture(struct sway_view *view,
56 int *width, int *height);
57
58#endif 45#endif
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h
index 620c41e0..37fd02bc 100644
--- a/include/sway/tree/view.h
+++ b/include/sway/tree/view.h
@@ -85,6 +85,9 @@ struct sway_view {
85 bool allow_request_urgent; 85 bool allow_request_urgent;
86 struct wl_event_source *urgent_timer; 86 struct wl_event_source *urgent_timer;
87 87
88 struct wlr_buffer *saved_buffer;
89 int saved_buffer_width, saved_buffer_height;
90
88 bool destroying; 91 bool destroying;
89 92
90 list_t *executed_criteria; // struct criteria * 93 list_t *executed_criteria; // struct criteria *
@@ -339,4 +342,8 @@ void view_set_urgent(struct sway_view *view, bool enable);
339 342
340bool view_is_urgent(struct sway_view *view); 343bool view_is_urgent(struct sway_view *view);
341 344
345void view_remove_saved_buffer(struct sway_view *view);
346
347void view_save_buffer(struct sway_view *view);
348
342#endif 349#endif
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index ea4361f2..1f374740 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -222,17 +222,14 @@ static void render_saved_view(struct sway_view *view,
222 struct sway_output *output, pixman_region32_t *damage, float alpha) { 222 struct sway_output *output, pixman_region32_t *damage, float alpha) {
223 struct wlr_output *wlr_output = output->wlr_output; 223 struct wlr_output *wlr_output = output->wlr_output;
224 224
225 int width, height; 225 if (!view->saved_buffer || !view->saved_buffer->texture) {
226 struct wlr_texture *texture =
227 transaction_get_saved_texture(view, &width, &height);
228 if (!texture) {
229 return; 226 return;
230 } 227 }
231 struct wlr_box box = { 228 struct wlr_box box = {
232 .x = view->swayc->current.view_x - output->swayc->current.swayc_x, 229 .x = view->swayc->current.view_x - output->swayc->current.swayc_x,
233 .y = view->swayc->current.view_y - output->swayc->current.swayc_y, 230 .y = view->swayc->current.view_y - output->swayc->current.swayc_y,
234 .width = width, 231 .width = view->saved_buffer_width,
235 .height = height, 232 .height = view->saved_buffer_height,
236 }; 233 };
237 234
238 struct wlr_box output_box = { 235 struct wlr_box output_box = {
@@ -252,7 +249,8 @@ static void render_saved_view(struct sway_view *view,
252 wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0, 249 wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0,
253 wlr_output->transform_matrix); 250 wlr_output->transform_matrix);
254 251
255 render_texture(wlr_output, damage, texture, &box, matrix, alpha); 252 render_texture(wlr_output, damage, view->saved_buffer->texture,
253 &box, matrix, alpha);
256} 254}
257 255
258/** 256/**
@@ -261,7 +259,7 @@ static void render_saved_view(struct sway_view *view,
261static void render_view(struct sway_output *output, pixman_region32_t *damage, 259static void render_view(struct sway_output *output, pixman_region32_t *damage,
262 struct sway_container *con, struct border_colors *colors) { 260 struct sway_container *con, struct border_colors *colors) {
263 struct sway_view *view = con->sway_view; 261 struct sway_view *view = con->sway_view;
264 if (view->swayc->instructions->length) { 262 if (view->saved_buffer) {
265 render_saved_view(view, output, damage, view->swayc->alpha); 263 render_saved_view(view, output, damage, view->swayc->alpha);
266 } else { 264 } else {
267 render_view_toplevels(view, output, damage, view->swayc->alpha); 265 render_view_toplevels(view, output, damage, view->swayc->alpha);
@@ -864,7 +862,7 @@ void output_render(struct sway_output *output, struct timespec *when,
864 862
865 // TODO: handle views smaller than the output 863 // TODO: handle views smaller than the output
866 if (fullscreen_con->type == C_VIEW) { 864 if (fullscreen_con->type == C_VIEW) {
867 if (fullscreen_con->instructions->length) { 865 if (fullscreen_con->sway_view->saved_buffer) {
868 render_saved_view(fullscreen_con->sway_view, 866 render_saved_view(fullscreen_con->sway_view,
869 output, damage, 1.0f); 867 output, damage, 1.0f);
870 } else { 868 } else {
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c
index 7975366e..94070363 100644
--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -41,8 +41,6 @@ struct sway_transaction_instruction {
41 struct sway_transaction *transaction; 41 struct sway_transaction *transaction;
42 struct sway_container *container; 42 struct sway_container *container;
43 struct sway_container_state state; 43 struct sway_container_state state;
44 struct wlr_buffer *saved_buffer;
45 int saved_buffer_width, saved_buffer_height;
46 uint32_t serial; 44 uint32_t serial;
47 bool ready; 45 bool ready;
48}; 46};
@@ -57,27 +55,6 @@ static struct sway_transaction *transaction_create() {
57 return transaction; 55 return transaction;
58} 56}
59 57
60static void remove_saved_view_buffer(
61 struct sway_transaction_instruction *instruction) {
62 if (instruction->saved_buffer) {
63 wlr_buffer_unref(instruction->saved_buffer);
64 instruction->saved_buffer = NULL;
65 }
66}
67
68static void save_view_buffer(struct sway_view *view,
69 struct sway_transaction_instruction *instruction) {
70 if (!sway_assert(instruction->saved_buffer == NULL,
71 "Didn't expect instruction to have a saved buffer already")) {
72 remove_saved_view_buffer(instruction);
73 }
74 if (view->surface && wlr_surface_has_buffer(view->surface)) {
75 instruction->saved_buffer = wlr_buffer_ref(view->surface->buffer);
76 instruction->saved_buffer_width = view->surface->current.width;
77 instruction->saved_buffer_height = view->surface->current.height;
78 }
79}
80
81static void transaction_destroy(struct sway_transaction *transaction) { 58static void transaction_destroy(struct sway_transaction *transaction) {
82 // Free instructions 59 // Free instructions
83 for (int i = 0; i < transaction->instructions->length; ++i) { 60 for (int i = 0; i < transaction->instructions->length; ++i) {
@@ -93,7 +70,6 @@ static void transaction_destroy(struct sway_transaction *transaction) {
93 if (con->destroying && !con->instructions->length) { 70 if (con->destroying && !con->instructions->length) {
94 container_free(con); 71 container_free(con);
95 } 72 }
96 remove_saved_view_buffer(instruction);
97 free(instruction); 73 free(instruction);
98 } 74 }
99 list_free(transaction->instructions); 75 list_free(transaction->instructions);
@@ -158,9 +134,6 @@ static void transaction_add_container(struct sway_transaction *transaction,
158 134
159 copy_pending_state(container, &instruction->state); 135 copy_pending_state(container, &instruction->state);
160 136
161 if (container->type == C_VIEW) {
162 save_view_buffer(container->sway_view, instruction);
163 }
164 list_add(transaction->instructions, instruction); 137 list_add(transaction->instructions, instruction);
165} 138}
166 139
@@ -220,6 +193,15 @@ static void transaction_apply(struct sway_transaction *transaction) {
220 193
221 memcpy(&container->current, &instruction->state, 194 memcpy(&container->current, &instruction->state,
222 sizeof(struct sway_container_state)); 195 sizeof(struct sway_container_state));
196
197 if (container->type == C_VIEW) {
198 if (container->sway_view->saved_buffer) {
199 view_remove_saved_buffer(container->sway_view);
200 }
201 if (container->instructions->length > 1) {
202 view_save_buffer(container->sway_view);
203 }
204 }
223 } 205 }
224} 206}
225 207
@@ -294,6 +276,9 @@ static void transaction_commit(struct sway_transaction *transaction) {
294 // mapping and its default geometry doesn't intersect an output. 276 // mapping and its default geometry doesn't intersect an output.
295 struct timespec when; 277 struct timespec when;
296 wlr_surface_send_frame_done(con->sway_view->surface, &when); 278 wlr_surface_send_frame_done(con->sway_view->surface, &when);
279 if (!con->sway_view->saved_buffer) {
280 view_save_buffer(con->sway_view);
281 }
297 } 282 }
298 list_add(con->instructions, instruction); 283 list_add(con->instructions, instruction);
299 } 284 }
@@ -400,18 +385,6 @@ void transaction_notify_view_ready_by_size(struct sway_view *view,
400 } 385 }
401} 386}
402 387
403struct wlr_texture *transaction_get_saved_texture(struct sway_view *view,
404 int *width, int *height) {
405 struct sway_transaction_instruction *instruction =
406 view->swayc->instructions->items[0];
407 if (!instruction->saved_buffer) {
408 return NULL;
409 }
410 *width = instruction->saved_buffer_width;
411 *height = instruction->saved_buffer_height;
412 return instruction->saved_buffer->texture;
413}
414
415void transaction_commit_dirty(void) { 388void transaction_commit_dirty(void) {
416 if (!server.dirty_containers->length) { 389 if (!server.dirty_containers->length) {
417 return; 390 return;
diff --git a/sway/tree/view.c b/sway/tree/view.c
index 02a33c10..051b93ce 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -2,6 +2,7 @@
2#include <stdlib.h> 2#include <stdlib.h>
3#include <wayland-server.h> 3#include <wayland-server.h>
4#include <wlr/render/wlr_renderer.h> 4#include <wlr/render/wlr_renderer.h>
5#include <wlr/types/wlr_buffer.h>
5#include <wlr/types/wlr_output_layout.h> 6#include <wlr/types/wlr_output_layout.h>
6#include "config.h" 7#include "config.h"
7#ifdef HAVE_XWAYLAND 8#ifdef HAVE_XWAYLAND
@@ -1093,3 +1094,22 @@ void view_set_urgent(struct sway_view *view, bool enable) {
1093bool view_is_urgent(struct sway_view *view) { 1094bool view_is_urgent(struct sway_view *view) {
1094 return view->urgent.tv_sec || view->urgent.tv_nsec; 1095 return view->urgent.tv_sec || view->urgent.tv_nsec;
1095} 1096}
1097
1098void view_remove_saved_buffer(struct sway_view *view) {
1099 if (!sway_assert(view->saved_buffer, "Expected a saved buffer")) {
1100 return;
1101 }
1102 wlr_buffer_unref(view->saved_buffer);
1103 view->saved_buffer = NULL;
1104}
1105
1106void view_save_buffer(struct sway_view *view) {
1107 if (!sway_assert(!view->saved_buffer, "Didn't expect saved buffer")) {
1108 view_remove_saved_buffer(view);
1109 }
1110 if (view->surface && wlr_surface_has_buffer(view->surface)) {
1111 view->saved_buffer = wlr_buffer_ref(view->surface->buffer);
1112 view->saved_buffer_width = view->surface->current.width;
1113 view->saved_buffer_height = view->surface->current.height;
1114 }
1115}