diff options
-rw-r--r-- | include/sway/commands.h | 1 | ||||
-rw-r--r-- | include/sway/config.h | 7 | ||||
-rw-r--r-- | include/sway/tree/container.h | 3 | ||||
-rw-r--r-- | include/sway/tree/view.h | 4 | ||||
-rw-r--r-- | sway/commands.c | 1 | ||||
-rw-r--r-- | sway/commands/popup_during_fullscreen.c | 25 | ||||
-rw-r--r-- | sway/config.c | 1 | ||||
-rw-r--r-- | sway/desktop/output.c | 8 | ||||
-rw-r--r-- | sway/desktop/render.c | 8 | ||||
-rw-r--r-- | sway/desktop/xdg_shell.c | 17 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 16 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 17 | ||||
-rw-r--r-- | sway/input/cursor.c | 12 | ||||
-rw-r--r-- | sway/input/seat.c | 5 | ||||
-rw-r--r-- | sway/meson.build | 1 | ||||
-rw-r--r-- | sway/sway.5.scd | 6 | ||||
-rw-r--r-- | sway/tree/container.c | 7 | ||||
-rw-r--r-- | sway/tree/view.c | 23 |
18 files changed, 160 insertions, 2 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h index 21b8b87a..48228a98 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h | |||
@@ -154,6 +154,7 @@ sway_cmd cmd_new_window; | |||
154 | sway_cmd cmd_no_focus; | 154 | sway_cmd cmd_no_focus; |
155 | sway_cmd cmd_output; | 155 | sway_cmd cmd_output; |
156 | sway_cmd cmd_permit; | 156 | sway_cmd cmd_permit; |
157 | sway_cmd cmd_popup_during_fullscreen; | ||
157 | sway_cmd cmd_reject; | 158 | sway_cmd cmd_reject; |
158 | sway_cmd cmd_reload; | 159 | sway_cmd cmd_reload; |
159 | sway_cmd cmd_rename; | 160 | sway_cmd cmd_rename; |
diff --git a/include/sway/config.h b/include/sway/config.h index 0e51fbfb..00b5f25b 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -256,6 +256,12 @@ enum edge_border_types { | |||
256 | E_SMART_NO_GAPS, /**< hide both if one window and gaps to edge is zero */ | 256 | E_SMART_NO_GAPS, /**< hide both if one window and gaps to edge is zero */ |
257 | }; | 257 | }; |
258 | 258 | ||
259 | enum sway_popup_during_fullscreen { | ||
260 | POPUP_SMART, | ||
261 | POPUP_IGNORE, | ||
262 | POPUP_LEAVE, | ||
263 | }; | ||
264 | |||
259 | enum command_context { | 265 | enum command_context { |
260 | CONTEXT_CONFIG = 1, | 266 | CONTEXT_CONFIG = 1, |
261 | CONTEXT_BINDING = 2, | 267 | CONTEXT_BINDING = 2, |
@@ -355,6 +361,7 @@ struct sway_config { | |||
355 | bool pango_markup; | 361 | bool pango_markup; |
356 | size_t urgent_timeout; | 362 | size_t urgent_timeout; |
357 | enum sway_fowa focus_on_window_activation; | 363 | enum sway_fowa focus_on_window_activation; |
364 | enum sway_popup_during_fullscreen popup_during_fullscreen; | ||
358 | 365 | ||
359 | // Flags | 366 | // Flags |
360 | bool focus_follows_mouse; | 367 | bool focus_follows_mouse; |
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index da6592b4..920ef038 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h | |||
@@ -292,4 +292,7 @@ bool sway_dir_to_wlr(enum movement_direction dir, enum wlr_direction *out); | |||
292 | struct sway_container *container_split(struct sway_container *child, | 292 | struct sway_container *container_split(struct sway_container *child, |
293 | enum sway_container_layout layout); | 293 | enum sway_container_layout layout); |
294 | 294 | ||
295 | bool container_is_transient_for(struct sway_container *child, | ||
296 | struct sway_container *ancestor); | ||
297 | |||
295 | #endif | 298 | #endif |
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 028be536..eb1e98e1 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h | |||
@@ -49,6 +49,8 @@ struct sway_view_impl { | |||
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, | 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 | bool (*is_transient_for)(struct sway_view *child, | ||
53 | struct sway_view *ancestor); | ||
52 | void (*close)(struct sway_view *view); | 54 | void (*close)(struct sway_view *view); |
53 | void (*close_popups)(struct sway_view *view); | 55 | void (*close_popups)(struct sway_view *view); |
54 | void (*destroy)(struct sway_view *view); | 56 | void (*destroy)(struct sway_view *view); |
@@ -396,4 +398,6 @@ void view_remove_saved_buffer(struct sway_view *view); | |||
396 | 398 | ||
397 | void view_save_buffer(struct sway_view *view); | 399 | void view_save_buffer(struct sway_view *view); |
398 | 400 | ||
401 | bool view_is_transient_for(struct sway_view *child, struct sway_view *ancestor); | ||
402 | |||
399 | #endif | 403 | #endif |
diff --git a/sway/commands.c b/sway/commands.c index 780cd7d6..8db1df01 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -109,6 +109,7 @@ static struct cmd_handler handlers[] = { | |||
109 | { "new_window", cmd_default_border }, | 109 | { "new_window", cmd_default_border }, |
110 | { "no_focus", cmd_no_focus }, | 110 | { "no_focus", cmd_no_focus }, |
111 | { "output", cmd_output }, | 111 | { "output", cmd_output }, |
112 | { "popup_during_fullscreen", cmd_popup_during_fullscreen }, | ||
112 | { "raise_floating", cmd_raise_floating }, | 113 | { "raise_floating", cmd_raise_floating }, |
113 | { "seat", cmd_seat }, | 114 | { "seat", cmd_seat }, |
114 | { "set", cmd_set }, | 115 | { "set", cmd_set }, |
diff --git a/sway/commands/popup_during_fullscreen.c b/sway/commands/popup_during_fullscreen.c new file mode 100644 index 00000000..da1904b6 --- /dev/null +++ b/sway/commands/popup_during_fullscreen.c | |||
@@ -0,0 +1,25 @@ | |||
1 | #include <strings.h> | ||
2 | #include "sway/commands.h" | ||
3 | #include "sway/config.h" | ||
4 | |||
5 | struct cmd_results *cmd_popup_during_fullscreen(int argc, char **argv) { | ||
6 | struct cmd_results *error = NULL; | ||
7 | if ((error = checkarg(argc, "popup_during_fullscreen", | ||
8 | EXPECTED_EQUAL_TO, 1))) { | ||
9 | return error; | ||
10 | } | ||
11 | |||
12 | if (strcasecmp(argv[0], "smart") == 0) { | ||
13 | config->popup_during_fullscreen = POPUP_SMART; | ||
14 | } else if (strcasecmp(argv[0], "ignore") == 0) { | ||
15 | config->popup_during_fullscreen = POPUP_IGNORE; | ||
16 | } else if (strcasecmp(argv[0], "leave_fullscreen") == 0) { | ||
17 | config->popup_during_fullscreen = POPUP_LEAVE; | ||
18 | } else { | ||
19 | return cmd_results_new(CMD_INVALID, "popup_during_fullscreen", | ||
20 | "Expected " | ||
21 | "'popup_during_fullscreen smart|ignore|leave_fullscreen'"); | ||
22 | } | ||
23 | |||
24 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
25 | } | ||
diff --git a/sway/config.c b/sway/config.c index e95c7b35..a50e9144 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -214,6 +214,7 @@ static void config_defaults(struct sway_config *config) { | |||
214 | if (!(config->font = strdup("monospace 10"))) goto cleanup; | 214 | if (!(config->font = strdup("monospace 10"))) goto cleanup; |
215 | config->font_height = 17; // height of monospace 10 | 215 | config->font_height = 17; // height of monospace 10 |
216 | config->urgent_timeout = 500; | 216 | config->urgent_timeout = 500; |
217 | config->popup_during_fullscreen = POPUP_SMART; | ||
217 | 218 | ||
218 | // floating view | 219 | // floating view |
219 | config->floating_maximum_width = 0; | 220 | config->floating_maximum_width = 0; |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index cfb5a710..adc1ee10 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -329,6 +329,14 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { | |||
329 | workspace->current.fullscreen, &data); | 329 | workspace->current.fullscreen, &data); |
330 | container_for_each_child(workspace->current.fullscreen, | 330 | container_for_each_child(workspace->current.fullscreen, |
331 | send_frame_done_container_iterator, &data); | 331 | send_frame_done_container_iterator, &data); |
332 | for (int i = 0; i < workspace->current.floating->length; ++i) { | ||
333 | struct sway_container *floater = | ||
334 | workspace->current.floating->items[i]; | ||
335 | if (container_is_transient_for(floater, | ||
336 | workspace->current.fullscreen)) { | ||
337 | send_frame_done_container_iterator(floater, &data); | ||
338 | } | ||
339 | } | ||
332 | #ifdef HAVE_XWAYLAND | 340 | #ifdef HAVE_XWAYLAND |
333 | send_frame_done_unmanaged(output, &root->xwayland_unmanaged, when); | 341 | send_frame_done_unmanaged(output, &root->xwayland_unmanaged, when); |
334 | #endif | 342 | #endif |
diff --git a/sway/desktop/render.c b/sway/desktop/render.c index c8b08a58..3617da87 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c | |||
@@ -961,6 +961,14 @@ void output_render(struct sway_output *output, struct timespec *when, | |||
961 | render_container(output, damage, fullscreen_con, | 961 | render_container(output, damage, fullscreen_con, |
962 | fullscreen_con->current.focused); | 962 | fullscreen_con->current.focused); |
963 | } | 963 | } |
964 | |||
965 | for (int i = 0; i < workspace->current.floating->length; ++i) { | ||
966 | struct sway_container *floater = | ||
967 | workspace->current.floating->items[i]; | ||
968 | if (container_is_transient_for(floater, fullscreen_con)) { | ||
969 | render_floating_container(output, damage, floater); | ||
970 | } | ||
971 | } | ||
964 | #ifdef HAVE_XWAYLAND | 972 | #ifdef HAVE_XWAYLAND |
965 | render_unmanaged(output, damage, &root->xwayland_unmanaged); | 973 | render_unmanaged(output, damage, &root->xwayland_unmanaged); |
966 | #endif | 974 | #endif |
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index a8b527a7..4690a3c5 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c | |||
@@ -192,6 +192,21 @@ static void for_each_popup(struct sway_view *view, | |||
192 | wlr_xdg_surface_for_each_popup(view->wlr_xdg_surface, iterator, user_data); | 192 | wlr_xdg_surface_for_each_popup(view->wlr_xdg_surface, iterator, user_data); |
193 | } | 193 | } |
194 | 194 | ||
195 | static bool is_transient_for(struct sway_view *child, | ||
196 | struct sway_view *ancestor) { | ||
197 | if (xdg_shell_view_from_view(child) == NULL) { | ||
198 | return false; | ||
199 | } | ||
200 | struct wlr_xdg_surface *surface = child->wlr_xdg_surface; | ||
201 | while (surface) { | ||
202 | if (surface->toplevel->parent == ancestor->wlr_xdg_surface) { | ||
203 | return true; | ||
204 | } | ||
205 | surface = surface->toplevel->parent; | ||
206 | } | ||
207 | return false; | ||
208 | } | ||
209 | |||
195 | static void _close(struct sway_view *view) { | 210 | static void _close(struct sway_view *view) { |
196 | if (xdg_shell_view_from_view(view) == NULL) { | 211 | if (xdg_shell_view_from_view(view) == NULL) { |
197 | return; | 212 | return; |
@@ -233,6 +248,7 @@ static const struct sway_view_impl view_impl = { | |||
233 | .wants_floating = wants_floating, | 248 | .wants_floating = wants_floating, |
234 | .for_each_surface = for_each_surface, | 249 | .for_each_surface = for_each_surface, |
235 | .for_each_popup = for_each_popup, | 250 | .for_each_popup = for_each_popup, |
251 | .is_transient_for = is_transient_for, | ||
236 | .close = _close, | 252 | .close = _close, |
237 | .close_popups = close_popups, | 253 | .close_popups = close_popups, |
238 | .destroy = destroy, | 254 | .destroy = destroy, |
@@ -395,6 +411,7 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
395 | arrange_workspace(view->container->workspace); | 411 | arrange_workspace(view->container->workspace); |
396 | } | 412 | } |
397 | } | 413 | } |
414 | |||
398 | transaction_commit_dirty(); | 415 | transaction_commit_dirty(); |
399 | 416 | ||
400 | xdg_shell_view->commit.notify = handle_commit; | 417 | xdg_shell_view->commit.notify = handle_commit; |
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index a7838c0f..ff950c70 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c | |||
@@ -189,6 +189,21 @@ static void for_each_popup(struct sway_view *view, | |||
189 | user_data); | 189 | user_data); |
190 | } | 190 | } |
191 | 191 | ||
192 | static bool is_transient_for(struct sway_view *child, | ||
193 | struct sway_view *ancestor) { | ||
194 | if (xdg_shell_v6_view_from_view(child) == NULL) { | ||
195 | return false; | ||
196 | } | ||
197 | struct wlr_xdg_surface_v6 *surface = child->wlr_xdg_surface_v6; | ||
198 | while (surface) { | ||
199 | if (surface->toplevel->parent == ancestor->wlr_xdg_surface_v6) { | ||
200 | return true; | ||
201 | } | ||
202 | surface = surface->toplevel->parent; | ||
203 | } | ||
204 | return false; | ||
205 | } | ||
206 | |||
192 | static void _close(struct sway_view *view) { | 207 | static void _close(struct sway_view *view) { |
193 | if (xdg_shell_v6_view_from_view(view) == NULL) { | 208 | if (xdg_shell_v6_view_from_view(view) == NULL) { |
194 | return; | 209 | return; |
@@ -230,6 +245,7 @@ static const struct sway_view_impl view_impl = { | |||
230 | .wants_floating = wants_floating, | 245 | .wants_floating = wants_floating, |
231 | .for_each_surface = for_each_surface, | 246 | .for_each_surface = for_each_surface, |
232 | .for_each_popup = for_each_popup, | 247 | .for_each_popup = for_each_popup, |
248 | .is_transient_for = is_transient_for, | ||
233 | .close = _close, | 249 | .close = _close, |
234 | .close_popups = close_popups, | 250 | .close_popups = close_popups, |
235 | .destroy = destroy, | 251 | .destroy = destroy, |
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 4c710f7e..ebf2131e 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include "sway/tree/arrange.h" | 15 | #include "sway/tree/arrange.h" |
16 | #include "sway/tree/container.h" | 16 | #include "sway/tree/container.h" |
17 | #include "sway/tree/view.h" | 17 | #include "sway/tree/view.h" |
18 | #include "sway/tree/workspace.h" | ||
18 | 19 | ||
19 | static const char *atom_map[ATOM_LAST] = { | 20 | static const char *atom_map[ATOM_LAST] = { |
20 | "_NET_WM_WINDOW_TYPE_NORMAL", | 21 | "_NET_WM_WINDOW_TYPE_NORMAL", |
@@ -253,6 +254,21 @@ static void handle_set_decorations(struct wl_listener *listener, void *data) { | |||
253 | view_update_csd_from_client(view, csd); | 254 | view_update_csd_from_client(view, csd); |
254 | } | 255 | } |
255 | 256 | ||
257 | static bool is_transient_for(struct sway_view *child, | ||
258 | struct sway_view *ancestor) { | ||
259 | if (xwayland_view_from_view(child) == NULL) { | ||
260 | return false; | ||
261 | } | ||
262 | struct wlr_xwayland_surface *surface = child->wlr_xwayland_surface; | ||
263 | while (surface) { | ||
264 | if (surface->parent == ancestor->wlr_xwayland_surface) { | ||
265 | return true; | ||
266 | } | ||
267 | surface = surface->parent; | ||
268 | } | ||
269 | return false; | ||
270 | } | ||
271 | |||
256 | static void _close(struct sway_view *view) { | 272 | static void _close(struct sway_view *view) { |
257 | if (xwayland_view_from_view(view) == NULL) { | 273 | if (xwayland_view_from_view(view) == NULL) { |
258 | return; | 274 | return; |
@@ -276,6 +292,7 @@ static const struct sway_view_impl view_impl = { | |||
276 | .set_tiled = set_tiled, | 292 | .set_tiled = set_tiled, |
277 | .set_fullscreen = set_fullscreen, | 293 | .set_fullscreen = set_fullscreen, |
278 | .wants_floating = wants_floating, | 294 | .wants_floating = wants_floating, |
295 | .is_transient_for = is_transient_for, | ||
279 | .close = _close, | 296 | .close = _close, |
280 | .destroy = destroy, | 297 | .destroy = destroy, |
281 | }; | 298 | }; |
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 331c6c7e..6d57c45f 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -98,6 +98,18 @@ static struct sway_node *node_at_coords( | |||
98 | return NULL; | 98 | return NULL; |
99 | } | 99 | } |
100 | if (ws->fullscreen) { | 100 | if (ws->fullscreen) { |
101 | // Try transient containers | ||
102 | for (int i = 0; i < ws->floating->length; ++i) { | ||
103 | struct sway_container *floater = ws->floating->items[i]; | ||
104 | if (container_is_transient_for(floater, ws->fullscreen)) { | ||
105 | struct sway_container *con = tiling_container_at( | ||
106 | &floater->node, lx, ly, surface, sx, sy); | ||
107 | if (con) { | ||
108 | return &con->node; | ||
109 | } | ||
110 | } | ||
111 | } | ||
112 | // Try fullscreen container | ||
101 | struct sway_container *con = | 113 | struct sway_container *con = |
102 | tiling_container_at(&ws->fullscreen->node, lx, ly, surface, sx, sy); | 114 | tiling_container_at(&ws->fullscreen->node, lx, ly, surface, sx, sy); |
103 | if (con) { | 115 | if (con) { |
diff --git a/sway/input/seat.c b/sway/input/seat.c index f5cb2f9e..f418785d 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -655,7 +655,10 @@ void seat_set_focus_warp(struct sway_seat *seat, struct sway_node *node, | |||
655 | // Deny setting focus to a view which is hidden by a fullscreen container | 655 | // Deny setting focus to a view which is hidden by a fullscreen container |
656 | if (new_workspace && new_workspace->fullscreen && container && | 656 | if (new_workspace && new_workspace->fullscreen && container && |
657 | !container_is_fullscreen_or_child(container)) { | 657 | !container_is_fullscreen_or_child(container)) { |
658 | return; | 658 | // Unless it's a transient container |
659 | if (!container_is_transient_for(container, new_workspace->fullscreen)) { | ||
660 | return; | ||
661 | } | ||
659 | } | 662 | } |
660 | 663 | ||
661 | struct sway_output *last_output = last_workspace ? | 664 | struct sway_output *last_output = last_workspace ? |
diff --git a/sway/meson.build b/sway/meson.build index 8ab28869..c7fc9697 100644 --- a/sway/meson.build +++ b/sway/meson.build | |||
@@ -70,6 +70,7 @@ sway_sources = files( | |||
70 | 'commands/no_focus.c', | 70 | 'commands/no_focus.c', |
71 | 'commands/nop.c', | 71 | 'commands/nop.c', |
72 | 'commands/output.c', | 72 | 'commands/output.c', |
73 | 'commands/popup_during_fullscreen.c', | ||
73 | 'commands/reload.c', | 74 | 'commands/reload.c', |
74 | 'commands/rename.c', | 75 | 'commands/rename.c', |
75 | 'commands/resize.c', | 76 | 'commands/resize.c', |
diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 43f0e132..28ab15df 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd | |||
@@ -555,6 +555,12 @@ You may combine output commands into one, like so: | |||
555 | You can get a list of output names with *swaymsg -t get\_outputs*. You may also | 555 | You can get a list of output names with *swaymsg -t get\_outputs*. You may also |
556 | match any output by using the output name "\*". | 556 | match any output by using the output name "\*". |
557 | 557 | ||
558 | *popup\_during\_fullscreen* smart|ignore|leave\_fullscreen | ||
559 | Determines what to do when a fullscreen view opens a dialog. | ||
560 | If _smart_ (the default), the dialog will be displayed. If _ignore_, the | ||
561 | dialog will not be rendered. If _leave\_fullscreen_, the view will exit | ||
562 | fullscreen mode and the dialog will be rendered. | ||
563 | |||
558 | *set* $<name> <value> | 564 | *set* $<name> <value> |
559 | Sets variable $_name_ to _value_. You can use the new variable in the | 565 | Sets variable $_name_ to _value_. You can use the new variable in the |
560 | arguments of future commands. When the variable is used, it can be escaped | 566 | arguments of future commands. When the variable is used, it can be escaped |
diff --git a/sway/tree/container.c b/sway/tree/container.c index 9db7aed1..1664514a 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -1212,3 +1212,10 @@ struct sway_container *container_split(struct sway_container *child, | |||
1212 | 1212 | ||
1213 | return cont; | 1213 | return cont; |
1214 | } | 1214 | } |
1215 | |||
1216 | bool container_is_transient_for(struct sway_container *child, | ||
1217 | struct sway_container *ancestor) { | ||
1218 | return config->popup_during_fullscreen == POPUP_SMART && | ||
1219 | child->view && ancestor->view && | ||
1220 | view_is_transient_for(child->view, ancestor->view); | ||
1221 | } | ||
diff --git a/sway/tree/view.c b/sway/tree/view.c index 73ce55ac..97525d6b 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -575,6 +575,16 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { | |||
575 | view_set_tiled(view, true); | 575 | view_set_tiled(view, true); |
576 | } | 576 | } |
577 | 577 | ||
578 | if (config->popup_during_fullscreen == POPUP_LEAVE && | ||
579 | view->container->workspace && | ||
580 | view->container->workspace->fullscreen && | ||
581 | view->container->workspace->fullscreen->view) { | ||
582 | struct sway_container *fs = view->container->workspace->fullscreen; | ||
583 | if (view_is_transient_for(view, fs->view)) { | ||
584 | container_set_fullscreen(fs, false); | ||
585 | } | ||
586 | } | ||
587 | |||
578 | if (should_focus(view)) { | 588 | if (should_focus(view)) { |
579 | input_manager_set_focus(input_manager, &view->container->node); | 589 | input_manager_set_focus(input_manager, &view->container->node); |
580 | } | 590 | } |
@@ -1042,7 +1052,12 @@ bool view_is_visible(struct sway_view *view) { | |||
1042 | // Check view isn't hidden by another fullscreen view | 1052 | // Check view isn't hidden by another fullscreen view |
1043 | if (workspace->fullscreen && | 1053 | if (workspace->fullscreen && |
1044 | !container_is_fullscreen_or_child(view->container)) { | 1054 | !container_is_fullscreen_or_child(view->container)) { |
1045 | return false; | 1055 | // However, if we're transient for the fullscreen view and we allow |
1056 | // "popups" during fullscreen then it might be visible | ||
1057 | if (!container_is_transient_for(view->container, | ||
1058 | workspace->fullscreen)) { | ||
1059 | return false; | ||
1060 | } | ||
1046 | } | 1061 | } |
1047 | return true; | 1062 | return true; |
1048 | } | 1063 | } |
@@ -1095,3 +1110,9 @@ void view_save_buffer(struct sway_view *view) { | |||
1095 | view->saved_buffer_height = view->surface->current.height; | 1110 | view->saved_buffer_height = view->surface->current.height; |
1096 | } | 1111 | } |
1097 | } | 1112 | } |
1113 | |||
1114 | bool view_is_transient_for(struct sway_view *child, | ||
1115 | struct sway_view *ancestor) { | ||
1116 | return child->impl->is_transient_for && | ||
1117 | child->impl->is_transient_for(child, ancestor); | ||
1118 | } | ||