summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-04-16 20:36:40 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-04-16 20:36:40 +1000
commit52420cc24d61db8d22cf0d391f1f84b37bf087d5 (patch)
treef975a3708c0d1562a8d2fcdceaed9a76aadbf1f4
parentMerge pull request #1816 from thejan2009/multi-output-ws-destroy (diff)
downloadsway-52420cc24d61db8d22cf0d391f1f84b37bf087d5.tar.gz
sway-52420cc24d61db8d22cf0d391f1f84b37bf087d5.tar.zst
sway-52420cc24d61db8d22cf0d391f1f84b37bf087d5.zip
Implement fullscreen.
-rw-r--r--include/sway/ipc-server.h1
-rw-r--r--include/sway/tree/container.h4
-rw-r--r--include/sway/tree/view.h9
-rw-r--r--sway/commands.c1
-rw-r--r--sway/commands/fullscreen.c40
-rw-r--r--sway/desktop/output.c24
-rw-r--r--sway/desktop/xdg_shell_v6.c26
-rw-r--r--sway/desktop/xwayland.c34
-rw-r--r--sway/input/seat.c14
-rw-r--r--sway/meson.build1
-rw-r--r--sway/tree/layout.c18
-rw-r--r--sway/tree/view.c40
12 files changed, 204 insertions, 8 deletions
diff --git a/include/sway/ipc-server.h b/include/sway/ipc-server.h
index c3389fe8..dd16a175 100644
--- a/include/sway/ipc-server.h
+++ b/include/sway/ipc-server.h
@@ -1,6 +1,7 @@
1#ifndef _SWAY_IPC_SERVER_H 1#ifndef _SWAY_IPC_SERVER_H
2#define _SWAY_IPC_SERVER_H 2#define _SWAY_IPC_SERVER_H
3#include <sys/socket.h> 3#include <sys/socket.h>
4#include "sway/config.h"
4#include "sway/tree/container.h" 5#include "sway/tree/container.h"
5#include "ipc.h" 6#include "ipc.h"
6 7
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index 2a8b8aba..22bd7240 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -72,9 +72,13 @@ struct sway_container {
72 // For C_OUTPUT, this is the output position in layout coordinates 72 // For C_OUTPUT, this is the output position in layout coordinates
73 // For other types, this is the position in output-local coordinates 73 // For other types, this is the position in output-local coordinates
74 double x, y; 74 double x, y;
75 double saved_x, saved_y;
75 // does not include borders or gaps. 76 // does not include borders or gaps.
76 double width, height; 77 double width, height;
77 78
79 // For C_WORKSPACE only
80 struct sway_view *fullscreen;
81
78 list_t *children; 82 list_t *children;
79 83
80 struct sway_container *parent; 84 struct sway_container *parent;
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h
index b51c54b5..73d5f6c7 100644
--- a/include/sway/tree/view.h
+++ b/include/sway/tree/view.h
@@ -28,6 +28,7 @@ struct sway_view_impl {
28 void (*configure)(struct sway_view *view, double ox, double oy, int width, 28 void (*configure)(struct sway_view *view, double ox, double oy, int width,
29 int height); 29 int height);
30 void (*set_activated)(struct sway_view *view, bool activated); 30 void (*set_activated)(struct sway_view *view, bool activated);
31 void (*set_fullscreen)(struct sway_view *view, bool fullscreen);
31 void (*for_each_surface)(struct sway_view *view, 32 void (*for_each_surface)(struct sway_view *view,
32 wlr_surface_iterator_func_t iterator, void *user_data); 33 wlr_surface_iterator_func_t iterator, void *user_data);
33 void (*close)(struct sway_view *view); 34 void (*close)(struct sway_view *view);
@@ -41,6 +42,8 @@ struct sway_view {
41 struct sway_container *swayc; // NULL for unmanaged views 42 struct sway_container *swayc; // NULL for unmanaged views
42 struct wlr_surface *surface; // NULL for unmapped views 43 struct wlr_surface *surface; // NULL for unmapped views
43 int width, height; 44 int width, height;
45 int saved_width, saved_height;
46 bool is_fullscreen;
44 47
45 union { 48 union {
46 struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6; 49 struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6;
@@ -63,6 +66,7 @@ struct sway_xdg_shell_v6_view {
63 struct wl_listener request_move; 66 struct wl_listener request_move;
64 struct wl_listener request_resize; 67 struct wl_listener request_resize;
65 struct wl_listener request_maximize; 68 struct wl_listener request_maximize;
69 struct wl_listener request_fullscreen;
66 struct wl_listener new_popup; 70 struct wl_listener new_popup;
67 struct wl_listener map; 71 struct wl_listener map;
68 struct wl_listener unmap; 72 struct wl_listener unmap;
@@ -79,6 +83,7 @@ struct sway_xwayland_view {
79 struct wl_listener request_resize; 83 struct wl_listener request_resize;
80 struct wl_listener request_maximize; 84 struct wl_listener request_maximize;
81 struct wl_listener request_configure; 85 struct wl_listener request_configure;
86 struct wl_listener request_fullscreen;
82 struct wl_listener map; 87 struct wl_listener map;
83 struct wl_listener unmap; 88 struct wl_listener unmap;
84 struct wl_listener destroy; 89 struct wl_listener destroy;
@@ -93,6 +98,7 @@ struct sway_xwayland_unmanaged {
93 int lx, ly; 98 int lx, ly;
94 99
95 struct wl_listener request_configure; 100 struct wl_listener request_configure;
101 struct wl_listener request_fullscreen;
96 struct wl_listener commit; 102 struct wl_listener commit;
97 struct wl_listener map; 103 struct wl_listener map;
98 struct wl_listener unmap; 104 struct wl_listener unmap;
@@ -106,6 +112,7 @@ struct sway_wl_shell_view {
106 struct wl_listener request_move; 112 struct wl_listener request_move;
107 struct wl_listener request_resize; 113 struct wl_listener request_resize;
108 struct wl_listener request_maximize; 114 struct wl_listener request_maximize;
115 struct wl_listener request_fullscreen;
109 struct wl_listener destroy; 116 struct wl_listener destroy;
110 117
111 int pending_width, pending_height; 118 int pending_width, pending_height;
@@ -155,6 +162,8 @@ void view_configure(struct sway_view *view, double ox, double oy, int width,
155 162
156void view_set_activated(struct sway_view *view, bool activated); 163void view_set_activated(struct sway_view *view, bool activated);
157 164
165void view_set_fullscreen(struct sway_view *view, bool fullscreen);
166
158void view_close(struct sway_view *view); 167void view_close(struct sway_view *view);
159 168
160void view_damage(struct sway_view *view, bool whole); 169void view_damage(struct sway_view *view, bool whole);
diff --git a/sway/commands.c b/sway/commands.c
index 99f42524..8ddc033b 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -99,6 +99,7 @@ static struct cmd_handler handlers[] = {
99 { "exec", cmd_exec }, 99 { "exec", cmd_exec },
100 { "exec_always", cmd_exec_always }, 100 { "exec_always", cmd_exec_always },
101 { "focus_follows_mouse", cmd_focus_follows_mouse }, 101 { "focus_follows_mouse", cmd_focus_follows_mouse },
102 { "fullscreen", cmd_fullscreen },
102 { "include", cmd_include }, 103 { "include", cmd_include },
103 { "input", cmd_input }, 104 { "input", cmd_input },
104 { "mode", cmd_mode }, 105 { "mode", cmd_mode },
diff --git a/sway/commands/fullscreen.c b/sway/commands/fullscreen.c
new file mode 100644
index 00000000..3e256282
--- /dev/null
+++ b/sway/commands/fullscreen.c
@@ -0,0 +1,40 @@
1#include <wlr/types/wlr_wl_shell.h>
2#include "log.h"
3#include "sway/commands.h"
4#include "sway/config.h"
5#include "sway/tree/container.h"
6#include "sway/tree/view.h"
7#include "sway/tree/layout.h"
8
9// fullscreen toggle|enable|disable
10struct cmd_results *cmd_fullscreen(int argc, char **argv) {
11 struct cmd_results *error = NULL;
12 if (config->reading) return cmd_results_new(CMD_FAILURE, "fullscreen", "Can't be used in config file.");
13 if (!config->active) return cmd_results_new(CMD_FAILURE, "fullscreen", "Can only be used when sway is running.");
14 if ((error = checkarg(argc, "fullscreen", EXPECTED_AT_LEAST, 1))) {
15 return error;
16 }
17 struct sway_container *container =
18 config->handler_context.current_container;
19 if (container->type != C_VIEW) {
20 return cmd_results_new(CMD_INVALID, "fullscreen",
21 "Only views can fullscreen");
22 }
23 struct sway_view *view = container->sway_view;
24 bool wants_fullscreen;
25
26 if (strcmp(argv[0], "enable") == 0) {
27 wants_fullscreen = true;
28 } else if (strcmp(argv[0], "disable") == 0) {
29 wants_fullscreen = false;
30 } else if (strcmp(argv[0], "toggle") == 0) {
31 wants_fullscreen = !view->is_fullscreen;
32 } else {
33 return cmd_results_new(CMD_INVALID, "fullscreen",
34 "Expected 'fullscreen <enable|disable|toggle>'");
35 }
36
37 view_set_fullscreen(view, wants_fullscreen);
38
39 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
40}
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 1b3143d0..b86f20e8 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -273,17 +273,25 @@ static void render_output(struct sway_output *output, struct timespec *when,
273 float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; 273 float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f};
274 wlr_renderer_clear(renderer, clear_color); 274 wlr_renderer_clear(renderer, clear_color);
275 275
276 render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]);
277 render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
278
279 struct sway_container *workspace = output_get_active_workspace(output); 276 struct sway_container *workspace = output_get_active_workspace(output);
280 render_container(output, workspace);
281 277
282 render_unmanaged(output, &root_container.sway_root->xwayland_unmanaged); 278 if (workspace->fullscreen) {
279 wlr_output_set_fullscreen_surface(wlr_output,
280 workspace->fullscreen->surface);
281 } else {
282 wlr_output_set_fullscreen_surface(wlr_output, NULL);
283 render_layer(output,
284 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]);
285 render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
286
287 render_container(output, workspace);
283 288
284 // TODO: consider revising this when fullscreen windows are supported 289 render_unmanaged(output, &root_container.sway_root->xwayland_unmanaged);
285 render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); 290
286 render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); 291 render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
292 render_layer(output,
293 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
294 }
287 295
288renderer_end: 296renderer_end:
289 if (root_container.sway_root->debug_tree) { 297 if (root_container.sway_root->debug_tree) {
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c
index e4703040..133b60c3 100644
--- a/sway/desktop/xdg_shell_v6.c
+++ b/sway/desktop/xdg_shell_v6.c
@@ -118,6 +118,14 @@ static void set_activated(struct sway_view *view, bool activated) {
118 } 118 }
119} 119}
120 120
121static void set_fullscreen(struct sway_view *view, bool fullscreen) {
122 if (xdg_shell_v6_view_from_view(view) == NULL) {
123 return;
124 }
125 struct wlr_xdg_surface_v6 *surface = view->wlr_xdg_surface_v6;
126 wlr_xdg_toplevel_v6_set_fullscreen(surface, fullscreen);
127}
128
121static void for_each_surface(struct sway_view *view, 129static void for_each_surface(struct sway_view *view,
122 wlr_surface_iterator_func_t iterator, void *user_data) { 130 wlr_surface_iterator_func_t iterator, void *user_data) {
123 if (xdg_shell_v6_view_from_view(view) == NULL) { 131 if (xdg_shell_v6_view_from_view(view) == NULL) {
@@ -146,6 +154,7 @@ static void destroy(struct sway_view *view) {
146 wl_list_remove(&xdg_shell_v6_view->destroy.link); 154 wl_list_remove(&xdg_shell_v6_view->destroy.link);
147 wl_list_remove(&xdg_shell_v6_view->map.link); 155 wl_list_remove(&xdg_shell_v6_view->map.link);
148 wl_list_remove(&xdg_shell_v6_view->unmap.link); 156 wl_list_remove(&xdg_shell_v6_view->unmap.link);
157 wl_list_remove(&xdg_shell_v6_view->request_fullscreen.link);
149 free(xdg_shell_v6_view); 158 free(xdg_shell_v6_view);
150} 159}
151 160
@@ -153,6 +162,7 @@ static const struct sway_view_impl view_impl = {
153 .get_prop = get_prop, 162 .get_prop = get_prop,
154 .configure = configure, 163 .configure = configure,
155 .set_activated = set_activated, 164 .set_activated = set_activated,
165 .set_fullscreen = set_fullscreen,
156 .for_each_surface = for_each_surface, 166 .for_each_surface = for_each_surface,
157 .close = _close, 167 .close = _close,
158 .destroy = destroy, 168 .destroy = destroy,
@@ -210,6 +220,18 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
210 view_destroy(&xdg_shell_v6_view->view); 220 view_destroy(&xdg_shell_v6_view->view);
211} 221}
212 222
223static void handle_request_fullscreen(struct wl_listener *listener, void *data) {
224 struct sway_xdg_shell_v6_view *xdg_shell_v6_view =
225 wl_container_of(listener, xdg_shell_v6_view, request_fullscreen);
226 struct wlr_xdg_toplevel_v6_set_fullscreen_event *e = data;
227
228 if (xdg_shell_v6_view->view.wlr_xdg_surface_v6->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) {
229 return;
230 }
231
232 view_set_fullscreen(&xdg_shell_v6_view->view, e->fullscreen);
233}
234
213void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { 235void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) {
214 struct sway_server *server = wl_container_of(listener, server, 236 struct sway_server *server = wl_container_of(listener, server,
215 xdg_shell_v6_surface); 237 xdg_shell_v6_surface);
@@ -246,4 +268,8 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) {
246 268
247 xdg_shell_v6_view->destroy.notify = handle_destroy; 269 xdg_shell_v6_view->destroy.notify = handle_destroy;
248 wl_signal_add(&xdg_surface->events.destroy, &xdg_shell_v6_view->destroy); 270 wl_signal_add(&xdg_surface->events.destroy, &xdg_shell_v6_view->destroy);
271
272 xdg_shell_v6_view->request_fullscreen.notify = handle_request_fullscreen;
273 wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen,
274 &xdg_shell_v6_view->request_fullscreen);
249} 275}
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 69166af0..716d8882 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -25,6 +25,15 @@ static void unmanaged_handle_request_configure(struct wl_listener *listener,
25 ev->width, ev->height); 25 ev->width, ev->height);
26} 26}
27 27
28static void unmanaged_handle_request_fullscreen(struct wl_listener *listener,
29 void *data) {
30 struct sway_xwayland_view *xwayland_view =
31 wl_container_of(listener, xwayland_view, request_fullscreen);
32 struct sway_view *view = &xwayland_view->view;
33 struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
34 view_set_fullscreen(view, xsurface->fullscreen);
35}
36
28static void unmanaged_handle_commit(struct wl_listener *listener, void *data) { 37static void unmanaged_handle_commit(struct wl_listener *listener, void *data) {
29 struct sway_xwayland_unmanaged *surface = 38 struct sway_xwayland_unmanaged *surface =
30 wl_container_of(listener, surface, commit); 39 wl_container_of(listener, surface, commit);
@@ -106,6 +115,9 @@ static struct sway_xwayland_unmanaged *create_unmanaged(
106 wl_signal_add(&xsurface->events.request_configure, 115 wl_signal_add(&xsurface->events.request_configure,
107 &surface->request_configure); 116 &surface->request_configure);
108 surface->request_configure.notify = unmanaged_handle_request_configure; 117 surface->request_configure.notify = unmanaged_handle_request_configure;
118 wl_signal_add(&xsurface->events.request_fullscreen,
119 &surface->request_fullscreen);
120 surface->request_fullscreen.notify = unmanaged_handle_request_fullscreen;
109 wl_signal_add(&xsurface->events.map, &surface->map); 121 wl_signal_add(&xsurface->events.map, &surface->map);
110 surface->map.notify = unmanaged_handle_map; 122 surface->map.notify = unmanaged_handle_map;
111 wl_signal_add(&xsurface->events.unmap, &surface->unmap); 123 wl_signal_add(&xsurface->events.unmap, &surface->unmap);
@@ -179,6 +191,14 @@ static void set_activated(struct sway_view *view, bool activated) {
179 wlr_xwayland_surface_activate(surface, activated); 191 wlr_xwayland_surface_activate(surface, activated);
180} 192}
181 193
194static void set_fullscreen(struct sway_view *view, bool fullscreen) {
195 if (xwayland_view_from_view(view) == NULL) {
196 return;
197 }
198 struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface;
199 wlr_xwayland_surface_set_fullscreen(surface, fullscreen);
200}
201
182static void _close(struct sway_view *view) { 202static void _close(struct sway_view *view) {
183 if (xwayland_view_from_view(view) == NULL) { 203 if (xwayland_view_from_view(view) == NULL) {
184 return; 204 return;
@@ -193,6 +213,7 @@ static void destroy(struct sway_view *view) {
193 } 213 }
194 wl_list_remove(&xwayland_view->destroy.link); 214 wl_list_remove(&xwayland_view->destroy.link);
195 wl_list_remove(&xwayland_view->request_configure.link); 215 wl_list_remove(&xwayland_view->request_configure.link);
216 wl_list_remove(&xwayland_view->request_fullscreen.link);
196 wl_list_remove(&xwayland_view->map.link); 217 wl_list_remove(&xwayland_view->map.link);
197 wl_list_remove(&xwayland_view->unmap.link); 218 wl_list_remove(&xwayland_view->unmap.link);
198 free(xwayland_view); 219 free(xwayland_view);
@@ -202,6 +223,7 @@ static const struct sway_view_impl view_impl = {
202 .get_prop = get_prop, 223 .get_prop = get_prop,
203 .configure = configure, 224 .configure = configure,
204 .set_activated = set_activated, 225 .set_activated = set_activated,
226 .set_fullscreen = set_fullscreen,
205 .close = _close, 227 .close = _close,
206 .destroy = destroy, 228 .destroy = destroy,
207}; 229};
@@ -263,6 +285,14 @@ static void handle_request_configure(struct wl_listener *listener, void *data) {
263 ev->width, ev->height); 285 ev->width, ev->height);
264} 286}
265 287
288static void handle_request_fullscreen(struct wl_listener *listener, void *data) {
289 struct sway_xwayland_view *xwayland_view =
290 wl_container_of(listener, xwayland_view, request_fullscreen);
291 struct sway_view *view = &xwayland_view->view;
292 struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
293 view_set_fullscreen(view, xsurface->fullscreen);
294}
295
266void handle_xwayland_surface(struct wl_listener *listener, void *data) { 296void handle_xwayland_surface(struct wl_listener *listener, void *data) {
267 struct sway_server *server = wl_container_of(listener, server, 297 struct sway_server *server = wl_container_of(listener, server,
268 xwayland_surface); 298 xwayland_surface);
@@ -298,6 +328,10 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
298 &xwayland_view->request_configure); 328 &xwayland_view->request_configure);
299 xwayland_view->request_configure.notify = handle_request_configure; 329 xwayland_view->request_configure.notify = handle_request_configure;
300 330
331 wl_signal_add(&xsurface->events.request_fullscreen,
332 &xwayland_view->request_fullscreen);
333 xwayland_view->request_fullscreen.notify = handle_request_fullscreen;
334
301 wl_signal_add(&xsurface->events.unmap, &xwayland_view->unmap); 335 wl_signal_add(&xsurface->events.unmap, &xwayland_view->unmap);
302 xwayland_view->unmap.notify = handle_unmap; 336 xwayland_view->unmap.notify = handle_unmap;
303 337
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 09927a1a..f60c43b5 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -448,6 +448,20 @@ void seat_set_focus_warp(struct sway_seat *seat,
448 return; 448 return;
449 } 449 }
450 450
451 struct sway_container *last_workspace = last_focus;
452 if (last_workspace && last_workspace->type != C_WORKSPACE) {
453 last_workspace = container_parent(last_workspace, C_WORKSPACE);
454 }
455 struct sway_container *new_workspace = container;
456 if (new_workspace && new_workspace->type != C_WORKSPACE) {
457 new_workspace = container_parent(new_workspace, C_WORKSPACE);
458 }
459
460 if (last_workspace == new_workspace && last_workspace->fullscreen
461 && !container->sway_view->is_fullscreen) {
462 return;
463 }
464
451 struct sway_container *last_output = last_focus; 465 struct sway_container *last_output = last_focus;
452 if (last_output && last_output->type != C_OUTPUT) { 466 if (last_output && last_output->type != C_OUTPUT) {
453 last_output = container_parent(last_output, C_OUTPUT); 467 last_output = container_parent(last_output, C_OUTPUT);
diff --git a/sway/meson.build b/sway/meson.build
index 9e55e335..0bbb8da1 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -34,6 +34,7 @@ sway_sources = files(
34 'commands/exec_always.c', 34 'commands/exec_always.c',
35 'commands/focus.c', 35 'commands/focus.c',
36 'commands/focus_follows_mouse.c', 36 'commands/focus_follows_mouse.c',
37 'commands/fullscreen.c',
37 'commands/kill.c', 38 'commands/kill.c',
38 'commands/opacity.c', 39 'commands/opacity.c',
39 'commands/include.c', 40 'commands/include.c',
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index 0b637822..ae6db454 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -137,6 +137,21 @@ void container_move_to(struct sway_container *container,
137 || container_has_anscestor(container, destination)) { 137 || container_has_anscestor(container, destination)) {
138 return; 138 return;
139 } 139 }
140
141 if (container->sway_view->is_fullscreen) {
142 struct sway_container *old_workspace = container;
143 if (old_workspace->type != C_WORKSPACE) {
144 old_workspace = container_parent(old_workspace, C_WORKSPACE);
145 }
146 struct sway_container *new_workspace = destination;
147 if (new_workspace->type != C_WORKSPACE) {
148 new_workspace = container_parent(new_workspace, C_WORKSPACE);
149 }
150 if (old_workspace != new_workspace) {
151 view_set_fullscreen(container->sway_view, false);
152 }
153 }
154
140 struct sway_container *old_parent = container_remove_child(container); 155 struct sway_container *old_parent = container_remove_child(container);
141 container->width = container->height = 0; 156 container->width = container->height = 0;
142 struct sway_container *new_parent; 157 struct sway_container *new_parent;
@@ -557,6 +572,9 @@ void arrange_windows(struct sway_container *container,
557 return; 572 return;
558 case C_WORKSPACE: 573 case C_WORKSPACE:
559 { 574 {
575 if (container->fullscreen) {
576 return;
577 }
560 struct sway_container *output = 578 struct sway_container *output =
561 container_parent(container, C_OUTPUT); 579 container_parent(container, C_OUTPUT);
562 struct wlr_box *area = &output->sway_output->usable_area; 580 struct wlr_box *area = &output->sway_output->usable_area;
diff --git a/sway/tree/view.c b/sway/tree/view.c
index 99b44720..b958233b 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -2,6 +2,7 @@
2#include <wayland-server.h> 2#include <wayland-server.h>
3#include <wlr/types/wlr_output_layout.h> 3#include <wlr/types/wlr_output_layout.h>
4#include "log.h" 4#include "log.h"
5#include "sway/ipc-server.h"
5#include "sway/output.h" 6#include "sway/output.h"
6#include "sway/tree/container.h" 7#include "sway/tree/container.h"
7#include "sway/tree/layout.h" 8#include "sway/tree/layout.h"
@@ -73,7 +74,46 @@ void view_set_activated(struct sway_view *view, bool activated) {
73 } 74 }
74} 75}
75 76
77void view_set_fullscreen(struct sway_view *view, bool fullscreen) {
78 if (view->is_fullscreen == fullscreen) {
79 return;
80 }
81
82 struct sway_container *container = container_parent(view->swayc, C_OUTPUT);
83 struct sway_output *output = container->sway_output;
84 struct sway_container *workspace = container_parent(view->swayc, C_WORKSPACE);
85
86 if (view->impl->set_fullscreen) {
87 view->impl->set_fullscreen(view, fullscreen);
88 }
89
90 if (fullscreen) {
91 view->swayc->saved_x = view->swayc->x;
92 view->swayc->saved_y = view->swayc->y;
93 view->saved_width = view->width;
94 view->saved_height = view->height;
95 view_configure(view, 0, 0, output->wlr_output->width, output->wlr_output->height);
96 workspace->fullscreen = view;
97 } else {
98 view_configure(view, view->swayc->saved_x, view->swayc->saved_y,
99 view->saved_width, view->saved_height);
100 workspace->fullscreen = NULL;
101 }
102
103 view->is_fullscreen = fullscreen;
104 output_damage_whole(output);
105
106 arrange_windows(workspace, -1, -1);
107
108 ipc_event_window(view->swayc, "fullscreen_mode");
109}
110
76void view_close(struct sway_view *view) { 111void view_close(struct sway_view *view) {
112 if (view->is_fullscreen) {
113 struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
114 ws->fullscreen = NULL;
115 }
116
77 if (view->impl->close) { 117 if (view->impl->close) {
78 view->impl->close(view); 118 view->impl->close(view);
79 } 119 }