summaryrefslogtreecommitdiffstats
path: root/sway/desktop/output.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-07-31 18:41:30 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-07-31 18:41:30 +1000
commitde86d65627e96cffe77f4abf11c4a0b982326ff9 (patch)
tree1a3a914fdf561884b1bb0425d51d15684b629b3a /sway/desktop/output.c
parentMerge pull request #2390 from emersion/fix-fullscreen-segfault (diff)
downloadsway-de86d65627e96cffe77f4abf11c4a0b982326ff9.tar.gz
sway-de86d65627e96cffe77f4abf11c4a0b982326ff9.tar.zst
sway-de86d65627e96cffe77f4abf11c4a0b982326ff9.zip
Fix popups
Fixes the render and container_at order for popups. Fixes #2210 For rendering: * render_view_surfaces has been renamed to render_view_toplevels * render_view_toplevels now uses output_surface_for_each_surface (which is now public), as that function uses wlr_surface_for_each_surface which doesn't descend into popups * Views now have a for_each_popup iterator, which is used by the renderer to render the focused view's popups * When rendering a popup, toplevels (xdg subsurfaces) of that popup are also rendered For sending frame done, the logic has been updated to match the rendering logic: * send_frame_done_container no longer descends into popups * for_each_popup is used to send frame done to the focused view's popups and their child toplevels For container_at: * floating_container_at is now static, which means it had to be moved higher in the file. * container_at now considers popups for the focused view before checking containers. * tiling_container_at has been introduced, so that it doesn't call container_at recursively (it would check popups recursively if it did)
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r--sway/desktop/output.c52
1 files changed, 49 insertions, 3 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 31b53213..4c9d978c 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -119,7 +119,7 @@ static void output_for_each_surface_iterator(struct wlr_surface *surface,
119 data->user_data); 119 data->user_data);
120} 120}
121 121
122static void output_surface_for_each_surface(struct sway_output *output, 122void output_surface_for_each_surface(struct sway_output *output,
123 struct wlr_surface *surface, double ox, double oy, 123 struct wlr_surface *surface, double ox, double oy,
124 sway_surface_iterator_func_t iterator, void *user_data) { 124 sway_surface_iterator_func_t iterator, void *user_data) {
125 struct surface_iterator_data data = { 125 struct surface_iterator_data data = {
@@ -155,6 +155,23 @@ void output_view_for_each_surface(struct sway_output *output,
155 output_for_each_surface_iterator, &data); 155 output_for_each_surface_iterator, &data);
156} 156}
157 157
158void output_view_for_each_popup(struct sway_output *output,
159 struct sway_view *view, sway_surface_iterator_func_t iterator,
160 void *user_data) {
161 struct surface_iterator_data data = {
162 .user_iterator = iterator,
163 .user_data = user_data,
164 .output = output,
165 .ox = view->swayc->current.view_x - output->swayc->current.swayc_x,
166 .oy = view->swayc->current.view_y - output->swayc->current.swayc_y,
167 .width = view->swayc->current.view_width,
168 .height = view->swayc->current.view_height,
169 .rotation = 0, // TODO
170 };
171
172 view_for_each_popup(view, output_for_each_surface_iterator, &data);
173}
174
158void output_layer_for_each_surface(struct sway_output *output, 175void output_layer_for_each_surface(struct sway_output *output,
159 struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, 176 struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator,
160 void *user_data) { 177 void *user_data) {
@@ -295,8 +312,9 @@ static void send_frame_done_container_iterator(struct sway_container *con,
295 return; 312 return;
296 } 313 }
297 314
298 output_view_for_each_surface(data->output, con->sway_view, 315 // Toplevels only
299 send_frame_done_iterator, data->when); 316 output_surface_for_each_surface(data->output, con->sway_view->surface,
317 con->x, con->y, send_frame_done_iterator, data->when);
300} 318}
301 319
302static void send_frame_done_container(struct sway_output *output, 320static void send_frame_done_container(struct sway_output *output,
@@ -309,6 +327,27 @@ static void send_frame_done_container(struct sway_output *output,
309 send_frame_done_container_iterator, &data); 327 send_frame_done_container_iterator, &data);
310} 328}
311 329
330static void send_frame_done_popup_iterator(struct sway_output *output,
331 struct wlr_surface *surface, struct wlr_box *box, float rotation,
332 void *data) {
333 // Send frame done to this popup's surface
334 send_frame_done_iterator(output, surface, box, rotation, data);
335
336 // Send frame done to this popup's child toplevels
337 output_surface_for_each_surface(output, surface, box->x, box->y,
338 send_frame_done_iterator, data);
339}
340
341static void send_frame_done_popups(struct sway_output *output,
342 struct sway_view *view, struct timespec *when) {
343 struct send_frame_done_data data = {
344 .output = output,
345 .when = when,
346 };
347 output_view_for_each_popup(output, view,
348 send_frame_done_popup_iterator, &data);
349}
350
312static void send_frame_done(struct sway_output *output, struct timespec *when) { 351static void send_frame_done(struct sway_output *output, struct timespec *when) {
313 if (output_has_opaque_overlay_layer_surface(output)) { 352 if (output_has_opaque_overlay_layer_surface(output)) {
314 goto send_frame_overlay; 353 goto send_frame_overlay;
@@ -346,6 +385,13 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) {
346 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], when); 385 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], when);
347 } 386 }
348 387
388 struct sway_seat *seat = input_manager_current_seat(input_manager);
389 struct sway_container *focus = seat_get_focus(seat);
390 if (focus && focus->type == C_VIEW) {
391 send_frame_done_popups(output, focus->sway_view, when);
392 }
393
394
349send_frame_overlay: 395send_frame_overlay:
350 send_frame_done_layer(output, 396 send_frame_done_layer(output,
351 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], when); 397 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], when);