diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-04-16 20:36:40 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-04-16 20:36:40 +1000 |
commit | 52420cc24d61db8d22cf0d391f1f84b37bf087d5 (patch) | |
tree | f975a3708c0d1562a8d2fcdceaed9a76aadbf1f4 | |
parent | Merge pull request #1816 from thejan2009/multi-output-ws-destroy (diff) | |
download | sway-52420cc24d61db8d22cf0d391f1f84b37bf087d5.tar.gz sway-52420cc24d61db8d22cf0d391f1f84b37bf087d5.tar.zst sway-52420cc24d61db8d22cf0d391f1f84b37bf087d5.zip |
Implement fullscreen.
-rw-r--r-- | include/sway/ipc-server.h | 1 | ||||
-rw-r--r-- | include/sway/tree/container.h | 4 | ||||
-rw-r--r-- | include/sway/tree/view.h | 9 | ||||
-rw-r--r-- | sway/commands.c | 1 | ||||
-rw-r--r-- | sway/commands/fullscreen.c | 40 | ||||
-rw-r--r-- | sway/desktop/output.c | 24 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 26 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 34 | ||||
-rw-r--r-- | sway/input/seat.c | 14 | ||||
-rw-r--r-- | sway/meson.build | 1 | ||||
-rw-r--r-- | sway/tree/layout.c | 18 | ||||
-rw-r--r-- | sway/tree/view.c | 40 |
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 | ||
156 | void view_set_activated(struct sway_view *view, bool activated); | 163 | void view_set_activated(struct sway_view *view, bool activated); |
157 | 164 | ||
165 | void view_set_fullscreen(struct sway_view *view, bool fullscreen); | ||
166 | |||
158 | void view_close(struct sway_view *view); | 167 | void view_close(struct sway_view *view); |
159 | 168 | ||
160 | void view_damage(struct sway_view *view, bool whole); | 169 | void 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 | ||
10 | struct 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 | ||
288 | renderer_end: | 296 | renderer_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 | ||
121 | static 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 | |||
121 | static void for_each_surface(struct sway_view *view, | 129 | static 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 | ||
223 | static 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 | |||
213 | void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { | 235 | void 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 | ||
28 | static 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 | |||
28 | static void unmanaged_handle_commit(struct wl_listener *listener, void *data) { | 37 | static 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 | ||
194 | static 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 | |||
182 | static void _close(struct sway_view *view) { | 202 | static 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 | ||
288 | static 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 | |||
266 | void handle_xwayland_surface(struct wl_listener *listener, void *data) { | 296 | void 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 | ||
77 | void 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 | |||
76 | void view_close(struct sway_view *view) { | 111 | void 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 | } |