diff --git a/LICENSE b/LICENSE
index 932e1dff..a4db75f7 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2015 Drew DeVault
+Copyright (c) 2016 Drew DeVault
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of
 this software and associated documentation files (the "Software"), to deal in
diff --git a/config b/config
index f7e9e751..17160d5e 100644
--- a/config
+++ b/config
@@ -106,9 +106,9 @@ output * bg /usr/share/sway/wallpaper.jpg fill
 # Layout stuff:
 #
     # You can "split" the current object of your focus with
-    # $mod+h or $mod+v, for horizontal and vertical splits
+    # $mod+s or $mod+v, for horizontal and vertical splits
     # respectively.
-    bindsym $mod+h splith
+    bindsym $mod+s splith
     bindsym $mod+v splitv
 
     # Switch the current container between different layout styles
diff --git a/include/extensions.h b/include/extensions.h
index 164688ee..158a40a2 100644
--- a/include/extensions.h
+++ b/include/extensions.h
@@ -28,7 +28,6 @@ struct desktop_shell_state {
         list_t *panels;
         list_t *lock_surfaces;
         bool is_locked;
-        struct wlc_size panel_size;
 };
 
 struct swaylock_state {
diff --git a/include/workspace.h b/include/workspace.h
index c69ccdbb..6911e3d4 100644
--- a/include/workspace.h
+++ b/include/workspace.h
@@ -7,7 +7,7 @@
 
 extern char *prev_workspace_name;
 
-char *workspace_next_name(void);
+char *workspace_next_name(const char *output_name);
 swayc_t *workspace_create(const char*);
 swayc_t *workspace_by_name(const char*);
 swayc_t *workspace_by_number(const char*);
diff --git a/sway/CMakeLists.txt b/sway/CMakeLists.txt
index e49d1d3d..5b6104f3 100644
--- a/sway/CMakeLists.txt
+++ b/sway/CMakeLists.txt
@@ -57,3 +57,4 @@ install(
 add_manpage(sway 1)
 add_manpage(sway 5)
 add_manpage(sway-input 5)
+add_manpage(sway-bar 5)
diff --git a/sway/commands.c b/sway/commands.c
index 3b8556ca..ebb63691 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -362,10 +362,8 @@ static struct cmd_results *cmd_exec_always(int argc, char **argv) {
 			return error;
 		}
 
-		add_quotes(argv + 1, argc - 1);
 		tmp = join_args(argv + 1, argc - 1);
 	} else {
-		add_quotes(argv, argc);
 		tmp = join_args(argv, argc);
 	}
 
@@ -2869,10 +2867,12 @@ struct cmd_results *handle_command(char *_exec) {
 			//TODO better handling of argv
 			int argc;
 			char **argv = split_args(cmd, &argc);
-			int i;
-			for (i = 1; i < argc; ++i) {
-				if (*argv[i] == '\"' || *argv[i] == '\'') {
-					strip_quotes(argv[i]);
+			if (strcmp(argv[0], "exec") != 0) {
+				int i;
+				for (i = 1; i < argc; ++i) {
+					if (*argv[i] == '\"' || *argv[i] == '\'') {
+						strip_quotes(argv[i]);
+					}
 				}
 			}
 			struct cmd_handler *handler = find_handler(argv[0], CMD_BLOCK_END);
diff --git a/sway/container.c b/sway/container.c
index 2db7b218..e4c20bc9 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -143,7 +143,7 @@ swayc_t *new_output(wlc_handle handle) {
 		}
 	}
 	if (!ws_name) {
-		ws_name = workspace_next_name();
+		ws_name = workspace_next_name(output->name);
 	}
 
 	// create and initilize default workspace
diff --git a/sway/extensions.c b/sway/extensions.c
index bd279276..c646ac91 100644
--- a/sway/extensions.c
+++ b/sway/extensions.c
@@ -1,10 +1,12 @@
 #include <stdlib.h>
 #include <wlc/wlc.h>
 #include <wlc/wlc-wayland.h>
+#include <wlc/wlc-render.h>
 #include "wayland-desktop-shell-server-protocol.h"
 #include "wayland-swaylock-server-protocol.h"
 #include "layout.h"
 #include "log.h"
+#include "input_state.h"
 #include "extensions.h"
 
 struct desktop_shell_state desktop_shell;
@@ -76,6 +78,7 @@ static void set_background(struct wl_client *client, struct wl_resource *resourc
 	config->wl_surface_res = surface;
 	list_add(desktop_shell.backgrounds, config);
 	wl_resource_set_destructor(surface, background_surface_destructor);
+	wlc_output_schedule_render(config->output);
 }
 
 static void set_panel(struct wl_client *client, struct wl_resource *resource,
@@ -90,8 +93,8 @@ static void set_panel(struct wl_client *client, struct wl_resource *resource,
 	config->surface = wlc_resource_from_wl_surface_resource(surface);
 	config->wl_surface_res = surface;
 	wl_resource_set_destructor(surface, panel_surface_destructor);
-	desktop_shell.panel_size = *wlc_surface_get_size(config->surface);
 	arrange_windows(&root_container, -1, -1);
+	wlc_output_schedule_render(config->output);
 }
 
 static void desktop_set_lock_surface(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface) {
@@ -123,7 +126,14 @@ static void set_lock_surface(struct wl_client *client, struct wl_resource *resou
 		wlc_view_set_state(view->handle, WLC_BIT_FULLSCREEN, true);
 		workspace->fullscreen = view;
 		desktop_shell.is_locked = true;
-		set_focused_container(view);
+		// reset input state
+		input_init();
+		// set focus if the lockscreen is spawned on the currently
+		// active output
+		swayc_t *focus_output = swayc_active_output();
+		if (focus_output == output) {
+			set_focused_container(view);
+		}
 		arrange_windows(workspace, -1, -1);
 		list_add(desktop_shell.lock_surfaces, surface);
 		wl_resource_set_destructor(surface, lock_surface_destructor);
diff --git a/sway/focus.c b/sway/focus.c
index c2ded212..7f96eda7 100644
--- a/sway/focus.c
+++ b/sway/focus.c
@@ -139,6 +139,11 @@ bool set_focused_container(swayc_t *c) {
 				wlc_view_focus(p->handle);
 			}
 		}
+	} else if (p->type == C_WORKSPACE) {
+		// remove previous focus if view_focus is unlocked
+		if (!locked_view_focus) {
+			wlc_view_focus(0);
+		}
 	}
 
 	if (active_ws != workspace) {
diff --git a/sway/handlers.c b/sway/handlers.c
index 69f325eb..d992a7b6 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -141,10 +141,6 @@ static void handle_output_pre_render(wlc_handle output) {
 				break;
 			}
 			wlc_surface_render(config->surface, &geo);
-			if (size.w != desktop_shell.panel_size.w || size.h != desktop_shell.panel_size.h) {
-				desktop_shell.panel_size = size;
-				arrange_windows(&root_container, -1, -1);
-			}
 			break;
 		}
 	}
diff --git a/sway/layout.c b/sway/layout.c
index dca4e47f..e9998bc8 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -364,7 +364,7 @@ void move_workspace_to(swayc_t* workspace, swayc_t* destination) {
 
 	// make sure source output has a workspace
 	if (src_op->children->length == 0) {
-		char *ws_name = workspace_next_name();
+		char *ws_name = workspace_next_name(src_op->name);
 		swayc_t *ws = new_workspace(src_op, ws_name);
 		ws->is_focused = true;
 		free(ws_name);
diff --git a/sway/sway-bar.5.txt b/sway/sway-bar.5.txt
new file mode 100644
index 00000000..c23519a4
--- /dev/null
+++ b/sway/sway-bar.5.txt
@@ -0,0 +1,112 @@
+/////
+vim:set ts=4 sw=4 tw=82 noet:
+/////
+sway-bar (5)
+============
+
+Name
+----
+sway-bar - bar configuration file and commands
+
+Description
+-----------
+
+Sway allows for configuration of swaybar within the sway configuation file.
+Swaybar commands must be used inside a _bar { }_ block in the config.
+
+
+Commands
+--------
+
+**status_command** <status command>::
+	Executes the bar _status command_ with _sh -c_.
+
+**id** <bar_id>::
+	Sets the ID of the bar.
+
+**position** <top|bottom|left|right>::
+	Sets position of the bar. Default is _bottom_.
+
+**output** <output>::
+	Restrict the bar to a certain output, can be specified multiple times. If the
+	output command is omitted, the bar will be displayed on all outputs.
+
+**swaybar_command** <command>::
+	Executes custom bar command, default is _swaybar_.
+
+**font** <font>::
+	Specifies the font to be used in the bar.
+
+**separator_symbol** <symbol>::
+	Specifies the separator symbol to separate blocks on the bar.
+
+**workspace_buttons** <yes|no>::
+	Enables or disables workspace buttons on the bar. Default is to enable
+	buttons.
+
+**strip_workspace_numbers** <yes|no>::
+	If set to _yes_, then workspace numbers will be omitted from the workspace
+	button and only the custom name will be shown.
+
+**binding_mode_indicator** <yes|no>::
+	Enable or disable binding mode indicator. It's enabled by default.
+
+**height** <height>::
+	Sets the height of the bar. Default height will match the font size.
+
+Colors
+------
+
+Colors are defined within a _colors { }_ block inside a _bar { }_ block. Colors
+must be defined in hex. E.g. _#fff000_ or _#fff000ff_ when including the alpha
+channel.
+
+**background** <color>::
+	Background color of the bar.
+
+**statusline** <color>::
+	Text color to be used for the statusline.
+
+**separator** <color>::
+	Text color to be used for the separator.
+
+**focused_background** <color>::
+	Background color of the bar on the currently focused monitor output. If not
+	used, the color will be taken from _background_.
+
+**focused_statusline** <color>::
+	Text color to be used for the statusline on the currently focused monitor
+	output. If not used, the color will be taken from _statusline_.
+
+**focused_separator** <color>::
+	Text color to be used for the separator on the currently focused monitor
+	output. If not used, the color will be taken from _separator_.
+
+**focused_workspace** <border> <background> <text>::
+	Border, background and text color for a workspace button when the workspace
+	has focus.
+
+**active_workspace** <border> <background> <text>::
+	Border, background and text color for a workspace button when the workspace is
+	active (visible) on some output, but the focus is on another one. You can only
+	tell this apart from the focused workspace when you are using multiple
+	monitors.
+
+**inactive_workspace** <border> <background> <text>::
+	Border, background and text color for a workspace button when the workspace
+	does not have focus and is not active (visible) on any output. This will be
+	the case for most workspaces.
+
+**urgent_workspace** <border> <background> <text>::
+	Border, background and text color for a workspace button when the workspace
+	contains a window with the urgency hint set.
+
+**binding_mode** <border> <background> <text>::
+	Border, background and text color for the binding mode indicator. If not used,
+	the colors will be taken from _urgent_workspace_.
+
+
+See Also
+--------
+
+**sway**(5) **sway-input**(5)
diff --git a/sway/sway-input.5.txt b/sway/sway-input.5.txt
index 1380d1f4..1ef1dbf8 100644
--- a/sway/sway-input.5.txt
+++ b/sway/sway-input.5.txt
@@ -48,4 +48,4 @@ Commands
 See Also
 --------
 
-**sway**(5)
+**sway**(5) **sway-bar**(5)
diff --git a/sway/sway.5.txt b/sway/sway.5.txt
index 5c1cf44d..4e73cd45 100644
--- a/sway/sway.5.txt
+++ b/sway/sway.5.txt
@@ -242,4 +242,4 @@ Currently supported attributes:
 See Also
 --------
 
-**sway**(1) **sway-input**(5)
+**sway**(1) **sway-input**(5) **sway-bar**(5)
diff --git a/sway/workspace.c b/sway/workspace.c
index ad989de9..90edc6e9 100644
--- a/sway/workspace.c
+++ b/sway/workspace.c
@@ -25,8 +25,22 @@ struct workspace_by_number_data {
 	const char *name;
 };
 
-char *workspace_next_name(void) {
-	sway_log(L_DEBUG, "Workspace: Generating new name");
+static bool workspace_valid_on_output(const char *output_name, const char *ws_name) {
+	int i;
+	for (i = 0; i < config->workspace_outputs->length; ++i) {
+		struct workspace_output *wso = config->workspace_outputs->items[i];
+		if (strcasecmp(wso->workspace, ws_name) == 0) {
+			if (strcasecmp(wso->output, output_name) != 0) {
+				return false;
+			}
+		}
+	}
+
+	return true;
+}
+
+char *workspace_next_name(const char *output_name) {
+	sway_log(L_DEBUG, "Workspace: Generating new workspace name for output %s", output_name);
 	int i;
 	int l = 1;
 	// Scan all workspace bindings to find the next available workspace name,
@@ -73,6 +87,14 @@ char *workspace_next_name(void) {
 				free(_target);
 				continue;
 			}
+
+			// make sure that the workspace can appear on the given
+			// output
+			if (!workspace_valid_on_output(output_name, _target)) {
+				free(_target);
+				continue;
+			}
+
 			if (binding->order < order) {
 				order = binding->order;
 				target = _target;