From 5fa8f91655ccc0346a360e95a72237eb772c7e18 Mon Sep 17 00:00:00 2001
From: "S. Christoffer Eliesen" <christoffer@eliesen.no>
Date: Sat, 24 Oct 2015 03:31:54 +0200
Subject: [PATCH] commands: Learn 'focus output <direction|name>'

---
 sway.5.txt      |  5 +++++
 sway/commands.c | 19 ++++++++++++++++++-
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/sway.5.txt b/sway.5.txt
index d97720c5..dad55c5f 100644
--- a/sway.5.txt
+++ b/sway.5.txt
@@ -53,6 +53,11 @@ Commands
 	container, which is useful, for example, to open a sibling of the parent
 	container, or to move the entire container around.
 
+**focus** output <direction|name>::
+	Direction may be one of _up_, _down_, _left_, _right_. The directional focus
+	commands will move the focus to the output in that direction. When name is
+	given the focus is changed to the output with that name.
+
 **focus** mode_toggle::
 	Toggles focus between floating view and tiled view.
 
diff --git a/sway/commands.c b/sway/commands.c
index c81379fd..441b6fd7 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -17,6 +17,7 @@
 #include "workspace.h"
 #include "commands.h"
 #include "container.h"
+#include "output.h"
 #include "handlers.h"
 #include "sway.h"
 #include "resize.h"
@@ -372,7 +373,20 @@ static struct cmd_results *cmd_floating_mod(int argc, char **argv) {
 static struct cmd_results *cmd_focus(int argc, char **argv) {
 	if (config->reading) return cmd_results_new(CMD_FAILURE, "focus", "Can't be used in config file.");
 	struct cmd_results *error = NULL;
-	if ((error = checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1))) {
+	if (argc > 0 && strcasecmp(argv[0], "output") == 0) {
+		swayc_t *output = NULL;
+		if ((error = checkarg(argc, "focus", EXPECTED_EQUAL_TO, 2))) {
+			return error;
+		} else if (!(output = output_by_name(argv[1]))) {
+			return cmd_results_new(CMD_FAILURE, "focus output",
+				"Can't find output with name/at direction %s", argv[1]);
+		} else if (!workspace_switch(swayc_active_workspace_for(output))) {
+			return cmd_results_new(CMD_FAILURE, "focus output",
+				"Switching to workspace on output '%s' was blocked", argv[1]);
+		} else {
+			return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+		}
+	} else if ((error = checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1))) {
 		return error;
 	}
 	static int floating_toggled_index = 0;
@@ -424,6 +438,9 @@ static struct cmd_results *cmd_focus(int argc, char **argv) {
 				}
 			}
 		}
+	} else {
+		return cmd_results_new(CMD_INVALID, "focus",
+				"Expected 'focus <direction|parent|mode_toggle>' or 'focus output <direction|name>'");
 	}
 	return cmd_results_new(CMD_SUCCESS, NULL, NULL);
 }