From 863914ec9574eb58cb0746d59f216997c4863cdf Mon Sep 17 00:00:00 2001
From: Brian Ashworth <bosrsf04@gmail.com>
Date: Mon, 23 Jul 2018 15:04:46 -0400
Subject: Switch to using a function to parse booleans

---
 sway/commands/fullscreen.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

(limited to 'sway/commands/fullscreen.c')

diff --git a/sway/commands/fullscreen.c b/sway/commands/fullscreen.c
index 0b5beaa2..b423fd23 100644
--- a/sway/commands/fullscreen.c
+++ b/sway/commands/fullscreen.c
@@ -5,6 +5,7 @@
 #include "sway/tree/container.h"
 #include "sway/tree/view.h"
 #include "sway/tree/layout.h"
+#include "util.h"
 
 struct cmd_results *cmd_fullscreen(int argc, char **argv) {
 	struct cmd_results *error = NULL;
@@ -18,17 +19,10 @@ struct cmd_results *cmd_fullscreen(int argc, char **argv) {
 				"Only views can fullscreen");
 	}
 	struct sway_view *view = container->sway_view;
-	bool wants_fullscreen;
+	bool wants_fullscreen = !view->is_fullscreen;
 
-	if (argc == 0 || strcmp(argv[0], "toggle") == 0) {
-		wants_fullscreen = !view->is_fullscreen;
-	} else if (strcmp(argv[0], "enable") == 0) {
-		wants_fullscreen = true;
-	} else if (strcmp(argv[0], "disable") == 0) {
-		wants_fullscreen = false;
-	} else {
-		return cmd_results_new(CMD_INVALID, "fullscreen",
-				"Expected 'fullscreen' or 'fullscreen <enable|disable|toggle>'");
+	if (argc) {
+		wants_fullscreen = parse_boolean(argv[0], view->is_fullscreen);
 	}
 
 	view_set_fullscreen(view, wants_fullscreen);
-- 
cgit v1.2.3


From 27a20a488465468511de9b2307941ac1bc4db8bf Mon Sep 17 00:00:00 2001
From: Ryan Dwyer <ryandwyer1@gmail.com>
Date: Wed, 25 Jul 2018 20:56:23 +1000
Subject: Allow containers to be fullscreen

---
 include/sway/tree/container.h | 23 +++++++++++-
 include/sway/tree/view.h      |  6 ---
 include/sway/tree/workspace.h |  2 +-
 sway/commands/fullscreen.c    | 18 ++++++---
 sway/commands/move.c          |  2 +-
 sway/desktop/output.c         | 14 ++++---
 sway/desktop/render.c         | 23 +++++++-----
 sway/desktop/transaction.c    |  2 +-
 sway/desktop/xdg_shell.c      |  4 +-
 sway/desktop/xdg_shell_v6.c   |  4 +-
 sway/desktop/xwayland.c       |  4 +-
 sway/input/cursor.c           | 14 ++-----
 sway/input/seat.c             |  3 +-
 sway/scratchpad.c             |  2 +-
 sway/tree/arrange.c           | 18 ++++++++-
 sway/tree/container.c         | 87 +++++++++++++++++++++++++++++++++++++++++++
 sway/tree/layout.c            | 83 ++++++++++++++++++++++++-----------------
 sway/tree/view.c              | 73 ++----------------------------------
 18 files changed, 226 insertions(+), 156 deletions(-)

(limited to 'sway/commands/fullscreen.c')

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 {
 	double swayc_x, swayc_y;
 	double swayc_width, swayc_height;
 
+	bool is_fullscreen;
+
 	bool has_gaps;
 	double current_gaps;
 	double gaps_inner;
@@ -74,7 +76,6 @@ struct sway_container_state {
 	// View properties
 	double view_x, view_y;
 	double view_width, view_height;
-	bool is_fullscreen;
 
 	enum sway_container_border border;
 	int border_thickness;
@@ -84,7 +85,7 @@ struct sway_container_state {
 	bool border_right;
 
 	// Workspace properties
-	struct sway_view *ws_fullscreen;
+	struct sway_container *ws_fullscreen;
 	struct sway_container *ws_floating;
 };
 
@@ -124,6 +125,8 @@ struct sway_container {
 	double saved_x, saved_y;
 	double saved_width, saved_height;
 
+	bool is_fullscreen;
+
 	// The gaps currently applied to the container.
 	double current_gaps;
 
@@ -335,4 +338,20 @@ bool container_has_urgent_child(struct sway_container *container);
  */
 void container_end_mouse_operation(struct sway_container *container);
 
+void container_set_fullscreen(struct sway_container *container, bool enable);
+
+/**
+ * Return true if the container is fullscreen, or a child of a fullscreen split
+ * container.
+ */
+bool container_is_fullscreen_or_child(struct sway_container *container);
+
+/**
+ * Wrap the children of parent in a new container. The new container will be the
+ * only child of parent.
+ *
+ * The new container is returned.
+ */
+struct sway_container *container_wrap_children(struct sway_container *parent);
+
 #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 {
 	// Used when changing a view from tiled to floating.
 	int natural_width, natural_height;
 
-	bool is_fullscreen;
-
 	char *title_format;
 	enum sway_container_border border;
 	int border_thickness;
@@ -251,10 +249,6 @@ void view_set_activated(struct sway_view *view, bool activated);
 
 void view_set_tiled(struct sway_view *view, bool tiled);
 
-void view_set_fullscreen_raw(struct sway_view *view, bool fullscreen);
-
-void view_set_fullscreen(struct sway_view *view, bool fullscreen);
-
 void view_close(struct sway_view *view);
 
 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;
 
 struct sway_workspace {
 	struct sway_container *swayc;
-	struct sway_view *fullscreen;
+	struct sway_container *fullscreen;
 	struct sway_container *floating;
 	list_t *output_priority;
 	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) {
 	}
 	struct sway_container *container =
 		config->handler_context.current_container;
-	if (container->type != C_VIEW) {
+	if (container->type == C_WORKSPACE && container->children->length == 0) {
 		return cmd_results_new(CMD_INVALID, "fullscreen",
-				"Only views can fullscreen");
+				"Can't fullscreen an empty workspace");
 	}
-	struct sway_view *view = container->sway_view;
-	bool wants_fullscreen = !view->is_fullscreen;
+	if (container->type == C_WORKSPACE) {
+		// Wrap the workspace's children in a container so we can fullscreen it
+		struct sway_container *workspace = container;
+		container = container_wrap_children(container);
+		workspace->layout = L_HORIZ;
+		seat_set_focus(config->handler_context.seat, container);
+	}
+	bool enable = !container->is_fullscreen;
 
 	if (argc) {
-		wants_fullscreen = parse_boolean(argv[0], view->is_fullscreen);
+		enable = parse_boolean(argv[0], container->is_fullscreen);
 	}
 
-	view_set_fullscreen(view, wants_fullscreen);
+	container_set_fullscreen(container, enable);
 
 	struct sway_container *workspace = container_parent(container, C_WORKSPACE);
 	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,
 				"Cannot move workspaces in a direction");
 	}
 	if (container_is_floating(container)) {
-		if (container->type == C_VIEW && container->sway_view->is_fullscreen) {
+		if (container->is_fullscreen) {
 			return cmd_results_new(CMD_FAILURE, "move",
 					"Cannot move fullscreen floating container");
 		}
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) {
 
 	struct sway_container *workspace = output_get_active_workspace(output);
 	if (workspace->current.ws_fullscreen) {
-		send_frame_done_container_iterator(
-			workspace->current.ws_fullscreen->swayc, &data);
-#ifdef HAVE_XWAYLAND
-		if (workspace->current.ws_fullscreen->type == SWAY_VIEW_XWAYLAND) {
-			send_frame_done_unmanaged(&data,
-				&root_container.sway_root->xwayland_unmanaged);
+		if (workspace->current.ws_fullscreen->type == C_VIEW) {
+			send_frame_done_container_iterator(
+				workspace->current.ws_fullscreen, &data);
+		} else {
+			send_frame_done_container(&data, workspace->current.ws_fullscreen);
 		}
+#ifdef HAVE_XWAYLAND
+		send_frame_done_unmanaged(&data,
+			&root_container.sway_root->xwayland_unmanaged);
 #endif
 	} else {
 		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,
 	}
 
 	struct sway_container *workspace = output_get_active_workspace(output);
-	struct sway_view *fullscreen_view = workspace->current.ws_fullscreen;
+	struct sway_container *fullscreen_con = workspace->current.ws_fullscreen;
 
 	if (output_has_opaque_overlay_layer_surface(output)) {
 		goto render_overlay;
 	}
 
-	if (fullscreen_view) {
+	if (fullscreen_con) {
 		float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
 
 		int nrects;
@@ -853,16 +853,21 @@ void output_render(struct sway_output *output, struct timespec *when,
 		}
 
 		// TODO: handle views smaller than the output
-		if (fullscreen_view->swayc->instructions->length) {
-			render_saved_view(fullscreen_view, output, damage, 1.0f);
+		if (fullscreen_con->type == C_VIEW) {
+			if (fullscreen_con->instructions->length) {
+				render_saved_view(fullscreen_con->sway_view,
+						output, damage, 1.0f);
 		} else {
-			render_view_surfaces(fullscreen_view, output, damage, 1.0f);
+				render_view_surfaces(fullscreen_con->sway_view,
+						output, damage, 1.0f);
+			}
+		} else {
+			render_container(output, damage, fullscreen_con,
+					fullscreen_con->current.focused);
 		}
 #ifdef HAVE_XWAYLAND
-		if (fullscreen_view->type == SWAY_VIEW_XWAYLAND) {
-			render_unmanaged(output, damage,
-				&root_container.sway_root->xwayland_unmanaged);
-		}
+		render_unmanaged(output, damage,
+			&root_container.sway_root->xwayland_unmanaged);
 #endif
 	} else {
 		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,
 	state->swayc_y = container->y;
 	state->swayc_width = container->width;
 	state->swayc_height = container->height;
+	state->is_fullscreen = container->is_fullscreen;
 	state->has_gaps = container->has_gaps;
 	state->current_gaps = container->current_gaps;
 	state->gaps_inner = container->gaps_inner;
@@ -122,7 +123,6 @@ static void copy_pending_state(struct sway_container *container,
 		state->view_y = view->y;
 		state->view_width = view->width;
 		state->view_height = view->height;
-		state->is_fullscreen = view->is_fullscreen;
 		state->border = view->border;
 		state->border_thickness = view->border_thickness;
 		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)
 		return;
 	}
 
-	view_set_fullscreen(view, e->fullscreen);
+	container_set_fullscreen(view->swayc, e->fullscreen);
 
 	struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
 	arrange_windows(output);
@@ -338,7 +338,7 @@ static void handle_map(struct wl_listener *listener, void *data) {
 	view_map(view, view->wlr_xdg_surface->surface);
 
 	if (xdg_surface->toplevel->client_pending.fullscreen) {
-		view_set_fullscreen(view, true);
+		container_set_fullscreen(view->swayc, true);
 		struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
 		arrange_windows(ws);
 	} 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)
 		return;
 	}
 
-	view_set_fullscreen(view, e->fullscreen);
+	container_set_fullscreen(view->swayc, e->fullscreen);
 
 	struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
 	arrange_windows(output);
@@ -333,7 +333,7 @@ static void handle_map(struct wl_listener *listener, void *data) {
 	view_map(view, view->wlr_xdg_surface_v6->surface);
 
 	if (xdg_surface->toplevel->client_pending.fullscreen) {
-		view_set_fullscreen(view, true);
+		container_set_fullscreen(view->swayc, true);
 		struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
 		arrange_windows(ws);
 	} 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) {
 	view_map(view, xsurface->surface);
 
 	if (xsurface->fullscreen) {
-		view_set_fullscreen(view, true);
+		container_set_fullscreen(view->swayc, true);
 		struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
 		arrange_windows(ws);
 	} else {
@@ -395,7 +395,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
 	if (!xsurface->mapped) {
 		return;
 	}
-	view_set_fullscreen(view, xsurface->fullscreen);
+	container_set_fullscreen(view->swayc, xsurface->fullscreen);
 
 	struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
 	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(
 		return ws;
 	}
 	if (ws->sway_workspace->fullscreen) {
-		struct wlr_surface *wlr_surface = ws->sway_workspace->fullscreen->surface;
-		if (wlr_surface_point_accepts_input(wlr_surface, ox, oy)) {
-			*sx = ox;
-			*sy = oy;
-			*surface = wlr_surface;
-			return ws->sway_workspace->fullscreen->swayc;
-		}
-		return NULL;
+		return container_at(ws->sway_workspace->fullscreen, lx, ly,
+				surface, sx, sy);
 	}
 	if ((*surface = layer_surface_at(output,
 				&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
@@ -438,8 +432,8 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor,
 		struct sway_container *cont) {
 	struct sway_seat *seat = cursor->seat;
 
-	// Deny moving or resizing a fullscreen view
-	if (cont->type == C_VIEW && cont->sway_view->is_fullscreen) {
+	// Deny moving or resizing a fullscreen container
+	if (container_is_fullscreen_or_child(cont)) {
 		seat_pointer_notify_button(seat, time_msec, button, state);
 		return;
 	}
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,
 
 	if (last_workspace && last_workspace == new_workspace
 			&& last_workspace->sway_workspace->fullscreen
-			&& container && container->type == C_VIEW
-			&& !container->sway_view->is_fullscreen) {
+			&& container && !container_is_fullscreen_or_child(container)) {
 		return;
 	}
 
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) {
     // If the current con or any of its parents are in fullscreen mode, we
     // first need to disable it before showing the scratchpad con.
 	if (ws->sway_workspace->fullscreen) {
-		view_set_fullscreen(ws->sway_workspace->fullscreen, false);
+		container_set_fullscreen(ws->sway_workspace->fullscreen, false);
 	}
 
 	// 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) {
 	container_set_dirty(workspace);
 	wlr_log(WLR_DEBUG, "Arranging workspace '%s' at %f, %f", workspace->name,
 			workspace->x, workspace->y);
-	arrange_floating(workspace->sway_workspace->floating);
-	arrange_children_of(workspace);
+	if (workspace->sway_workspace->fullscreen) {
+		struct sway_container *fs = workspace->sway_workspace->fullscreen;
+		fs->x = workspace->parent->x;
+		fs->y = workspace->parent->y;
+		fs->width = workspace->parent->width;
+		fs->height = workspace->parent->height;
+		if (fs->type == C_VIEW) {
+			view_autoconfigure(fs->sway_view);
+		} else {
+			arrange_children_of(fs);
+		}
+		container_set_dirty(fs);
+	} else {
+		arrange_floating(workspace->sway_workspace->floating);
+		arrange_children_of(workspace);
+	}
 }
 
 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) {
 		}
 	}
 }
+
+static void set_fullscreen_iterator(struct sway_container *con, void *data) {
+	if (con->type != C_VIEW) {
+		return;
+	}
+	if (con->sway_view->impl->set_fullscreen) {
+		bool *enable = data;
+		con->sway_view->impl->set_fullscreen(con->sway_view, *enable);
+	}
+}
+
+void container_set_fullscreen(struct sway_container *container, bool enable) {
+	if (container->is_fullscreen == enable) {
+		return;
+	}
+
+	struct sway_container *workspace = container_parent(container, C_WORKSPACE);
+	if (enable && workspace->sway_workspace->fullscreen) {
+		container_set_fullscreen(workspace->sway_workspace->fullscreen, false);
+	}
+
+	container_for_each_descendant_dfs(container,
+			set_fullscreen_iterator, &enable);
+
+	container->is_fullscreen = enable;
+
+	if (enable) {
+		workspace->sway_workspace->fullscreen = container;
+		container->saved_x = container->x;
+		container->saved_y = container->y;
+		container->saved_width = container->width;
+		container->saved_height = container->height;
+
+		struct sway_seat *seat;
+		struct sway_container *focus, *focus_ws;
+		wl_list_for_each(seat, &input_manager->seats, link) {
+			focus = seat_get_focus(seat);
+			if (focus) {
+				focus_ws = focus;
+				if (focus_ws->type != C_WORKSPACE) {
+					focus_ws = container_parent(focus_ws, C_WORKSPACE);
+				}
+				if (focus_ws == workspace) {
+					seat_set_focus(seat, container);
+				}
+			}
+		}
+	} else {
+		workspace->sway_workspace->fullscreen = NULL;
+		if (container_is_floating(container)) {
+			container->x = container->saved_x;
+			container->y = container->saved_y;
+			container->width = container->saved_width;
+			container->height = container->saved_height;
+		} else {
+			container->width = container->saved_width;
+			container->height = container->saved_height;
+		}
+	}
+
+	container_end_mouse_operation(container);
+
+	ipc_event_window(container, "fullscreen_mode");
+}
+
+bool container_is_fullscreen_or_child(struct sway_container *container) {
+	do {
+		if (container->is_fullscreen) {
+			return true;
+		}
+		container = container->parent;
+	} while (container && container->type != C_WORKSPACE);
+
+	return false;
+}
+
+struct sway_container *container_wrap_children(struct sway_container *parent) {
+	struct sway_container *middle = container_create(C_CONTAINER);
+	middle->layout = parent->layout;
+	while (parent->children->length) {
+		struct sway_container *child = parent->children->items[0];
+		container_remove_child(child);
+		container_add_child(middle, child);
+	}
+	container_add_child(parent, middle);
+	return middle;
+}
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) {
 
 static void container_handle_fullscreen_reparent(struct sway_container *con,
 		struct sway_container *old_parent) {
-	if (con->type != C_VIEW || !con->sway_view->is_fullscreen) {
+	if (!con->is_fullscreen) {
 		return;
 	}
-	struct sway_view *view = con->sway_view;
 	struct sway_container *old_workspace = old_parent;
 	if (old_workspace && old_workspace->type != C_WORKSPACE) {
 		old_workspace = container_parent(old_workspace, C_WORKSPACE);
@@ -85,19 +84,27 @@ static void container_handle_fullscreen_reparent(struct sway_container *con,
 
 	// Mark the new workspace as fullscreen
 	if (new_workspace->sway_workspace->fullscreen) {
-		view_set_fullscreen(new_workspace->sway_workspace->fullscreen, false);
+		container_set_fullscreen(
+				new_workspace->sway_workspace->fullscreen, false);
 	}
-	new_workspace->sway_workspace->fullscreen = view;
-	// Resize view to new output dimensions
+	new_workspace->sway_workspace->fullscreen = con;
+
+	// Resize container to new output dimensions
 	struct sway_container *output = new_workspace->parent;
-	view->x = output->x;
-	view->y = output->y;
-	view->width = output->width;
-	view->height = output->height;
 	con->x = output->x;
 	con->y = output->y;
 	con->width = output->width;
 	con->height = output->height;
+
+	if (con->type == C_VIEW) {
+		struct sway_view *view = con->sway_view;
+		view->x = output->x;
+		view->y = output->y;
+		view->width = output->width;
+		view->height = output->height;
+	} else {
+		arrange_windows(new_workspace);
+	}
 }
 
 void container_insert_child(struct sway_container *parent,
@@ -146,7 +153,7 @@ void container_add_child(struct sway_container *parent,
 }
 
 struct sway_container *container_remove_child(struct sway_container *child) {
-	if (child->type == C_VIEW && child->sway_view->is_fullscreen) {
+	if (child->is_fullscreen) {
 		struct sway_container *workspace = container_parent(child, C_WORKSPACE);
 		workspace->sway_workspace->fullscreen = NULL;
 	}
@@ -229,10 +236,10 @@ void container_move_to(struct sway_container *container,
 			if (focus_ws->type != C_WORKSPACE) {
 				focus_ws = container_parent(focus_ws, C_WORKSPACE);
 			}
-			seat_set_focus(seat,
-					new_workspace->sway_workspace->fullscreen->swayc);
-			if (focus_ws != new_workspace) {
-				seat_set_focus(seat, focus);
+			if (focus_ws == new_workspace) {
+				struct sway_container *new_focus = seat_get_focus_inactive(seat,
+						new_workspace->sway_workspace->fullscreen);
+				seat_set_focus(seat, new_focus);
 			}
 		}
 	}
@@ -375,10 +382,16 @@ void container_move(struct sway_container *container,
 	struct sway_container *sibling = NULL;
 	struct sway_container *current = container;
 	struct sway_container *parent = current->parent;
+	struct sway_container *top = &root_container;
 
 	// If moving a fullscreen view, only consider outputs
-	if (container->type == C_VIEW && container->sway_view->is_fullscreen) {
+	if (container->is_fullscreen) {
 		current = container_parent(container, C_OUTPUT);
+	} else if (container_is_fullscreen_or_child(container)) {
+		// If we've fullscreened a split container, only allow the child to move
+		// around within the fullscreen parent.
+		struct sway_container *ws = container_parent(container, C_WORKSPACE);
+		top = ws->sway_workspace->fullscreen;
 	}
 
 	struct sway_container *new_parent = container_flatten(parent);
@@ -388,7 +401,7 @@ void container_move(struct sway_container *container,
 	}
 
 	while (!sibling) {
-		if (current->type == C_ROOT) {
+		if (current == top) {
 			return;
 		}
 
@@ -452,8 +465,9 @@ void container_move(struct sway_container *container,
 				if ((index == parent->children->length - 1 && offs > 0)
 						|| (index == 0 && offs < 0)) {
 					if (current->parent == container->parent) {
-						if (parent->layout == L_TABBED
-								|| parent->layout == L_STACKED) {
+						if (!parent->is_fullscreen &&
+								(parent->layout == L_TABBED ||
+								 parent->layout == L_STACKED)) {
 							move_out_of_tabs_stacks(container, current,
 									move_dir, offs);
 							return;
@@ -474,8 +488,8 @@ void container_move(struct sway_container *container,
 					sibling = parent->children->items[index + offs];
 					wlr_log(WLR_DEBUG, "Selecting sibling id:%zd", sibling->id);
 				}
-			} else if (parent->layout == L_TABBED
-					|| parent->layout == L_STACKED) {
+			} else if (!parent->is_fullscreen && (parent->layout == L_TABBED ||
+						parent->layout == L_STACKED)) {
 				move_out_of_tabs_stacks(container, current, move_dir, offs);
 				return;
 			} else {
@@ -707,16 +721,16 @@ struct sway_container *container_get_in_direction(
 		return NULL;
 	}
 
-	if (container->type == C_VIEW && container->sway_view->is_fullscreen) {
-		if (dir == MOVE_PARENT || dir == MOVE_CHILD) {
+	if (dir == MOVE_CHILD) {
+		return seat_get_focus_inactive(seat, container);
+	}
+	if (container->is_fullscreen) {
+		if (dir == MOVE_PARENT) {
 			return NULL;
 		}
 		container = container_parent(container, C_OUTPUT);
 		parent = container->parent;
 	} else {
-		if (dir == MOVE_CHILD) {
-			return seat_get_focus_inactive(seat, container);
-		}
 		if (dir == MOVE_PARENT) {
 			if (parent->type == C_OUTPUT) {
 				return NULL;
@@ -767,7 +781,8 @@ struct sway_container *container_get_in_direction(
 			}
 			sway_assert(next_workspace, "Next container has no workspace");
 			if (next_workspace->sway_workspace->fullscreen) {
-				return next_workspace->sway_workspace->fullscreen->swayc;
+				return seat_get_focus_inactive(seat,
+						next_workspace->sway_workspace->fullscreen);
 			}
 			if (next->children && next->children->length) {
 				// TODO consider floating children as well
@@ -1014,13 +1029,13 @@ void container_swap(struct sway_container *con1, struct sway_container *con2) {
 
 	wlr_log(WLR_DEBUG, "Swapping containers %zu and %zu", con1->id, con2->id);
 
-	int fs1 = con1->type == C_VIEW && con1->sway_view->is_fullscreen;
-	int fs2 = con2->type == C_VIEW && con2->sway_view->is_fullscreen;
+	int fs1 = con1->is_fullscreen;
+	int fs2 = con2->is_fullscreen;
 	if (fs1) {
-		view_set_fullscreen(con1->sway_view, false);
+		container_set_fullscreen(con1, false);
 	}
 	if (fs2) {
-		view_set_fullscreen(con2->sway_view, false);
+		container_set_fullscreen(con2, false);
 	}
 
 	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) {
 		prev_workspace_name = stored_prev_name;
 	}
 
-	if (fs1 && con2->type == C_VIEW) {
-		view_set_fullscreen(con2->sway_view, true);
+	if (fs1) {
+		container_set_fullscreen(con2, true);
 	}
-	if (fs2 && con1->type == C_VIEW) {
-		view_set_fullscreen(con1->sway_view, true);
+	if (fs2) {
+		container_set_fullscreen(con1, true);
 	}
 }
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) {
 
 	struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
 
-	if (view->is_fullscreen) {
+	if (view->swayc->is_fullscreen) {
 		view->x = output->x;
 		view->y = output->y;
 		view->width = output->width;
@@ -233,10 +233,6 @@ void view_autoconfigure(struct sway_view *view) {
 		return;
 	}
 
-	if (container_is_floating(view->swayc)) {
-		return;
-	}
-
 	struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
 
 	int other_views = 0;
@@ -349,68 +345,6 @@ void view_set_tiled(struct sway_view *view, bool tiled) {
 	}
 }
 
-void view_set_fullscreen(struct sway_view *view, bool fullscreen) {
-	if (view->is_fullscreen == fullscreen) {
-		return;
-	}
-
-	struct sway_container *workspace =
-		container_parent(view->swayc, C_WORKSPACE);
-
-	if (view->impl->set_fullscreen) {
-		view->impl->set_fullscreen(view, fullscreen);
-	}
-
-	view->is_fullscreen = fullscreen;
-
-	if (fullscreen) {
-		if (workspace->sway_workspace->fullscreen) {
-			view_set_fullscreen(workspace->sway_workspace->fullscreen, false);
-		}
-		workspace->sway_workspace->fullscreen = view;
-		view->saved_x = view->x;
-		view->saved_y = view->y;
-		view->saved_width = view->width;
-		view->saved_height = view->height;
-		view->swayc->saved_x = view->swayc->x;
-		view->swayc->saved_y = view->swayc->y;
-		view->swayc->saved_width = view->swayc->width;
-		view->swayc->saved_height = view->swayc->height;
-
-		struct sway_seat *seat;
-		struct sway_container *focus, *focus_ws;
-		wl_list_for_each(seat, &input_manager->seats, link) {
-			focus = seat_get_focus(seat);
-			if (focus) {
-				focus_ws = focus;
-				if (focus && focus_ws->type != C_WORKSPACE) {
-					focus_ws = container_parent(focus_ws, C_WORKSPACE);
-				}
-				seat_set_focus(seat, view->swayc);
-				if (focus_ws != workspace) {
-					seat_set_focus(seat, focus);
-				}
-			}
-		}
-	} else {
-		workspace->sway_workspace->fullscreen = NULL;
-		if (container_is_floating(view->swayc)) {
-			view->x = view->saved_x;
-			view->y = view->saved_y;
-			view->width = view->saved_width;
-			view->height = view->saved_height;
-			container_set_geometry_from_floating_view(view->swayc);
-		} else {
-			view->swayc->width = view->swayc->saved_width;
-			view->swayc->height = view->swayc->saved_height;
-		}
-	}
-
-	container_end_mouse_operation(view->swayc);
-
-	ipc_event_window(view->swayc, "fullscreen_mode");
-}
-
 void view_close(struct sway_view *view) {
 	if (view->impl->close) {
 		view->impl->close(view);
@@ -680,7 +614,7 @@ void view_unmap(struct sway_view *view) {
 	struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
 
 	struct sway_container *parent;
-	if (view->is_fullscreen) {
+	if (view->swayc->is_fullscreen) {
 		ws->sway_workspace->fullscreen = NULL;
 		parent = container_destroy(view->swayc);
 
@@ -1133,7 +1067,8 @@ bool view_is_visible(struct sway_view *view) {
 		container = container->parent;
 	}
 	// Check view isn't hidden by another fullscreen view
-	if (workspace->sway_workspace->fullscreen && !view->is_fullscreen) {
+	if (workspace->sway_workspace->fullscreen &&
+			!container_is_fullscreen_or_child(view->swayc)) {
 		return false;
 	}
 	// Check the workspace is visible
-- 
cgit v1.2.3