diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-07-31 18:41:30 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-07-31 18:41:30 +1000 |
commit | de86d65627e96cffe77f4abf11c4a0b982326ff9 (patch) | |
tree | 1a3a914fdf561884b1bb0425d51d15684b629b3a /sway | |
parent | Merge pull request #2390 from emersion/fix-fullscreen-segfault (diff) | |
download | sway-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')
-rw-r--r-- | sway/desktop/output.c | 52 | ||||
-rw-r--r-- | sway/desktop/render.c | 37 | ||||
-rw-r--r-- | sway/desktop/xdg_shell.c | 9 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 10 | ||||
-rw-r--r-- | sway/input/cursor.c | 3 | ||||
-rw-r--r-- | sway/tree/container.c | 134 | ||||
-rw-r--r-- | sway/tree/view.c | 10 |
7 files changed, 207 insertions, 48 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 | ||
122 | static void output_surface_for_each_surface(struct sway_output *output, | 122 | void 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 | ||
158 | void 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 | |||
158 | void output_layer_for_each_surface(struct sway_output *output, | 175 | void 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 | ||
302 | static void send_frame_done_container(struct sway_output *output, | 320 | static 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 | ||
330 | static 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 | |||
341 | static 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 | |||
312 | static void send_frame_done(struct sway_output *output, struct timespec *when) { | 351 | static 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 | |||
349 | send_frame_overlay: | 395 | send_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); |
diff --git a/sway/desktop/render.c b/sway/desktop/render.c index f25055b8..ea4361f2 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c | |||
@@ -186,13 +186,36 @@ static void premultiply_alpha(float color[4], float opacity) { | |||
186 | color[2] *= color[3]; | 186 | color[2] *= color[3]; |
187 | } | 187 | } |
188 | 188 | ||
189 | static void render_view_surfaces(struct sway_view *view, | 189 | static void render_view_toplevels(struct sway_view *view, |
190 | struct sway_output *output, pixman_region32_t *damage, float alpha) { | 190 | struct sway_output *output, pixman_region32_t *damage, float alpha) { |
191 | struct render_data data = { | 191 | struct render_data data = { |
192 | .damage = damage, | 192 | .damage = damage, |
193 | .alpha = alpha, | 193 | .alpha = alpha, |
194 | }; | 194 | }; |
195 | output_view_for_each_surface(output, view, render_surface_iterator, &data); | 195 | // Render all toplevels without descending into popups |
196 | output_surface_for_each_surface(output, view->surface, | ||
197 | view->swayc->current.view_x, view->swayc->current.view_y, | ||
198 | render_surface_iterator, &data); | ||
199 | } | ||
200 | |||
201 | static void render_popup_iterator(struct sway_output *output, | ||
202 | struct wlr_surface *surface, struct wlr_box *box, float rotation, | ||
203 | void *data) { | ||
204 | // Render this popup's surface | ||
205 | render_surface_iterator(output, surface, box, rotation, data); | ||
206 | |||
207 | // Render this popup's child toplevels | ||
208 | output_surface_for_each_surface(output, surface, box->x, box->y, | ||
209 | render_surface_iterator, data); | ||
210 | } | ||
211 | |||
212 | static void render_view_popups(struct sway_view *view, | ||
213 | struct sway_output *output, pixman_region32_t *damage, float alpha) { | ||
214 | struct render_data data = { | ||
215 | .damage = damage, | ||
216 | .alpha = alpha, | ||
217 | }; | ||
218 | output_view_for_each_popup(output, view, render_popup_iterator, &data); | ||
196 | } | 219 | } |
197 | 220 | ||
198 | static void render_saved_view(struct sway_view *view, | 221 | static void render_saved_view(struct sway_view *view, |
@@ -241,7 +264,7 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage, | |||
241 | if (view->swayc->instructions->length) { | 264 | if (view->swayc->instructions->length) { |
242 | render_saved_view(view, output, damage, view->swayc->alpha); | 265 | render_saved_view(view, output, damage, view->swayc->alpha); |
243 | } else { | 266 | } else { |
244 | render_view_surfaces(view, output, damage, view->swayc->alpha); | 267 | render_view_toplevels(view, output, damage, view->swayc->alpha); |
245 | } | 268 | } |
246 | 269 | ||
247 | if (view->using_csd) { | 270 | if (view->using_csd) { |
@@ -845,7 +868,7 @@ void output_render(struct sway_output *output, struct timespec *when, | |||
845 | render_saved_view(fullscreen_con->sway_view, | 868 | render_saved_view(fullscreen_con->sway_view, |
846 | output, damage, 1.0f); | 869 | output, damage, 1.0f); |
847 | } else { | 870 | } else { |
848 | render_view_surfaces(fullscreen_con->sway_view, | 871 | render_view_toplevels(fullscreen_con->sway_view, |
849 | output, damage, 1.0f); | 872 | output, damage, 1.0f); |
850 | } | 873 | } |
851 | } else { | 874 | } else { |
@@ -881,6 +904,12 @@ void output_render(struct sway_output *output, struct timespec *when, | |||
881 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); | 904 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); |
882 | } | 905 | } |
883 | 906 | ||
907 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
908 | struct sway_container *focus = seat_get_focus(seat); | ||
909 | if (focus && focus->type == C_VIEW) { | ||
910 | render_view_popups(focus->sway_view, output, damage, focus->alpha); | ||
911 | } | ||
912 | |||
884 | render_overlay: | 913 | render_overlay: |
885 | render_layer(output, damage, | 914 | render_layer(output, damage, |
886 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); | 915 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); |
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index e6e1527e..9f94bd74 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c | |||
@@ -179,6 +179,14 @@ static void for_each_surface(struct sway_view *view, | |||
179 | user_data); | 179 | user_data); |
180 | } | 180 | } |
181 | 181 | ||
182 | static void for_each_popup(struct sway_view *view, | ||
183 | wlr_surface_iterator_func_t iterator, void *user_data) { | ||
184 | if (xdg_shell_view_from_view(view) == NULL) { | ||
185 | return; | ||
186 | } | ||
187 | wlr_xdg_surface_for_each_popup(view->wlr_xdg_surface, iterator, user_data); | ||
188 | } | ||
189 | |||
182 | static void _close(struct sway_view *view) { | 190 | static void _close(struct sway_view *view) { |
183 | if (xdg_shell_view_from_view(view) == NULL) { | 191 | if (xdg_shell_view_from_view(view) == NULL) { |
184 | return; | 192 | return; |
@@ -207,6 +215,7 @@ static const struct sway_view_impl view_impl = { | |||
207 | .set_fullscreen = set_fullscreen, | 215 | .set_fullscreen = set_fullscreen, |
208 | .wants_floating = wants_floating, | 216 | .wants_floating = wants_floating, |
209 | .for_each_surface = for_each_surface, | 217 | .for_each_surface = for_each_surface, |
218 | .for_each_popup = for_each_popup, | ||
210 | .close = _close, | 219 | .close = _close, |
211 | .destroy = destroy, | 220 | .destroy = destroy, |
212 | }; | 221 | }; |
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 5feee3e4..4502c386 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c | |||
@@ -175,6 +175,15 @@ static void for_each_surface(struct sway_view *view, | |||
175 | user_data); | 175 | user_data); |
176 | } | 176 | } |
177 | 177 | ||
178 | static void for_each_popup(struct sway_view *view, | ||
179 | wlr_surface_iterator_func_t iterator, void *user_data) { | ||
180 | if (xdg_shell_v6_view_from_view(view) == NULL) { | ||
181 | return; | ||
182 | } | ||
183 | wlr_xdg_surface_v6_for_each_popup(view->wlr_xdg_surface_v6, iterator, | ||
184 | user_data); | ||
185 | } | ||
186 | |||
178 | static void _close(struct sway_view *view) { | 187 | static void _close(struct sway_view *view) { |
179 | if (xdg_shell_v6_view_from_view(view) == NULL) { | 188 | if (xdg_shell_v6_view_from_view(view) == NULL) { |
180 | return; | 189 | return; |
@@ -203,6 +212,7 @@ static const struct sway_view_impl view_impl = { | |||
203 | .set_fullscreen = set_fullscreen, | 212 | .set_fullscreen = set_fullscreen, |
204 | .wants_floating = wants_floating, | 213 | .wants_floating = wants_floating, |
205 | .for_each_surface = for_each_surface, | 214 | .for_each_surface = for_each_surface, |
215 | .for_each_popup = for_each_popup, | ||
206 | .close = _close, | 216 | .close = _close, |
207 | .destroy = destroy, | 217 | .destroy = destroy, |
208 | }; | 218 | }; |
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 96ac7b33..ad4b1718 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -109,9 +109,6 @@ static struct sway_container *container_at_coords( | |||
109 | } | 109 | } |
110 | 110 | ||
111 | struct sway_container *c; | 111 | struct sway_container *c; |
112 | if ((c = floating_container_at(lx, ly, surface, sx, sy))) { | ||
113 | return c; | ||
114 | } | ||
115 | if ((c = container_at(ws, lx, ly, surface, sx, sy))) { | 112 | if ((c = container_at(ws, lx, ly, surface, sx, sy))) { |
116 | return c; | 113 | return c; |
117 | } | 114 | } |
diff --git a/sway/tree/container.c b/sway/tree/container.c index 4e85021d..b5fefd17 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -561,10 +561,15 @@ static struct sway_container *container_at_view(struct sway_container *swayc, | |||
561 | *sx = _sx; | 561 | *sx = _sx; |
562 | *sy = _sy; | 562 | *sy = _sy; |
563 | *surface = _surface; | 563 | *surface = _surface; |
564 | return swayc; | ||
564 | } | 565 | } |
565 | return swayc; | 566 | return NULL; |
566 | } | 567 | } |
567 | 568 | ||
569 | static struct sway_container *tiling_container_at( | ||
570 | struct sway_container *con, double lx, double ly, | ||
571 | struct wlr_surface **surface, double *sx, double *sy); | ||
572 | |||
568 | /** | 573 | /** |
569 | * container_at for a container with layout L_TABBED. | 574 | * container_at for a container with layout L_TABBED. |
570 | */ | 575 | */ |
@@ -591,7 +596,7 @@ static struct sway_container *container_at_tabbed(struct sway_container *parent, | |||
591 | // Surfaces | 596 | // Surfaces |
592 | struct sway_container *current = seat_get_active_child(seat, parent); | 597 | struct sway_container *current = seat_get_active_child(seat, parent); |
593 | 598 | ||
594 | return container_at(current, lx, ly, surface, sx, sy); | 599 | return tiling_container_at(current, lx, ly, surface, sx, sy); |
595 | } | 600 | } |
596 | 601 | ||
597 | /** | 602 | /** |
@@ -616,7 +621,7 @@ static struct sway_container *container_at_stacked( | |||
616 | // Surfaces | 621 | // Surfaces |
617 | struct sway_container *current = seat_get_active_child(seat, parent); | 622 | struct sway_container *current = seat_get_active_child(seat, parent); |
618 | 623 | ||
619 | return container_at(current, lx, ly, surface, sx, sy); | 624 | return tiling_container_at(current, lx, ly, surface, sx, sy); |
620 | } | 625 | } |
621 | 626 | ||
622 | /** | 627 | /** |
@@ -634,45 +639,13 @@ static struct sway_container *container_at_linear(struct sway_container *parent, | |||
634 | .height = child->height, | 639 | .height = child->height, |
635 | }; | 640 | }; |
636 | if (wlr_box_contains_point(&box, lx, ly)) { | 641 | if (wlr_box_contains_point(&box, lx, ly)) { |
637 | return container_at(child, lx, ly, surface, sx, sy); | 642 | return tiling_container_at(child, lx, ly, surface, sx, sy); |
638 | } | 643 | } |
639 | } | 644 | } |
640 | return NULL; | 645 | return NULL; |
641 | } | 646 | } |
642 | 647 | ||
643 | struct sway_container *container_at(struct sway_container *parent, | 648 | static struct sway_container *floating_container_at(double lx, double ly, |
644 | double lx, double ly, | ||
645 | struct wlr_surface **surface, double *sx, double *sy) { | ||
646 | if (!sway_assert(parent->type >= C_WORKSPACE, | ||
647 | "Expected workspace or deeper")) { | ||
648 | return NULL; | ||
649 | } | ||
650 | if (parent->type == C_VIEW) { | ||
651 | return container_at_view(parent, lx, ly, surface, sx, sy); | ||
652 | } | ||
653 | if (!parent->children->length) { | ||
654 | return NULL; | ||
655 | } | ||
656 | |||
657 | switch (parent->layout) { | ||
658 | case L_HORIZ: | ||
659 | case L_VERT: | ||
660 | return container_at_linear(parent, lx, ly, surface, sx, sy); | ||
661 | case L_TABBED: | ||
662 | return container_at_tabbed(parent, lx, ly, surface, sx, sy); | ||
663 | case L_STACKED: | ||
664 | return container_at_stacked(parent, lx, ly, surface, sx, sy); | ||
665 | case L_FLOATING: | ||
666 | sway_assert(false, "Didn't expect to see floating here"); | ||
667 | return NULL; | ||
668 | case L_NONE: | ||
669 | return NULL; | ||
670 | } | ||
671 | |||
672 | return NULL; | ||
673 | } | ||
674 | |||
675 | struct sway_container *floating_container_at(double lx, double ly, | ||
676 | struct wlr_surface **surface, double *sx, double *sy) { | 649 | struct wlr_surface **surface, double *sx, double *sy) { |
677 | for (int i = 0; i < root_container.children->length; ++i) { | 650 | for (int i = 0; i < root_container.children->length; ++i) { |
678 | struct sway_container *output = root_container.children->items[i]; | 651 | struct sway_container *output = root_container.children->items[i]; |
@@ -694,7 +667,8 @@ struct sway_container *floating_container_at(double lx, double ly, | |||
694 | .height = floater->height, | 667 | .height = floater->height, |
695 | }; | 668 | }; |
696 | if (wlr_box_contains_point(&box, lx, ly)) { | 669 | if (wlr_box_contains_point(&box, lx, ly)) { |
697 | return container_at(floater, lx, ly, surface, sx, sy); | 670 | return tiling_container_at(floater, lx, ly, |
671 | surface, sx, sy); | ||
698 | } | 672 | } |
699 | } | 673 | } |
700 | } | 674 | } |
@@ -702,6 +676,90 @@ struct sway_container *floating_container_at(double lx, double ly, | |||
702 | return NULL; | 676 | return NULL; |
703 | } | 677 | } |
704 | 678 | ||
679 | static struct sway_container *tiling_container_at( | ||
680 | struct sway_container *con, double lx, double ly, | ||
681 | struct wlr_surface **surface, double *sx, double *sy) { | ||
682 | if (con->type == C_VIEW) { | ||
683 | return container_at_view(con, lx, ly, surface, sx, sy); | ||
684 | } | ||
685 | if (!con->children->length) { | ||
686 | return NULL; | ||
687 | } | ||
688 | |||
689 | switch (con->layout) { | ||
690 | case L_HORIZ: | ||
691 | case L_VERT: | ||
692 | return container_at_linear(con, lx, ly, surface, sx, sy); | ||
693 | case L_TABBED: | ||
694 | return container_at_tabbed(con, lx, ly, surface, sx, sy); | ||
695 | case L_STACKED: | ||
696 | return container_at_stacked(con, lx, ly, surface, sx, sy); | ||
697 | case L_FLOATING: | ||
698 | sway_assert(false, "Didn't expect to see floating here"); | ||
699 | return NULL; | ||
700 | case L_NONE: | ||
701 | return NULL; | ||
702 | } | ||
703 | return NULL; | ||
704 | } | ||
705 | |||
706 | static bool surface_is_popup(struct wlr_surface *surface) { | ||
707 | if (wlr_surface_is_xdg_surface(surface)) { | ||
708 | struct wlr_xdg_surface *xdg_surface = | ||
709 | wlr_xdg_surface_from_wlr_surface(surface); | ||
710 | while (xdg_surface) { | ||
711 | if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { | ||
712 | return true; | ||
713 | } | ||
714 | xdg_surface = xdg_surface->toplevel->parent; | ||
715 | } | ||
716 | return false; | ||
717 | } | ||
718 | |||
719 | if (wlr_surface_is_xdg_surface_v6(surface)) { | ||
720 | struct wlr_xdg_surface_v6 *xdg_surface_v6 = | ||
721 | wlr_xdg_surface_v6_from_wlr_surface(surface); | ||
722 | while (xdg_surface_v6) { | ||
723 | if (xdg_surface_v6->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) { | ||
724 | return true; | ||
725 | } | ||
726 | xdg_surface_v6 = xdg_surface_v6->toplevel->parent; | ||
727 | } | ||
728 | return false; | ||
729 | } | ||
730 | |||
731 | return false; | ||
732 | } | ||
733 | |||
734 | struct sway_container *container_at(struct sway_container *workspace, | ||
735 | double lx, double ly, | ||
736 | struct wlr_surface **surface, double *sx, double *sy) { | ||
737 | if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) { | ||
738 | return NULL; | ||
739 | } | ||
740 | struct sway_container *c; | ||
741 | // Focused view's popups | ||
742 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
743 | struct sway_container *focus = | ||
744 | seat_get_focus_inactive(seat, &root_container); | ||
745 | if (focus && focus->type == C_VIEW) { | ||
746 | container_at_view(focus, lx, ly, surface, sx, sy); | ||
747 | if (*surface && surface_is_popup(*surface)) { | ||
748 | return focus; | ||
749 | } | ||
750 | *surface = NULL; | ||
751 | } | ||
752 | // Floating | ||
753 | if ((c = floating_container_at(lx, ly, surface, sx, sy))) { | ||
754 | return c; | ||
755 | } | ||
756 | // Tiling | ||
757 | if ((c = tiling_container_at(workspace, lx, ly, surface, sx, sy))) { | ||
758 | return c; | ||
759 | } | ||
760 | return NULL; | ||
761 | } | ||
762 | |||
705 | void container_for_each_descendant_dfs(struct sway_container *container, | 763 | void container_for_each_descendant_dfs(struct sway_container *container, |
706 | void (*f)(struct sway_container *container, void *data), | 764 | void (*f)(struct sway_container *container, void *data), |
707 | void *data) { | 765 | void *data) { |
diff --git a/sway/tree/view.c b/sway/tree/view.c index 8f54cc11..c1207821 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -332,6 +332,16 @@ void view_for_each_surface(struct sway_view *view, | |||
332 | } | 332 | } |
333 | } | 333 | } |
334 | 334 | ||
335 | void view_for_each_popup(struct sway_view *view, | ||
336 | wlr_surface_iterator_func_t iterator, void *user_data) { | ||
337 | if (!view->surface) { | ||
338 | return; | ||
339 | } | ||
340 | if (view->impl->for_each_popup) { | ||
341 | view->impl->for_each_popup(view, iterator, user_data); | ||
342 | } | ||
343 | } | ||
344 | |||
335 | static void view_subsurface_create(struct sway_view *view, | 345 | static void view_subsurface_create(struct sway_view *view, |
336 | struct wlr_subsurface *subsurface); | 346 | struct wlr_subsurface *subsurface); |
337 | 347 | ||