From 1a1ac64662a603fdeb7025bed3822e24f9158076 Mon Sep 17 00:00:00 2001
From: taiyu <taiyu.len@gmail.com>
Date: Fri, 21 Aug 2015 10:28:37 -0700
Subject: [PATCH 1/5] bugfixes, renames

---
 include/container.h |  13 ++++-
 include/layout.h    |   7 ---
 include/workspace.h |   4 +-
 sway/commands.c     |  56 +++++++++++----------
 sway/container.c    | 118 ++++++++++++++++++++++++++++++++++----------
 sway/focus.c        |  46 ++++++++---------
 sway/handlers.c     |  22 ++++-----
 sway/layout.c       |  37 ++------------
 sway/log.c          |   5 +-
 sway/workspace.c    |  27 +++++-----
 10 files changed, 187 insertions(+), 148 deletions(-)

diff --git a/include/container.h b/include/container.h
index 4e21461c..2ced248b 100644
--- a/include/container.h
+++ b/include/container.h
@@ -81,13 +81,22 @@ swayc_t *destroy_view(swayc_t *view);
 
 // Container Lookup
 
+swayc_t *swayc_by_test(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data);
 swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types);
 swayc_t *swayc_parent_by_layout(swayc_t *container, enum swayc_layouts);
+swayc_t *swayc_by_handle(wlc_handle handle);
+swayc_t *swayc_active_output(void);
+swayc_t *swayc_active_workspace(void);
+swayc_t *swayc_active_workspace_for(swayc_t *view);
+
+// Container information
+
+bool swayc_is_fullscreen(swayc_t *view);
+
+// Mapping functions
 
-swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data);
 void container_map(swayc_t *, void (*f)(swayc_t *, void *), void *);
 
-
 // Mappings
 void set_view_visibility(swayc_t *view, void *data);
 void reset_gaps(swayc_t *view, void *data);
diff --git a/include/layout.h b/include/layout.h
index 55bb6709..7b8829ed 100644
--- a/include/layout.h
+++ b/include/layout.h
@@ -19,17 +19,10 @@ swayc_t *remove_child(swayc_t *child);
 
 void move_container(swayc_t* container,swayc_t* root,enum movement_direction direction);
 
-
 // Layout
 void arrange_windows(swayc_t *container, double width, double height);
 
-// Focus
-void unfocus_all(swayc_t *container);
-void focus_view(swayc_t *view);
-void focus_view_for(swayc_t *ancestor, swayc_t *container);
-
 swayc_t *get_focused_container(swayc_t *parent);
-swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent);
 swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir);
 
 void recursive_resize(swayc_t *container, double amount, enum wlc_resize_edge edge);
diff --git a/include/workspace.h b/include/workspace.h
index 042a15d9..d447ac2d 100644
--- a/include/workspace.h
+++ b/include/workspace.h
@@ -5,11 +5,9 @@
 #include "list.h"
 #include "layout.h"
 
-extern swayc_t *active_workspace;
-
 char *workspace_next_name(void);
 swayc_t *workspace_create(const char*);
-swayc_t *workspace_find_by_name(const char*);
+swayc_t *workspace_by_name(const char*);
 void workspace_switch(swayc_t*);
 void workspace_output_next();
 void workspace_next();
diff --git a/sway/commands.c b/sway/commands.c
index e90a40a3..e485cdb5 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -208,16 +208,16 @@ static bool cmd_floating(struct sway_config *config, int argc, char **argv) {
 			destroy_container(remove_child(view));
 
 			// and move it into workspace floating
-			add_floating(active_workspace,view);
-			view->x = (active_workspace->width - view->width)/2;
-			view->y = (active_workspace->height - view->height)/2;
+			add_floating(swayc_active_workspace(),view);
+			view->x = (swayc_active_workspace()->width - view->width)/2;
+			view->y = (swayc_active_workspace()->height - view->height)/2;
 			if (view->desired_width != -1) {
 				view->width = view->desired_width;
 			}
 			if (view->desired_height != -1) {
 				view->height = view->desired_height;
 			}
-			arrange_windows(active_workspace, -1, -1);
+			arrange_windows(swayc_active_workspace(), -1, -1);
 		} else {
 			// Delete the view from the floating list and unset its is_floating flag
 			// Using length-1 as the index is safe because the view must be the currently
@@ -228,7 +228,7 @@ static bool cmd_floating(struct sway_config *config, int argc, char **argv) {
 			swayc_t *focused = container_under_pointer();
 			// If focused is null, it's because the currently focused container is a workspace
 			if (focused == NULL) {
-				focused = active_workspace;
+				focused = swayc_active_workspace();
 			}
 			set_focused_container(focused);
 
@@ -244,7 +244,7 @@ static bool cmd_floating(struct sway_config *config, int argc, char **argv) {
 			}
 			// Refocus on the view once its been put back into the layout
 			view->width = view->height = 0;
-			arrange_windows(active_workspace, -1, -1);
+			arrange_windows(swayc_active_workspace(), -1, -1);
 		}
 		set_focused_container(view);
 	}
@@ -293,37 +293,38 @@ static bool cmd_focus(struct sway_config *config, int argc, char **argv) {
 		return move_focus(MOVE_PARENT);
 	} else if (strcasecmp(argv[0], "mode_toggle") == 0) {
 		int i;
-		swayc_t *focused = get_focused_view(active_workspace);
+		swayc_t *workspace = swayc_active_workspace();
+		swayc_t *focused = get_focused_view(workspace);
 		if (focused->is_floating) {
-			if (active_workspace->children->length > 0) {
-				for (i = 0;i < active_workspace->floating->length; i++) {
-					if (active_workspace->floating->items[i] == focused) {
+			if (workspace->children->length > 0) {
+				for (i = 0;i < workspace->floating->length; i++) {
+					if (workspace->floating->items[i] == focused) {
 						floating_toggled_index = i;
 						break;
 					}
 				}
-				if (active_workspace->children->length > tiled_toggled_index) {
-					set_focused_container(get_focused_view(active_workspace->children->items[tiled_toggled_index]));
+				if (workspace->children->length > tiled_toggled_index) {
+					set_focused_container(get_focused_view(workspace->children->items[tiled_toggled_index]));
 				} else {
-					set_focused_container(get_focused_view(active_workspace->children->items[0]));
+					set_focused_container(get_focused_view(workspace->children->items[0]));
 					tiled_toggled_index = 0;
 				}
 			}
 		} else {
-			if (active_workspace->floating->length > 0) {
-				for (i = 0;i < active_workspace->children->length; i++) {
-					if (active_workspace->children->items[i] == focused) {
+			if (workspace->floating->length > 0) {
+				for (i = 0;i < workspace->children->length; i++) {
+					if (workspace->children->items[i] == focused) {
 						tiled_toggled_index = i;
 						break;
 					}
 				}
-				if (active_workspace->floating->length > floating_toggled_index) {
-					swayc_t *floating = active_workspace->floating->items[floating_toggled_index];
+				if (workspace->floating->length > floating_toggled_index) {
+					swayc_t *floating = workspace->floating->items[floating_toggled_index];
 					set_focused_container(get_focused_view(floating));
 				} else {
-					swayc_t *floating = active_workspace->floating->items[active_workspace->floating->length - 1];
+					swayc_t *floating = workspace->floating->items[workspace->floating->length - 1];
 					set_focused_container(get_focused_view(floating));
-					tiled_toggled_index = active_workspace->floating->length - 1;
+					tiled_toggled_index = workspace->floating->length - 1;
 				}
 			}
 		}
@@ -459,7 +460,7 @@ static bool cmd_resize(struct sway_config *config, int argc, char **argv) {
 		amount *= -1;
 	}
 
-	swayc_t *parent = get_focused_view(active_workspace);
+	swayc_t *parent = get_focused_view(swayc_active_workspace());
 	swayc_t *focused = parent;
 	swayc_t *sibling;
 	if (!parent) {
@@ -529,7 +530,7 @@ static bool cmd_resize(struct sway_config *config, int argc, char **argv) {
 		}
 		// Recursive resize does not handle positions, let arrange_windows
 		// take care of that.
-		arrange_windows(active_workspace, -1, -1);
+		arrange_windows(swayc_active_workspace(), -1, -1);
 		return true;
 	} else if (strcmp(argv[1], "height") == 0) {
 		int tnumber = 0;
@@ -589,7 +590,7 @@ static bool cmd_resize(struct sway_config *config, int argc, char **argv) {
 				}
 			}
 		}
-		arrange_windows(active_workspace, -1, -1);
+		arrange_windows(swayc_active_workspace(), -1, -1);
 		return true;
 	}
 	return true;
@@ -616,8 +617,12 @@ static bool _do_split(struct sway_config *config, int argc, char **argv, int lay
 	}
 	swayc_t *focused = get_focused_container(&root_container);
 
+	// Case of floating window, dont split
+	if (focused->is_floating) {
+		return true;
+	}
+	/* Case that focus is on an workspace with 0/1 children.change its layout */
 	if (focused->type == C_WORKSPACE && focused->children->length <= 1) {
-		/* Case that focus is on an workspace with 0/1 children.change its layout */
 		sway_log(L_DEBUG, "changing workspace layout");
 		focused->layout = layout;
 	} else if (focused->type != C_WORKSPACE && focused->parent->children->length == 1) {
@@ -632,7 +637,6 @@ static bool _do_split(struct sway_config *config, int argc, char **argv, int lay
 		set_focused_container(focused);
 		arrange_windows(parent, -1, -1);
 	}
-
 	return true;
 }
 
@@ -721,7 +725,7 @@ static bool cmd_workspace(struct sway_config *config, int argc, char **argv) {
 			return true;
 		}
 
-		swayc_t *workspace = workspace_find_by_name(argv[0]);
+		swayc_t *workspace = workspace_by_name(argv[0]);
 		if (!workspace) {
 			workspace = workspace_create(argv[0]);
 		}
diff --git a/sway/container.c b/sway/container.c
index 7ccc2e09..5f1510a9 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -57,10 +57,6 @@ static void free_swayc(swayc_t *cont) {
 
 // New containers
 
-static bool workspace_test(swayc_t *view, void *name) {
-	return strcasecmp(view->name, (char *)name) == 0;
-}
-
 swayc_t *new_output(wlc_handle handle) {
 	const struct wlc_size* size = wlc_output_get_resolution(handle);
 	const char *name = wlc_output_get_name(handle);
@@ -84,7 +80,7 @@ swayc_t *new_output(wlc_handle handle) {
 			if (strcasecmp(wso->output, name) == 0) {
 				sway_log(L_DEBUG, "Matched workspace to output: %s for %s", wso->workspace, wso->output);
 				// Check if any other workspaces are using this name
-				if (find_container(&root_container, workspace_test, wso->workspace)) {
+				if (workspace_by_name(wso->workspace)) {
 					sway_log(L_DEBUG, "But it's already taken");
 					break;
 				}
@@ -128,7 +124,8 @@ swayc_t *new_workspace(swayc_t *output, const char *name) {
 }
 
 swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) {
-	if (!ASSERT_NONNULL(child)) {
+	if (!ASSERT_NONNULL(child)
+			&& !sway_assert(!child->is_floating, "cannot create container around floating window")) {
 		return NULL;
 	}
 	swayc_t *cont = new_swayc(C_CONTAINER);
@@ -207,6 +204,9 @@ swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {
 }
 
 swayc_t *new_floating_view(wlc_handle handle) {
+	if (swayc_active_workspace() == NULL) {
+		return NULL;
+	}
 	const char *title = wlc_view_get_title(handle);
 	swayc_t *view = new_swayc(C_VIEW);
 	sway_log(L_DEBUG, "Adding new view %lu:%x:%s as a floating view",
@@ -220,8 +220,8 @@ swayc_t *new_floating_view(wlc_handle handle) {
 	const struct wlc_geometry* geometry = wlc_view_get_geometry(handle);
 
 	// give it requested geometry, but place in center
-	view->x = (active_workspace->width - geometry->size.w) / 2;
-	view->y = (active_workspace->height- geometry->size.h) / 2;
+	view->x = (swayc_active_workspace()->width - geometry->size.w) / 2;
+	view->y = (swayc_active_workspace()->height- geometry->size.h) / 2;
 	view->width = geometry->size.w;
 	view->height = geometry->size.h;
 
@@ -231,10 +231,10 @@ swayc_t *new_floating_view(wlc_handle handle) {
 	view->is_floating = true;
 
 	// Case of focused workspace, just create as child of it
-	list_add(active_workspace->floating, view);
-	view->parent = active_workspace;
-	if (active_workspace->focused == NULL) {
-		set_focused_container_for(active_workspace, view);
+	list_add(swayc_active_workspace()->floating, view);
+	view->parent = swayc_active_workspace();
+	if (swayc_active_workspace()->focused == NULL) {
+		set_focused_container_for(swayc_active_workspace(), view);
 	}
 	return view;
 }
@@ -306,6 +306,35 @@ swayc_t *destroy_view(swayc_t *view) {
 
 // Container lookup
 
+
+swayc_t *swayc_by_test(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) {
+	if (!container->children) {
+		return NULL;
+	}
+	// Special case for checking floating stuff
+	int i;
+	if (container->type == C_WORKSPACE) {
+		for (i = 0; i < container->floating->length; ++i) {
+			swayc_t *child = container->floating->items[i];
+			if (test(child, data)) {
+				return child;
+			}
+		}
+	}
+	for (i = 0; i < container->children->length; ++i) {
+		swayc_t *child = container->children->items[i];
+		if (test(child, data)) {
+			return child;
+		} else {
+			swayc_t *res = swayc_by_test(child, test, data);
+			if (res) {
+				return res;
+			}
+		}
+	}
+	return NULL;
+}
+
 swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) {
 	if (!ASSERT_NONNULL(container)) {
 		return NULL;
@@ -332,27 +361,30 @@ swayc_t *swayc_parent_by_layout(swayc_t *container, enum swayc_layouts layout) {
 	return container;
 }
 
-swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) {
-	if (!container->children) {
+static swayc_t *_swayc_by_handle_helper(wlc_handle handle, swayc_t *parent) {
+	if (!parent || !parent->children) {
 		return NULL;
 	}
-	// Special case for checking floating stuff
-	int i;
-	if (container->type == C_WORKSPACE) {
-		for (i = 0; i < container->floating->length; ++i) {
-			swayc_t *child = container->floating->items[i];
-			if (test(child, data)) {
-				return child;
+	int i, len;
+	swayc_t **child;
+	if (parent->type == C_WORKSPACE) {
+		len = parent->floating->length;
+		child = (swayc_t **)parent->floating->items;
+		for (i = 0; i < len; ++i, ++child) {
+			if ((*child)->handle == handle) {
+				return *child;
 			}
 		}
 	}
-	for (i = 0; i < container->children->length; ++i) {
-		swayc_t *child = container->children->items[i];
-		if (test(child, data)) {
-			return child;
+
+	len = parent->children->length;
+	child = (swayc_t**)parent->children->items;
+	for (i = 0; i < len; ++i, ++child) {
+		if ((*child)->handle == handle) {
+			return *child;
 		} else {
-			swayc_t *res = find_container(child, test, data);
-			if (res) {
+			swayc_t *res;
+			if ((res = _swayc_by_handle_helper(handle, *child))) {
 				return res;
 			}
 		}
@@ -360,6 +392,38 @@ swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *da
 	return NULL;
 }
 
+swayc_t *swayc_by_handle(wlc_handle handle) {
+	return _swayc_by_handle_helper(handle, &root_container);
+}
+
+swayc_t *swayc_active_output(void) {
+	return root_container.focused;
+}
+
+swayc_t *swayc_active_workspace(void) {
+	return root_container.focused ? root_container.focused->focused : NULL;
+}
+
+swayc_t *swayc_active_workspace_for(swayc_t *cont) {
+	if (! cont) {
+		return NULL;
+	}
+	switch (cont->type) {
+	case C_ROOT: cont = cont->focused;
+	case C_OUTPUT: cont = cont->focused;
+	case C_WORKSPACE: return cont;
+	default: return swayc_parent_by_type(cont, C_WORKSPACE);
+	}
+}
+
+// Container information
+
+bool swayc_is_fullscreen(swayc_t *view) {
+	return view && view->type == C_VIEW && (wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN);
+}
+
+// Mapping
+
 void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
 	if (container && container->children && container->children->length)  {
 		int i;
diff --git a/sway/focus.c b/sway/focus.c
index 5008dbbf..a3e5e77a 100644
--- a/sway/focus.c
+++ b/sway/focus.c
@@ -21,8 +21,6 @@ static void update_focus(swayc_t *c) {
 		// Case where output changes
 		case C_OUTPUT:
 			wlc_output_focus(c->handle);
-			// Set new workspace to the outputs focused workspace
-			active_workspace = c->focused;
 			break;
 
 		// Case where workspace changes
@@ -39,7 +37,6 @@ static void update_focus(swayc_t *c) {
 				c->parent->focused = c;
 				destroy_workspace(ws);
 			}
-			active_workspace = c;
 			break;
 
 		default:
@@ -54,8 +51,8 @@ static void update_focus(swayc_t *c) {
 }
 
 bool move_focus(enum movement_direction direction) {
-	swayc_t *view = get_swayc_in_direction(
-			get_focused_container(&root_container), direction);
+	swayc_t *view = get_focused_container(&root_container);
+	view = get_swayc_in_direction(view, direction);
 	if (view) {
 		if (direction == MOVE_PARENT) {
 			set_focused_container(view);
@@ -68,13 +65,12 @@ bool move_focus(enum movement_direction direction) {
 }
 
 swayc_t *get_focused_container(swayc_t *parent) {
-	while (parent && !parent->is_focused) {
-		parent = parent->focused;
+	if (!parent) {
+		return swayc_active_workspace();
 	}
-	// just incase
-	if (parent == NULL) {
-		sway_log(L_DEBUG, "get_focused_container unable to find container");
-		return active_workspace;
+	// get focusde container
+	while (!parent->is_focused && parent->focused) {
+		parent = parent->focused;
 	}
 	return parent;
 }
@@ -85,9 +81,13 @@ void set_focused_container(swayc_t *c) {
 	}
 	sway_log(L_DEBUG, "Setting focus to %p:%ld", c, c->handle);
 
-	// Find previous focused view, and the new focused view, if they are the same return
-	swayc_t *focused = get_focused_view(&root_container);
-	swayc_t *workspace = active_workspace;
+	// Get workspace for c, get that workspaces current focused container.
+	swayc_t *workspace = swayc_active_workspace_for(c);
+	swayc_t *focused = get_focused_view(workspace);
+	// if the workspace we are changing focus to has a fullscreen view return
+	if (swayc_is_fullscreen(focused) && focused != c) {
+		return;
+	}
 
 	// update container focus from here to root, making necessary changes along
 	// the way
@@ -101,13 +101,6 @@ void set_focused_container(swayc_t *c) {
 		p->is_focused = false;
 	}
 
-	// if the workspace is the same, and previous focus is fullscreen, dont
-	// change focus
-	if (workspace == active_workspace
-		&& wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) {
-		return;
-	}
-
 	// get new focused view and set focus to it.
 	p = get_focused_view(c);
 	if (p->type == C_VIEW && !(wlc_view_get_type(p->handle) & WLC_BIT_POPUP)) {
@@ -137,6 +130,15 @@ void set_focused_container_for(swayc_t *a, swayc_t *c) {
 			return;
 		}
 	}
+
+	// Get workspace for c, get that workspaces current focused container.
+	swayc_t *workspace = swayc_active_workspace_for(c);
+	swayc_t *focused = get_focused_view(workspace);
+	// if the workspace we are changing focus to has a fullscreen view return
+	if (swayc_is_fullscreen(focused) && c != focused) {
+		return;
+	}
+
 	// Check if we changing a parent container that will see chnage
 	bool effective = true;
 	while (find != &root_container) {
@@ -171,7 +173,7 @@ swayc_t *get_focused_view(swayc_t *parent) {
 		parent = parent->focused;
 	}
 	if (parent == NULL) {
-		return active_workspace;
+		return swayc_active_workspace_for(parent);
 	}
 	return parent;
 }
diff --git a/sway/handlers.c b/sway/handlers.c
index 78f8927d..8dc409e1 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -86,7 +86,7 @@ static bool handle_output_created(wlc_handle output) {
 	swayc_t *op = new_output(output);
 
 	// Switch to workspace if we need to
-	if (active_workspace == NULL) {
+	if (swayc_active_workspace() == NULL) {
 		swayc_t *ws = op->children->items[0];
 		workspace_switch(ws);
 	}
@@ -104,9 +104,7 @@ static void handle_output_destroyed(wlc_handle output) {
 	if (i < list->length) {
 		destroy_output(list->items[i]);
 	}
-	if (list->length == 0) {
-		active_workspace = NULL;
-	} else {
+	if (list->length > 0) {
 		// switch to other outputs active workspace
 		workspace_switch(((swayc_t *)root_container.children->items[0])->focused);
 	}
@@ -114,7 +112,7 @@ static void handle_output_destroyed(wlc_handle output) {
 
 static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) {
 	sway_log(L_DEBUG, "Output %u resolution changed to %d x %d", (unsigned int)output, to->w, to->h);
-	swayc_t *c = get_swayc_for_handle(output, &root_container);
+	swayc_t *c = swayc_by_handle(output);
 	if (!c) return;
 	c->width = to->w;
 	c->height = to->h;
@@ -122,7 +120,7 @@ static void handle_output_resolution_change(wlc_handle output, const struct wlc_
 }
 
 static void handle_output_focused(wlc_handle output, bool focus) {
-	swayc_t *c = get_swayc_for_handle(output, &root_container);
+	swayc_t *c = swayc_by_handle(output);
 	// if for some reason this output doesnt exist, create it.
 	if (!c) {
 		handle_output_created(output);
@@ -140,7 +138,7 @@ static bool handle_view_created(wlc_handle handle) {
 
 	// Get parent container, to add view in
 	if (parent) {
-		focused = get_swayc_for_handle(parent, &root_container);
+		focused = swayc_by_handle(parent);
 	}
 	if (!focused || focused->type == C_OUTPUT) {
 		focused = get_focused_container(&root_container);
@@ -197,7 +195,7 @@ static bool handle_view_created(wlc_handle handle) {
 
 static void handle_view_destroyed(wlc_handle handle) {
 	sway_log(L_DEBUG, "Destroying window %lu", handle);
-	swayc_t *view = get_swayc_for_handle(handle, &root_container);
+	swayc_t *view = swayc_by_handle(handle);
 
 	switch (wlc_view_get_type(handle)) {
 	// regular view created regularly
@@ -231,7 +229,7 @@ static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geo
 	// If the view is floating, then apply the geometry.
 	// Otherwise save the desired width/height for the view.
 	// This will not do anything for the time being as WLC improperly sends geometry requests
-	swayc_t *view = get_swayc_for_handle(handle, &root_container);
+	swayc_t *view = swayc_by_handle(handle);
 	if (view) {
 		view->desired_width = geometry->size.w;
 		view->desired_height = geometry->size.h;
@@ -247,7 +245,7 @@ static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geo
 }
 
 static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) {
-	swayc_t *c = get_swayc_for_handle(view, &root_container);
+	swayc_t *c = swayc_by_handle(view);
 	switch (state) {
 	case WLC_BIT_FULLSCREEN:
 		// i3 just lets it become fullscreen
@@ -342,7 +340,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
 	bool changed_tiling = false;
 	int min_sane_w = 100;
 	int min_sane_h = 60;
-	if (!active_workspace) {
+	if (!swayc_active_workspace()) {
 		return false;
 	}
 	// Do checks to determine if proper keys are being held
@@ -518,7 +516,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
 					}
 				}
 			}
-			arrange_windows(active_workspace, -1, -1);
+			arrange_windows(swayc_active_workspace(), -1, -1);
 		}
 	}
 	if (config->focus_follows_mouse && prev_handle != handle) {
diff --git a/sway/layout.c b/sway/layout.c
index 573c6f70..446ad066 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -35,7 +35,7 @@ void add_child(swayc_t *parent, swayc_t *child) {
 	child->parent = parent;
 	// set focus for this container
 	if (parent->children->length == 1) {
-		set_focused_container_for(parent, child);
+		parent->focused = child;
 	}
 }
 
@@ -46,7 +46,7 @@ void add_floating(swayc_t *ws, swayc_t *child) {
 	child->parent = ws;
 	child->is_floating = true;
 	if (!ws->focused) {
-		set_focused_container_for(ws, child);
+		ws->focused = child;
 	}
 }
 
@@ -71,7 +71,7 @@ swayc_t *replace_child(swayc_t *child, swayc_t *new_child) {
 	new_child->parent = child->parent;
 
 	if (child->parent->focused == child) {
-		set_focused_container_for(child->parent, new_child);
+		child->parent->focused = new_child;
 	}
 	child->parent = NULL;
 	return parent;
@@ -100,7 +100,7 @@ swayc_t *remove_child(swayc_t *child) {
 	// Set focused to new container
 	if (parent->focused == child) {
 		if (parent->children->length > 0) {
-			set_focused_container_for(parent, parent->children->items[i?i-1:0]);
+			parent->focused = parent->children->items[i?i-1:0];
 		} else {
 			parent->focused = NULL;
 		}
@@ -328,35 +328,6 @@ void arrange_windows(swayc_t *container, double width, double height) {
 	layout_log(&root_container, 0);
 }
 
-swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent) {
-	if (parent->children == NULL) {
-		return NULL;
-	}
-
-	// Search for floating workspaces
-	int i;
-	if (parent->type == C_WORKSPACE) {
-		for (i = 0; i < parent->floating->length; ++i) {
-			swayc_t *child = parent->floating->items[i];
-			if (child->handle == handle) {
-				return child;
-			}
-		}
-	}
-
-	for (i = 0; i < parent->children->length; ++i) {
-		swayc_t *child = parent->children->items[i];
-		if (child->handle == handle) {
-			return child;
-		} else {
-			swayc_t *res;
-			if ((res = get_swayc_for_handle(handle, child))) {
-				return res;
-			}
-		}
-	}
-	return NULL;
-}
 
 swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir) {
 	swayc_t *parent = container->parent;
diff --git a/sway/log.c b/sway/log.c
index a1e89bad..4a047eef 100644
--- a/sway/log.c
+++ b/sway/log.c
@@ -119,8 +119,9 @@ bool sway_assert(bool condition, const char* format, ...) {
 /* XXX:DEBUG:XXX */
 static void container_log(const swayc_t *c) {
 	fprintf(stderr, "focus:%c|",
-			c->is_focused ? 'F' : // Focused
-			c == active_workspace ? 'W' : // active workspace
+			c == get_focused_view(&root_container) ? 'K':
+			c == get_focused_container(&root_container) ? 'F' : // Focused
+			c == swayc_active_workspace() ? 'W' : // active workspace
 			c == &root_container  ? 'R' : // root
 			'X');// not any others
 	fprintf(stderr,"(%p)",c);
diff --git a/sway/workspace.c b/sway/workspace.c
index d436da8e..80b67128 100644
--- a/sway/workspace.c
+++ b/sway/workspace.c
@@ -1,6 +1,7 @@
 #include <stdlib.h>
 #include <stdbool.h>
 #include <wlc/wlc.h>
+#include <string.h>
 #include "workspace.h"
 #include "layout.h"
 #include "list.h"
@@ -11,8 +12,6 @@
 #include "stringop.h"
 #include "focus.h"
 
-swayc_t *active_workspace = NULL;
-
 char *workspace_next_name(void) {
 	sway_log(L_DEBUG, "Workspace: Generating new name");
 	int i;
@@ -48,7 +47,7 @@ char *workspace_next_name(void) {
 			}
 
 			// Make sure that the workspace doesn't already exist
-			if (workspace_find_by_name(target)) {
+			if (workspace_by_name(target)) {
 				list_free(args);
 				continue;
 			}
@@ -79,22 +78,22 @@ swayc_t *workspace_create(const char* name) {
 	return new_workspace(parent, name);
 }
 
-bool workspace_by_name(swayc_t *view, void *data) {
+static bool _workspace_by_name(swayc_t *view, void *data) {
 	return (view->type == C_WORKSPACE) &&
 		   (strcasecmp(view->name, (char *) data) == 0);
 }
 
-swayc_t *workspace_find_by_name(const char* name) {
-	return find_container(&root_container, workspace_by_name, (void *) name);
+swayc_t *workspace_by_name(const char* name) {
+	return swayc_by_test(&root_container, _workspace_by_name, (void *) name);
 }
 
 void workspace_output_next() {
 	// Get the index of the workspace in the current output, and change the view to index+1 workspace.
 	// if we're currently focused on the last workspace in the output, switch to the first
-	swayc_t *current_output = active_workspace->parent;
+	swayc_t *current_output = swayc_active_workspace()->parent;
 	int i;
 	for (i = 0; i < current_output->children->length - 1; i++) {
-		if (strcmp((((swayc_t *)current_output->children->items[i])->name), active_workspace->name) == 0) {
+		if (strcmp((((swayc_t *)current_output->children->items[i])->name), swayc_active_workspace()->name) == 0) {
 			workspace_switch(current_output->children->items[i + 1]);
 			return;
 		}
@@ -106,10 +105,10 @@ void workspace_next() {
 	// Get the index of the workspace in the current output, and change the view to index+1 workspace.
 	// if we're currently focused on the last workspace in the output, change focus to there
 	// and call workspace_output_next(), as long as another output actually exists
-	swayc_t *current_output = active_workspace->parent;
+	swayc_t *current_output = swayc_active_workspace()->parent;
 	int i;
 	for (i = 0; i < current_output->children->length - 1; i++) {
-		if (strcmp((((swayc_t *)current_output->children->items[i])->name), active_workspace->name) == 0) {
+		if (strcmp((((swayc_t *)current_output->children->items[i])->name), swayc_active_workspace()->name) == 0) {
 			workspace_switch(current_output->children->items[i + 1]);
 			return;
 		}
@@ -134,10 +133,10 @@ void workspace_next() {
 void workspace_output_prev() {
 	// Get the index of the workspace in the current output, and change the view to index+1 workspace
 	// if we're currently focused on the first workspace in the output, do nothing and return false
-	swayc_t *current_output = active_workspace->parent;
+	swayc_t *current_output = swayc_active_workspace()->parent;
 	int i;
 	for (i = 1; i < current_output->children->length; i++) {
-		if (strcmp((((swayc_t *)current_output->children->items[i])->name), active_workspace->name) == 0) {
+		if (strcmp((((swayc_t *)current_output->children->items[i])->name), swayc_active_workspace()->name) == 0) {
 			workspace_switch(current_output->children->items[i - 1]);
 			return;
 		}
@@ -150,10 +149,10 @@ void workspace_prev() {
 	// if we're currently focused on the last workspace in the output, change focus to there
 	// and call workspace_output_next(), as long as another output actually exists
 
-	swayc_t *current_output = active_workspace->parent;
+	swayc_t *current_output = swayc_active_workspace()->parent;
 	int i;
 	for (i = 1; i < current_output->children->length; i++) {
-		if (strcmp((((swayc_t *)current_output->children->items[i])->name), active_workspace->name) == 0) {
+		if (strcmp((((swayc_t *)current_output->children->items[i])->name), swayc_active_workspace()->name) == 0) {
 			workspace_switch(current_output->children->items[i - 1]);
 			return;
 		}

From dde8bfe72838b2a08a6367a3bc26fde528c6dafe Mon Sep 17 00:00:00 2001
From: taiyu <taiyu.len@gmail.com>
Date: Fri, 21 Aug 2015 10:34:37 -0700
Subject: [PATCH 2/5] check floating mod for resizing windows, and dont send
 click

---
 sway/handlers.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/sway/handlers.c b/sway/handlers.c
index 07247b1c..3dda3e43 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -640,8 +640,12 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
 			// Dont want pointer sent to window while dragging or resizing
 			return (pointer_state.floating.drag || pointer_state.floating.resize);
 		} else {
-			pointer_state.tiling.resize = pointer_state.r_held;
-			pointer_state.tiling.init_view = pointer;
+			if (modifiers->mods & config->floating_mod) {
+				pointer_state.tiling.resize = pointer_state.r_held;
+				pointer_state.tiling.init_view = pointer;
+				// Dont want pointer sent when resizing
+				return (pointer_state.tiling.resize);
+			}
 		}
 		return (pointer && pointer != focused);
 	} else {

From d2e1c660b19e8bb24e496b3dd52d4696456863f0 Mon Sep 17 00:00:00 2001
From: taiyu <taiyu.len@gmail.com>
Date: Fri, 21 Aug 2015 10:45:18 -0700
Subject: [PATCH 3/5] swayc_is_fullscreen

---
 sway/commands.c | 2 +-
 sway/handlers.c | 4 ++--
 sway/layout.c   | 6 +++---
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/sway/commands.c b/sway/commands.c
index e485cdb5..efaa7472 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -684,7 +684,7 @@ static bool cmd_fullscreen(struct sway_config *config, int argc, char **argv) {
 	}
 
 	swayc_t *container = get_focused_view(&root_container);
-	bool current = (wlc_view_get_state(container->handle) & WLC_BIT_FULLSCREEN) > 0;
+	bool current = swayc_is_fullscreen(container);
 	wlc_view_set_state(container->handle, WLC_BIT_FULLSCREEN, !current);
 	// Resize workspace if going from  fullscreen -> notfullscreen
 	// otherwise just resize container
diff --git a/sway/handlers.c b/sway/handlers.c
index 3dda3e43..98809958 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -568,7 +568,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
 	if (config->focus_follows_mouse && prev_handle != handle) {
 		// Dont change focus if fullscreen
 		swayc_t *focused = get_focused_view(view);
-		if (!(focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN)
+		if (!swayc_is_fullscreen(focused)
 				&& !(pointer_state.l_held || pointer_state.r_held)) {
 			set_focused_container(container_under_pointer());
 		}
@@ -600,7 +600,7 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
 		uint32_t button, enum wlc_button_state state, const struct wlc_origin *origin) {
 	swayc_t *focused = get_focused_container(&root_container);
 	// dont change focus if fullscreen
-	if (focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) {
+	if (swayc_is_fullscreen(focused)) {
 		return false;
 	}
 	if (state == WLC_BUTTON_STATE_PRESSED) {
diff --git a/sway/layout.c b/sway/layout.c
index 446ad066..70d9eb21 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -204,7 +204,7 @@ void arrange_windows(swayc_t *container, double width, double height) {
 					.h = height - container->gaps
 				}
 			};
-			if (wlc_view_get_state(container->handle) & WLC_BIT_FULLSCREEN) {
+			if (swayc_is_fullscreen(container)) {
 				swayc_t *parent = swayc_parent_by_type(container, C_OUTPUT);
 				geometry.origin.x = 0;
 				geometry.origin.y = 0;
@@ -303,7 +303,7 @@ void arrange_windows(swayc_t *container, double width, double height) {
 						.h = view->height
 					}
 				};
-				if (wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN) {
+				if (swayc_is_fullscreen(view)) {
 					swayc_t *parent = swayc_parent_by_type(view, C_OUTPUT);
 					geometry.origin.x = 0;
 					geometry.origin.y = 0;
@@ -318,7 +318,7 @@ void arrange_windows(swayc_t *container, double width, double height) {
 					// have higher indexes
 					// This is conditional on there not being a fullscreen view in the workspace
 					if (!container->focused
-							|| !(wlc_view_get_state(container->focused->handle) & WLC_BIT_FULLSCREEN)) {
+							|| !swayc_is_fullscreen(container->focused)) {
 						wlc_view_bring_to_front(view->handle);
 					}
 				}

From de5196dc1e6427d76d93d9cafe147fedbffbaad4 Mon Sep 17 00:00:00 2001
From: taiyu <taiyu.len@gmail.com>
Date: Fri, 21 Aug 2015 12:19:29 -0700
Subject: [PATCH 4/5] comments + fixed leak

---
 sway/container.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/sway/container.c b/sway/container.c
index 5f1510a9..e6645fd2 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -26,14 +26,11 @@ static void free_swayc(swayc_t *cont) {
 	if (!ASSERT_NONNULL(cont)) {
 		return;
 	}
-	// TODO does not properly handle containers with children,
-	// TODO but functions that call this usually check for that
 	if (cont->children) {
-		if (cont->children->length) {
-			int i;
-			for (i = 0; i < cont->children->length; ++i) {
-				free_swayc(cont->children->items[i]);
-			}
+		// remove children until there are no more, free_swayc calls
+		// remove_child, which removes child from this container
+		while (cont->children->length) {
+			free_swayc(cont->children->items[0]);
 		}
 		list_free(cont->children);
 	}
@@ -409,9 +406,13 @@ swayc_t *swayc_active_workspace_for(swayc_t *cont) {
 		return NULL;
 	}
 	switch (cont->type) {
+		/* set root -> output */
 	case C_ROOT: cont = cont->focused;
+		/* set output -> workspace  */
 	case C_OUTPUT: cont = cont->focused;
+		/* return workspace */
 	case C_WORKSPACE: return cont;
+		/* Find parent workspace */
 	default: return swayc_parent_by_type(cont, C_WORKSPACE);
 	}
 }

From b05317c3a60c751ee4fbc596182b02f568b71c2e Mon Sep 17 00:00:00 2001
From: taiyu <taiyu.len@gmail.com>
Date: Fri, 21 Aug 2015 12:41:54 -0700
Subject: [PATCH 5/5] style

---
 sway/container.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/sway/container.c b/sway/container.c
index e6645fd2..62ff1c4a 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -341,7 +341,7 @@ swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) {
 	}
 	do {
 		container = container->parent;
-	} while(container && container->type != type);
+	} while (container && container->type != type);
 	return container;
 }
 
@@ -402,18 +402,23 @@ swayc_t *swayc_active_workspace(void) {
 }
 
 swayc_t *swayc_active_workspace_for(swayc_t *cont) {
-	if (! cont) {
+	if (!cont) {
 		return NULL;
 	}
 	switch (cont->type) {
-		/* set root -> output */
-	case C_ROOT: cont = cont->focused;
-		/* set output -> workspace  */
-	case C_OUTPUT: cont = cont->focused;
-		/* return workspace */
-	case C_WORKSPACE: return cont;
-		/* Find parent workspace */
-	default: return swayc_parent_by_type(cont, C_WORKSPACE);
+	case C_ROOT:
+		cont = cont->focused;
+		/* Fallthrough */
+
+	case C_OUTPUT:
+		cont = cont->focused;
+		/* Fallthrough */
+
+	case C_WORKSPACE:
+		return cont;
+
+	default:
+		return swayc_parent_by_type(cont, C_WORKSPACE);
 	}
 }