From eac0920f49a728ad6a3809528c4757b73e4cd8af Mon Sep 17 00:00:00 2001
From: Drew DeVault <sir@cmpwn.com>
Date: Sat, 22 Aug 2015 14:44:47 -0400
Subject: [PATCH 01/15] Set x/y positions for output containers

---
 sway/container.c | 19 ++++++++++++++++++-
 sway/layout.c    |  9 ++-------
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/sway/container.c b/sway/container.c
index 5d544934..41d21c3b 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -59,7 +59,7 @@ swayc_t *new_output(wlc_handle handle) {
 	const char *name = wlc_output_get_name(handle);
 	sway_log(L_DEBUG, "Added output %lu:%s", handle, name);
 
-	struct output_config *oc ;
+	struct output_config *oc = NULL;
 	int i;
 	for (i = 0; i < config->output_configs->length; ++i) {
 		oc = config->output_configs->items[i];
@@ -83,6 +83,23 @@ swayc_t *new_output(wlc_handle handle) {
 	output->handle = handle;
 	output->name = name ? strdup(name) : NULL;
 	output->gaps = config->gaps_outer + config->gaps_inner / 2;
+	
+	// Find position for it
+	if (oc && oc->x != -1 && oc->y != -1) {
+		output->x = oc->x;
+		output->y = oc->y;
+	} else {
+		int x = 0;
+		for (i = 0; i < root_container.children->length; ++i) {
+			swayc_t *c = root_container.children->items[i];
+			if (c->type == C_OUTPUT) {
+				if (c->width + c->x > x) {
+					x = c->width + c->x;
+				}
+			}
+		}
+		output->x = x;
+	}
 
 	add_child(&root_container, output);
 
diff --git a/sway/layout.c b/sway/layout.c
index 18ecb1e7..7f3adc31 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -172,18 +172,13 @@ void arrange_windows(swayc_t *container, double width, double height) {
 			child->x = x;
 			child->y = y;
 			arrange_windows(child, -1, -1);
-			// Removed for now because wlc works with relative positions
-			// Addition can be reconsidered once wlc positions are changed
-			// x += child->width;
+			x += child->width;
 		}
 		return;
 	case C_OUTPUT:
 		container->width = width;
 		container->height = height;
-		// These lines make x/y negative and result in stuff glitching out
-		// Their addition can be reconsidered once wlc positions are changed
-		// x -= container->x;
-		// y -= container->y;
+		x = 0, y = 0;
 		for (i = 0; i < container->children->length; ++i) {
 			swayc_t *child = container->children->items[i];
 			child->x = x + container->gaps;

From 07229edfe627762df9c27ed2700d737f74bb7b88 Mon Sep 17 00:00:00 2001
From: Drew DeVault <sir@cmpwn.com>
Date: Sat, 22 Aug 2015 15:19:02 -0400
Subject: [PATCH 02/15] Implement output positioning

:tada:
---
 sway/container.c |  1 +
 sway/layout.c    | 76 ++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 68 insertions(+), 9 deletions(-)

diff --git a/sway/container.c b/sway/container.c
index 41d21c3b..67a34551 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -86,6 +86,7 @@ swayc_t *new_output(wlc_handle handle) {
 	
 	// Find position for it
 	if (oc && oc->x != -1 && oc->y != -1) {
+		sway_log(L_DEBUG, "Set %s position to %d, %d", name, oc->x, oc->y);
 		output->x = oc->x;
 		output->y = oc->y;
 	} else {
diff --git a/sway/layout.c b/sway/layout.c
index 7f3adc31..7a7ccc0e 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -169,8 +169,6 @@ void arrange_windows(swayc_t *container, double width, double height) {
 		for (i = 0; i < container->children->length; ++i) {
 			swayc_t *child = container->children->items[i];
 			sway_log(L_DEBUG, "Arranging output at %d", x);
-			child->x = x;
-			child->y = y;
 			arrange_windows(child, -1, -1);
 			x += child->width;
 		}
@@ -340,19 +338,79 @@ swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir)
 		// Test if we can even make a difference here
 		bool can_move = false;
 		int diff = 0;
-		if (dir == MOVE_LEFT || dir == MOVE_RIGHT) {
-			if (parent->layout == L_HORIZ || parent->type == C_ROOT) {
+		int i;
+		if (parent->type == C_ROOT) {
+			// Find the next output
+			int target = -1, max_x = 0, max_y = 0, self = -1;
+			sway_log(L_DEBUG, "Moving between outputs");
+			
+			for (i = 0; i < parent->children->length; ++i) {
+				swayc_t *next = parent->children->items[i];
+				if (next == container) {
+					self = i;
+					sway_log(L_DEBUG, "self is %p %d", next, self);
+					continue;
+				}
+				if (next->type == C_OUTPUT) {
+					sway_log(L_DEBUG, "Testing with %p %d (dir %d)", next, i, dir);
+					// Check if it's more extreme
+					if (dir == MOVE_RIGHT) {
+						if (container->x + container->width <= next->x) {
+							if (target == -1 || next->x < max_x) {
+								target = i;
+								max_x = next->x;
+							}
+						}
+					} else if (dir == MOVE_LEFT) {
+						sway_log(L_DEBUG, "next->x: %d, next->width: %d, container->x: %d",
+								(int)next->x, (int)next->width, (int)container->x);
+						if (container->x > next->x + next->width) {
+							sway_log(L_DEBUG, "match");
+							if (target == -1 || max_x < next->x) {
+								sway_log(L_DEBUG, "hit");
+								target = i;
+								max_x = next->x;
+							}
+						}
+					} else if (dir == MOVE_DOWN) {
+						if (container->y + container->height <= next->y) {
+							if (target == -1 || next->y < max_y) {
+								target = i;
+								max_y = next->y;
+							}
+						}
+					} else if (dir == MOVE_UP) {
+						if (container->y > next->y + next->height) {
+							if (target == -1 || max_y < next->y) {
+								target = i;
+								max_y = next->y;
+							}
+						}
+					}
+				}
+			}
+
+			if (target == -1) {
+				can_move = false;
+			} else {
 				can_move = true;
-				diff = dir == MOVE_LEFT ? -1 : 1;
+				diff = target - self;
 			}
 		} else {
-			if (parent->layout == L_VERT) {
-				can_move = true;
-				diff = dir == MOVE_UP ? -1 : 1;
+			if (dir == MOVE_LEFT || dir == MOVE_RIGHT) {
+				if (parent->layout == L_HORIZ) {
+					can_move = true;
+					diff = dir == MOVE_LEFT ? -1 : 1;
+				}
+			} else {
+				if (parent->layout == L_VERT) {
+					can_move = true;
+					diff = dir == MOVE_UP ? -1 : 1;
+				}
 			}
 		}
+
 		if (can_move) {
-			int i;
 			for (i = 0; i < parent->children->length; ++i) {
 				swayc_t *child = parent->children->items[i];
 				if (child == container) {

From 1fd5962aeb5bab722a26182ad39fddecf43c6f95 Mon Sep 17 00:00:00 2001
From: Drew DeVault <sir@cmpwn.com>
Date: Sat, 22 Aug 2015 15:21:56 -0400
Subject: [PATCH 03/15] Fix minor bug with output positioning

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

diff --git a/sway/layout.c b/sway/layout.c
index 7a7ccc0e..035fea34 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -362,12 +362,8 @@ swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir)
 							}
 						}
 					} else if (dir == MOVE_LEFT) {
-						sway_log(L_DEBUG, "next->x: %d, next->width: %d, container->x: %d",
-								(int)next->x, (int)next->width, (int)container->x);
-						if (container->x > next->x + next->width) {
-							sway_log(L_DEBUG, "match");
+						if (container->x >= next->x + next->width) {
 							if (target == -1 || max_x < next->x) {
-								sway_log(L_DEBUG, "hit");
 								target = i;
 								max_x = next->x;
 							}
@@ -380,7 +376,7 @@ swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir)
 							}
 						}
 					} else if (dir == MOVE_UP) {
-						if (container->y > next->y + next->height) {
+						if (container->y >= next->y + next->height) {
 							if (target == -1 || max_y < next->y) {
 								target = i;
 								max_y = next->y;

From 36cd180f02cf032fa1d041540fff236061c3df5a Mon Sep 17 00:00:00 2001
From: taiyu <taiyu.len@gmail.com>
Date: Sat, 22 Aug 2015 18:25:05 -0700
Subject: [PATCH 04/15] fixed vanishing floating view

---
 sway/container.c | 17 ++++++++++-------
 sway/focus.c     |  1 -
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/sway/container.c b/sway/container.c
index 67a34551..127e1ecd 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -299,7 +299,8 @@ swayc_t *destroy_workspace(swayc_t *workspace) {
 		return NULL;
 	}
 
-	if (workspace->children->length == 0) {
+	// Do not destroy if there are children
+	if (workspace->children->length == 0 && workspace->floating->length == 0) {
 		sway_log(L_DEBUG, "%s: '%s'", __func__, workspace->name);
 		swayc_t *parent = workspace->parent;
 		free_swayc(workspace);
@@ -466,14 +467,16 @@ bool swayc_is_fullscreen(swayc_t *view) {
 // Mapping
 
 void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
-	if (container && container->children && container->children->length)  {
+	if (container) {
 		int i;
-		for (i = 0; i < container->children->length; ++i) {
-			swayc_t *child = container->children->items[i];
-			f(child, data);
-			container_map(child, f, data);
+		if (container->children)  {
+			for (i = 0; i < container->children->length; ++i) {
+				swayc_t *child = container->children->items[i];
+				f(child, data);
+				container_map(child, f, data);
+			}
 		}
-		if (container->type == C_WORKSPACE) {
+		if (container->floating) {
 			for (i = 0; i < container->floating->length; ++i) {
 				swayc_t *child = container->floating->items[i];
 				f(child, data);
diff --git a/sway/focus.c b/sway/focus.c
index a3e5e77a..e369de30 100644
--- a/sway/focus.c
+++ b/sway/focus.c
@@ -34,7 +34,6 @@ static void update_focus(swayc_t *c) {
 				mask = 2;
 				container_map(c, set_view_visibility, &mask);
 				wlc_output_set_mask(parent->handle, 2);
-				c->parent->focused = c;
 				destroy_workspace(ws);
 			}
 			break;

From 1e18ba9f2d170c89c4cf202a9dfd7b87da4fa769 Mon Sep 17 00:00:00 2001
From: Drew DeVault <sir@cmpwn.com>
Date: Sun, 23 Aug 2015 11:27:16 -0400
Subject: [PATCH 05/15] Add note to config about floating_modifier

---
 config | 1 +
 1 file changed, 1 insertion(+)

diff --git a/config b/config
index 7e34c0b9..8e7f7b70 100644
--- a/config
+++ b/config
@@ -32,6 +32,7 @@ set $menu dmenu_run
 
     # Drag floating windows by holding down $mod and left mouse button.
     # Resize them with right mouse button + $mod.
+    # Despite the name, also works for non-floating windows.
     floating_modifier $mod
 
     # reload the configuration file

From ac2034df99e1ec19e8bca60a802cd9f9d8fbbf83 Mon Sep 17 00:00:00 2001
From: Drew DeVault <sir@cmpwn.com>
Date: Sun, 23 Aug 2015 13:08:04 -0400
Subject: [PATCH 06/15] Handle wlc log events

---
 sway/handlers.c |  1 -
 sway/main.c     | 12 ++++++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/sway/handlers.c b/sway/handlers.c
index cb42196f..e4018811 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -498,7 +498,6 @@ static void handle_wlc_ready(void) {
 	config->active = true;
 }
 
-
 struct wlc_interface interface = {
 	.output = {
 		.created = handle_output_created,
diff --git a/sway/main.c b/sway/main.c
index ffbcdbdf..f8959009 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -21,6 +21,16 @@ void sway_terminate(void) {
 
 static void sigchld_handle(int signal);
 
+static void wlc_log_handler(enum wlc_log_type type, const char *str) {
+	if (type == WLC_LOG_ERROR) {
+		sway_log(L_ERROR, "%s", str);
+	} else if (type == WLC_LOG_WARN) {
+		sway_log(L_INFO, "%s", str);
+	} else {
+		sway_log(L_DEBUG, "%s", str);
+	}
+}
+
 int main(int argc, char **argv) {
 	static int verbose = 0, debug = 0, validate = 0;
 
@@ -38,6 +48,8 @@ int main(int argc, char **argv) {
 
 	setenv("WLC_DIM", "0", 0);
 
+	wlc_log_set_handler(wlc_log_handler);
+
 	/* Changing code earlier than this point requires detailed review */
 	if (!wlc_init(&interface, argc, argv)) {
 		return 1;

From e2322414666488945ffcbcab06f9cca95ff731d3 Mon Sep 17 00:00:00 2001
From: Drew DeVault <sir@cmpwn.com>
Date: Sun, 23 Aug 2015 13:16:37 -0400
Subject: [PATCH 07/15] Do not log with colors unless stdout is a tty

---
 sway/log.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sway/log.c b/sway/log.c
index 4a047eef..a7d73d5c 100644
--- a/sway/log.c
+++ b/sway/log.c
@@ -53,7 +53,7 @@ void sway_log(log_importance_t verbosity, const char* format, ...) {
 			c = sizeof(verbosity_colors) / sizeof(char *) - 1;
 		}
 
-		if (colored) {
+		if (colored && isatty(STDERR_FILENO)) {
 			fprintf(stderr, "%s", verbosity_colors[c]);
 		}
 
@@ -62,7 +62,7 @@ void sway_log(log_importance_t verbosity, const char* format, ...) {
 		vfprintf(stderr, format, args);
 		va_end(args);
 
-		if (colored) {
+		if (colored && isatty(STDERR_FILENO)) {
 			fprintf(stderr, "\x1B[0m");
 		}
 		fprintf(stderr, "\n");
@@ -76,7 +76,7 @@ void sway_log_errno(log_importance_t verbosity, char* format, ...) {
 			c = sizeof(verbosity_colors) / sizeof(char *) - 1;
 		}
 
-		if (colored) {
+		if (colored && isatty(STDERR_FILENO)) {
 			fprintf(stderr, "%s", verbosity_colors[c]);
 		}
 
@@ -90,7 +90,7 @@ void sway_log_errno(log_importance_t verbosity, char* format, ...) {
 		strerror_r(errno, error, sizeof(error));
 		fprintf(stderr, "%s", error);
 
-		if (colored) {
+		if (colored && isatty(STDERR_FILENO)) {
 			fprintf(stderr, "\x1B[0m");
 		}
 		fprintf(stderr, "\n");

From 98fad060e28c81c8340afbb473615f7889a6097a Mon Sep 17 00:00:00 2001
From: Luminarys <kizunanohikari@gmail.com>
Date: Sun, 23 Aug 2015 12:22:33 -0500
Subject: [PATCH 08/15] Added in glitchy disabling

---
 include/config.h |  1 +
 sway/commands.c  |  5 +++++
 sway/container.c |  4 ++++
 sway/handlers.c  | 11 +++++++++++
 4 files changed, 21 insertions(+)

diff --git a/include/config.h b/include/config.h
index c896b423..3d501cbe 100644
--- a/include/config.h
+++ b/include/config.h
@@ -24,6 +24,7 @@ struct sway_mode {
 
 struct output_config {
 	char *name;
+    bool enabled;
 	int width, height;
 	int x, y;
 };
diff --git a/sway/commands.c b/sway/commands.c
index 5de1fb0c..9a0bc076 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -372,8 +372,13 @@ static bool cmd_output(struct sway_config *config, int argc, char **argv) {
 	struct output_config *output = calloc(1, sizeof(struct output_config));
 	output->x = output->y = output->width = output->height = -1;
 	output->name = strdup(argv[0]);
+    output->enabled = true;
 
 	// TODO: atoi doesn't handle invalid numbers
+    
+    if (strcmp(argv[1], "disable") == 0) {
+        output->enabled = false;
+    }
 
 	int i;
 	for (i = 1; i < argc; ++i) {
diff --git a/sway/container.c b/sway/container.c
index 127e1ecd..6debeea3 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -70,6 +70,10 @@ swayc_t *new_output(wlc_handle handle) {
 		oc = NULL;
 	}
 
+    if (oc && !oc->enabled) {
+        return NULL;
+    }
+
 	swayc_t *output = new_swayc(C_OUTPUT);
 	if (oc && oc->width != -1 && oc->height != -1) {
 		output->width = oc->width;
diff --git a/sway/handlers.c b/sway/handlers.c
index e4018811..9fca6387 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -86,11 +86,22 @@ swayc_t *container_under_pointer(void) {
 static bool handle_output_created(wlc_handle output) {
 	swayc_t *op = new_output(output);
 
+    if (!op) {
+        return false;
+    }
+
+        wlc_output_focus(output);
 	// Switch to workspace if we need to
 	if (swayc_active_workspace() == NULL) {
+        sway_log(L_INFO, "Focus switch");
 		swayc_t *ws = op->children->items[0];
 		workspace_switch(ws);
 	}
+    /*
+    if (wlc_output_get_sleep(wlc_get_focused_output())) {
+        wlc_output_focus(output);
+    }
+    */
 	return true;
 }
 

From e01cf0b56654ff459a98a90e5e35615ad8d9203e Mon Sep 17 00:00:00 2001
From: Luminarys <kizunanohikari@gmail.com>
Date: Sun, 23 Aug 2015 12:22:45 -0500
Subject: [PATCH 09/15] Added in glitchy disabling

---
 sway/commands.c  | 10 +++++-----
 sway/container.c |  6 +++---
 sway/handlers.c  | 20 ++++++++++----------
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/sway/commands.c b/sway/commands.c
index 9a0bc076..ae75ec67 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -372,13 +372,13 @@ static bool cmd_output(struct sway_config *config, int argc, char **argv) {
 	struct output_config *output = calloc(1, sizeof(struct output_config));
 	output->x = output->y = output->width = output->height = -1;
 	output->name = strdup(argv[0]);
-    output->enabled = true;
+	output->enabled = true;
 
 	// TODO: atoi doesn't handle invalid numbers
-    
-    if (strcmp(argv[1], "disable") == 0) {
-        output->enabled = false;
-    }
+	
+	if (strcmp(argv[1], "disable") == 0) {
+		output->enabled = false;
+	}
 
 	int i;
 	for (i = 1; i < argc; ++i) {
diff --git a/sway/container.c b/sway/container.c
index 6debeea3..d4f7c693 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -70,9 +70,9 @@ swayc_t *new_output(wlc_handle handle) {
 		oc = NULL;
 	}
 
-    if (oc && !oc->enabled) {
-        return NULL;
-    }
+	if (oc && !oc->enabled) {
+		return NULL;
+	}
 
 	swayc_t *output = new_swayc(C_OUTPUT);
 	if (oc && oc->width != -1 && oc->height != -1) {
diff --git a/sway/handlers.c b/sway/handlers.c
index 9fca6387..1ff430f2 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -86,22 +86,22 @@ swayc_t *container_under_pointer(void) {
 static bool handle_output_created(wlc_handle output) {
 	swayc_t *op = new_output(output);
 
-    if (!op) {
-        return false;
-    }
+	if (!op) {
+		return false;
+	}
 
-        wlc_output_focus(output);
+		wlc_output_focus(output);
 	// Switch to workspace if we need to
 	if (swayc_active_workspace() == NULL) {
-        sway_log(L_INFO, "Focus switch");
+		sway_log(L_INFO, "Focus switch");
 		swayc_t *ws = op->children->items[0];
 		workspace_switch(ws);
 	}
-    /*
-    if (wlc_output_get_sleep(wlc_get_focused_output())) {
-        wlc_output_focus(output);
-    }
-    */
+	/*
+	if (wlc_output_get_sleep(wlc_get_focused_output())) {
+		wlc_output_focus(output);
+	}
+	*/
 	return true;
 }
 

From e78221e6a0413b8cccd41f75288798ae15b792b6 Mon Sep 17 00:00:00 2001
From: Drew DeVault <sir@cmpwn.com>
Date: Sun, 23 Aug 2015 13:31:16 -0400
Subject: [PATCH 10/15] Prefix log events from wlc with [wlc]

---
 sway/main.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sway/main.c b/sway/main.c
index f8959009..3f2fcd94 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -23,11 +23,11 @@ static void sigchld_handle(int signal);
 
 static void wlc_log_handler(enum wlc_log_type type, const char *str) {
 	if (type == WLC_LOG_ERROR) {
-		sway_log(L_ERROR, "%s", str);
+		sway_log(L_ERROR, "[wlc] %s", str);
 	} else if (type == WLC_LOG_WARN) {
-		sway_log(L_INFO, "%s", str);
+		sway_log(L_INFO, "[wlc] %s", str);
 	} else {
-		sway_log(L_DEBUG, "%s", str);
+		sway_log(L_DEBUG, "[wlc] %s", str);
 	}
 }
 

From 5bfed9b2131761f29e2cc095fbdf2083d2665848 Mon Sep 17 00:00:00 2001
From: Luminarys <kizunanohikari@gmail.com>
Date: Sun, 23 Aug 2015 13:18:07 -0500
Subject: [PATCH 11/15] Cleanup and minor adjustments to disabling

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

diff --git a/sway/handlers.c b/sway/handlers.c
index 1ff430f2..23db5c15 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -90,18 +90,11 @@ static bool handle_output_created(wlc_handle output) {
 		return false;
 	}
 
-		wlc_output_focus(output);
 	// Switch to workspace if we need to
 	if (swayc_active_workspace() == NULL) {
-		sway_log(L_INFO, "Focus switch");
 		swayc_t *ws = op->children->items[0];
 		workspace_switch(ws);
 	}
-	/*
-	if (wlc_output_get_sleep(wlc_get_focused_output())) {
-		wlc_output_focus(output);
-	}
-	*/
 	return true;
 }
 
@@ -115,6 +108,8 @@ static void handle_output_destroyed(wlc_handle output) {
 	}
 	if (i < list->length) {
 		destroy_output(list->items[i]);
+	} else {
+		return;
 	}
 	if (list->length > 0) {
 		// switch to other outputs active workspace

From a65dca04e89282822fbda01aee00aadac8fb2540 Mon Sep 17 00:00:00 2001
From: Luminarys <kizunanohikari@gmail.com>
Date: Sun, 23 Aug 2015 13:19:47 -0500
Subject: [PATCH 12/15] Style fix

---
 include/config.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/config.h b/include/config.h
index 3d501cbe..6d36eb41 100644
--- a/include/config.h
+++ b/include/config.h
@@ -24,7 +24,7 @@ struct sway_mode {
 
 struct output_config {
 	char *name;
-    bool enabled;
+	bool enabled;
 	int width, height;
 	int x, y;
 };

From 3f1bb40769df708de8f488d432d56d8bce6edb5a Mon Sep 17 00:00:00 2001
From: Luminarys <kizunanohikari@gmail.com>
Date: Sun, 23 Aug 2015 13:27:37 -0500
Subject: [PATCH 13/15] Man page update

---
 sway.5.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sway.5.txt b/sway.5.txt
index e0052ee1..15a465c1 100644
--- a/sway.5.txt
+++ b/sway.5.txt
@@ -85,6 +85,9 @@ Commands
 	arranged at the given position in the layout tree. You may omit either of
 	these parameters if you only want to set one of them.
 
+**output** <name> disable::
+	Disables the specified output.
+
 **reload**::
 	Reloads the sway config file without restarting sway.
 

From 7a213889974daad72fd6b925edc3dc2cf1a394a1 Mon Sep 17 00:00:00 2001
From: Luminarys <kizunanohikari@gmail.com>
Date: Sun, 23 Aug 2015 13:32:47 -0500
Subject: [PATCH 14/15] Minor fix

---
 sway/commands.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sway/commands.c b/sway/commands.c
index ae75ec67..7ee8c558 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -376,7 +376,7 @@ static bool cmd_output(struct sway_config *config, int argc, char **argv) {
 
 	// TODO: atoi doesn't handle invalid numbers
 	
-	if (strcmp(argv[1], "disable") == 0) {
+	if (strcasecmp(argv[1], "disable") == 0) {
 		output->enabled = false;
 	}
 

From 1ac0c8cd47f734809c20bf6a6a0a7278680ed597 Mon Sep 17 00:00:00 2001
From: Drew DeVault <sir@cmpwn.com>
Date: Sun, 23 Aug 2015 15:28:49 -0400
Subject: [PATCH 15/15] Refactor keyboard to consider modified keysyms

Press Shift
Press 0       # Reads as ')'
Release Shift
Release 0     # Reads as '0' but we now recognize it as the same
---
 include/input_state.h |  8 +++----
 sway/handlers.c       | 16 +++----------
 sway/input_state.c    | 54 ++++++++++++++++++++++++++++++++-----------
 3 files changed, 46 insertions(+), 32 deletions(-)

diff --git a/include/input_state.h b/include/input_state.h
index 04fde42d..29064fd0 100644
--- a/include/input_state.h
+++ b/include/input_state.h
@@ -6,16 +6,14 @@
 
 /* Keyboard state */
 
-typedef uint32_t keycode;
-
 // returns true if key has been pressed, otherwise false
-bool check_key(keycode key);
+bool check_key(uint32_t key_sym, uint32_t key_code);
 
 // sets a key as pressed
-void press_key(keycode key);
+void press_key(uint32_t key_sym, uint32_t key_code);
 
 // unsets a key as pressed
-void release_key(keycode key);
+void release_key(uint32_t key_sym, uint32_t key_code);
 
 /* Pointer state */
 
diff --git a/sway/handlers.c b/sway/handlers.c
index 23db5c15..acf3e6a4 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -295,22 +295,12 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
 
 	struct sway_mode *mode = config->current_mode;
 
-	if (sym < 70000 /* bullshit made up number */) {
-		if (!isalnum(sym) && sym != ' ' && sym != XKB_KEY_Escape && sym != XKB_KEY_Tab) {
-			// God fucking dammit
-			return false;
-		}
-	}
-
-	// Lowercase if necessary
-	sym = tolower(sym);
-
 	int i;
 
 	if (state == WLC_KEY_STATE_PRESSED) {
-		press_key(sym);
+		press_key(sym, key);
 	} else { // WLC_KEY_STATE_RELEASED
-		release_key(sym);
+		release_key(sym, key);
 	}
 
 	// TODO: reminder to check conflicts with mod+q+a versus mod+q
@@ -322,7 +312,7 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
 			int j;
 			for (j = 0; j < binding->keys->length; ++j) {
 				xkb_keysym_t *key = binding->keys->items[j];
-				if ((match = check_key(*key)) == false) {
+				if ((match = check_key(*key, 0)) == false) {
 					break;
 				}
 			}
diff --git a/sway/input_state.c b/sway/input_state.c
index e2f3c754..9e065e60 100644
--- a/sway/input_state.c
+++ b/sway/input_state.c
@@ -1,50 +1,76 @@
 #include <string.h>
 #include <stdbool.h>
 #include <ctype.h>
+#include "log.h"
 
 #include "input_state.h"
 
 #define KEY_STATE_MAX_LENGTH 64
 
-static keycode key_state_array[KEY_STATE_MAX_LENGTH];
+struct key_state {
+	/*
+	 * Aims to store state regardless of modifiers.
+	 * If you press a key, then hold shift, then release the key, we'll
+	 * get two different key syms, but the same key code. This handles
+	 * that scenario and makes sure we can use the right bindings.
+	 */
+	uint32_t key_sym;
+	uint32_t alt_sym;
+	uint32_t key_code;
+};
+
+static struct key_state key_state_array[KEY_STATE_MAX_LENGTH];
 
 void input_init(void) {
 	int i;
 	for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
-		key_state_array[i] = 0;
+		struct key_state none = { 0, 0, 0 };
+		key_state_array[i] = none;
 	}
 }
 
-static uint8_t find_key(keycode key) {
+static uint8_t find_key(uint32_t key_sym, uint32_t key_code, bool update) {
 	int i;
 	for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
-		if (key_state_array[i] == key) {
+		if (0 == key_sym && 0 == key_code && key_state_array[i].key_sym == 0) {
+			break;
+		}
+		if (key_state_array[i].key_sym == key_sym
+			|| key_state_array[i].alt_sym == key_sym) {
+			break;
+		}
+		if (update && key_state_array[i].key_code == key_code) {
+			key_state_array[i].alt_sym = key_sym;
 			break;
 		}
 	}
 	return i;
 }
 
-bool check_key(keycode key) {
-	return find_key(key) < KEY_STATE_MAX_LENGTH;
+bool check_key(uint32_t key_sym, uint32_t key_code) {
+	return find_key(key_sym, key_code, false) < KEY_STATE_MAX_LENGTH;
 }
 
-void press_key(keycode key) {
+void press_key(uint32_t key_sym, uint32_t key_code) {
+	if (key_code == 0) {
+		return;
+	}
 	// Check if key exists
-	if (!check_key(key)) {
+	if (!check_key(key_sym, key_code)) {
 		// Check that we dont exceed buffer length
-		int insert = find_key(0);
+		int insert = find_key(0, 0, true);
 		if (insert < KEY_STATE_MAX_LENGTH) {
-			key_state_array[insert] = key;
+			key_state_array[insert].key_sym = key_sym;
+			key_state_array[insert].key_code = key_code;
 		}
 	}
 }
 
-void release_key(keycode key) {
-	uint8_t index = find_key(key);
+void release_key(uint32_t key_sym, uint32_t key_code) {
+	uint8_t index = find_key(key_sym, key_code, true);
 	if (index < KEY_STATE_MAX_LENGTH) {
-		// shift it over and remove key
-		key_state_array[index] = 0;
+		struct key_state none = { 0, 0, 0 };
+		key_state_array[index] = none;
 	}
 }