diff options
author | Drew DeVault <sir@cmpwn.com> | 2019-01-27 18:06:50 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-27 18:06:50 -0500 |
commit | 783fadab284c79c8e13625e5e2a2eefae02c75d3 (patch) | |
tree | 795c5c69a7fcfc9336115ac157a41b943190f206 | |
parent | Merge pull request #3519 from emersion/pointer-frame (diff) | |
parent | Implement fullscreen global (diff) | |
download | sway-783fadab284c79c8e13625e5e2a2eefae02c75d3.tar.gz sway-783fadab284c79c8e13625e5e2a2eefae02c75d3.tar.zst sway-783fadab284c79c8e13625e5e2a2eefae02c75d3.zip |
Merge pull request #3423 from RyanDwyer/fullscreen-global
Implement fullscreen global
-rw-r--r-- | include/sway/tree/container.h | 18 | ||||
-rw-r--r-- | include/sway/tree/root.h | 2 | ||||
-rw-r--r-- | sway/commands/focus.c | 26 | ||||
-rw-r--r-- | sway/commands/fullscreen.c | 34 | ||||
-rw-r--r-- | sway/commands/move.c | 44 | ||||
-rw-r--r-- | sway/commands/split.c | 6 | ||||
-rw-r--r-- | sway/commands/swap.c | 27 | ||||
-rw-r--r-- | sway/commands/workspace.c | 5 | ||||
-rw-r--r-- | sway/desktop/output.c | 30 | ||||
-rw-r--r-- | sway/desktop/render.c | 10 | ||||
-rw-r--r-- | sway/desktop/transaction.c | 2 | ||||
-rw-r--r-- | sway/desktop/xdg_shell.c | 2 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 2 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 2 | ||||
-rw-r--r-- | sway/input/cursor.c | 12 | ||||
-rw-r--r-- | sway/input/seat.c | 12 | ||||
-rw-r--r-- | sway/ipc-json.c | 4 | ||||
-rw-r--r-- | sway/sway.5.scd | 5 | ||||
-rw-r--r-- | sway/tree/arrange.c | 16 | ||||
-rw-r--r-- | sway/tree/container.c | 174 | ||||
-rw-r--r-- | sway/tree/root.c | 5 | ||||
-rw-r--r-- | sway/tree/view.c | 26 |
22 files changed, 332 insertions, 132 deletions
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 9a432cb2..f0d0b3ce 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h | |||
@@ -25,6 +25,12 @@ enum sway_container_border { | |||
25 | B_CSD, | 25 | B_CSD, |
26 | }; | 26 | }; |
27 | 27 | ||
28 | enum sway_fullscreen_mode { | ||
29 | FULLSCREEN_NONE, | ||
30 | FULLSCREEN_WORKSPACE, | ||
31 | FULLSCREEN_GLOBAL, | ||
32 | }; | ||
33 | |||
28 | struct sway_root; | 34 | struct sway_root; |
29 | struct sway_output; | 35 | struct sway_output; |
30 | struct sway_workspace; | 36 | struct sway_workspace; |
@@ -38,7 +44,7 @@ struct sway_container_state { | |||
38 | double x, y; | 44 | double x, y; |
39 | double width, height; | 45 | double width, height; |
40 | 46 | ||
41 | bool is_fullscreen; | 47 | enum sway_fullscreen_mode fullscreen_mode; |
42 | 48 | ||
43 | struct sway_workspace *workspace; | 49 | struct sway_workspace *workspace; |
44 | struct sway_container *parent; | 50 | struct sway_container *parent; |
@@ -85,7 +91,7 @@ struct sway_container { | |||
85 | double content_x, content_y; | 91 | double content_x, content_y; |
86 | int content_width, content_height; | 92 | int content_width, content_height; |
87 | 93 | ||
88 | bool is_fullscreen; | 94 | enum sway_fullscreen_mode fullscreen_mode; |
89 | 95 | ||
90 | enum sway_container_border border; | 96 | enum sway_container_border border; |
91 | 97 | ||
@@ -249,7 +255,13 @@ bool container_has_urgent_child(struct sway_container *container); | |||
249 | */ | 255 | */ |
250 | void container_end_mouse_operation(struct sway_container *container); | 256 | void container_end_mouse_operation(struct sway_container *container); |
251 | 257 | ||
252 | void container_set_fullscreen(struct sway_container *container, bool enable); | 258 | void container_set_fullscreen(struct sway_container *con, |
259 | enum sway_fullscreen_mode mode); | ||
260 | |||
261 | /** | ||
262 | * Convenience function. | ||
263 | */ | ||
264 | void container_fullscreen_disable(struct sway_container *con); | ||
253 | 265 | ||
254 | /** | 266 | /** |
255 | * Return true if the container is floating, or a child of a floating split | 267 | * Return true if the container is floating, or a child of a floating split |
diff --git a/include/sway/tree/root.h b/include/sway/tree/root.h index 8f4deaa7..9ff45eb5 100644 --- a/include/sway/tree/root.h +++ b/include/sway/tree/root.h | |||
@@ -35,6 +35,8 @@ struct sway_root { | |||
35 | // For when there's no connected outputs | 35 | // For when there's no connected outputs |
36 | struct sway_output *noop_output; | 36 | struct sway_output *noop_output; |
37 | 37 | ||
38 | struct sway_container *fullscreen_global; | ||
39 | |||
38 | struct { | 40 | struct { |
39 | struct wl_signal new_node; | 41 | struct wl_signal new_node; |
40 | } events; | 42 | } events; |
diff --git a/sway/commands/focus.c b/sway/commands/focus.c index 0622f2e8..87fe6cf3 100644 --- a/sway/commands/focus.c +++ b/sway/commands/focus.c | |||
@@ -89,19 +89,23 @@ static struct sway_node *get_node_in_output_direction( | |||
89 | 89 | ||
90 | static struct sway_node *node_get_in_direction(struct sway_container *container, | 90 | static struct sway_node *node_get_in_direction(struct sway_container *container, |
91 | struct sway_seat *seat, enum wlr_direction dir) { | 91 | struct sway_seat *seat, enum wlr_direction dir) { |
92 | if (container->is_fullscreen) { | ||
93 | // Fullscreen container with a direction - go straight to outputs | ||
94 | struct sway_output *output = container->workspace->output; | ||
95 | struct sway_output *new_output = output_get_in_direction(output, dir); | ||
96 | if (!new_output) { | ||
97 | return NULL; | ||
98 | } | ||
99 | return get_node_in_output_direction(new_output, dir); | ||
100 | } | ||
101 | |||
102 | struct sway_container *wrap_candidate = NULL; | 92 | struct sway_container *wrap_candidate = NULL; |
103 | struct sway_container *current = container; | 93 | struct sway_container *current = container; |
104 | while (current) { | 94 | while (current) { |
95 | if (current->fullscreen_mode == FULLSCREEN_WORKSPACE) { | ||
96 | // Fullscreen container with a direction - go straight to outputs | ||
97 | struct sway_output *output = current->workspace->output; | ||
98 | struct sway_output *new_output = | ||
99 | output_get_in_direction(output, dir); | ||
100 | if (!new_output) { | ||
101 | return NULL; | ||
102 | } | ||
103 | return get_node_in_output_direction(new_output, dir); | ||
104 | } | ||
105 | if (current->fullscreen_mode == FULLSCREEN_GLOBAL) { | ||
106 | return NULL; | ||
107 | } | ||
108 | |||
105 | bool can_move = false; | 109 | bool can_move = false; |
106 | int desired; | 110 | int desired; |
107 | int idx = container_sibling_index(current); | 111 | int idx = container_sibling_index(current); |
@@ -227,7 +231,7 @@ static struct cmd_results *focus_output(struct sway_seat *seat, | |||
227 | static struct cmd_results *focus_parent(void) { | 231 | static struct cmd_results *focus_parent(void) { |
228 | struct sway_seat *seat = config->handler_context.seat; | 232 | struct sway_seat *seat = config->handler_context.seat; |
229 | struct sway_container *con = config->handler_context.container; | 233 | struct sway_container *con = config->handler_context.container; |
230 | if (!con || con->is_fullscreen) { | 234 | if (!con || con->fullscreen_mode) { |
231 | return cmd_results_new(CMD_SUCCESS, NULL); | 235 | return cmd_results_new(CMD_SUCCESS, NULL); |
232 | } | 236 | } |
233 | struct sway_node *parent = node_get_parent(&con->node); | 237 | struct sway_node *parent = node_get_parent(&con->node); |
diff --git a/sway/commands/fullscreen.c b/sway/commands/fullscreen.c index 920b9bd0..52248ce4 100644 --- a/sway/commands/fullscreen.c +++ b/sway/commands/fullscreen.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <strings.h> | ||
1 | #include "log.h" | 2 | #include "log.h" |
2 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
3 | #include "sway/config.h" | 4 | #include "sway/config.h" |
@@ -7,9 +8,10 @@ | |||
7 | #include "sway/tree/workspace.h" | 8 | #include "sway/tree/workspace.h" |
8 | #include "util.h" | 9 | #include "util.h" |
9 | 10 | ||
11 | // fullscreen [enable|disable|toggle] [global] | ||
10 | struct cmd_results *cmd_fullscreen(int argc, char **argv) { | 12 | struct cmd_results *cmd_fullscreen(int argc, char **argv) { |
11 | struct cmd_results *error = NULL; | 13 | struct cmd_results *error = NULL; |
12 | if ((error = checkarg(argc, "fullscreen", EXPECTED_AT_MOST, 1))) { | 14 | if ((error = checkarg(argc, "fullscreen", EXPECTED_AT_MOST, 2))) { |
13 | return error; | 15 | return error; |
14 | } | 16 | } |
15 | if (!root->outputs->length) { | 17 | if (!root->outputs->length) { |
@@ -23,20 +25,38 @@ struct cmd_results *cmd_fullscreen(int argc, char **argv) { | |||
23 | return cmd_results_new(CMD_FAILURE, | 25 | return cmd_results_new(CMD_FAILURE, |
24 | "Can't fullscreen an empty workspace"); | 26 | "Can't fullscreen an empty workspace"); |
25 | } | 27 | } |
26 | if (node->type == N_WORKSPACE) { | 28 | |
29 | bool is_fullscreen = container && | ||
30 | container->fullscreen_mode != FULLSCREEN_NONE; | ||
31 | bool global = false; | ||
32 | bool enable = !is_fullscreen; | ||
33 | |||
34 | if (argc >= 1) { | ||
35 | if (strcasecmp(argv[0], "global") == 0) { | ||
36 | global = true; | ||
37 | } else { | ||
38 | enable = parse_boolean(argv[0], is_fullscreen); | ||
39 | } | ||
40 | } | ||
41 | |||
42 | if (argc >= 2) { | ||
43 | global = strcasecmp(argv[1], "global") == 0; | ||
44 | } | ||
45 | |||
46 | if (enable && node->type == N_WORKSPACE) { | ||
27 | // Wrap the workspace's children in a container so we can fullscreen it | 47 | // Wrap the workspace's children in a container so we can fullscreen it |
28 | container = workspace_wrap_children(workspace); | 48 | container = workspace_wrap_children(workspace); |
29 | workspace->layout = L_HORIZ; | 49 | workspace->layout = L_HORIZ; |
30 | seat_set_focus_container(config->handler_context.seat, container); | 50 | seat_set_focus_container(config->handler_context.seat, container); |
31 | } | 51 | } |
32 | bool enable = !container->is_fullscreen; | ||
33 | 52 | ||
34 | if (argc) { | 53 | enum sway_fullscreen_mode mode = FULLSCREEN_NONE; |
35 | enable = parse_boolean(argv[0], container->is_fullscreen); | 54 | if (enable) { |
55 | mode = global ? FULLSCREEN_GLOBAL : FULLSCREEN_WORKSPACE; | ||
36 | } | 56 | } |
37 | 57 | ||
38 | container_set_fullscreen(container, enable); | 58 | container_set_fullscreen(container, mode); |
39 | arrange_workspace(workspace); | 59 | arrange_root(); |
40 | 60 | ||
41 | return cmd_results_new(CMD_SUCCESS, NULL); | 61 | return cmd_results_new(CMD_SUCCESS, NULL); |
42 | } | 62 | } |
diff --git a/sway/commands/move.c b/sway/commands/move.c index acb5f44f..aa06b168 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c | |||
@@ -191,7 +191,7 @@ static void container_move_to_workspace(struct sway_container *container, | |||
191 | workspace_add_floating(workspace, container); | 191 | workspace_add_floating(workspace, container); |
192 | container_handle_fullscreen_reparent(container); | 192 | container_handle_fullscreen_reparent(container); |
193 | // If changing output, center it within the workspace | 193 | // If changing output, center it within the workspace |
194 | if (old_output != workspace->output && !container->is_fullscreen) { | 194 | if (old_output != workspace->output && !container->fullscreen_mode) { |
195 | container_floating_move_to_center(container); | 195 | container_floating_move_to_center(container); |
196 | } | 196 | } |
197 | } else { | 197 | } else { |
@@ -276,7 +276,7 @@ static void workspace_rejigger(struct sway_workspace *ws, | |||
276 | static bool container_move_in_direction(struct sway_container *container, | 276 | static bool container_move_in_direction(struct sway_container *container, |
277 | enum wlr_direction move_dir) { | 277 | enum wlr_direction move_dir) { |
278 | // If moving a fullscreen view, only consider outputs | 278 | // If moving a fullscreen view, only consider outputs |
279 | if (container->is_fullscreen) { | 279 | if (container->fullscreen_mode == FULLSCREEN_WORKSPACE) { |
280 | struct sway_output *new_output = | 280 | struct sway_output *new_output = |
281 | output_get_in_direction(container->workspace->output, move_dir); | 281 | output_get_in_direction(container->workspace->output, move_dir); |
282 | if (!new_output) { | 282 | if (!new_output) { |
@@ -286,6 +286,9 @@ static bool container_move_in_direction(struct sway_container *container, | |||
286 | container_move_to_workspace(container, ws); | 286 | container_move_to_workspace(container, ws); |
287 | return true; | 287 | return true; |
288 | } | 288 | } |
289 | if (container->fullscreen_mode == FULLSCREEN_GLOBAL) { | ||
290 | return false; | ||
291 | } | ||
289 | 292 | ||
290 | // If container is in a split container by itself, move out of the split | 293 | // If container is in a split container by itself, move out of the split |
291 | if (container->parent) { | 294 | if (container->parent) { |
@@ -309,13 +312,19 @@ static bool container_move_in_direction(struct sway_container *container, | |||
309 | int index = list_find(siblings, current); | 312 | int index = list_find(siblings, current); |
310 | int desired = index + offs; | 313 | int desired = index + offs; |
311 | 314 | ||
315 | // Don't allow containers to move out of their | ||
316 | // fullscreen or floating parent | ||
317 | if (current->fullscreen_mode || container_is_floating(current)) { | ||
318 | return false; | ||
319 | } | ||
320 | |||
312 | if (is_parallel(layout, move_dir)) { | 321 | if (is_parallel(layout, move_dir)) { |
313 | if (desired == -1 || desired == siblings->length) { | 322 | if (desired == -1 || desired == siblings->length) { |
314 | if (current->parent == container->parent) { | 323 | if (current->parent == container->parent) { |
315 | current = current->parent; | 324 | current = current->parent; |
316 | continue; | 325 | continue; |
317 | } else { | 326 | } else { |
318 | // Special case | 327 | // Reparenting |
319 | if (current->parent) { | 328 | if (current->parent) { |
320 | container_insert_child(current->parent, container, | 329 | container_insert_child(current->parent, container, |
321 | index + (offs < 0 ? 0 : 1)); | 330 | index + (offs < 0 ? 0 : 1)); |
@@ -334,13 +343,6 @@ static bool container_move_in_direction(struct sway_container *container, | |||
334 | } | 343 | } |
335 | 344 | ||
336 | current = current->parent; | 345 | current = current->parent; |
337 | |||
338 | // Don't allow containers to move out of their | ||
339 | // fullscreen or floating parent | ||
340 | if (current && | ||
341 | (current->is_fullscreen || container_is_floating(current))) { | ||
342 | return false; | ||
343 | } | ||
344 | } | 346 | } |
345 | 347 | ||
346 | // Maybe rejigger the workspace | 348 | // Maybe rejigger the workspace |
@@ -563,10 +565,14 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) { | |||
563 | } | 565 | } |
564 | 566 | ||
565 | // arrange windows | 567 | // arrange windows |
566 | if (old_ws && !old_ws->node.destroying) { | 568 | if (root->fullscreen_global) { |
567 | arrange_workspace(old_ws); | 569 | arrange_root(); |
570 | } else { | ||
571 | if (old_ws && !old_ws->node.destroying) { | ||
572 | arrange_workspace(old_ws); | ||
573 | } | ||
574 | arrange_node(node_get_parent(destination)); | ||
568 | } | 575 | } |
569 | arrange_node(node_get_parent(destination)); | ||
570 | 576 | ||
571 | return cmd_results_new(CMD_SUCCESS, NULL); | 577 | return cmd_results_new(CMD_SUCCESS, NULL); |
572 | } | 578 | } |
@@ -658,7 +664,7 @@ static struct cmd_results *cmd_move_in_direction( | |||
658 | "Cannot move a hidden scratchpad container"); | 664 | "Cannot move a hidden scratchpad container"); |
659 | } | 665 | } |
660 | if (container_is_floating(container)) { | 666 | if (container_is_floating(container)) { |
661 | if (container->is_fullscreen) { | 667 | if (container->fullscreen_mode) { |
662 | return cmd_results_new(CMD_FAILURE, | 668 | return cmd_results_new(CMD_FAILURE, |
663 | "Cannot move fullscreen floating container"); | 669 | "Cannot move fullscreen floating container"); |
664 | } | 670 | } |
@@ -690,9 +696,13 @@ static struct cmd_results *cmd_move_in_direction( | |||
690 | 696 | ||
691 | struct sway_workspace *new_ws = container->workspace; | 697 | struct sway_workspace *new_ws = container->workspace; |
692 | 698 | ||
693 | arrange_workspace(old_ws); | 699 | if (root->fullscreen_global) { |
694 | if (new_ws != old_ws) { | 700 | arrange_root(); |
695 | arrange_workspace(new_ws); | 701 | } else { |
702 | arrange_workspace(old_ws); | ||
703 | if (new_ws != old_ws) { | ||
704 | arrange_workspace(new_ws); | ||
705 | } | ||
696 | } | 706 | } |
697 | 707 | ||
698 | if (container->view) { | 708 | if (container->view) { |
diff --git a/sway/commands/split.c b/sway/commands/split.c index 06b7df5e..b7ab7b79 100644 --- a/sway/commands/split.c +++ b/sway/commands/split.c | |||
@@ -26,7 +26,11 @@ static struct cmd_results *do_split(int layout) { | |||
26 | container_flatten(con->parent->parent); | 26 | container_flatten(con->parent->parent); |
27 | } | 27 | } |
28 | 28 | ||
29 | arrange_workspace(ws); | 29 | if (root->fullscreen_global) { |
30 | arrange_root(); | ||
31 | } else { | ||
32 | arrange_workspace(ws); | ||
33 | } | ||
30 | 34 | ||
31 | return cmd_results_new(CMD_SUCCESS, NULL); | 35 | return cmd_results_new(CMD_SUCCESS, NULL); |
32 | } | 36 | } |
diff --git a/sway/commands/swap.c b/sway/commands/swap.c index 0d8d1116..0e2c2d10 100644 --- a/sway/commands/swap.c +++ b/sway/commands/swap.c | |||
@@ -77,6 +77,11 @@ static void swap_focus(struct sway_container *con1, | |||
77 | } else { | 77 | } else { |
78 | seat_set_focus_container(seat, focus); | 78 | seat_set_focus_container(seat, focus); |
79 | } | 79 | } |
80 | |||
81 | if (root->fullscreen_global) { | ||
82 | seat_set_focus(seat, | ||
83 | seat_get_focus_inactive(seat, &root->fullscreen_global->node)); | ||
84 | } | ||
80 | } | 85 | } |
81 | 86 | ||
82 | static void container_swap(struct sway_container *con1, | 87 | static void container_swap(struct sway_container *con1, |
@@ -98,13 +103,13 @@ static void container_swap(struct sway_container *con1, | |||
98 | sway_log(SWAY_DEBUG, "Swapping containers %zu and %zu", | 103 | sway_log(SWAY_DEBUG, "Swapping containers %zu and %zu", |
99 | con1->node.id, con2->node.id); | 104 | con1->node.id, con2->node.id); |
100 | 105 | ||
101 | bool fs1 = con1->is_fullscreen; | 106 | enum sway_fullscreen_mode fs1 = con1->fullscreen_mode; |
102 | bool fs2 = con2->is_fullscreen; | 107 | enum sway_fullscreen_mode fs2 = con2->fullscreen_mode; |
103 | if (fs1) { | 108 | if (fs1) { |
104 | container_set_fullscreen(con1, false); | 109 | container_fullscreen_disable(con1); |
105 | } | 110 | } |
106 | if (fs2) { | 111 | if (fs2) { |
107 | container_set_fullscreen(con2, false); | 112 | container_fullscreen_disable(con2); |
108 | } | 113 | } |
109 | 114 | ||
110 | struct sway_seat *seat = config->handler_context.seat; | 115 | struct sway_seat *seat = config->handler_context.seat; |
@@ -136,10 +141,10 @@ static void container_swap(struct sway_container *con1, | |||
136 | } | 141 | } |
137 | 142 | ||
138 | if (fs1) { | 143 | if (fs1) { |
139 | container_set_fullscreen(con2, true); | 144 | container_set_fullscreen(con2, fs1); |
140 | } | 145 | } |
141 | if (fs2) { | 146 | if (fs2) { |
142 | container_set_fullscreen(con1, true); | 147 | container_set_fullscreen(con1, fs2); |
143 | } | 148 | } |
144 | } | 149 | } |
145 | 150 | ||
@@ -220,9 +225,13 @@ struct cmd_results *cmd_swap(int argc, char **argv) { | |||
220 | 225 | ||
221 | container_swap(current, other); | 226 | container_swap(current, other); |
222 | 227 | ||
223 | arrange_node(node_get_parent(¤t->node)); | 228 | if (root->fullscreen_global) { |
224 | if (node_get_parent(&other->node) != node_get_parent(¤t->node)) { | 229 | arrange_root(); |
225 | arrange_node(node_get_parent(&other->node)); | 230 | } else { |
231 | arrange_node(node_get_parent(¤t->node)); | ||
232 | if (node_get_parent(&other->node) != node_get_parent(¤t->node)) { | ||
233 | arrange_node(node_get_parent(&other->node)); | ||
234 | } | ||
226 | } | 235 | } |
227 | 236 | ||
228 | return cmd_results_new(CMD_SUCCESS, NULL); | 237 | return cmd_results_new(CMD_SUCCESS, NULL); |
diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index 6bfca506..c5d6435a 100644 --- a/sway/commands/workspace.c +++ b/sway/commands/workspace.c | |||
@@ -168,6 +168,11 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { | |||
168 | "Can't run this command while there's no outputs connected."); | 168 | "Can't run this command while there's no outputs connected."); |
169 | } | 169 | } |
170 | 170 | ||
171 | if (root->fullscreen_global) { | ||
172 | return cmd_results_new(CMD_FAILURE, "workspace", | ||
173 | "Can't switch workspaces while fullscreen global"); | ||
174 | } | ||
175 | |||
171 | bool no_auto_back_and_forth = false; | 176 | bool no_auto_back_and_forth = false; |
172 | while (strcasecmp(argv[0], "--no-auto-back-and-forth") == 0) { | 177 | while (strcasecmp(argv[0], "--no-auto-back-and-forth") == 0) { |
173 | no_auto_back_and_forth = true; | 178 | no_auto_back_and_forth = true; |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index f18a118f..b5f164cb 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -251,17 +251,27 @@ static void output_for_each_surface(struct sway_output *output, | |||
251 | }; | 251 | }; |
252 | 252 | ||
253 | struct sway_workspace *workspace = output_get_active_workspace(output); | 253 | struct sway_workspace *workspace = output_get_active_workspace(output); |
254 | if (workspace->current.fullscreen) { | 254 | struct sway_container *fullscreen_con = root->fullscreen_global; |
255 | for_each_surface_container_iterator( | 255 | if (fullscreen_con && fullscreen_con->scratchpad && |
256 | workspace->current.fullscreen, &data); | 256 | !fullscreen_con->workspace) { |
257 | container_for_each_child(workspace->current.fullscreen, | 257 | fullscreen_con = NULL; |
258 | } | ||
259 | if (!fullscreen_con) { | ||
260 | fullscreen_con = workspace->current.fullscreen; | ||
261 | } | ||
262 | if (fullscreen_con) { | ||
263 | for_each_surface_container_iterator(fullscreen_con, &data); | ||
264 | container_for_each_child(fullscreen_con, | ||
258 | for_each_surface_container_iterator, &data); | 265 | for_each_surface_container_iterator, &data); |
259 | for (int i = 0; i < workspace->current.floating->length; ++i) { | 266 | |
260 | struct sway_container *floater = | 267 | // TODO: Show transient containers for fullscreen global |
261 | workspace->current.floating->items[i]; | 268 | if (fullscreen_con == workspace->current.fullscreen) { |
262 | if (container_is_transient_for(floater, | 269 | for (int i = 0; i < workspace->current.floating->length; ++i) { |
263 | workspace->current.fullscreen)) { | 270 | struct sway_container *floater = |
264 | for_each_surface_container_iterator(floater, &data); | 271 | workspace->current.floating->items[i]; |
272 | if (container_is_transient_for(floater, fullscreen_con)) { | ||
273 | for_each_surface_container_iterator(floater, &data); | ||
274 | } | ||
265 | } | 275 | } |
266 | } | 276 | } |
267 | #if HAVE_XWAYLAND | 277 | #if HAVE_XWAYLAND |
diff --git a/sway/desktop/render.c b/sway/desktop/render.c index a38c6a07..fa27500e 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c | |||
@@ -985,7 +985,15 @@ void output_render(struct sway_output *output, struct timespec *when, | |||
985 | goto render_overlay; | 985 | goto render_overlay; |
986 | } | 986 | } |
987 | 987 | ||
988 | struct sway_container *fullscreen_con = workspace->current.fullscreen; | 988 | struct sway_container *fullscreen_con = root->fullscreen_global; |
989 | if (fullscreen_con && fullscreen_con->scratchpad && | ||
990 | !fullscreen_con->workspace) { | ||
991 | fullscreen_con = NULL; | ||
992 | } | ||
993 | if (!fullscreen_con) { | ||
994 | fullscreen_con = workspace->current.fullscreen; | ||
995 | } | ||
996 | |||
989 | if (fullscreen_con) { | 997 | if (fullscreen_con) { |
990 | float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; | 998 | float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; |
991 | 999 | ||
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 88a9b027..9155f0a1 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c | |||
@@ -132,7 +132,7 @@ static void copy_container_state(struct sway_container *container, | |||
132 | state->y = container->y; | 132 | state->y = container->y; |
133 | state->width = container->width; | 133 | state->width = container->width; |
134 | state->height = container->height; | 134 | state->height = container->height; |
135 | state->is_fullscreen = container->is_fullscreen; | 135 | state->fullscreen_mode = container->fullscreen_mode; |
136 | state->parent = container->parent; | 136 | state->parent = container->parent; |
137 | state->workspace = container->workspace; | 137 | state->workspace = container->workspace; |
138 | state->border = container->border; | 138 | state->border = container->border; |
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index e2c614b3..007b0a94 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c | |||
@@ -349,7 +349,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) | |||
349 | 349 | ||
350 | container_set_fullscreen(view->container, e->fullscreen); | 350 | container_set_fullscreen(view->container, e->fullscreen); |
351 | 351 | ||
352 | arrange_workspace(view->container->workspace); | 352 | arrange_root(); |
353 | transaction_commit_dirty(); | 353 | transaction_commit_dirty(); |
354 | } | 354 | } |
355 | 355 | ||
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index f11c00b1..386e350e 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c | |||
@@ -342,7 +342,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) | |||
342 | 342 | ||
343 | container_set_fullscreen(view->container, e->fullscreen); | 343 | container_set_fullscreen(view->container, e->fullscreen); |
344 | 344 | ||
345 | arrange_workspace(view->container->workspace); | 345 | arrange_root(); |
346 | transaction_commit_dirty(); | 346 | transaction_commit_dirty(); |
347 | } | 347 | } |
348 | 348 | ||
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 4ea661f8..d9e1b0a9 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -453,7 +453,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) | |||
453 | } | 453 | } |
454 | container_set_fullscreen(view->container, xsurface->fullscreen); | 454 | container_set_fullscreen(view->container, xsurface->fullscreen); |
455 | 455 | ||
456 | arrange_workspace(view->container->workspace); | 456 | arrange_root(); |
457 | transaction_commit_dirty(); | 457 | transaction_commit_dirty(); |
458 | } | 458 | } |
459 | 459 | ||
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index af2799ce..c84d6c40 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -90,6 +90,16 @@ struct sway_node *node_at_coords( | |||
90 | double ox = lx, oy = ly; | 90 | double ox = lx, oy = ly; |
91 | wlr_output_layout_output_coords(root->output_layout, wlr_output, &ox, &oy); | 91 | wlr_output_layout_output_coords(root->output_layout, wlr_output, &ox, &oy); |
92 | 92 | ||
93 | if (root->fullscreen_global) { | ||
94 | // Try fullscreen container | ||
95 | struct sway_container *con = tiling_container_at( | ||
96 | &root->fullscreen_global->node, lx, ly, surface, sx, sy); | ||
97 | if (con) { | ||
98 | return &con->node; | ||
99 | } | ||
100 | return NULL; | ||
101 | } | ||
102 | |||
93 | // find the focused workspace on the output for this seat | 103 | // find the focused workspace on the output for this seat |
94 | struct sway_workspace *ws = output_get_active_workspace(output); | 104 | struct sway_workspace *ws = output_get_active_workspace(output); |
95 | 105 | ||
@@ -659,7 +669,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor, | |||
659 | // Handle moving a tiling container | 669 | // Handle moving a tiling container |
660 | if (config->tiling_drag && (mod_pressed || on_titlebar) && | 670 | if (config->tiling_drag && (mod_pressed || on_titlebar) && |
661 | state == WLR_BUTTON_PRESSED && !is_floating_or_child && | 671 | state == WLR_BUTTON_PRESSED && !is_floating_or_child && |
662 | cont && !cont->is_fullscreen) { | 672 | cont && cont->fullscreen_mode == FULLSCREEN_NONE) { |
663 | struct sway_container *focus = seat_get_focused_container(seat); | 673 | struct sway_container *focus = seat_get_focused_container(seat); |
664 | bool focused = focus == cont || container_has_ancestor(focus, cont); | 674 | bool focused = focus == cont || container_has_ancestor(focus, cont); |
665 | if (on_titlebar && !focused) { | 675 | if (on_titlebar && !focused) { |
diff --git a/sway/input/seat.c b/sway/input/seat.c index b6ccd830..8cb1d8e9 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -752,6 +752,18 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { | |||
752 | return; | 752 | return; |
753 | } | 753 | } |
754 | } | 754 | } |
755 | // Deny setting focus to a workspace node when using fullscreen global | ||
756 | if (root->fullscreen_global && !container && new_workspace) { | ||
757 | return; | ||
758 | } | ||
759 | // Deny setting focus to a view which is hidden by a fullscreen global | ||
760 | if (root->fullscreen_global && container != root->fullscreen_global && | ||
761 | !container_has_ancestor(container, root->fullscreen_global)) { | ||
762 | // Unless it's a transient container | ||
763 | if (!container_is_transient_for(container, root->fullscreen_global)) { | ||
764 | return; | ||
765 | } | ||
766 | } | ||
755 | 767 | ||
756 | struct sway_output *new_output = new_workspace->output; | 768 | struct sway_output *new_output = new_workspace->output; |
757 | 769 | ||
diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 778bf773..87d2c1ec 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c | |||
@@ -425,7 +425,9 @@ static void ipc_json_describe_container(struct sway_container *c, json_object *o | |||
425 | view_is_urgent(c->view) : container_has_urgent_child(c); | 425 | view_is_urgent(c->view) : container_has_urgent_child(c); |
426 | json_object_object_add(object, "urgent", json_object_new_boolean(urgent)); | 426 | json_object_object_add(object, "urgent", json_object_new_boolean(urgent)); |
427 | json_object_object_add(object, "sticky", json_object_new_boolean(c->is_sticky)); | 427 | json_object_object_add(object, "sticky", json_object_new_boolean(c->is_sticky)); |
428 | json_object_object_add(object, "fullscreen_mode", json_object_new_int(c->is_fullscreen)); | 428 | |
429 | json_object_object_add(object, "fullscreen_mode", | ||
430 | json_object_new_int(c->fullscreen_mode)); | ||
429 | 431 | ||
430 | struct sway_node *parent = node_get_parent(&c->node); | 432 | struct sway_node *parent = node_get_parent(&c->node); |
431 | struct wlr_box parent_box = {0, 0, 0, 0}; | 433 | struct wlr_box parent_box = {0, 0, 0, 0}; |
diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 0ac6f185..55de3c9c 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd | |||
@@ -134,9 +134,10 @@ They are expected to be used with *bindsym* or at runtime through *swaymsg*(1). | |||
134 | *focus* mode_toggle | 134 | *focus* mode_toggle |
135 | Moves focus between the floating and tiled layers. | 135 | Moves focus between the floating and tiled layers. |
136 | 136 | ||
137 | *fullscreen* [enable|disable|toggle] | 137 | *fullscreen* [enable|disable|toggle] [global] |
138 | Makes focused view fullscreen, non-fullscreen, or the opposite of what it | 138 | Makes focused view fullscreen, non-fullscreen, or the opposite of what it |
139 | is now. If no argument is given, it does the same as _toggle_. | 139 | is now. If no argument is given, it does the same as _toggle_. If _global_ |
140 | is specified, the view will be fullscreen across all outputs. | ||
140 | 141 | ||
141 | *gaps* inner|outer|horizontal|vertical|top|right|bottom|left all|current | 142 | *gaps* inner|outer|horizontal|vertical|top|right|bottom|left all|current |
142 | set|plus|minus <amount> | 143 | set|plus|minus <amount> |
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c index f78d95a4..da372aa4 100644 --- a/sway/tree/arrange.c +++ b/sway/tree/arrange.c | |||
@@ -261,9 +261,19 @@ void arrange_root(void) { | |||
261 | root->y = layout_box->y; | 261 | root->y = layout_box->y; |
262 | root->width = layout_box->width; | 262 | root->width = layout_box->width; |
263 | root->height = layout_box->height; | 263 | root->height = layout_box->height; |
264 | for (int i = 0; i < root->outputs->length; ++i) { | 264 | |
265 | struct sway_output *output = root->outputs->items[i]; | 265 | if (root->fullscreen_global) { |
266 | arrange_output(output); | 266 | struct sway_container *fs = root->fullscreen_global; |
267 | fs->x = root->x; | ||
268 | fs->y = root->y; | ||
269 | fs->width = root->width; | ||
270 | fs->height = root->height; | ||
271 | arrange_container(fs); | ||
272 | } else { | ||
273 | for (int i = 0; i < root->outputs->length; ++i) { | ||
274 | struct sway_output *output = root->outputs->items[i]; | ||
275 | arrange_output(output); | ||
276 | } | ||
267 | } | 277 | } |
268 | } | 278 | } |
269 | 279 | ||
diff --git a/sway/tree/container.c b/sway/tree/container.c index 0c0684c0..d8ad3bc0 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -92,7 +92,7 @@ void container_begin_destroy(struct sway_container *con) { | |||
92 | } | 92 | } |
93 | // The workspace must have the fullscreen pointer cleared so that the | 93 | // The workspace must have the fullscreen pointer cleared so that the |
94 | // seat code can find an appropriate new focus. | 94 | // seat code can find an appropriate new focus. |
95 | if (con->is_fullscreen && con->workspace) { | 95 | if (con->fullscreen_mode == FULLSCREEN_WORKSPACE && con->workspace) { |
96 | con->workspace->fullscreen = NULL; | 96 | con->workspace->fullscreen = NULL; |
97 | } | 97 | } |
98 | wl_signal_emit(&con->node.events.destroy, &con->node); | 98 | wl_signal_emit(&con->node.events.destroy, &con->node); |
@@ -106,6 +106,10 @@ void container_begin_destroy(struct sway_container *con) { | |||
106 | root_scratchpad_remove_container(con); | 106 | root_scratchpad_remove_container(con); |
107 | } | 107 | } |
108 | 108 | ||
109 | if (con->fullscreen_mode == FULLSCREEN_GLOBAL) { | ||
110 | container_fullscreen_disable(con); | ||
111 | } | ||
112 | |||
109 | if (con->parent || con->workspace) { | 113 | if (con->parent || con->workspace) { |
110 | container_detach(con); | 114 | container_detach(con); |
111 | } | 115 | } |
@@ -840,15 +844,15 @@ void container_floating_move_to_center(struct sway_container *con) { | |||
840 | return; | 844 | return; |
841 | } | 845 | } |
842 | struct sway_workspace *ws = con->workspace; | 846 | struct sway_workspace *ws = con->workspace; |
843 | bool full = con->is_fullscreen; | 847 | enum sway_fullscreen_mode fullscreen_mode = con->fullscreen_mode; |
844 | if (full) { | 848 | if (fullscreen_mode) { |
845 | container_set_fullscreen(con, false); | 849 | container_fullscreen_disable(con); |
846 | } | 850 | } |
847 | double new_lx = ws->x + (ws->width - con->width) / 2; | 851 | double new_lx = ws->x + (ws->width - con->width) / 2; |
848 | double new_ly = ws->y + (ws->height - con->height) / 2; | 852 | double new_ly = ws->y + (ws->height - con->height) / 2; |
849 | container_floating_translate(con, new_lx - con->x, new_ly - con->y); | 853 | container_floating_translate(con, new_lx - con->x, new_ly - con->y); |
850 | if (full) { | 854 | if (fullscreen_mode) { |
851 | container_set_fullscreen(con, true); | 855 | container_set_fullscreen(con, fullscreen_mode); |
852 | } | 856 | } |
853 | } | 857 | } |
854 | 858 | ||
@@ -877,59 +881,125 @@ static void set_fullscreen_iterator(struct sway_container *con, void *data) { | |||
877 | } | 881 | } |
878 | } | 882 | } |
879 | 883 | ||
880 | void container_set_fullscreen(struct sway_container *container, bool enable) { | 884 | static void container_fullscreen_workspace(struct sway_container *con) { |
881 | if (container->is_fullscreen == enable) { | 885 | if (!sway_assert(con->fullscreen_mode == FULLSCREEN_NONE, |
886 | "Expected a non-fullscreen container")) { | ||
882 | return; | 887 | return; |
883 | } | 888 | } |
889 | bool enable = true; | ||
890 | set_fullscreen_iterator(con, &enable); | ||
891 | container_for_each_child(con, set_fullscreen_iterator, &enable); | ||
884 | 892 | ||
885 | struct sway_workspace *workspace = container->workspace; | 893 | con->workspace->fullscreen = con; |
886 | if (enable && workspace->fullscreen) { | 894 | con->saved_x = con->x; |
887 | container_set_fullscreen(workspace->fullscreen, false); | 895 | con->saved_y = con->y; |
896 | con->saved_width = con->width; | ||
897 | con->saved_height = con->height; | ||
898 | |||
899 | struct sway_seat *seat; | ||
900 | struct sway_workspace *focus_ws; | ||
901 | wl_list_for_each(seat, &server.input->seats, link) { | ||
902 | focus_ws = seat_get_focused_workspace(seat); | ||
903 | if (focus_ws == con->workspace) { | ||
904 | seat_set_focus_container(seat, con); | ||
905 | } | ||
888 | } | 906 | } |
889 | 907 | ||
890 | set_fullscreen_iterator(container, &enable); | 908 | con->fullscreen_mode = FULLSCREEN_WORKSPACE; |
891 | container_for_each_child(container, set_fullscreen_iterator, &enable); | 909 | container_end_mouse_operation(con); |
910 | ipc_event_window(con, "fullscreen_mode"); | ||
911 | } | ||
912 | |||
913 | static void container_fullscreen_global(struct sway_container *con) { | ||
914 | if (!sway_assert(con->fullscreen_mode == FULLSCREEN_NONE, | ||
915 | "Expected a non-fullscreen container")) { | ||
916 | return; | ||
917 | } | ||
918 | bool enable = true; | ||
919 | set_fullscreen_iterator(con, &enable); | ||
920 | container_for_each_child(con, set_fullscreen_iterator, &enable); | ||
892 | 921 | ||
893 | container->is_fullscreen = enable; | 922 | root->fullscreen_global = con; |
923 | con->saved_x = con->x; | ||
924 | con->saved_y = con->y; | ||
925 | con->saved_width = con->width; | ||
926 | con->saved_height = con->height; | ||
894 | 927 | ||
895 | if (enable) { | 928 | struct sway_seat *seat; |
896 | workspace->fullscreen = container; | 929 | wl_list_for_each(seat, &server.input->seats, link) { |
897 | container->saved_x = container->x; | 930 | struct sway_container *focus = seat_get_focused_container(seat); |
898 | container->saved_y = container->y; | 931 | if (focus && focus != con) { |
899 | container->saved_width = container->width; | 932 | seat_set_focus_container(seat, con); |
900 | container->saved_height = container->height; | ||
901 | |||
902 | struct sway_seat *seat; | ||
903 | struct sway_workspace *focus_ws; | ||
904 | wl_list_for_each(seat, &server.input->seats, link) { | ||
905 | focus_ws = seat_get_focused_workspace(seat); | ||
906 | if (focus_ws) { | ||
907 | if (focus_ws == workspace) { | ||
908 | seat_set_focus_container(seat, container); | ||
909 | } | ||
910 | } | ||
911 | } | 933 | } |
912 | } else { | 934 | } |
913 | workspace->fullscreen = NULL; | 935 | |
914 | if (container_is_floating(container)) { | 936 | con->fullscreen_mode = FULLSCREEN_GLOBAL; |
915 | container->x = container->saved_x; | 937 | container_end_mouse_operation(con); |
916 | container->y = container->saved_y; | 938 | ipc_event_window(con, "fullscreen_mode"); |
917 | container->width = container->saved_width; | 939 | } |
918 | container->height = container->saved_height; | 940 | |
919 | struct sway_output *output = | 941 | void container_fullscreen_disable(struct sway_container *con) { |
920 | container_floating_find_output(container); | 942 | if (!sway_assert(con->fullscreen_mode != FULLSCREEN_NONE, |
921 | if (workspace->output != output) { | 943 | "Expected a fullscreen container")) { |
922 | container_floating_move_to_center(container); | 944 | return; |
945 | } | ||
946 | bool enable = false; | ||
947 | set_fullscreen_iterator(con, &enable); | ||
948 | container_for_each_child(con, set_fullscreen_iterator, &enable); | ||
949 | |||
950 | if (container_is_floating(con)) { | ||
951 | con->x = con->saved_x; | ||
952 | con->y = con->saved_y; | ||
953 | } | ||
954 | con->width = con->saved_width; | ||
955 | con->height = con->saved_height; | ||
956 | |||
957 | if (con->fullscreen_mode == FULLSCREEN_WORKSPACE) { | ||
958 | con->workspace->fullscreen = NULL; | ||
959 | if (container_is_floating(con)) { | ||
960 | struct sway_output *output = container_floating_find_output(con); | ||
961 | if (con->workspace->output != output) { | ||
962 | container_floating_move_to_center(con); | ||
923 | } | 963 | } |
924 | } else { | ||
925 | container->width = container->saved_width; | ||
926 | container->height = container->saved_height; | ||
927 | } | 964 | } |
965 | } else { | ||
966 | root->fullscreen_global = NULL; | ||
928 | } | 967 | } |
929 | 968 | ||
930 | container_end_mouse_operation(container); | 969 | con->fullscreen_mode = FULLSCREEN_NONE; |
970 | container_end_mouse_operation(con); | ||
971 | ipc_event_window(con, "fullscreen_mode"); | ||
972 | } | ||
973 | |||
974 | void container_set_fullscreen(struct sway_container *con, | ||
975 | enum sway_fullscreen_mode mode) { | ||
976 | if (con->fullscreen_mode == mode) { | ||
977 | return; | ||
978 | } | ||
931 | 979 | ||
932 | ipc_event_window(container, "fullscreen_mode"); | 980 | switch (mode) { |
981 | case FULLSCREEN_NONE: | ||
982 | container_fullscreen_disable(con); | ||
983 | break; | ||
984 | case FULLSCREEN_WORKSPACE: | ||
985 | if (root->fullscreen_global) { | ||
986 | container_fullscreen_disable(root->fullscreen_global); | ||
987 | } | ||
988 | if (con->workspace->fullscreen) { | ||
989 | container_fullscreen_disable(con->workspace->fullscreen); | ||
990 | } | ||
991 | container_fullscreen_workspace(con); | ||
992 | break; | ||
993 | case FULLSCREEN_GLOBAL: | ||
994 | if (root->fullscreen_global) { | ||
995 | container_fullscreen_disable(root->fullscreen_global); | ||
996 | } | ||
997 | if (con->fullscreen_mode == FULLSCREEN_WORKSPACE) { | ||
998 | container_fullscreen_disable(con); | ||
999 | } | ||
1000 | container_fullscreen_global(con); | ||
1001 | break; | ||
1002 | } | ||
933 | } | 1003 | } |
934 | 1004 | ||
935 | bool container_is_floating_or_child(struct sway_container *container) { | 1005 | bool container_is_floating_or_child(struct sway_container *container) { |
@@ -941,7 +1011,7 @@ bool container_is_floating_or_child(struct sway_container *container) { | |||
941 | 1011 | ||
942 | bool container_is_fullscreen_or_child(struct sway_container *container) { | 1012 | bool container_is_fullscreen_or_child(struct sway_container *container) { |
943 | do { | 1013 | do { |
944 | if (container->is_fullscreen) { | 1014 | if (container->fullscreen_mode) { |
945 | return true; | 1015 | return true; |
946 | } | 1016 | } |
947 | container = container->parent; | 1017 | container = container->parent; |
@@ -1111,12 +1181,12 @@ list_t *container_get_current_siblings(struct sway_container *container) { | |||
1111 | } | 1181 | } |
1112 | 1182 | ||
1113 | void container_handle_fullscreen_reparent(struct sway_container *con) { | 1183 | void container_handle_fullscreen_reparent(struct sway_container *con) { |
1114 | if (!con->is_fullscreen || !con->workspace || | 1184 | if (con->fullscreen_mode != FULLSCREEN_WORKSPACE || !con->workspace || |
1115 | con->workspace->fullscreen == con) { | 1185 | con->workspace->fullscreen == con) { |
1116 | return; | 1186 | return; |
1117 | } | 1187 | } |
1118 | if (con->workspace->fullscreen) { | 1188 | if (con->workspace->fullscreen) { |
1119 | container_set_fullscreen(con->workspace->fullscreen, false); | 1189 | container_fullscreen_disable(con->workspace->fullscreen); |
1120 | } | 1190 | } |
1121 | con->workspace->fullscreen = con; | 1191 | con->workspace->fullscreen = con; |
1122 | 1192 | ||
@@ -1171,9 +1241,12 @@ void container_add_child(struct sway_container *parent, | |||
1171 | } | 1241 | } |
1172 | 1242 | ||
1173 | void container_detach(struct sway_container *child) { | 1243 | void container_detach(struct sway_container *child) { |
1174 | if (child->is_fullscreen) { | 1244 | if (child->fullscreen_mode == FULLSCREEN_WORKSPACE) { |
1175 | child->workspace->fullscreen = NULL; | 1245 | child->workspace->fullscreen = NULL; |
1176 | } | 1246 | } |
1247 | if (child->fullscreen_mode == FULLSCREEN_GLOBAL) { | ||
1248 | root->fullscreen_global = NULL; | ||
1249 | } | ||
1177 | 1250 | ||
1178 | struct sway_container *old_parent = child->parent; | 1251 | struct sway_container *old_parent = child->parent; |
1179 | struct sway_workspace *old_workspace = child->workspace; | 1252 | struct sway_workspace *old_workspace = child->workspace; |
@@ -1387,4 +1460,3 @@ void container_raise_floating(struct sway_container *con) { | |||
1387 | node_set_dirty(&floater->workspace->node); | 1460 | node_set_dirty(&floater->workspace->node); |
1388 | } | 1461 | } |
1389 | } | 1462 | } |
1390 | |||
diff --git a/sway/tree/root.c b/sway/tree/root.c index 99cf91a7..476e47a3 100644 --- a/sway/tree/root.c +++ b/sway/tree/root.c | |||
@@ -101,7 +101,10 @@ void root_scratchpad_show(struct sway_container *con) { | |||
101 | // If the current con or any of its parents are in fullscreen mode, we | 101 | // If the current con or any of its parents are in fullscreen mode, we |
102 | // first need to disable it before showing the scratchpad con. | 102 | // first need to disable it before showing the scratchpad con. |
103 | if (new_ws->fullscreen) { | 103 | if (new_ws->fullscreen) { |
104 | container_set_fullscreen(new_ws->fullscreen, false); | 104 | container_fullscreen_disable(new_ws->fullscreen); |
105 | } | ||
106 | if (root->fullscreen_global) { | ||
107 | container_fullscreen_disable(root->fullscreen_global); | ||
105 | } | 108 | } |
106 | 109 | ||
107 | // Show the container | 110 | // Show the container |
diff --git a/sway/tree/view.c b/sway/tree/view.c index 8795e04f..561c6ef1 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -203,12 +203,18 @@ void view_autoconfigure(struct sway_view *view) { | |||
203 | } | 203 | } |
204 | struct sway_output *output = con->workspace->output; | 204 | struct sway_output *output = con->workspace->output; |
205 | 205 | ||
206 | if (con->is_fullscreen) { | 206 | if (con->fullscreen_mode == FULLSCREEN_WORKSPACE) { |
207 | con->content_x = output->lx; | 207 | con->content_x = output->lx; |
208 | con->content_y = output->ly; | 208 | con->content_y = output->ly; |
209 | con->content_width = output->width; | 209 | con->content_width = output->width; |
210 | con->content_height = output->height; | 210 | con->content_height = output->height; |
211 | return; | 211 | return; |
212 | } else if (con->fullscreen_mode == FULLSCREEN_GLOBAL) { | ||
213 | con->content_x = root->x; | ||
214 | con->content_y = root->y; | ||
215 | con->content_width = root->width; | ||
216 | con->content_height = root->height; | ||
217 | return; | ||
212 | } | 218 | } |
213 | 219 | ||
214 | struct sway_workspace *ws = view->container->workspace; | 220 | struct sway_workspace *ws = view->container->workspace; |
@@ -648,7 +654,10 @@ void view_unmap(struct sway_view *view) { | |||
648 | workspace_consider_destroy(ws); | 654 | workspace_consider_destroy(ws); |
649 | } | 655 | } |
650 | 656 | ||
651 | if (ws && !ws->node.destroying) { | 657 | if (root->fullscreen_global) { |
658 | // Container may have been a child of the root fullscreen container | ||
659 | arrange_root(); | ||
660 | } else if (ws && !ws->node.destroying) { | ||
652 | arrange_workspace(ws); | 661 | arrange_workspace(ws); |
653 | workspace_detect_urgent(ws); | 662 | workspace_detect_urgent(ws); |
654 | } | 663 | } |
@@ -1008,14 +1017,11 @@ bool view_is_visible(struct sway_view *view) { | |||
1008 | con = con->parent; | 1017 | con = con->parent; |
1009 | } | 1018 | } |
1010 | // Check view isn't hidden by another fullscreen view | 1019 | // Check view isn't hidden by another fullscreen view |
1011 | if (workspace->fullscreen && | 1020 | struct sway_container *fs = root->fullscreen_global ? |
1012 | !container_is_fullscreen_or_child(view->container)) { | 1021 | root->fullscreen_global : workspace->fullscreen; |
1013 | // However, if we're transient for the fullscreen view and we allow | 1022 | if (fs && !container_is_fullscreen_or_child(view->container) && |
1014 | // "popups" during fullscreen then it might be visible | 1023 | !container_is_transient_for(view->container, fs)) { |
1015 | if (!container_is_transient_for(view->container, | 1024 | return false; |
1016 | workspace->fullscreen)) { | ||
1017 | return false; | ||
1018 | } | ||
1019 | } | 1025 | } |
1020 | return true; | 1026 | return true; |
1021 | } | 1027 | } |