diff --git a/include/sway/desktop/launcher.h b/include/sway/desktop/launcher.h
index cb22eb98..bbc4a2c3 100644
--- a/include/sway/desktop/launcher.h
+++ b/include/sway/desktop/launcher.h
@@ -9,6 +9,4 @@ void root_record_workspace_pid(pid_t pid);
 
 void root_remove_workspace_pid(pid_t pid);
 
-void root_rename_pid_workspaces(const char *old_name, const char *new_name);
-
 #endif
diff --git a/sway/commands/rename.c b/sway/commands/rename.c
index 4656a410..60a66d58 100644
--- a/sway/commands/rename.c
+++ b/sway/commands/rename.c
@@ -92,8 +92,6 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
 
 	sway_log(SWAY_DEBUG, "renaming workspace '%s' to '%s'", workspace->name, new_name);
 
-	root_rename_pid_workspaces(workspace->name, new_name);
-
 	free(workspace->name);
 	workspace->name = new_name;
 
diff --git a/sway/desktop/launcher.c b/sway/desktop/launcher.c
index 4e0d9dc1..dd81e23d 100644
--- a/sway/desktop/launcher.c
+++ b/sway/desktop/launcher.c
@@ -4,19 +4,21 @@
 #include "sway/input/seat.h"
 #include "sway/output.h"
 #include "sway/desktop/launcher.h"
+#include "sway/tree/node.h"
 #include "sway/tree/container.h"
 #include "sway/tree/workspace.h"
+#include "sway/tree/root.h"
 #include "log.h"
 
 static struct wl_list pid_workspaces;
 
 struct pid_workspace {
 	pid_t pid;
-	char *workspace;
+	char *name;
 	struct timespec time_added;
 
-	struct sway_output *output;
-	struct wl_listener output_destroy;
+	struct sway_node *node;
+	struct wl_listener node_destroy;
 
 	struct wl_list link;
 };
@@ -56,9 +58,9 @@ static pid_t get_parent_pid(pid_t child) {
 }
 
 static void pid_workspace_destroy(struct pid_workspace *pw) {
-	wl_list_remove(&pw->output_destroy.link);
+	wl_list_remove(&pw->node_destroy.link);
 	wl_list_remove(&pw->link);
-	free(pw->workspace);
+	free(pw->name);
 	free(pw);
 }
 
@@ -69,6 +71,7 @@ struct sway_workspace *root_workspace_for_pid(pid_t pid) {
 	}
 
 	struct sway_workspace *ws = NULL;
+	struct sway_output *output = NULL;
 	struct pid_workspace *pw = NULL;
 
 	sway_log(SWAY_DEBUG, "Looking up workspace for pid %d", pid);
@@ -79,45 +82,84 @@ struct sway_workspace *root_workspace_for_pid(pid_t pid) {
 			if (pid == _pw->pid) {
 				pw = _pw;
 				sway_log(SWAY_DEBUG,
-						"found pid_workspace for pid %d, workspace %s",
-						pid, pw->workspace);
-				goto found;
+					"found %s match for pid %d: %s",
+					node_type_to_str(pw->node->type), pid, node_get_name(pw->node));
+				break;
 			}
 		}
 		pid = get_parent_pid(pid);
 	} while (pid > 1);
 
-found:
-	if (pw && pw->workspace) {
-		ws = workspace_by_name(pw->workspace);
-
-		if (!ws) {
-			sway_log(SWAY_DEBUG,
-					"Creating workspace %s for pid %d because it disappeared",
-					pw->workspace, pid);
-
-			struct sway_output *output = pw->output;
-			if (pw->output && !pw->output->enabled) {
+	if (pw) {
+		switch (pw->node->type) {
+		case N_CONTAINER:
+			// Unimplemented
+			// TODO: add container matching?
+			ws = pw->node->sway_container->pending.workspace;
+			break;
+		case N_WORKSPACE:
+			ws = pw->node->sway_workspace;
+			break;
+		case N_OUTPUT:
+			output = pw->node->sway_output;
+			ws = workspace_by_name(pw->name);
+			if (!ws) {
 				sway_log(SWAY_DEBUG,
-						"Workspace output %s is disabled, trying another one",
-						pw->output->wlr_output->name);
-				output = NULL;
+						"Creating workspace %s for pid %d because it disappeared",
+						pw->name, pid);
+				if (!output->enabled) {
+					sway_log(SWAY_DEBUG,
+							"Workspace output %s is disabled, trying another one",
+							output->wlr_output->name);
+					output = NULL;
+				}
+				ws = workspace_create(output, pw->name);
 			}
-
-			ws = workspace_create(output, pw->workspace);
+			break;
+		case N_ROOT:
+			ws = workspace_create(NULL, pw->name);
+			break;
 		}
-
 		pid_workspace_destroy(pw);
 	}
 
 	return ws;
 }
 
-static void pw_handle_output_destroy(struct wl_listener *listener, void *data) {
-	struct pid_workspace *pw = wl_container_of(listener, pw, output_destroy);
-	pw->output = NULL;
-	wl_list_remove(&pw->output_destroy.link);
-	wl_list_init(&pw->output_destroy.link);
+static void pw_handle_node_destroy(struct wl_listener *listener, void *data) {
+	struct pid_workspace *pw = wl_container_of(listener, pw, node_destroy);
+	switch (pw->node->type) {
+	case N_CONTAINER:
+		// Unimplemented
+		break;
+	case N_WORKSPACE:;
+		struct sway_workspace *ws = pw->node->sway_workspace;
+		wl_list_remove(&pw->node_destroy.link);
+		wl_list_init(&pw->node_destroy.link);
+		// We want to save this ws name to recreate later, hopefully on the
+		// same output
+		free(pw->name);
+		pw->name = strdup(ws->name);
+		if (!ws->output || ws->output->node.destroying) {
+			// If the output is being destroyed it would be pointless to track
+			// If the output is being disabled, we'll find out if it's still
+			// disabled when we try to match it.
+			pw->node = &root->node;
+			break;
+		}
+		pw->node = &ws->output->node;
+		wl_signal_add(&pw->node->events.destroy, &pw->node_destroy);
+		break;
+	case N_OUTPUT:
+		wl_list_remove(&pw->node_destroy.link);
+		wl_list_init(&pw->node_destroy.link);
+		// We'll make the ws pw->name somewhere else
+		pw->node = &root->node;
+		break;
+	case N_ROOT:
+		// Unreachable
+		break;
+	}
 }
 
 void root_record_workspace_pid(pid_t pid) {
@@ -132,11 +174,6 @@ void root_record_workspace_pid(pid_t pid) {
 		sway_log(SWAY_DEBUG, "Bailing out, no workspace");
 		return;
 	}
-	struct sway_output *output = ws->output;
-	if (!output) {
-		sway_log(SWAY_DEBUG, "Bailing out, no output");
-		return;
-	}
 
 	struct timespec now;
 	clock_gettime(CLOCK_MONOTONIC, &now);
@@ -151,12 +188,13 @@ void root_record_workspace_pid(pid_t pid) {
 	}
 
 	struct pid_workspace *pw = calloc(1, sizeof(struct pid_workspace));
-	pw->workspace = strdup(ws->name);
-	pw->output = output;
+	pw->name = strdup(ws->name);
+	pw->node = &ws->node;
 	pw->pid = pid;
+
 	memcpy(&pw->time_added, &now, sizeof(struct timespec));
-	pw->output_destroy.notify = pw_handle_output_destroy;
-	wl_signal_add(&output->wlr_output->events.destroy, &pw->output_destroy);
+	pw->node_destroy.notify = pw_handle_node_destroy;
+	wl_signal_add(&pw->node->events.destroy, &pw->node_destroy);
 	wl_list_insert(&pid_workspaces, &pw->link);
 }
 
@@ -173,17 +211,3 @@ void root_remove_workspace_pid(pid_t pid) {
 		}
 	}
 }
-
-void root_rename_pid_workspaces(const char *old_name, const char *new_name) {
-	if (!pid_workspaces.prev && !pid_workspaces.next) {
-		wl_list_init(&pid_workspaces);
-	}
-
-	struct pid_workspace *pw = NULL;
-	wl_list_for_each(pw, &pid_workspaces, link) {
-		if (strcmp(pw->workspace, old_name) == 0) {
-			free(pw->workspace);
-			pw->workspace = strdup(new_name);
-		}
-	}
-}