diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2019-01-25 08:29:21 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2019-01-25 08:29:21 +1000 |
commit | 20aa8ee67dc528299dbc8735220a1c081c7ff9f6 (patch) | |
tree | 685de48be3db51fc01510ccf051e2b63a4655fba /sway/commands | |
parent | Update for swaywm/wlroots#1402 (diff) | |
download | sway-20aa8ee67dc528299dbc8735220a1c081c7ff9f6.tar.gz sway-20aa8ee67dc528299dbc8735220a1c081c7ff9f6.tar.zst sway-20aa8ee67dc528299dbc8735220a1c081c7ff9f6.zip |
Implement fullscreen global
Diffstat (limited to 'sway/commands')
-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 |
6 files changed, 97 insertions, 45 deletions
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; |