diff options
-rw-r--r-- | include/sway/tree/view.h | 3 | ||||
-rw-r--r-- | sway/desktop/output.c | 33 | ||||
-rw-r--r-- | sway/desktop/xdg_shell.c | 13 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 13 | ||||
-rw-r--r-- | sway/input/seat.c | 7 | ||||
-rw-r--r-- | sway/tree/view.c | 6 |
6 files changed, 44 insertions, 31 deletions
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 9f6d36fe..e722ca5e 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h | |||
@@ -50,6 +50,7 @@ struct sway_view_impl { | |||
50 | void (*for_each_popup)(struct sway_view *view, | 50 | void (*for_each_popup)(struct sway_view *view, |
51 | wlr_surface_iterator_func_t iterator, void *user_data); | 51 | wlr_surface_iterator_func_t iterator, void *user_data); |
52 | void (*close)(struct sway_view *view); | 52 | void (*close)(struct sway_view *view); |
53 | void (*close_popups)(struct sway_view *view); | ||
53 | void (*destroy)(struct sway_view *view); | 54 | void (*destroy)(struct sway_view *view); |
54 | }; | 55 | }; |
55 | 56 | ||
@@ -248,6 +249,8 @@ void view_set_tiled(struct sway_view *view, bool tiled); | |||
248 | 249 | ||
249 | void view_close(struct sway_view *view); | 250 | void view_close(struct sway_view *view); |
250 | 251 | ||
252 | void view_close_popups(struct sway_view *view); | ||
253 | |||
251 | void view_damage_from(struct sway_view *view); | 254 | void view_damage_from(struct sway_view *view); |
252 | 255 | ||
253 | /** | 256 | /** |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 4c9d978c..66747a3f 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -312,9 +312,8 @@ static void send_frame_done_container_iterator(struct sway_container *con, | |||
312 | return; | 312 | return; |
313 | } | 313 | } |
314 | 314 | ||
315 | // Toplevels only | 315 | output_view_for_each_surface(data->output, con->sway_view, |
316 | output_surface_for_each_surface(data->output, con->sway_view->surface, | 316 | send_frame_done_iterator, data->when); |
317 | con->x, con->y, send_frame_done_iterator, data->when); | ||
318 | } | 317 | } |
319 | 318 | ||
320 | static void send_frame_done_container(struct sway_output *output, | 319 | static void send_frame_done_container(struct sway_output *output, |
@@ -327,27 +326,6 @@ static void send_frame_done_container(struct sway_output *output, | |||
327 | send_frame_done_container_iterator, &data); | 326 | send_frame_done_container_iterator, &data); |
328 | } | 327 | } |
329 | 328 | ||
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 | |||
351 | static void send_frame_done(struct sway_output *output, struct timespec *when) { | 329 | static void send_frame_done(struct sway_output *output, struct timespec *when) { |
352 | if (output_has_opaque_overlay_layer_surface(output)) { | 330 | if (output_has_opaque_overlay_layer_surface(output)) { |
353 | goto send_frame_overlay; | 331 | goto send_frame_overlay; |
@@ -385,13 +363,6 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { | |||
385 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], when); | 363 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], when); |
386 | } | 364 | } |
387 | 365 | ||
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 | |||
395 | send_frame_overlay: | 366 | send_frame_overlay: |
396 | send_frame_done_layer(output, | 367 | send_frame_done_layer(output, |
397 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], when); | 368 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], when); |
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 9f94bd74..b364663d 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c | |||
@@ -197,6 +197,18 @@ static void _close(struct sway_view *view) { | |||
197 | } | 197 | } |
198 | } | 198 | } |
199 | 199 | ||
200 | static 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 | |||
207 | static 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 | |||
200 | static void destroy(struct sway_view *view) { | 212 | static void destroy(struct sway_view *view) { |
201 | struct sway_xdg_shell_view *xdg_shell_view = | 213 | struct sway_xdg_shell_view *xdg_shell_view = |
202 | xdg_shell_view_from_view(view); | 214 | xdg_shell_view_from_view(view); |
@@ -217,6 +229,7 @@ static const struct sway_view_impl view_impl = { | |||
217 | .for_each_surface = for_each_surface, | 229 | .for_each_surface = for_each_surface, |
218 | .for_each_popup = for_each_popup, | 230 | .for_each_popup = for_each_popup, |
219 | .close = _close, | 231 | .close = _close, |
232 | .close_popups = close_popups, | ||
220 | .destroy = destroy, | 233 | .destroy = destroy, |
221 | }; | 234 | }; |
222 | 235 | ||
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 4502c386..ffea03ad 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c | |||
@@ -194,6 +194,18 @@ static void _close(struct sway_view *view) { | |||
194 | } | 194 | } |
195 | } | 195 | } |
196 | 196 | ||
197 | static 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 | |||
204 | static 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 | |||
197 | static void destroy(struct sway_view *view) { | 209 | static void destroy(struct sway_view *view) { |
198 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = | 210 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = |
199 | xdg_shell_v6_view_from_view(view); | 211 | xdg_shell_v6_view_from_view(view); |
@@ -214,6 +226,7 @@ static const struct sway_view_impl view_impl = { | |||
214 | .for_each_surface = for_each_surface, | 226 | .for_each_surface = for_each_surface, |
215 | .for_each_popup = for_each_popup, | 227 | .for_each_popup = for_each_popup, |
216 | .close = _close, | 228 | .close = _close, |
229 | .close_popups = close_popups, | ||
217 | .destroy = destroy, | 230 | .destroy = destroy, |
218 | }; | 231 | }; |
219 | 232 | ||
diff --git a/sway/input/seat.c b/sway/input/seat.c index 53a92989..8ed0dce2 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 | ipc_event_workspace(last_workspace, container, "focus"); | 749 | ipc_event_workspace(last_workspace, container, "focus"); |
diff --git a/sway/tree/view.c b/sway/tree/view.c index c1207821..5d9b625f 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 | ||
305 | void view_close_popups(struct sway_view *view) { | ||
306 | if (view->impl->close_popups) { | ||
307 | view->impl->close_popups(view); | ||
308 | } | ||
309 | } | ||
310 | |||
305 | void view_damage_from(struct sway_view *view) { | 311 | void 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]; |