diff options
author | emersion <contact@emersion.fr> | 2018-08-02 08:20:39 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-02 08:20:39 +0100 |
commit | fe39129b96794032c396411f96f2eb016050a545 (patch) | |
tree | 8f0085c1829ab97a920acd9d5116732779177631 | |
parent | Merge pull request #2391 from RyanDwyer/fix-popups-v2 (diff) | |
parent | Merge branch 'master' into fix-resize-wiggle (diff) | |
download | sway-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.h | 13 | ||||
-rw-r--r-- | include/sway/tree/view.h | 7 | ||||
-rw-r--r-- | sway/desktop/render.c | 16 | ||||
-rw-r--r-- | sway/desktop/transaction.c | 51 | ||||
-rw-r--r-- | sway/tree/view.c | 20 |
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); | |||
42 | void transaction_notify_view_ready_by_size(struct sway_view *view, | 42 | void 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 | */ | ||
55 | struct 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 | ||
340 | bool view_is_urgent(struct sway_view *view); | 343 | bool view_is_urgent(struct sway_view *view); |
341 | 344 | ||
345 | void view_remove_saved_buffer(struct sway_view *view); | ||
346 | |||
347 | void 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, | |||
261 | static void render_view(struct sway_output *output, pixman_region32_t *damage, | 259 | static 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 | ||
60 | static 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 | |||
68 | static 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 | |||
81 | static void transaction_destroy(struct sway_transaction *transaction) { | 58 | static 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 | ||
403 | struct 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 | |||
415 | void transaction_commit_dirty(void) { | 388 | void 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) { | |||
1093 | bool view_is_urgent(struct sway_view *view) { | 1094 | bool 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 | |||
1098 | void 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 | |||
1106 | void 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 | } | ||