diff options
-rw-r--r-- | include/sway/commands.h | 1 | ||||
-rw-r--r-- | include/sway/config.h | 7 | ||||
-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 | 11 | ||||
-rw-r--r-- | sway/desktop/render.c | 11 | ||||
-rw-r--r-- | sway/desktop/xdg_shell.c | 29 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 28 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 29 | ||||
-rw-r--r-- | sway/input/cursor.c | 16 | ||||
-rw-r--r-- | sway/input/seat.c | 9 | ||||
-rw-r--r-- | sway/meson.build | 1 | ||||
-rw-r--r-- | sway/sway.5.scd | 6 | ||||
-rw-r--r-- | sway/tree/view.c | 15 |
16 files changed, 192 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/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 8f8ed438..070b15c8 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -212,6 +212,7 @@ static void config_defaults(struct sway_config *config) { | |||
212 | if (!(config->font = strdup("monospace 10"))) goto cleanup; | 212 | if (!(config->font = strdup("monospace 10"))) goto cleanup; |
213 | config->font_height = 17; // height of monospace 10 | 213 | config->font_height = 17; // height of monospace 10 |
214 | config->urgent_timeout = 500; | 214 | config->urgent_timeout = 500; |
215 | config->popup_during_fullscreen = POPUP_SMART; | ||
215 | 216 | ||
216 | // floating view | 217 | // floating view |
217 | config->floating_maximum_width = 0; | 218 | config->floating_maximum_width = 0; |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index cfb5a710..0bcdcac1 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -329,6 +329,17 @@ 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 | if (config->popup_during_fullscreen == POPUP_SMART && | ||
333 | workspace->current.fullscreen->view) { | ||
334 | for (int i = 0; i < workspace->current.floating->length; ++i) { | ||
335 | struct sway_container *floater = | ||
336 | workspace->current.floating->items[i]; | ||
337 | if (floater->view && view_is_transient_for(floater->view, | ||
338 | workspace->current.fullscreen->view)) { | ||
339 | send_frame_done_container_iterator(floater, &data); | ||
340 | } | ||
341 | } | ||
342 | } | ||
332 | #ifdef HAVE_XWAYLAND | 343 | #ifdef HAVE_XWAYLAND |
333 | send_frame_done_unmanaged(output, &root->xwayland_unmanaged, when); | 344 | send_frame_done_unmanaged(output, &root->xwayland_unmanaged, when); |
334 | #endif | 345 | #endif |
diff --git a/sway/desktop/render.c b/sway/desktop/render.c index c8b08a58..c2a0d29f 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c | |||
@@ -961,6 +961,17 @@ 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 | if (config->popup_during_fullscreen == POPUP_SMART && | ||
966 | fullscreen_con->view) { | ||
967 | for (int i = 0; i < workspace->floating->length; ++i) { | ||
968 | struct sway_container *floater = workspace->floating->items[i]; | ||
969 | if (floater->view && view_is_transient_for( | ||
970 | floater->view, fullscreen_con->view)) { | ||
971 | render_floating_container(output, damage, floater); | ||
972 | } | ||
973 | } | ||
974 | } | ||
964 | #ifdef HAVE_XWAYLAND | 975 | #ifdef HAVE_XWAYLAND |
965 | render_unmanaged(output, damage, &root->xwayland_unmanaged); | 976 | render_unmanaged(output, damage, &root->xwayland_unmanaged); |
966 | #endif | 977 | #endif |
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index a8b527a7..54831679 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, |
@@ -385,6 +401,18 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
385 | view_update_csd_from_client(view, csd); | 401 | view_update_csd_from_client(view, csd); |
386 | } | 402 | } |
387 | 403 | ||
404 | if (config->popup_during_fullscreen == POPUP_LEAVE && | ||
405 | view->container->workspace && | ||
406 | view->container->workspace->fullscreen && | ||
407 | xdg_surface->toplevel->parent) { | ||
408 | struct wlr_xdg_surface *psurface = xdg_surface->toplevel->parent; | ||
409 | struct sway_xdg_shell_view *parent = psurface->data; | ||
410 | struct sway_view *sway_view = &parent->view; | ||
411 | if (sway_view->container && sway_view->container->is_fullscreen) { | ||
412 | container_set_fullscreen(sway_view->container, false); | ||
413 | } | ||
414 | } | ||
415 | |||
388 | if (xdg_surface->toplevel->client_pending.fullscreen) { | 416 | if (xdg_surface->toplevel->client_pending.fullscreen) { |
389 | container_set_fullscreen(view->container, true); | 417 | container_set_fullscreen(view->container, true); |
390 | arrange_workspace(view->container->workspace); | 418 | arrange_workspace(view->container->workspace); |
@@ -395,6 +423,7 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
395 | arrange_workspace(view->container->workspace); | 423 | arrange_workspace(view->container->workspace); |
396 | } | 424 | } |
397 | } | 425 | } |
426 | |||
398 | transaction_commit_dirty(); | 427 | transaction_commit_dirty(); |
399 | 428 | ||
400 | xdg_shell_view->commit.notify = handle_commit; | 429 | 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..dacfca02 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, |
@@ -380,6 +396,18 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
380 | WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT; | 396 | WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT; |
381 | view_update_csd_from_client(view, csd); | 397 | view_update_csd_from_client(view, csd); |
382 | 398 | ||
399 | if (config->popup_during_fullscreen == POPUP_LEAVE && | ||
400 | view->container->workspace && | ||
401 | view->container->workspace->fullscreen && | ||
402 | xdg_surface->toplevel->parent) { | ||
403 | struct wlr_xdg_surface_v6 *psurface = xdg_surface->toplevel->parent; | ||
404 | struct sway_xdg_shell_v6_view *parent = psurface->data; | ||
405 | struct sway_view *sway_view = &parent->view; | ||
406 | if (sway_view->container && sway_view->container->is_fullscreen) { | ||
407 | container_set_fullscreen(sway_view->container, false); | ||
408 | } | ||
409 | } | ||
410 | |||
383 | if (xdg_surface->toplevel->client_pending.fullscreen) { | 411 | if (xdg_surface->toplevel->client_pending.fullscreen) { |
384 | container_set_fullscreen(view->container, true); | 412 | container_set_fullscreen(view->container, true); |
385 | arrange_workspace(view->container->workspace); | 413 | arrange_workspace(view->container->workspace); |
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 4c710f7e..80489f93 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 | }; |
@@ -390,6 +407,18 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
390 | // Put it back into the tree | 407 | // Put it back into the tree |
391 | view_map(view, xsurface->surface); | 408 | view_map(view, xsurface->surface); |
392 | 409 | ||
410 | if (config->popup_during_fullscreen == POPUP_LEAVE && | ||
411 | view->container->workspace && | ||
412 | view->container->workspace->fullscreen && | ||
413 | xsurface->parent) { | ||
414 | struct wlr_xwayland_surface *psurface = xsurface->parent; | ||
415 | struct sway_xwayland_view *parent = psurface->data; | ||
416 | struct sway_view *sway_view = &parent->view; | ||
417 | if (sway_view->container && sway_view->container->is_fullscreen) { | ||
418 | container_set_fullscreen(sway_view->container, false); | ||
419 | } | ||
420 | } | ||
421 | |||
393 | if (xsurface->fullscreen) { | 422 | if (xsurface->fullscreen) { |
394 | container_set_fullscreen(view->container, true); | 423 | container_set_fullscreen(view->container, true); |
395 | arrange_workspace(view->container->workspace); | 424 | arrange_workspace(view->container->workspace); |
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 331c6c7e..08eeb812 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -98,6 +98,22 @@ 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 | if (config->popup_during_fullscreen == POPUP_SMART && | ||
103 | ws->fullscreen->view) { | ||
104 | for (int i = 0; i < ws->floating->length; ++i) { | ||
105 | struct sway_container *floater = ws->floating->items[i]; | ||
106 | if (floater->view && view_is_transient_for( | ||
107 | floater->view, ws->fullscreen->view)) { | ||
108 | struct sway_container *con = tiling_container_at( | ||
109 | &floater->node, lx, ly, surface, sx, sy); | ||
110 | if (con) { | ||
111 | return &con->node; | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | // Try fullscreen container | ||
101 | struct sway_container *con = | 117 | struct sway_container *con = |
102 | tiling_container_at(&ws->fullscreen->node, lx, ly, surface, sx, sy); | 118 | tiling_container_at(&ws->fullscreen->node, lx, ly, surface, sx, sy); |
103 | if (con) { | 119 | if (con) { |
diff --git a/sway/input/seat.c b/sway/input/seat.c index f5cb2f9e..690b59e6 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -655,7 +655,14 @@ 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 | bool is_transient = new_workspace->fullscreen->view && | ||
660 | config->popup_during_fullscreen == POPUP_SMART && | ||
661 | container->view && view_is_transient_for( | ||
662 | container->view, new_workspace->fullscreen->view); | ||
663 | if (!is_transient) { | ||
664 | return; | ||
665 | } | ||
659 | } | 666 | } |
660 | 667 | ||
661 | struct sway_output *last_output = last_workspace ? | 668 | 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 3fda6cef..387edf54 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd | |||
@@ -549,6 +549,12 @@ You may combine output commands into one, like so: | |||
549 | You can get a list of output names with *swaymsg -t get\_outputs*. You may also | 549 | You can get a list of output names with *swaymsg -t get\_outputs*. You may also |
550 | match any output by using the output name "\*". | 550 | match any output by using the output name "\*". |
551 | 551 | ||
552 | *popup\_during\_fullscreen* smart|ignore|leave\_fullscreen | ||
553 | Determines what to do when a fullscreen view opens a dialog. | ||
554 | If _smart_ (the default), the dialog will be displayed. If _ignore_, the | ||
555 | dialog will not be rendered. If _leave\_fullscreen_, the view will exit | ||
556 | fullscreen mode and the dialog will be rendered. | ||
557 | |||
552 | *set* $<name> <value> | 558 | *set* $<name> <value> |
553 | Sets variable $_name_ to _value_. You can use the new variable in the | 559 | Sets variable $_name_ to _value_. You can use the new variable in the |
554 | arguments of future commands. When the variable is used, it can be escaped | 560 | arguments of future commands. When the variable is used, it can be escaped |
diff --git a/sway/tree/view.c b/sway/tree/view.c index 73ce55ac..edf771c1 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -1042,7 +1042,14 @@ bool view_is_visible(struct sway_view *view) { | |||
1042 | // Check view isn't hidden by another fullscreen view | 1042 | // Check view isn't hidden by another fullscreen view |
1043 | if (workspace->fullscreen && | 1043 | if (workspace->fullscreen && |
1044 | !container_is_fullscreen_or_child(view->container)) { | 1044 | !container_is_fullscreen_or_child(view->container)) { |
1045 | return false; | 1045 | // However, if we're transient for the fullscreen view and we allow |
1046 | // "popups" during fullscreen then it might be visible | ||
1047 | bool is_transient = config->popup_during_fullscreen == POPUP_SMART && | ||
1048 | workspace->fullscreen->view && | ||
1049 | view_is_transient_for(view, workspace->fullscreen->view); | ||
1050 | if (!is_transient) { | ||
1051 | return false; | ||
1052 | } | ||
1046 | } | 1053 | } |
1047 | return true; | 1054 | return true; |
1048 | } | 1055 | } |
@@ -1095,3 +1102,9 @@ void view_save_buffer(struct sway_view *view) { | |||
1095 | view->saved_buffer_height = view->surface->current.height; | 1102 | view->saved_buffer_height = view->surface->current.height; |
1096 | } | 1103 | } |
1097 | } | 1104 | } |
1105 | |||
1106 | bool view_is_transient_for(struct sway_view *child, | ||
1107 | struct sway_view *ancestor) { | ||
1108 | return child->impl->is_transient_for && | ||
1109 | child->impl->is_transient_for(child, ancestor); | ||
1110 | } | ||