aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-08-01 22:02:12 -0400
committerLibravatar GitHub <noreply@github.com>2018-08-01 22:02:12 -0400
commit9564c73c0ddca9d7b45f0476fcaee8bd878d8345 (patch)
tree4405c7ab30e25c5234a61280a66d406921c52253
parentMerge pull request #2264 from ianyfan/ipc (diff)
parentClose popups when changing focus (diff)
downloadsway-9564c73c0ddca9d7b45f0476fcaee8bd878d8345.tar.gz
sway-9564c73c0ddca9d7b45f0476fcaee8bd878d8345.tar.zst
sway-9564c73c0ddca9d7b45f0476fcaee8bd878d8345.zip
Merge pull request #2391 from RyanDwyer/fix-popups-v2
Fix popups (v2)
-rw-r--r--include/sway/output.h8
-rw-r--r--include/sway/tree/container.h11
-rw-r--r--include/sway/tree/view.h14
-rw-r--r--sway/desktop/output.c19
-rw-r--r--sway/desktop/render.c37
-rw-r--r--sway/desktop/xdg_shell.c22
-rw-r--r--sway/desktop/xdg_shell_v6.c23
-rw-r--r--sway/input/cursor.c3
-rw-r--r--sway/input/seat.c7
-rw-r--r--sway/tree/container.c134
-rw-r--r--sway/tree/view.c16
11 files changed, 239 insertions, 55 deletions
diff --git a/include/sway/output.h b/include/sway/output.h
index 6283db68..80dcd37b 100644
--- a/include/sway/output.h
+++ b/include/sway/output.h
@@ -67,10 +67,18 @@ struct sway_container *output_get_active_workspace(struct sway_output *output);
67void output_render(struct sway_output *output, struct timespec *when, 67void output_render(struct sway_output *output, struct timespec *when,
68 pixman_region32_t *damage); 68 pixman_region32_t *damage);
69 69
70void output_surface_for_each_surface(struct sway_output *output,
71 struct wlr_surface *surface, double ox, double oy,
72 sway_surface_iterator_func_t iterator, void *user_data);
73
70void output_view_for_each_surface(struct sway_output *output, 74void output_view_for_each_surface(struct sway_output *output,
71 struct sway_view *view, sway_surface_iterator_func_t iterator, 75 struct sway_view *view, sway_surface_iterator_func_t iterator,
72 void *user_data); 76 void *user_data);
73 77
78void output_view_for_each_popup(struct sway_output *output,
79 struct sway_view *view, sway_surface_iterator_func_t iterator,
80 void *user_data);
81
74void output_layer_for_each_surface(struct sway_output *output, 82void output_layer_for_each_surface(struct sway_output *output,
75 struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, 83 struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator,
76 void *user_data); 84 void *user_data);
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index d4a42a71..12ff8a5a 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -230,18 +230,11 @@ struct sway_container *container_parent(struct sway_container *container,
230 * surface-local coordinates of the given layout coordinates if the container 230 * surface-local coordinates of the given layout coordinates if the container
231 * is a view and the view contains a surface at those coordinates. 231 * is a view and the view contains a surface at those coordinates.
232 */ 232 */
233struct sway_container *container_at(struct sway_container *container, 233struct sway_container *container_at(struct sway_container *workspace,
234 double ox, double oy, struct wlr_surface **surface, 234 double lx, double ly, struct wlr_surface **surface,
235 double *sx, double *sy); 235 double *sx, double *sy);
236 236
237/** 237/**
238 * Same as container_at, but only checks floating views and expects coordinates
239 * to be layout coordinates, as that's what floating views use.
240 */
241struct sway_container *floating_container_at(double lx, double ly,
242 struct wlr_surface **surface, double *sx, double *sy);
243
244/**
245 * Apply the function for each descendant of the container breadth first. 238 * Apply the function for each descendant of the container breadth first.
246 */ 239 */
247void container_for_each_descendant_bfs(struct sway_container *container, 240void container_for_each_descendant_bfs(struct sway_container *container,
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h
index 800df073..620c41e0 100644
--- a/include/sway/tree/view.h
+++ b/include/sway/tree/view.h
@@ -47,7 +47,10 @@ struct sway_view_impl {
47 bool (*has_client_side_decorations)(struct sway_view *view); 47 bool (*has_client_side_decorations)(struct sway_view *view);
48 void (*for_each_surface)(struct sway_view *view, 48 void (*for_each_surface)(struct sway_view *view,
49 wlr_surface_iterator_func_t iterator, void *user_data); 49 wlr_surface_iterator_func_t iterator, void *user_data);
50 void (*for_each_popup)(struct sway_view *view,
51 wlr_surface_iterator_func_t iterator, void *user_data);
50 void (*close)(struct sway_view *view); 52 void (*close)(struct sway_view *view);
53 void (*close_popups)(struct sway_view *view);
51 void (*destroy)(struct sway_view *view); 54 void (*destroy)(struct sway_view *view);
52}; 55};
53 56
@@ -246,11 +249,22 @@ void view_set_tiled(struct sway_view *view, bool tiled);
246 249
247void view_close(struct sway_view *view); 250void view_close(struct sway_view *view);
248 251
252void view_close_popups(struct sway_view *view);
253
249void view_damage_from(struct sway_view *view); 254void view_damage_from(struct sway_view *view);
250 255
256/**
257 * Iterate all surfaces of a view (toplevels + popups).
258 */
251void view_for_each_surface(struct sway_view *view, 259void view_for_each_surface(struct sway_view *view,
252 wlr_surface_iterator_func_t iterator, void *user_data); 260 wlr_surface_iterator_func_t iterator, void *user_data);
253 261
262/**
263 * Iterate all popups recursively.
264 */
265void view_for_each_popup(struct sway_view *view,
266 wlr_surface_iterator_func_t iterator, void *user_data);
267
254// view implementation 268// view implementation
255 269
256void view_init(struct sway_view *view, enum sway_view_type type, 270void view_init(struct sway_view *view, enum sway_view_type type,
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 31b53213..66747a3f 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) {
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
189static void render_view_surfaces(struct sway_view *view, 189static 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
201static 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
212static 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
198static void render_saved_view(struct sway_view *view, 221static 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
884render_overlay: 913render_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..b364663d 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
182static 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
182static void _close(struct sway_view *view) { 190static 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;
@@ -189,6 +197,18 @@ static void _close(struct sway_view *view) {
189 } 197 }
190} 198}
191 199
200static void close_popups_iterator(struct wlr_surface *surface,
201 int sx, int sy, void *data) {
202 struct wlr_xdg_surface *xdg_surface =
203 wlr_xdg_surface_from_wlr_surface(surface);
204 wlr_xdg_surface_send_close(xdg_surface);
205}
206
207static void close_popups(struct sway_view *view) {
208 wlr_xdg_surface_for_each_popup(view->wlr_xdg_surface,
209 close_popups_iterator, NULL);
210}
211
192static void destroy(struct sway_view *view) { 212static void destroy(struct sway_view *view) {
193 struct sway_xdg_shell_view *xdg_shell_view = 213 struct sway_xdg_shell_view *xdg_shell_view =
194 xdg_shell_view_from_view(view); 214 xdg_shell_view_from_view(view);
@@ -207,7 +227,9 @@ static const struct sway_view_impl view_impl = {
207 .set_fullscreen = set_fullscreen, 227 .set_fullscreen = set_fullscreen,
208 .wants_floating = wants_floating, 228 .wants_floating = wants_floating,
209 .for_each_surface = for_each_surface, 229 .for_each_surface = for_each_surface,
230 .for_each_popup = for_each_popup,
210 .close = _close, 231 .close = _close,
232 .close_popups = close_popups,
211 .destroy = destroy, 233 .destroy = destroy,
212}; 234};
213 235
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c
index 5feee3e4..ffea03ad 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
178static 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
178static void _close(struct sway_view *view) { 187static 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;
@@ -185,6 +194,18 @@ static void _close(struct sway_view *view) {
185 } 194 }
186} 195}
187 196
197static void close_popups_iterator(struct wlr_surface *surface,
198 int sx, int sy, void *data) {
199 struct wlr_xdg_surface_v6 *xdg_surface_v6 =
200 wlr_xdg_surface_v6_from_wlr_surface(surface);
201 wlr_xdg_surface_v6_send_close(xdg_surface_v6);
202}
203
204static void close_popups(struct sway_view *view) {
205 wlr_xdg_surface_v6_for_each_popup(view->wlr_xdg_surface_v6,
206 close_popups_iterator, NULL);
207}
208
188static void destroy(struct sway_view *view) { 209static void destroy(struct sway_view *view) {
189 struct sway_xdg_shell_v6_view *xdg_shell_v6_view = 210 struct sway_xdg_shell_v6_view *xdg_shell_v6_view =
190 xdg_shell_v6_view_from_view(view); 211 xdg_shell_v6_view_from_view(view);
@@ -203,7 +224,9 @@ static const struct sway_view_impl view_impl = {
203 .set_fullscreen = set_fullscreen, 224 .set_fullscreen = set_fullscreen,
204 .wants_floating = wants_floating, 225 .wants_floating = wants_floating,
205 .for_each_surface = for_each_surface, 226 .for_each_surface = for_each_surface,
227 .for_each_popup = for_each_popup,
206 .close = _close, 228 .close = _close,
229 .close_popups = close_popups,
207 .destroy = destroy, 230 .destroy = destroy,
208}; 231};
209 232
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index d6fdc1da..79f6ec46 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/input/seat.c b/sway/input/seat.c
index fe3cbc53..869560af 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -737,6 +737,13 @@ void seat_set_focus_warp(struct sway_seat *seat,
737 } 737 }
738 } 738 }
739 739
740 // Close any popups on the old focus
741 if (last_focus && last_focus != container) {
742 if (last_focus->type == C_VIEW) {
743 view_close_popups(last_focus->sway_view);
744 }
745 }
746
740 if (last_focus) { 747 if (last_focus) {
741 if (last_workspace) { 748 if (last_workspace) {
742 if (notify && last_workspace != new_workspace) { 749 if (notify && last_workspace != new_workspace) {
diff --git a/sway/tree/container.c b/sway/tree/container.c
index b6ff4d30..b980c5e9 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -569,10 +569,15 @@ static struct sway_container *container_at_view(struct sway_container *swayc,
569 *sx = _sx; 569 *sx = _sx;
570 *sy = _sy; 570 *sy = _sy;
571 *surface = _surface; 571 *surface = _surface;
572 return swayc;
572 } 573 }
573 return swayc; 574 return NULL;
574} 575}
575 576
577static struct sway_container *tiling_container_at(
578 struct sway_container *con, double lx, double ly,
579 struct wlr_surface **surface, double *sx, double *sy);
580
576/** 581/**
577 * container_at for a container with layout L_TABBED. 582 * container_at for a container with layout L_TABBED.
578 */ 583 */
@@ -599,7 +604,7 @@ static struct sway_container *container_at_tabbed(struct sway_container *parent,
599 // Surfaces 604 // Surfaces
600 struct sway_container *current = seat_get_active_child(seat, parent); 605 struct sway_container *current = seat_get_active_child(seat, parent);
601 606
602 return container_at(current, lx, ly, surface, sx, sy); 607 return tiling_container_at(current, lx, ly, surface, sx, sy);
603} 608}
604 609
605/** 610/**
@@ -624,7 +629,7 @@ static struct sway_container *container_at_stacked(
624 // Surfaces 629 // Surfaces
625 struct sway_container *current = seat_get_active_child(seat, parent); 630 struct sway_container *current = seat_get_active_child(seat, parent);
626 631
627 return container_at(current, lx, ly, surface, sx, sy); 632 return tiling_container_at(current, lx, ly, surface, sx, sy);
628} 633}
629 634
630/** 635/**
@@ -642,45 +647,13 @@ static struct sway_container *container_at_linear(struct sway_container *parent,
642 .height = child->height, 647 .height = child->height,
643 }; 648 };
644 if (wlr_box_contains_point(&box, lx, ly)) { 649 if (wlr_box_contains_point(&box, lx, ly)) {
645 return container_at(child, lx, ly, surface, sx, sy); 650 return tiling_container_at(child, lx, ly, surface, sx, sy);
646 } 651 }
647 } 652 }
648 return NULL; 653 return NULL;
649} 654}
650 655
651struct sway_container *container_at(struct sway_container *parent, 656static struct sway_container *floating_container_at(double lx, double ly,
652 double lx, double ly,
653 struct wlr_surface **surface, double *sx, double *sy) {
654 if (!sway_assert(parent->type >= C_WORKSPACE,
655 "Expected workspace or deeper")) {
656 return NULL;
657 }
658 if (parent->type == C_VIEW) {
659 return container_at_view(parent, lx, ly, surface, sx, sy);
660 }
661 if (!parent->children->length) {
662 return NULL;
663 }
664
665 switch (parent->layout) {
666 case L_HORIZ:
667 case L_VERT:
668 return container_at_linear(parent, lx, ly, surface, sx, sy);
669 case L_TABBED:
670 return container_at_tabbed(parent, lx, ly, surface, sx, sy);
671 case L_STACKED:
672 return container_at_stacked(parent, lx, ly, surface, sx, sy);
673 case L_FLOATING:
674 sway_assert(false, "Didn't expect to see floating here");
675 return NULL;
676 case L_NONE:
677 return NULL;
678 }
679
680 return NULL;
681}
682
683struct sway_container *floating_container_at(double lx, double ly,
684 struct wlr_surface **surface, double *sx, double *sy) { 657 struct wlr_surface **surface, double *sx, double *sy) {
685 for (int i = 0; i < root_container.children->length; ++i) { 658 for (int i = 0; i < root_container.children->length; ++i) {
686 struct sway_container *output = root_container.children->items[i]; 659 struct sway_container *output = root_container.children->items[i];
@@ -702,7 +675,8 @@ struct sway_container *floating_container_at(double lx, double ly,
702 .height = floater->height, 675 .height = floater->height,
703 }; 676 };
704 if (wlr_box_contains_point(&box, lx, ly)) { 677 if (wlr_box_contains_point(&box, lx, ly)) {
705 return container_at(floater, lx, ly, surface, sx, sy); 678 return tiling_container_at(floater, lx, ly,
679 surface, sx, sy);
706 } 680 }
707 } 681 }
708 } 682 }
@@ -710,6 +684,90 @@ struct sway_container *floating_container_at(double lx, double ly,
710 return NULL; 684 return NULL;
711} 685}
712 686
687static struct sway_container *tiling_container_at(
688 struct sway_container *con, double lx, double ly,
689 struct wlr_surface **surface, double *sx, double *sy) {
690 if (con->type == C_VIEW) {
691 return container_at_view(con, lx, ly, surface, sx, sy);
692 }
693 if (!con->children->length) {
694 return NULL;
695 }
696
697 switch (con->layout) {
698 case L_HORIZ:
699 case L_VERT:
700 return container_at_linear(con, lx, ly, surface, sx, sy);
701 case L_TABBED:
702 return container_at_tabbed(con, lx, ly, surface, sx, sy);
703 case L_STACKED:
704 return container_at_stacked(con, lx, ly, surface, sx, sy);
705 case L_FLOATING:
706 sway_assert(false, "Didn't expect to see floating here");
707 return NULL;
708 case L_NONE:
709 return NULL;
710 }
711 return NULL;
712}
713
714static bool surface_is_popup(struct wlr_surface *surface) {
715 if (wlr_surface_is_xdg_surface(surface)) {
716 struct wlr_xdg_surface *xdg_surface =
717 wlr_xdg_surface_from_wlr_surface(surface);
718 while (xdg_surface) {
719 if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
720 return true;
721 }
722 xdg_surface = xdg_surface->toplevel->parent;
723 }
724 return false;
725 }
726
727 if (wlr_surface_is_xdg_surface_v6(surface)) {
728 struct wlr_xdg_surface_v6 *xdg_surface_v6 =
729 wlr_xdg_surface_v6_from_wlr_surface(surface);
730 while (xdg_surface_v6) {
731 if (xdg_surface_v6->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) {
732 return true;
733 }
734 xdg_surface_v6 = xdg_surface_v6->toplevel->parent;
735 }
736 return false;
737 }
738
739 return false;
740}
741
742struct sway_container *container_at(struct sway_container *workspace,
743 double lx, double ly,
744 struct wlr_surface **surface, double *sx, double *sy) {
745 if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) {
746 return NULL;
747 }
748 struct sway_container *c;
749 // Focused view's popups
750 struct sway_seat *seat = input_manager_current_seat(input_manager);
751 struct sway_container *focus =
752 seat_get_focus_inactive(seat, &root_container);
753 if (focus && focus->type == C_VIEW) {
754 container_at_view(focus, lx, ly, surface, sx, sy);
755 if (*surface && surface_is_popup(*surface)) {
756 return focus;
757 }
758 *surface = NULL;
759 }
760 // Floating
761 if ((c = floating_container_at(lx, ly, surface, sx, sy))) {
762 return c;
763 }
764 // Tiling
765 if ((c = tiling_container_at(workspace, lx, ly, surface, sx, sy))) {
766 return c;
767 }
768 return NULL;
769}
770
713void container_for_each_descendant_dfs(struct sway_container *container, 771void container_for_each_descendant_dfs(struct sway_container *container,
714 void (*f)(struct sway_container *container, void *data), 772 void (*f)(struct sway_container *container, void *data),
715 void *data) { 773 void *data) {
diff --git a/sway/tree/view.c b/sway/tree/view.c
index 48b39e80..02a33c10 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -302,6 +302,12 @@ void view_close(struct sway_view *view) {
302 } 302 }
303} 303}
304 304
305void view_close_popups(struct sway_view *view) {
306 if (view->impl->close_popups) {
307 view->impl->close_popups(view);
308 }
309}
310
305void view_damage_from(struct sway_view *view) { 311void view_damage_from(struct sway_view *view) {
306 for (int i = 0; i < root_container.children->length; ++i) { 312 for (int i = 0; i < root_container.children->length; ++i) {
307 struct sway_container *cont = root_container.children->items[i]; 313 struct sway_container *cont = root_container.children->items[i];
@@ -332,6 +338,16 @@ void view_for_each_surface(struct sway_view *view,
332 } 338 }
333} 339}
334 340
341void view_for_each_popup(struct sway_view *view,
342 wlr_surface_iterator_func_t iterator, void *user_data) {
343 if (!view->surface) {
344 return;
345 }
346 if (view->impl->for_each_popup) {
347 view->impl->for_each_popup(view, iterator, user_data);
348 }
349}
350
335static void view_subsurface_create(struct sway_view *view, 351static void view_subsurface_create(struct sway_view *view,
336 struct wlr_subsurface *subsurface); 352 struct wlr_subsurface *subsurface);
337 353