From 22916e9ebc130dbd365e6403730b9e0857977b8e Mon Sep 17 00:00:00 2001
From: Mikkel Oscar Lyderik <mikkeloscar@gmail.com>
Date: Fri, 11 Dec 2015 11:39:24 +0100
Subject: [PATCH 1/3] Make mouse key used for drag/resize configurable

This makes it possible to define what mouse button key (left|right) to
use for dragging/resizing.
---
 include/config.h   |  2 +
 sway/commands.c    | 17 ++++++++-
 sway/config.c      |  2 +
 sway/input_state.c | 93 ++++++++++++++++++++++++++++++++++++----------
 4 files changed, 93 insertions(+), 21 deletions(-)

diff --git a/include/config.h b/include/config.h
index 81d4cd20..4019f479 100644
--- a/include/config.h
+++ b/include/config.h
@@ -109,6 +109,8 @@ struct sway_config {
 	struct sway_mode *current_mode;
 	struct bar_config bar;
 	uint32_t floating_mod;
+	uint32_t dragging_key;
+	uint32_t resizing_key;
 	enum swayc_layouts default_orientation;
 	enum swayc_layouts default_layout;
 
diff --git a/sway/commands.c b/sway/commands.c
index 8a087af8..205798ec 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -375,14 +375,14 @@ static struct cmd_results *cmd_floating(int argc, char **argv) {
 
 static struct cmd_results *cmd_floating_mod(int argc, char **argv) {
 	struct cmd_results *error = NULL;
-	if ((error = checkarg(argc, "floating_modifier", EXPECTED_EQUAL_TO, 1))) {
+	if ((error = checkarg(argc, "floating_modifier", EXPECTED_AT_LEAST, 1))) {
 		return error;
 	}
 	int i, j;
 	list_t *split = split_string(argv[0], "+");
 	config->floating_mod = 0;
 
-	// set modifer keys
+	// set modifier keys
 	for (i = 0; i < split->length; ++i) {
 		for (j = 0; j < (int)(sizeof(modifiers) / sizeof(struct modifier_key)); ++j) {
 			if (strcasecmp(modifiers[j].name, split->items[i]) == 0) {
@@ -395,6 +395,19 @@ static struct cmd_results *cmd_floating_mod(int argc, char **argv) {
 		error = cmd_results_new(CMD_INVALID, "floating_modifier", "Unknown keys %s", argv[0]);
 		return error;
 	}
+
+	if (argc >= 2) {
+		if (strcasecmp("inverse", argv[1]) == 0) {
+			config->dragging_key = M_RIGHT_CLICK;
+			config->resizing_key = M_LEFT_CLICK;
+		} else if (strcasecmp("normal", argv[1]) == 0) {
+			config->dragging_key = M_LEFT_CLICK;
+			config->resizing_key = M_RIGHT_CLICK;
+		} else {
+			error = cmd_results_new(CMD_INVALID, "floating_modifier", "Invalid definition %s", argv[1]);
+			return error;
+		}
+	}
 	return cmd_results_new(CMD_SUCCESS, NULL, NULL);
 }
 
diff --git a/sway/config.c b/sway/config.c
index 6a1d172b..d5a3f781 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -101,6 +101,8 @@ static void config_defaults(struct sway_config *config) {
 	list_add(config->modes, config->current_mode);
 
 	config->floating_mod = 0;
+	config->dragging_key = M_LEFT_CLICK;
+	config->resizing_key = M_RIGHT_CLICK;
 	config->default_layout = L_NONE;
 	config->default_orientation = L_NONE;
 	// Flags
diff --git a/sway/input_state.c b/sway/input_state.c
index 88506c92..24678f71 100644
--- a/sway/input_state.c
+++ b/sway/input_state.c
@@ -194,8 +194,16 @@ void center_pointer_on(swayc_t *view) {
 
 // Mode set left/right click
 
-static void pointer_mode_set_left(void) {
-	set_initial_view(pointer_state.left.view);
+static void pointer_mode_set_dragging(void) {
+	switch (config->dragging_key) {
+	case M_LEFT_CLICK:
+		set_initial_view(pointer_state.left.view);
+		break;
+	case M_RIGHT_CLICK:
+		set_initial_view(pointer_state.right.view);
+		break;
+	}
+
 	if (initial.ptr->is_floating) {
 		pointer_state.mode = M_DRAGGING | M_FLOATING;
 	} else {
@@ -208,8 +216,15 @@ static void pointer_mode_set_left(void) {
 	}
 }
 
-static void pointer_mode_set_right(void) {
-	set_initial_view(pointer_state.right.view);
+static void pointer_mode_set_resizing(void) {
+	switch (config->resizing_key) {
+	case M_LEFT_CLICK:
+		set_initial_view(pointer_state.left.view);
+		break;
+	case M_RIGHT_CLICK:
+		set_initial_view(pointer_state.right.view);
+		break;
+	}
 	// Setup locking information
 	int midway_x = initial.ptr->x + initial.ptr->width/2;
 	int midway_y = initial.ptr->y + initial.ptr->height/2;
@@ -233,15 +248,19 @@ void pointer_mode_set(uint32_t button, bool condition) {
 	// switch on drag/resize mode
 	switch (pointer_state.mode & (M_DRAGGING | M_RESIZING)) {
 	case M_DRAGGING:
-	// end drag mode when left click is unpressed
-		if (!pointer_state.left.held) {
+		// end drag mode when 'dragging' click is unpressed
+		if (config->dragging_key == M_LEFT_CLICK && !pointer_state.left.held) {
+			pointer_state.mode = 0;
+		} else if (config->dragging_key == M_RIGHT_CLICK && !pointer_state.right.held) {
 			pointer_state.mode = 0;
 		}
 		break;
 
 	case M_RESIZING:
-	// end resize mode when right click is unpressed
-		if (!pointer_state.right.held) {
+		// end resize mode when 'resizing' click is unpressed
+		if (config->resizing_key == M_LEFT_CLICK && !pointer_state.left.held) {
+			pointer_state.mode = 0;
+		} else if (config->resizing_key == M_RIGHT_CLICK && !pointer_state.right.held) {
 			pointer_state.mode = 0;
 		}
 		break;
@@ -255,19 +274,27 @@ void pointer_mode_set(uint32_t button, bool condition) {
 
 		// Set mode depending on current button press
 		switch (button) {
-		// Start dragging mode
+		// Start left-click mode
 		case M_LEFT_CLICK:
 			// if button release dont do anything
 			if (pointer_state.left.held) {
-				pointer_mode_set_left();
+				if (config->dragging_key == M_LEFT_CLICK) {
+					pointer_mode_set_dragging();
+				} else if (config->resizing_key == M_LEFT_CLICK) {
+					pointer_mode_set_resizing();
+				}
 			}
 			break;
 
-		// Start resize mode
+		// Start right-click mode
 		case M_RIGHT_CLICK:
 			// if button release dont do anyhting
 			if (pointer_state.right.held) {
-				pointer_mode_set_right();
+				if (config->dragging_key == M_RIGHT_CLICK) {
+					pointer_mode_set_dragging();
+				} else if (config->resizing_key == M_RIGHT_CLICK) {
+					pointer_mode_set_resizing();
+				}
 			}
 			break;
 		}
@@ -287,8 +314,17 @@ void pointer_mode_update(void) {
 	switch (pointer_state.mode) {
 	case M_FLOATING | M_DRAGGING:
 		// Update position
-		dx -= pointer_state.left.x;
-		dy -= pointer_state.left.y;
+		switch (config->resizing_key) {
+		case M_LEFT_CLICK:
+			dx -= pointer_state.left.x;
+			dy -= pointer_state.left.y;
+			break;
+		case M_RIGHT_CLICK:
+			dx -= pointer_state.right.x;
+			dy -= pointer_state.right.y;
+			break;
+		}
+
 		if (initial.x + dx != initial.ptr->x) {
 			initial.ptr->x = initial.x + dx;
 		}
@@ -299,9 +335,19 @@ void pointer_mode_update(void) {
 		break;
 
 	case M_FLOATING | M_RESIZING:
-		dx -= pointer_state.right.x;
-		dy -= pointer_state.right.y;
-		initial.ptr = pointer_state.right.view;
+		switch (config->resizing_key) {
+		case M_LEFT_CLICK:
+			dx -= pointer_state.left.x;
+			dy -= pointer_state.left.y;
+			initial.ptr = pointer_state.left.view;
+			break;
+		case M_RIGHT_CLICK:
+			dx -= pointer_state.right.x;
+			dy -= pointer_state.right.y;
+			initial.ptr = pointer_state.right.view;
+			break;
+		}
+
 		if (lock.left) {
 			if (initial.w + dx > min_sane_w) {
 				initial.ptr->width = initial.w + dx;
@@ -341,8 +387,17 @@ void pointer_mode_update(void) {
 		break;
 
 	case M_TILING | M_RESIZING:
-		dx -= pointer_state.right.x;
-		dy -= pointer_state.right.y;
+		switch (config->resizing_key) {
+		case M_LEFT_CLICK:
+			dx -= pointer_state.left.x;
+			dy -= pointer_state.left.y;
+			break;
+		case M_RIGHT_CLICK:
+			dx -= pointer_state.right.x;
+			dy -= pointer_state.right.y;
+			break;
+		}
+
 		// resize if we can
 		if (initial.horiz.ptr) {
 			if (lock.left) {

From c286d69deba17df69d1fd3fbdf2b51ae84dd1db3 Mon Sep 17 00:00:00 2001
From: Mikkel Oscar Lyderik <mikkeloscar@gmail.com>
Date: Fri, 11 Dec 2015 14:07:59 +0100
Subject: [PATCH 2/3] Add floating_modifier extension to example config

---
 config | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/config b/config
index bd9b980b..2bb37f4f 100644
--- a/config
+++ b/config
@@ -32,7 +32,9 @@ 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
+    # Change normal to inverse to use left mouse button for resizing and right
+    # mouse button for dragging.
+    floating_modifier $mod normal
 
     # reload the configuration file
     bindsym $mod+Shift+c reload

From f28a1d9183a90284329e6c048ba7785313a5a50f Mon Sep 17 00:00:00 2001
From: Mikkel Oscar Lyderik <mikkeloscar@gmail.com>
Date: Fri, 11 Dec 2015 14:22:18 +0100
Subject: [PATCH 3/3] Add floating_modifier extension to manpage

---
 sway/sway.5.txt | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/sway/sway.5.txt b/sway/sway.5.txt
index 24467d22..c3736d01 100644
--- a/sway/sway.5.txt
+++ b/sway/sway.5.txt
@@ -41,10 +41,12 @@ Commands
 **floating** <enable|disable|toggle>::
 	Make focused view floating, non-floating, or the opposite of what it is now.
 
-**floating_modifier** <modifier>::
+**floating_modifier** <modifier> [normal|inverse]::
 	When the _modifier_ key is held down, you may use left click to drag floating
 	windows, and right click to resize them. Unlike i3, this modifier may also be
-	used to resize and move windows that are tiled.
+	used to resize and move windows that are tiled. With the _inverse_ mode
+	enabled, left click is used for resizing and right click for dragging. The
+	mode paramenter is optional and defaults to _normal_ if it isn't defined.
 
 **focus** <direction>::
 	Direction may be one of _up_, _down_, _left_, _right_, or _parent_. The