diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-07-25 20:56:23 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-07-26 08:27:07 +1000 |
commit | 27a20a488465468511de9b2307941ac1bc4db8bf (patch) | |
tree | c5c1aff483cb089870ffebec00869347eec29f4c | |
parent | Merge pull request #2330 from progandy/set-modifier-locks (diff) | |
download | sway-27a20a488465468511de9b2307941ac1bc4db8bf.tar.gz sway-27a20a488465468511de9b2307941ac1bc4db8bf.tar.zst sway-27a20a488465468511de9b2307941ac1bc4db8bf.zip |
Allow containers to be fullscreen
-rw-r--r-- | include/sway/tree/container.h | 23 | ||||
-rw-r--r-- | include/sway/tree/view.h | 6 | ||||
-rw-r--r-- | include/sway/tree/workspace.h | 2 | ||||
-rw-r--r-- | sway/commands/fullscreen.c | 18 | ||||
-rw-r--r-- | sway/commands/move.c | 2 | ||||
-rw-r--r-- | sway/desktop/output.c | 14 | ||||
-rw-r--r-- | sway/desktop/render.c | 23 | ||||
-rw-r--r-- | sway/desktop/transaction.c | 2 | ||||
-rw-r--r-- | sway/desktop/xdg_shell.c | 4 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 4 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 4 | ||||
-rw-r--r-- | sway/input/cursor.c | 14 | ||||
-rw-r--r-- | sway/input/seat.c | 3 | ||||
-rw-r--r-- | sway/scratchpad.c | 2 | ||||
-rw-r--r-- | sway/tree/arrange.c | 18 | ||||
-rw-r--r-- | sway/tree/container.c | 87 | ||||
-rw-r--r-- | sway/tree/layout.c | 83 | ||||
-rw-r--r-- | sway/tree/view.c | 73 |
18 files changed, 226 insertions, 156 deletions
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 2a4be18c..c584cd92 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h | |||
@@ -60,6 +60,8 @@ struct sway_container_state { | |||
60 | double swayc_x, swayc_y; | 60 | double swayc_x, swayc_y; |
61 | double swayc_width, swayc_height; | 61 | double swayc_width, swayc_height; |
62 | 62 | ||
63 | bool is_fullscreen; | ||
64 | |||
63 | bool has_gaps; | 65 | bool has_gaps; |
64 | double current_gaps; | 66 | double current_gaps; |
65 | double gaps_inner; | 67 | double gaps_inner; |
@@ -74,7 +76,6 @@ struct sway_container_state { | |||
74 | // View properties | 76 | // View properties |
75 | double view_x, view_y; | 77 | double view_x, view_y; |
76 | double view_width, view_height; | 78 | double view_width, view_height; |
77 | bool is_fullscreen; | ||
78 | 79 | ||
79 | enum sway_container_border border; | 80 | enum sway_container_border border; |
80 | int border_thickness; | 81 | int border_thickness; |
@@ -84,7 +85,7 @@ struct sway_container_state { | |||
84 | bool border_right; | 85 | bool border_right; |
85 | 86 | ||
86 | // Workspace properties | 87 | // Workspace properties |
87 | struct sway_view *ws_fullscreen; | 88 | struct sway_container *ws_fullscreen; |
88 | struct sway_container *ws_floating; | 89 | struct sway_container *ws_floating; |
89 | }; | 90 | }; |
90 | 91 | ||
@@ -124,6 +125,8 @@ struct sway_container { | |||
124 | double saved_x, saved_y; | 125 | double saved_x, saved_y; |
125 | double saved_width, saved_height; | 126 | double saved_width, saved_height; |
126 | 127 | ||
128 | bool is_fullscreen; | ||
129 | |||
127 | // The gaps currently applied to the container. | 130 | // The gaps currently applied to the container. |
128 | double current_gaps; | 131 | double current_gaps; |
129 | 132 | ||
@@ -335,4 +338,20 @@ bool container_has_urgent_child(struct sway_container *container); | |||
335 | */ | 338 | */ |
336 | void container_end_mouse_operation(struct sway_container *container); | 339 | void container_end_mouse_operation(struct sway_container *container); |
337 | 340 | ||
341 | void container_set_fullscreen(struct sway_container *container, bool enable); | ||
342 | |||
343 | /** | ||
344 | * Return true if the container is fullscreen, or a child of a fullscreen split | ||
345 | * container. | ||
346 | */ | ||
347 | bool container_is_fullscreen_or_child(struct sway_container *container); | ||
348 | |||
349 | /** | ||
350 | * Wrap the children of parent in a new container. The new container will be the | ||
351 | * only child of parent. | ||
352 | * | ||
353 | * The new container is returned. | ||
354 | */ | ||
355 | struct sway_container *container_wrap_children(struct sway_container *parent); | ||
356 | |||
338 | #endif | 357 | #endif |
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 1972447b..7086314f 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h | |||
@@ -69,8 +69,6 @@ struct sway_view { | |||
69 | // Used when changing a view from tiled to floating. | 69 | // Used when changing a view from tiled to floating. |
70 | int natural_width, natural_height; | 70 | int natural_width, natural_height; |
71 | 71 | ||
72 | bool is_fullscreen; | ||
73 | |||
74 | char *title_format; | 72 | char *title_format; |
75 | enum sway_container_border border; | 73 | enum sway_container_border border; |
76 | int border_thickness; | 74 | int border_thickness; |
@@ -251,10 +249,6 @@ void view_set_activated(struct sway_view *view, bool activated); | |||
251 | 249 | ||
252 | void view_set_tiled(struct sway_view *view, bool tiled); | 250 | void view_set_tiled(struct sway_view *view, bool tiled); |
253 | 251 | ||
254 | void view_set_fullscreen_raw(struct sway_view *view, bool fullscreen); | ||
255 | |||
256 | void view_set_fullscreen(struct sway_view *view, bool fullscreen); | ||
257 | |||
258 | void view_close(struct sway_view *view); | 252 | void view_close(struct sway_view *view); |
259 | 253 | ||
260 | void view_damage_from(struct sway_view *view); | 254 | void view_damage_from(struct sway_view *view); |
diff --git a/include/sway/tree/workspace.h b/include/sway/tree/workspace.h index ff66da6b..5ae0ae3a 100644 --- a/include/sway/tree/workspace.h +++ b/include/sway/tree/workspace.h | |||
@@ -7,7 +7,7 @@ struct sway_view; | |||
7 | 7 | ||
8 | struct sway_workspace { | 8 | struct sway_workspace { |
9 | struct sway_container *swayc; | 9 | struct sway_container *swayc; |
10 | struct sway_view *fullscreen; | 10 | struct sway_container *fullscreen; |
11 | struct sway_container *floating; | 11 | struct sway_container *floating; |
12 | list_t *output_priority; | 12 | list_t *output_priority; |
13 | bool urgent; | 13 | bool urgent; |
diff --git a/sway/commands/fullscreen.c b/sway/commands/fullscreen.c index b423fd23..5ad06e40 100644 --- a/sway/commands/fullscreen.c +++ b/sway/commands/fullscreen.c | |||
@@ -14,18 +14,24 @@ struct cmd_results *cmd_fullscreen(int argc, char **argv) { | |||
14 | } | 14 | } |
15 | struct sway_container *container = | 15 | struct sway_container *container = |
16 | config->handler_context.current_container; | 16 | config->handler_context.current_container; |
17 | if (container->type != C_VIEW) { | 17 | if (container->type == C_WORKSPACE && container->children->length == 0) { |
18 | return cmd_results_new(CMD_INVALID, "fullscreen", | 18 | return cmd_results_new(CMD_INVALID, "fullscreen", |
19 | "Only views can fullscreen"); | 19 | "Can't fullscreen an empty workspace"); |
20 | } | 20 | } |
21 | struct sway_view *view = container->sway_view; | 21 | if (container->type == C_WORKSPACE) { |
22 | bool wants_fullscreen = !view->is_fullscreen; | 22 | // Wrap the workspace's children in a container so we can fullscreen it |
23 | struct sway_container *workspace = container; | ||
24 | container = container_wrap_children(container); | ||
25 | workspace->layout = L_HORIZ; | ||
26 | seat_set_focus(config->handler_context.seat, container); | ||
27 | } | ||
28 | bool enable = !container->is_fullscreen; | ||
23 | 29 | ||
24 | if (argc) { | 30 | if (argc) { |
25 | wants_fullscreen = parse_boolean(argv[0], view->is_fullscreen); | 31 | enable = parse_boolean(argv[0], container->is_fullscreen); |
26 | } | 32 | } |
27 | 33 | ||
28 | view_set_fullscreen(view, wants_fullscreen); | 34 | container_set_fullscreen(container, enable); |
29 | 35 | ||
30 | struct sway_container *workspace = container_parent(container, C_WORKSPACE); | 36 | struct sway_container *workspace = container_parent(container, C_WORKSPACE); |
31 | arrange_windows(workspace->parent); | 37 | arrange_windows(workspace->parent); |
diff --git a/sway/commands/move.c b/sway/commands/move.c index 1940043d..aede3d6c 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c | |||
@@ -196,7 +196,7 @@ static struct cmd_results *move_in_direction(struct sway_container *container, | |||
196 | "Cannot move workspaces in a direction"); | 196 | "Cannot move workspaces in a direction"); |
197 | } | 197 | } |
198 | if (container_is_floating(container)) { | 198 | if (container_is_floating(container)) { |
199 | if (container->type == C_VIEW && container->sway_view->is_fullscreen) { | 199 | if (container->is_fullscreen) { |
200 | return cmd_results_new(CMD_FAILURE, "move", | 200 | return cmd_results_new(CMD_FAILURE, "move", |
201 | "Cannot move fullscreen floating container"); | 201 | "Cannot move fullscreen floating container"); |
202 | } | 202 | } |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 1764b4e3..cecd300a 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -279,13 +279,15 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { | |||
279 | 279 | ||
280 | struct sway_container *workspace = output_get_active_workspace(output); | 280 | struct sway_container *workspace = output_get_active_workspace(output); |
281 | if (workspace->current.ws_fullscreen) { | 281 | if (workspace->current.ws_fullscreen) { |
282 | send_frame_done_container_iterator( | 282 | if (workspace->current.ws_fullscreen->type == C_VIEW) { |
283 | workspace->current.ws_fullscreen->swayc, &data); | 283 | send_frame_done_container_iterator( |
284 | #ifdef HAVE_XWAYLAND | 284 | workspace->current.ws_fullscreen, &data); |
285 | if (workspace->current.ws_fullscreen->type == SWAY_VIEW_XWAYLAND) { | 285 | } else { |
286 | send_frame_done_unmanaged(&data, | 286 | send_frame_done_container(&data, workspace->current.ws_fullscreen); |
287 | &root_container.sway_root->xwayland_unmanaged); | ||
288 | } | 287 | } |
288 | #ifdef HAVE_XWAYLAND | ||
289 | send_frame_done_unmanaged(&data, | ||
290 | &root_container.sway_root->xwayland_unmanaged); | ||
289 | #endif | 291 | #endif |
290 | } else { | 292 | } else { |
291 | send_frame_done_layer(&data, | 293 | send_frame_done_layer(&data, |
diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 15c5b94c..3e7b1a62 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c | |||
@@ -836,13 +836,13 @@ void output_render(struct sway_output *output, struct timespec *when, | |||
836 | } | 836 | } |
837 | 837 | ||
838 | struct sway_container *workspace = output_get_active_workspace(output); | 838 | struct sway_container *workspace = output_get_active_workspace(output); |
839 | struct sway_view *fullscreen_view = workspace->current.ws_fullscreen; | 839 | struct sway_container *fullscreen_con = workspace->current.ws_fullscreen; |
840 | 840 | ||
841 | if (output_has_opaque_overlay_layer_surface(output)) { | 841 | if (output_has_opaque_overlay_layer_surface(output)) { |
842 | goto render_overlay; | 842 | goto render_overlay; |
843 | } | 843 | } |
844 | 844 | ||
845 | if (fullscreen_view) { | 845 | if (fullscreen_con) { |
846 | float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; | 846 | float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; |
847 | 847 | ||
848 | int nrects; | 848 | int nrects; |
@@ -853,16 +853,21 @@ void output_render(struct sway_output *output, struct timespec *when, | |||
853 | } | 853 | } |
854 | 854 | ||
855 | // TODO: handle views smaller than the output | 855 | // TODO: handle views smaller than the output |
856 | if (fullscreen_view->swayc->instructions->length) { | 856 | if (fullscreen_con->type == C_VIEW) { |
857 | render_saved_view(fullscreen_view, output, damage, 1.0f); | 857 | if (fullscreen_con->instructions->length) { |
858 | render_saved_view(fullscreen_con->sway_view, | ||
859 | output, damage, 1.0f); | ||
858 | } else { | 860 | } else { |
859 | render_view_surfaces(fullscreen_view, output, damage, 1.0f); | 861 | render_view_surfaces(fullscreen_con->sway_view, |
862 | output, damage, 1.0f); | ||
863 | } | ||
864 | } else { | ||
865 | render_container(output, damage, fullscreen_con, | ||
866 | fullscreen_con->current.focused); | ||
860 | } | 867 | } |
861 | #ifdef HAVE_XWAYLAND | 868 | #ifdef HAVE_XWAYLAND |
862 | if (fullscreen_view->type == SWAY_VIEW_XWAYLAND) { | 869 | render_unmanaged(output, damage, |
863 | render_unmanaged(output, damage, | 870 | &root_container.sway_root->xwayland_unmanaged); |
864 | &root_container.sway_root->xwayland_unmanaged); | ||
865 | } | ||
866 | #endif | 871 | #endif |
867 | } else { | 872 | } else { |
868 | float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; | 873 | float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; |
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 2a89880a..ee7a0704 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c | |||
@@ -110,6 +110,7 @@ static void copy_pending_state(struct sway_container *container, | |||
110 | state->swayc_y = container->y; | 110 | state->swayc_y = container->y; |
111 | state->swayc_width = container->width; | 111 | state->swayc_width = container->width; |
112 | state->swayc_height = container->height; | 112 | state->swayc_height = container->height; |
113 | state->is_fullscreen = container->is_fullscreen; | ||
113 | state->has_gaps = container->has_gaps; | 114 | state->has_gaps = container->has_gaps; |
114 | state->current_gaps = container->current_gaps; | 115 | state->current_gaps = container->current_gaps; |
115 | state->gaps_inner = container->gaps_inner; | 116 | state->gaps_inner = container->gaps_inner; |
@@ -122,7 +123,6 @@ static void copy_pending_state(struct sway_container *container, | |||
122 | state->view_y = view->y; | 123 | state->view_y = view->y; |
123 | state->view_width = view->width; | 124 | state->view_width = view->width; |
124 | state->view_height = view->height; | 125 | state->view_height = view->height; |
125 | state->is_fullscreen = view->is_fullscreen; | ||
126 | state->border = view->border; | 126 | state->border = view->border; |
127 | state->border_thickness = view->border_thickness; | 127 | state->border_thickness = view->border_thickness; |
128 | state->border_top = view->border_top; | 128 | state->border_top = view->border_top; |
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index f3e4fef8..e6e1527e 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c | |||
@@ -267,7 +267,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) | |||
267 | return; | 267 | return; |
268 | } | 268 | } |
269 | 269 | ||
270 | view_set_fullscreen(view, e->fullscreen); | 270 | container_set_fullscreen(view->swayc, e->fullscreen); |
271 | 271 | ||
272 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); | 272 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); |
273 | arrange_windows(output); | 273 | arrange_windows(output); |
@@ -338,7 +338,7 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
338 | view_map(view, view->wlr_xdg_surface->surface); | 338 | view_map(view, view->wlr_xdg_surface->surface); |
339 | 339 | ||
340 | if (xdg_surface->toplevel->client_pending.fullscreen) { | 340 | if (xdg_surface->toplevel->client_pending.fullscreen) { |
341 | view_set_fullscreen(view, true); | 341 | container_set_fullscreen(view->swayc, true); |
342 | struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); | 342 | struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); |
343 | arrange_windows(ws); | 343 | arrange_windows(ws); |
344 | } else { | 344 | } else { |
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 46fd4769..5feee3e4 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c | |||
@@ -262,7 +262,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) | |||
262 | return; | 262 | return; |
263 | } | 263 | } |
264 | 264 | ||
265 | view_set_fullscreen(view, e->fullscreen); | 265 | container_set_fullscreen(view->swayc, e->fullscreen); |
266 | 266 | ||
267 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); | 267 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); |
268 | arrange_windows(output); | 268 | arrange_windows(output); |
@@ -333,7 +333,7 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
333 | view_map(view, view->wlr_xdg_surface_v6->surface); | 333 | view_map(view, view->wlr_xdg_surface_v6->surface); |
334 | 334 | ||
335 | if (xdg_surface->toplevel->client_pending.fullscreen) { | 335 | if (xdg_surface->toplevel->client_pending.fullscreen) { |
336 | view_set_fullscreen(view, true); | 336 | container_set_fullscreen(view->swayc, true); |
337 | struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); | 337 | struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); |
338 | arrange_windows(ws); | 338 | arrange_windows(ws); |
339 | } else { | 339 | } else { |
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 65d4fcd4..390ca580 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -357,7 +357,7 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
357 | view_map(view, xsurface->surface); | 357 | view_map(view, xsurface->surface); |
358 | 358 | ||
359 | if (xsurface->fullscreen) { | 359 | if (xsurface->fullscreen) { |
360 | view_set_fullscreen(view, true); | 360 | container_set_fullscreen(view->swayc, true); |
361 | struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); | 361 | struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); |
362 | arrange_windows(ws); | 362 | arrange_windows(ws); |
363 | } else { | 363 | } else { |
@@ -395,7 +395,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) | |||
395 | if (!xsurface->mapped) { | 395 | if (!xsurface->mapped) { |
396 | return; | 396 | return; |
397 | } | 397 | } |
398 | view_set_fullscreen(view, xsurface->fullscreen); | 398 | container_set_fullscreen(view->swayc, xsurface->fullscreen); |
399 | 399 | ||
400 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); | 400 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); |
401 | arrange_windows(output); | 401 | arrange_windows(output); |
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 02bd2239..cc0dbe99 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -99,14 +99,8 @@ static struct sway_container *container_at_coords( | |||
99 | return ws; | 99 | return ws; |
100 | } | 100 | } |
101 | if (ws->sway_workspace->fullscreen) { | 101 | if (ws->sway_workspace->fullscreen) { |
102 | struct wlr_surface *wlr_surface = ws->sway_workspace->fullscreen->surface; | 102 | return container_at(ws->sway_workspace->fullscreen, lx, ly, |
103 | if (wlr_surface_point_accepts_input(wlr_surface, ox, oy)) { | 103 | surface, sx, sy); |
104 | *sx = ox; | ||
105 | *sy = oy; | ||
106 | *surface = wlr_surface; | ||
107 | return ws->sway_workspace->fullscreen->swayc; | ||
108 | } | ||
109 | return NULL; | ||
110 | } | 104 | } |
111 | if ((*surface = layer_surface_at(output, | 105 | if ((*surface = layer_surface_at(output, |
112 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], | 106 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], |
@@ -438,8 +432,8 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor, | |||
438 | struct sway_container *cont) { | 432 | struct sway_container *cont) { |
439 | struct sway_seat *seat = cursor->seat; | 433 | struct sway_seat *seat = cursor->seat; |
440 | 434 | ||
441 | // Deny moving or resizing a fullscreen view | 435 | // Deny moving or resizing a fullscreen container |
442 | if (cont->type == C_VIEW && cont->sway_view->is_fullscreen) { | 436 | if (container_is_fullscreen_or_child(cont)) { |
443 | seat_pointer_notify_button(seat, time_msec, button, state); | 437 | seat_pointer_notify_button(seat, time_msec, button, state); |
444 | return; | 438 | return; |
445 | } | 439 | } |
diff --git a/sway/input/seat.c b/sway/input/seat.c index 8698d69e..e7b6e0c5 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -632,8 +632,7 @@ void seat_set_focus_warp(struct sway_seat *seat, | |||
632 | 632 | ||
633 | if (last_workspace && last_workspace == new_workspace | 633 | if (last_workspace && last_workspace == new_workspace |
634 | && last_workspace->sway_workspace->fullscreen | 634 | && last_workspace->sway_workspace->fullscreen |
635 | && container && container->type == C_VIEW | 635 | && container && !container_is_fullscreen_or_child(container)) { |
636 | && !container->sway_view->is_fullscreen) { | ||
637 | return; | 636 | return; |
638 | } | 637 | } |
639 | 638 | ||
diff --git a/sway/scratchpad.c b/sway/scratchpad.c index 1e836e7d..64636c77 100644 --- a/sway/scratchpad.c +++ b/sway/scratchpad.c | |||
@@ -54,7 +54,7 @@ static void scratchpad_show(struct sway_container *con) { | |||
54 | // If the current con or any of its parents are in fullscreen mode, we | 54 | // If the current con or any of its parents are in fullscreen mode, we |
55 | // first need to disable it before showing the scratchpad con. | 55 | // first need to disable it before showing the scratchpad con. |
56 | if (ws->sway_workspace->fullscreen) { | 56 | if (ws->sway_workspace->fullscreen) { |
57 | view_set_fullscreen(ws->sway_workspace->fullscreen, false); | 57 | container_set_fullscreen(ws->sway_workspace->fullscreen, false); |
58 | } | 58 | } |
59 | 59 | ||
60 | // Show the container | 60 | // Show the container |
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c index 533cf71c..5452b13c 100644 --- a/sway/tree/arrange.c +++ b/sway/tree/arrange.c | |||
@@ -220,8 +220,22 @@ static void arrange_workspace(struct sway_container *workspace) { | |||
220 | container_set_dirty(workspace); | 220 | container_set_dirty(workspace); |
221 | wlr_log(WLR_DEBUG, "Arranging workspace '%s' at %f, %f", workspace->name, | 221 | wlr_log(WLR_DEBUG, "Arranging workspace '%s' at %f, %f", workspace->name, |
222 | workspace->x, workspace->y); | 222 | workspace->x, workspace->y); |
223 | arrange_floating(workspace->sway_workspace->floating); | 223 | if (workspace->sway_workspace->fullscreen) { |
224 | arrange_children_of(workspace); | 224 | struct sway_container *fs = workspace->sway_workspace->fullscreen; |
225 | fs->x = workspace->parent->x; | ||
226 | fs->y = workspace->parent->y; | ||
227 | fs->width = workspace->parent->width; | ||
228 | fs->height = workspace->parent->height; | ||
229 | if (fs->type == C_VIEW) { | ||
230 | view_autoconfigure(fs->sway_view); | ||
231 | } else { | ||
232 | arrange_children_of(fs); | ||
233 | } | ||
234 | container_set_dirty(fs); | ||
235 | } else { | ||
236 | arrange_floating(workspace->sway_workspace->floating); | ||
237 | arrange_children_of(workspace); | ||
238 | } | ||
225 | } | 239 | } |
226 | 240 | ||
227 | static void arrange_output(struct sway_container *output) { | 241 | static void arrange_output(struct sway_container *output) { |
diff --git a/sway/tree/container.c b/sway/tree/container.c index 237e1a35..6ebf2653 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -1130,3 +1130,90 @@ void container_end_mouse_operation(struct sway_container *container) { | |||
1130 | } | 1130 | } |
1131 | } | 1131 | } |
1132 | } | 1132 | } |
1133 | |||
1134 | static void set_fullscreen_iterator(struct sway_container *con, void *data) { | ||
1135 | if (con->type != C_VIEW) { | ||
1136 | return; | ||
1137 | } | ||
1138 | if (con->sway_view->impl->set_fullscreen) { | ||
1139 | bool *enable = data; | ||
1140 | con->sway_view->impl->set_fullscreen(con->sway_view, *enable); | ||
1141 | } | ||
1142 | } | ||
1143 | |||
1144 | void container_set_fullscreen(struct sway_container *container, bool enable) { | ||
1145 | if (container->is_fullscreen == enable) { | ||
1146 | return; | ||
1147 | } | ||
1148 | |||
1149 | struct sway_container *workspace = container_parent(container, C_WORKSPACE); | ||
1150 | if (enable && workspace->sway_workspace->fullscreen) { | ||
1151 | container_set_fullscreen(workspace->sway_workspace->fullscreen, false); | ||
1152 | } | ||
1153 | |||
1154 | container_for_each_descendant_dfs(container, | ||
1155 | set_fullscreen_iterator, &enable); | ||
1156 | |||
1157 | container->is_fullscreen = enable; | ||
1158 | |||
1159 | if (enable) { | ||
1160 | workspace->sway_workspace->fullscreen = container; | ||
1161 | container->saved_x = container->x; | ||
1162 | container->saved_y = container->y; | ||
1163 | container->saved_width = container->width; | ||
1164 | container->saved_height = container->height; | ||
1165 | |||
1166 | struct sway_seat *seat; | ||
1167 | struct sway_container *focus, *focus_ws; | ||
1168 | wl_list_for_each(seat, &input_manager->seats, link) { | ||
1169 | focus = seat_get_focus(seat); | ||
1170 | if (focus) { | ||
1171 | focus_ws = focus; | ||
1172 | if (focus_ws->type != C_WORKSPACE) { | ||
1173 | focus_ws = container_parent(focus_ws, C_WORKSPACE); | ||
1174 | } | ||
1175 | if (focus_ws == workspace) { | ||
1176 | seat_set_focus(seat, container); | ||
1177 | } | ||
1178 | } | ||
1179 | } | ||
1180 | } else { | ||
1181 | workspace->sway_workspace->fullscreen = NULL; | ||
1182 | if (container_is_floating(container)) { | ||
1183 | container->x = container->saved_x; | ||
1184 | container->y = container->saved_y; | ||
1185 | container->width = container->saved_width; | ||
1186 | container->height = container->saved_height; | ||
1187 | } else { | ||
1188 | container->width = container->saved_width; | ||
1189 | container->height = container->saved_height; | ||
1190 | } | ||
1191 | } | ||
1192 | |||
1193 | container_end_mouse_operation(container); | ||
1194 | |||
1195 | ipc_event_window(container, "fullscreen_mode"); | ||
1196 | } | ||
1197 | |||
1198 | bool container_is_fullscreen_or_child(struct sway_container *container) { | ||
1199 | do { | ||
1200 | if (container->is_fullscreen) { | ||
1201 | return true; | ||
1202 | } | ||
1203 | container = container->parent; | ||
1204 | } while (container && container->type != C_WORKSPACE); | ||
1205 | |||
1206 | return false; | ||
1207 | } | ||
1208 | |||
1209 | struct sway_container *container_wrap_children(struct sway_container *parent) { | ||
1210 | struct sway_container *middle = container_create(C_CONTAINER); | ||
1211 | middle->layout = parent->layout; | ||
1212 | while (parent->children->length) { | ||
1213 | struct sway_container *child = parent->children->items[0]; | ||
1214 | container_remove_child(child); | ||
1215 | container_add_child(middle, child); | ||
1216 | } | ||
1217 | container_add_child(parent, middle); | ||
1218 | return middle; | ||
1219 | } | ||
diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 2b3263f8..ab5acc16 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c | |||
@@ -66,10 +66,9 @@ static int index_child(const struct sway_container *child) { | |||
66 | 66 | ||
67 | static void container_handle_fullscreen_reparent(struct sway_container *con, | 67 | static void container_handle_fullscreen_reparent(struct sway_container *con, |
68 | struct sway_container *old_parent) { | 68 | struct sway_container *old_parent) { |
69 | if (con->type != C_VIEW || !con->sway_view->is_fullscreen) { | 69 | if (!con->is_fullscreen) { |
70 | return; | 70 | return; |
71 | } | 71 | } |
72 | struct sway_view *view = con->sway_view; | ||
73 | struct sway_container *old_workspace = old_parent; | 72 | struct sway_container *old_workspace = old_parent; |
74 | if (old_workspace && old_workspace->type != C_WORKSPACE) { | 73 | if (old_workspace && old_workspace->type != C_WORKSPACE) { |
75 | old_workspace = container_parent(old_workspace, C_WORKSPACE); | 74 | old_workspace = container_parent(old_workspace, C_WORKSPACE); |
@@ -85,19 +84,27 @@ static void container_handle_fullscreen_reparent(struct sway_container *con, | |||
85 | 84 | ||
86 | // Mark the new workspace as fullscreen | 85 | // Mark the new workspace as fullscreen |
87 | if (new_workspace->sway_workspace->fullscreen) { | 86 | if (new_workspace->sway_workspace->fullscreen) { |
88 | view_set_fullscreen(new_workspace->sway_workspace->fullscreen, false); | 87 | container_set_fullscreen( |
88 | new_workspace->sway_workspace->fullscreen, false); | ||
89 | } | 89 | } |
90 | new_workspace->sway_workspace->fullscreen = view; | 90 | new_workspace->sway_workspace->fullscreen = con; |
91 | // Resize view to new output dimensions | 91 | |
92 | // Resize container to new output dimensions | ||
92 | struct sway_container *output = new_workspace->parent; | 93 | struct sway_container *output = new_workspace->parent; |
93 | view->x = output->x; | ||
94 | view->y = output->y; | ||
95 | view->width = output->width; | ||
96 | view->height = output->height; | ||
97 | con->x = output->x; | 94 | con->x = output->x; |
98 | con->y = output->y; | 95 | con->y = output->y; |
99 | con->width = output->width; | 96 | con->width = output->width; |
100 | con->height = output->height; | 97 | con->height = output->height; |
98 | |||
99 | if (con->type == C_VIEW) { | ||
100 | struct sway_view *view = con->sway_view; | ||
101 | view->x = output->x; | ||
102 | view->y = output->y; | ||
103 | view->width = output->width; | ||
104 | view->height = output->height; | ||
105 | } else { | ||
106 | arrange_windows(new_workspace); | ||
107 | } | ||
101 | } | 108 | } |
102 | 109 | ||
103 | void container_insert_child(struct sway_container *parent, | 110 | void container_insert_child(struct sway_container *parent, |
@@ -146,7 +153,7 @@ void container_add_child(struct sway_container *parent, | |||
146 | } | 153 | } |
147 | 154 | ||
148 | struct sway_container *container_remove_child(struct sway_container *child) { | 155 | struct sway_container *container_remove_child(struct sway_container *child) { |
149 | if (child->type == C_VIEW && child->sway_view->is_fullscreen) { | 156 | if (child->is_fullscreen) { |
150 | struct sway_container *workspace = container_parent(child, C_WORKSPACE); | 157 | struct sway_container *workspace = container_parent(child, C_WORKSPACE); |
151 | workspace->sway_workspace->fullscreen = NULL; | 158 | workspace->sway_workspace->fullscreen = NULL; |
152 | } | 159 | } |
@@ -229,10 +236,10 @@ void container_move_to(struct sway_container *container, | |||
229 | if (focus_ws->type != C_WORKSPACE) { | 236 | if (focus_ws->type != C_WORKSPACE) { |
230 | focus_ws = container_parent(focus_ws, C_WORKSPACE); | 237 | focus_ws = container_parent(focus_ws, C_WORKSPACE); |
231 | } | 238 | } |
232 | seat_set_focus(seat, | 239 | if (focus_ws == new_workspace) { |
233 | new_workspace->sway_workspace->fullscreen->swayc); | 240 | struct sway_container *new_focus = seat_get_focus_inactive(seat, |
234 | if (focus_ws != new_workspace) { | 241 | new_workspace->sway_workspace->fullscreen); |
235 | seat_set_focus(seat, focus); | 242 | seat_set_focus(seat, new_focus); |
236 | } | 243 | } |
237 | } | 244 | } |
238 | } | 245 | } |
@@ -375,10 +382,16 @@ void container_move(struct sway_container *container, | |||
375 | struct sway_container *sibling = NULL; | 382 | struct sway_container *sibling = NULL; |
376 | struct sway_container *current = container; | 383 | struct sway_container *current = container; |
377 | struct sway_container *parent = current->parent; | 384 | struct sway_container *parent = current->parent; |
385 | struct sway_container *top = &root_container; | ||
378 | 386 | ||
379 | // If moving a fullscreen view, only consider outputs | 387 | // If moving a fullscreen view, only consider outputs |
380 | if (container->type == C_VIEW && container->sway_view->is_fullscreen) { | 388 | if (container->is_fullscreen) { |
381 | current = container_parent(container, C_OUTPUT); | 389 | current = container_parent(container, C_OUTPUT); |
390 | } else if (container_is_fullscreen_or_child(container)) { | ||
391 | // If we've fullscreened a split container, only allow the child to move | ||
392 | // around within the fullscreen parent. | ||
393 | struct sway_container *ws = container_parent(container, C_WORKSPACE); | ||
394 | top = ws->sway_workspace->fullscreen; | ||
382 | } | 395 | } |
383 | 396 | ||
384 | struct sway_container *new_parent = container_flatten(parent); | 397 | struct sway_container *new_parent = container_flatten(parent); |
@@ -388,7 +401,7 @@ void container_move(struct sway_container *container, | |||
388 | } | 401 | } |
389 | 402 | ||
390 | while (!sibling) { | 403 | while (!sibling) { |
391 | if (current->type == C_ROOT) { | 404 | if (current == top) { |
392 | return; | 405 | return; |
393 | } | 406 | } |
394 | 407 | ||
@@ -452,8 +465,9 @@ void container_move(struct sway_container *container, | |||
452 | if ((index == parent->children->length - 1 && offs > 0) | 465 | if ((index == parent->children->length - 1 && offs > 0) |
453 | || (index == 0 && offs < 0)) { | 466 | || (index == 0 && offs < 0)) { |
454 | if (current->parent == container->parent) { | 467 | if (current->parent == container->parent) { |
455 | if (parent->layout == L_TABBED | 468 | if (!parent->is_fullscreen && |
456 | || parent->layout == L_STACKED) { | 469 | (parent->layout == L_TABBED || |
470 | parent->layout == L_STACKED)) { | ||
457 | move_out_of_tabs_stacks(container, current, | 471 | move_out_of_tabs_stacks(container, current, |
458 | move_dir, offs); | 472 | move_dir, offs); |
459 | return; | 473 | return; |
@@ -474,8 +488,8 @@ void container_move(struct sway_container *container, | |||
474 | sibling = parent->children->items[index + offs]; | 488 | sibling = parent->children->items[index + offs]; |
475 | wlr_log(WLR_DEBUG, "Selecting sibling id:%zd", sibling->id); | 489 | wlr_log(WLR_DEBUG, "Selecting sibling id:%zd", sibling->id); |
476 | } | 490 | } |
477 | } else if (parent->layout == L_TABBED | 491 | } else if (!parent->is_fullscreen && (parent->layout == L_TABBED || |
478 | || parent->layout == L_STACKED) { | 492 | parent->layout == L_STACKED)) { |
479 | move_out_of_tabs_stacks(container, current, move_dir, offs); | 493 | move_out_of_tabs_stacks(container, current, move_dir, offs); |
480 | return; | 494 | return; |
481 | } else { | 495 | } else { |
@@ -707,16 +721,16 @@ struct sway_container *container_get_in_direction( | |||
707 | return NULL; | 721 | return NULL; |
708 | } | 722 | } |
709 | 723 | ||
710 | if (container->type == C_VIEW && container->sway_view->is_fullscreen) { | 724 | if (dir == MOVE_CHILD) { |
711 | if (dir == MOVE_PARENT || dir == MOVE_CHILD) { | 725 | return seat_get_focus_inactive(seat, container); |
726 | } | ||
727 | if (container->is_fullscreen) { | ||
728 | if (dir == MOVE_PARENT) { | ||
712 | return NULL; | 729 | return NULL; |
713 | } | 730 | } |
714 | container = container_parent(container, C_OUTPUT); | 731 | container = container_parent(container, C_OUTPUT); |
715 | parent = container->parent; | 732 | parent = container->parent; |
716 | } else { | 733 | } else { |
717 | if (dir == MOVE_CHILD) { | ||
718 | return seat_get_focus_inactive(seat, container); | ||
719 | } | ||
720 | if (dir == MOVE_PARENT) { | 734 | if (dir == MOVE_PARENT) { |
721 | if (parent->type == C_OUTPUT) { | 735 | if (parent->type == C_OUTPUT) { |
722 | return NULL; | 736 | return NULL; |
@@ -767,7 +781,8 @@ struct sway_container *container_get_in_direction( | |||
767 | } | 781 | } |
768 | sway_assert(next_workspace, "Next container has no workspace"); | 782 | sway_assert(next_workspace, "Next container has no workspace"); |
769 | if (next_workspace->sway_workspace->fullscreen) { | 783 | if (next_workspace->sway_workspace->fullscreen) { |
770 | return next_workspace->sway_workspace->fullscreen->swayc; | 784 | return seat_get_focus_inactive(seat, |
785 | next_workspace->sway_workspace->fullscreen); | ||
771 | } | 786 | } |
772 | if (next->children && next->children->length) { | 787 | if (next->children && next->children->length) { |
773 | // TODO consider floating children as well | 788 | // TODO consider floating children as well |
@@ -1014,13 +1029,13 @@ void container_swap(struct sway_container *con1, struct sway_container *con2) { | |||
1014 | 1029 | ||
1015 | wlr_log(WLR_DEBUG, "Swapping containers %zu and %zu", con1->id, con2->id); | 1030 | wlr_log(WLR_DEBUG, "Swapping containers %zu and %zu", con1->id, con2->id); |
1016 | 1031 | ||
1017 | int fs1 = con1->type == C_VIEW && con1->sway_view->is_fullscreen; | 1032 | int fs1 = con1->is_fullscreen; |
1018 | int fs2 = con2->type == C_VIEW && con2->sway_view->is_fullscreen; | 1033 | int fs2 = con2->is_fullscreen; |
1019 | if (fs1) { | 1034 | if (fs1) { |
1020 | view_set_fullscreen(con1->sway_view, false); | 1035 | container_set_fullscreen(con1, false); |
1021 | } | 1036 | } |
1022 | if (fs2) { | 1037 | if (fs2) { |
1023 | view_set_fullscreen(con2->sway_view, false); | 1038 | container_set_fullscreen(con2, false); |
1024 | } | 1039 | } |
1025 | 1040 | ||
1026 | struct sway_seat *seat = input_manager_get_default_seat(input_manager); | 1041 | struct sway_seat *seat = input_manager_get_default_seat(input_manager); |
@@ -1053,10 +1068,10 @@ void container_swap(struct sway_container *con1, struct sway_container *con2) { | |||
1053 | prev_workspace_name = stored_prev_name; | 1068 | prev_workspace_name = stored_prev_name; |
1054 | } | 1069 | } |
1055 | 1070 | ||
1056 | if (fs1 && con2->type == C_VIEW) { | 1071 | if (fs1) { |
1057 | view_set_fullscreen(con2->sway_view, true); | 1072 | container_set_fullscreen(con2, true); |
1058 | } | 1073 | } |
1059 | if (fs2 && con1->type == C_VIEW) { | 1074 | if (fs2) { |
1060 | view_set_fullscreen(con1->sway_view, true); | 1075 | container_set_fullscreen(con1, true); |
1061 | } | 1076 | } |
1062 | } | 1077 | } |
diff --git a/sway/tree/view.c b/sway/tree/view.c index beeb8144..82c3ad4a 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -225,7 +225,7 @@ void view_autoconfigure(struct sway_view *view) { | |||
225 | 225 | ||
226 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); | 226 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); |
227 | 227 | ||
228 | if (view->is_fullscreen) { | 228 | if (view->swayc->is_fullscreen) { |
229 | view->x = output->x; | 229 | view->x = output->x; |
230 | view->y = output->y; | 230 | view->y = output->y; |
231 | view->width = output->width; | 231 | view->width = output->width; |
@@ -233,10 +233,6 @@ void view_autoconfigure(struct sway_view *view) { | |||
233 | return; | 233 | return; |
234 | } | 234 | } |
235 | 235 | ||
236 | if (container_is_floating(view->swayc)) { | ||
237 | return; | ||
238 | } | ||
239 | |||
240 | struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); | 236 | struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); |
241 | 237 | ||
242 | int other_views = 0; | 238 | int other_views = 0; |
@@ -349,68 +345,6 @@ void view_set_tiled(struct sway_view *view, bool tiled) { | |||
349 | } | 345 | } |
350 | } | 346 | } |
351 | 347 | ||
352 | void view_set_fullscreen(struct sway_view *view, bool fullscreen) { | ||
353 | if (view->is_fullscreen == fullscreen) { | ||
354 | return; | ||
355 | } | ||
356 | |||
357 | struct sway_container *workspace = | ||
358 | container_parent(view->swayc, C_WORKSPACE); | ||
359 | |||
360 | if (view->impl->set_fullscreen) { | ||
361 | view->impl->set_fullscreen(view, fullscreen); | ||
362 | } | ||
363 | |||
364 | view->is_fullscreen = fullscreen; | ||
365 | |||
366 | if (fullscreen) { | ||
367 | if (workspace->sway_workspace->fullscreen) { | ||
368 | view_set_fullscreen(workspace->sway_workspace->fullscreen, false); | ||
369 | } | ||
370 | workspace->sway_workspace->fullscreen = view; | ||
371 | view->saved_x = view->x; | ||
372 | view->saved_y = view->y; | ||
373 | view->saved_width = view->width; | ||
374 | view->saved_height = view->height; | ||
375 | view->swayc->saved_x = view->swayc->x; | ||
376 | view->swayc->saved_y = view->swayc->y; | ||
377 | view->swayc->saved_width = view->swayc->width; | ||
378 | view->swayc->saved_height = view->swayc->height; | ||
379 | |||
380 | struct sway_seat *seat; | ||
381 | struct sway_container *focus, *focus_ws; | ||
382 | wl_list_for_each(seat, &input_manager->seats, link) { | ||
383 | focus = seat_get_focus(seat); | ||
384 | if (focus) { | ||
385 | focus_ws = focus; | ||
386 | if (focus && focus_ws->type != C_WORKSPACE) { | ||
387 | focus_ws = container_parent(focus_ws, C_WORKSPACE); | ||
388 | } | ||
389 | seat_set_focus(seat, view->swayc); | ||
390 | if (focus_ws != workspace) { | ||
391 | seat_set_focus(seat, focus); | ||
392 | } | ||
393 | } | ||
394 | } | ||
395 | } else { | ||
396 | workspace->sway_workspace->fullscreen = NULL; | ||
397 | if (container_is_floating(view->swayc)) { | ||
398 | view->x = view->saved_x; | ||
399 | view->y = view->saved_y; | ||
400 | view->width = view->saved_width; | ||
401 | view->height = view->saved_height; | ||
402 | container_set_geometry_from_floating_view(view->swayc); | ||
403 | } else { | ||
404 | view->swayc->width = view->swayc->saved_width; | ||
405 | view->swayc->height = view->swayc->saved_height; | ||
406 | } | ||
407 | } | ||
408 | |||
409 | container_end_mouse_operation(view->swayc); | ||
410 | |||
411 | ipc_event_window(view->swayc, "fullscreen_mode"); | ||
412 | } | ||
413 | |||
414 | void view_close(struct sway_view *view) { | 348 | void view_close(struct sway_view *view) { |
415 | if (view->impl->close) { | 349 | if (view->impl->close) { |
416 | view->impl->close(view); | 350 | view->impl->close(view); |
@@ -680,7 +614,7 @@ void view_unmap(struct sway_view *view) { | |||
680 | struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); | 614 | struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); |
681 | 615 | ||
682 | struct sway_container *parent; | 616 | struct sway_container *parent; |
683 | if (view->is_fullscreen) { | 617 | if (view->swayc->is_fullscreen) { |
684 | ws->sway_workspace->fullscreen = NULL; | 618 | ws->sway_workspace->fullscreen = NULL; |
685 | parent = container_destroy(view->swayc); | 619 | parent = container_destroy(view->swayc); |
686 | 620 | ||
@@ -1133,7 +1067,8 @@ bool view_is_visible(struct sway_view *view) { | |||
1133 | container = container->parent; | 1067 | container = container->parent; |
1134 | } | 1068 | } |
1135 | // Check view isn't hidden by another fullscreen view | 1069 | // Check view isn't hidden by another fullscreen view |
1136 | if (workspace->sway_workspace->fullscreen && !view->is_fullscreen) { | 1070 | if (workspace->sway_workspace->fullscreen && |
1071 | !container_is_fullscreen_or_child(view->swayc)) { | ||
1137 | return false; | 1072 | return false; |
1138 | } | 1073 | } |
1139 | // Check the workspace is visible | 1074 | // Check the workspace is visible |