From f6b16ca089753beb4f7425fce195321e3073fb02 Mon Sep 17 00:00:00 2001
From: Luminarys <kizunanohikari@gmail.com>
Date: Fri, 21 Aug 2015 22:26:11 -0500
Subject: [PATCH] Refactored resizing functions into resize.c

---
 include/handlers.h |   1 +
 include/layout.h   |   3 +
 include/resize.h   |   8 +
 sway/commands.c    | 225 +--------------------
 sway/handlers.c    | 272 ++-----------------------
 sway/layout.c      |   2 +
 sway/resize.c      | 491 +++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 527 insertions(+), 475 deletions(-)
 create mode 100644 include/resize.h
 create mode 100644 sway/resize.c

diff --git a/include/handlers.h b/include/handlers.h
index c25c3309..4c71f953 100644
--- a/include/handlers.h
+++ b/include/handlers.h
@@ -5,6 +5,7 @@
 #include <wlc/wlc.h>
 
 extern struct wlc_interface interface;
+extern struct wlc_origin mouse_origin;
 extern uint32_t keys_pressed[32];
 
 // set focus to current pointer location and return focused container
diff --git a/include/layout.h b/include/layout.h
index 7b8829ed..f8aebe0a 100644
--- a/include/layout.h
+++ b/include/layout.h
@@ -8,6 +8,9 @@
 
 extern swayc_t root_container;
 
+extern int min_sane_w;
+extern int min_sane_h;
+
 void init_layout(void);
 
 void add_child(swayc_t *parent, swayc_t *child);
diff --git a/include/resize.h b/include/resize.h
new file mode 100644
index 00000000..4ace1815
--- /dev/null
+++ b/include/resize.h
@@ -0,0 +1,8 @@
+#ifndef _SWAY_RESIZE_H
+#define _SWAY_RESIZE_H
+
+bool mouse_resize_tiled(struct wlc_origin prev_pos);
+bool resize_floating(struct wlc_origin prev_pos);
+bool resize_tiled(int amount, bool use_width);
+
+#endif
diff --git a/sway/commands.c b/sway/commands.c
index 36299c8d..62794111 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -16,6 +16,7 @@
 #include "container.h"
 #include "handlers.h"
 #include "sway.h"
+#include "resize.h"
 
 struct modifier_key {
 	char *name;
@@ -448,240 +449,26 @@ static bool cmd_resize(struct sway_config *config, int argc, char **argv) {
 		return false;
 	}
 	char *end;
-	int min_sane_w = 100;
-	int min_sane_h = 60;
 	int amount = (int)strtol(argv[2], &end, 10);
 	if (errno == ERANGE || amount == 0) {
 		errno = 0;
 		return false;
 	}
+
 	if (strcmp(argv[0], "shrink") != 0 && strcmp(argv[0], "grow") != 0) {
 		return false;
 	}
+
 	if (strcmp(argv[0], "shrink") == 0) {
 		amount *= -1;
 	}
 
-	swayc_t *parent = get_focused_view(swayc_active_workspace());
-	swayc_t *focused = parent;
-	swayc_t *sibling;
-	if (!parent) {
-		return true;
-	}
-	// Find the closest parent container which has siblings of the proper layout.
-	// Then apply the resize to all of them.
-	int i;
 	if (strcmp(argv[1], "width") == 0) {
-		int lnumber = 0;
-		int rnumber = 0;
-		while (parent->parent) {
-			if (parent->parent->layout == L_HORIZ) {
-				for (i = 0; i < parent->parent->children->length; i++) {
-					sibling = parent->parent->children->items[i];
-					if (sibling->x != focused->x) {
-						if (sibling->x < parent->x) {
-							lnumber++;
-						} else if (sibling->x > parent->x) {
-							rnumber++;
-						}
-					}
-				}
-				if (rnumber || lnumber) {
-					break;
-				}
-			}
-			parent = parent->parent;
-		}
-		if (parent == &root_container) {
-			return true;
-		}
-		sway_log(L_DEBUG, "Found the proper parent: %p. It has %d l conts, and %d r conts", parent->parent, lnumber, rnumber);
-		//TODO: Ensure rounding is done in such a way that there are NO pixel leaks
-		bool valid = true;
-		for (i = 0; i < parent->parent->children->length; i++) {
-			sibling = parent->parent->children->items[i];
-			if (sibling->x != focused->x) {
-				if (sibling->x < parent->x) {
-					double pixels = -1 * amount;
-					pixels /= lnumber;
-					if (rnumber) {
-						if ((sibling->width + pixels/2) < min_sane_w) {
-							valid = false;
-							break;
-						}
-					} else {
-						if ((sibling->width + pixels) < min_sane_w) {
-							valid = false;
-							break;
-						}
-					}
-				} else if (sibling->x > parent->x) {
-					double pixels = -1 * amount;
-					pixels /= rnumber;
-					if (lnumber) {
-						if ((sibling->width + pixels/2) < min_sane_w) {
-							valid = false;
-							break;
-						}
-					} else {
-						if ((sibling->width + pixels) < min_sane_w) {
-							valid = false;
-							break;
-						}
-					}
-				}
-			} else {
-				double pixels = amount;
-				if (parent->width + pixels < min_sane_w) {
-					valid = false;
-					break;
-				}
-			}
-		}
-		if (valid) {
-			for (i = 0; i < parent->parent->children->length; i++) {
-				sibling = parent->parent->children->items[i];
-				if (sibling->x != focused->x) {
-					if (sibling->x < parent->x) {
-						double pixels = -1 * amount;
-						pixels /= lnumber;
-						if (rnumber) {
-							recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_RIGHT);
-						} else {
-							recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_RIGHT);
-						}
-					} else if (sibling->x > parent->x) {
-						double pixels = -1 * amount;
-						pixels /= rnumber;
-						if (lnumber) {
-							recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_LEFT);
-						} else {
-							recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_LEFT);
-						}
-					}
-				} else {
-					if (rnumber != 0 && lnumber != 0) {
-						double pixels = amount;
-						pixels /= 2;
-						recursive_resize(parent, pixels, WLC_RESIZE_EDGE_LEFT);
-						recursive_resize(parent, pixels, WLC_RESIZE_EDGE_RIGHT);
-					} else if (rnumber) {
-						recursive_resize(parent, amount, WLC_RESIZE_EDGE_RIGHT);
-					} else if (lnumber) {
-						recursive_resize(parent, amount, WLC_RESIZE_EDGE_LEFT);
-					}
-				}
-			}
-			// Recursive resize does not handle positions, let arrange_windows
-			// take care of that.
-			arrange_windows(swayc_active_workspace(), -1, -1);
-		}
-		return true;
+		return resize_tiled(amount, true);
 	} else if (strcmp(argv[1], "height") == 0) {
-		int tnumber = 0;
-		int bnumber = 0;
-		while (parent->parent) {
-			if (parent->parent->layout == L_VERT) {
-				for (i = 0; i < parent->parent->children->length; i++) {
-					sibling = parent->parent->children->items[i];
-					if (sibling->y != focused->y) {
-						if (sibling->y < parent->y) {
-							bnumber++;
-						} else if (sibling->y > parent->y) {
-							tnumber++;
-						}
-					}
-				}
-				if (bnumber || tnumber) {
-					break;
-				}
-			}
-			parent = parent->parent;
-		}
-		if (parent == &root_container) {
-			return true;
-		}
-		sway_log(L_DEBUG, "Found the proper parent: %p. It has %d b conts, and %d t conts", parent->parent, bnumber, tnumber);
-		//TODO: Ensure rounding is done in such a way that there are NO pixel leaks
-		bool valid = true;
-		for (i = 0; i < parent->parent->children->length; i++) {
-			sibling = parent->parent->children->items[i];
-			if (sibling->y != focused->y) {
-				if (sibling->y < parent->y) {
-					double pixels = -1 * amount;
-					pixels /= bnumber;
-					if (tnumber) {
-						if ((sibling->height + pixels/2) < min_sane_h) {
-							valid = false;
-							break;
-						}
-					} else {
-						if ((sibling->height + pixels) < min_sane_h) {
-							valid = false;
-							break;
-						}
-					}
-				} else if (sibling->y > parent->y) {
-					double pixels = -1 * amount;
-					pixels /= tnumber;
-					if (bnumber) {
-						if ((sibling->height + pixels/2) < min_sane_h) {
-							valid = false;
-							break;
-						}
-					} else {
-						if ((sibling->height + pixels) < min_sane_h) {
-							valid = false;
-							break;
-						}
-					}
-				}
-			} else {
-				double pixels = amount;
-				if (parent->height + pixels < min_sane_h) {
-					valid = false;
-					break;
-				}
-			}
-		}
-		if (valid) {
-			for (i = 0; i < parent->parent->children->length; i++) {
-				sibling = parent->parent->children->items[i];
-				if (sibling->y != focused->y) {
-					if (sibling->y < parent->y) {
-						double pixels = -1 * amount;
-						pixels /= bnumber;
-						if (tnumber) {
-							recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_BOTTOM);
-						} else {
-							recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_BOTTOM);
-						}
-					} else if (sibling->x > parent->x) {
-						double pixels = -1 * amount;
-						pixels /= tnumber;
-						if (bnumber) {
-							recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_TOP);
-						} else {
-							recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_TOP);
-						}
-					}
-				} else {
-					if (bnumber != 0 && tnumber != 0) {
-						double pixels = amount/2;
-						recursive_resize(parent, pixels, WLC_RESIZE_EDGE_TOP);
-						recursive_resize(parent, pixels, WLC_RESIZE_EDGE_BOTTOM);
-					} else if (tnumber) {
-						recursive_resize(parent, amount, WLC_RESIZE_EDGE_TOP);
-					} else if (bnumber) {
-						recursive_resize(parent, amount, WLC_RESIZE_EDGE_BOTTOM);
-					}
-				}
-			}
-			arrange_windows(swayc_active_workspace(), -1, -1);
-		}
-		return true;
+		return resize_tiled(amount, false);
 	}
-	return true;
+	return false;
 }
 
 static bool cmd_set(struct sway_config *config, int argc, char **argv) {
diff --git a/sway/handlers.c b/sway/handlers.c
index d8f9e987..1c4e044a 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -15,8 +15,9 @@
 #include "container.h"
 #include "focus.h"
 #include "input_state.h"
+#include "resize.h"
 
-static struct wlc_origin mouse_origin;
+struct wlc_origin mouse_origin;
 
 static bool pointer_test(swayc_t *view, void *_origin) {
 	const struct wlc_origin *origin = _origin;
@@ -338,261 +339,34 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
 	mouse_origin = *origin;
 	bool changed_floating = false;
 	bool changed_tiling = false;
-	int min_sane_w = 100;
-	int min_sane_h = 60;
 	if (!swayc_active_workspace()) {
 		return false;
 	}
 	// Do checks to determine if proper keys are being held
 	swayc_t *view = container_under_pointer();
-	uint32_t edge = 0;
 	if (pointer_state.floating.drag && view) {
 		if (view->is_floating) {
 			int dx = mouse_origin.x - prev_pos.x;
 			int dy = mouse_origin.y - prev_pos.y;
 			view->x += dx;
 			view->y += dy;
+			struct wlc_geometry geometry = {
+				.origin = {
+					.x = view->x,
+					.y = view->y
+				},
+				.size = {
+					.w = view->width,
+					.h = view->height
+				}
+			};
+			wlc_view_set_geometry(view->handle, 0, &geometry);
 			changed_floating = true;
 		}
 	} else if (pointer_state.floating.resize && view) {
-		if (view->is_floating) {
-			int dx = mouse_origin.x - prev_pos.x;
-			int dy = mouse_origin.y - prev_pos.y;
-
-			// Move and resize the view based on the dx/dy and mouse position
-			int midway_x = view->x + view->width/2;
-			int midway_y = view->y + view->height/2;
-			if (dx < 0) {
-				if (!pointer_state.lock.right) {
-					if (view->width > min_sane_w) {
-						changed_floating = true;
-						view->width += dx;
-						edge += WLC_RESIZE_EDGE_RIGHT;
-					}
-				} else if (mouse_origin.x < midway_x && !pointer_state.lock.left) {
-					changed_floating = true;
-					view->x += dx;
-					view->width -= dx;
-					edge += WLC_RESIZE_EDGE_LEFT;
-				}
-			} else if (dx > 0) {
-				if (mouse_origin.x > midway_x && !pointer_state.lock.right) {
-					changed_floating = true;
-					view->width += dx;
-					edge += WLC_RESIZE_EDGE_RIGHT;
-				} else if (!pointer_state.lock.left) {
-					if (view->width > min_sane_w) {
-						changed_floating = true;
-						view->x += dx;
-						view->width -= dx;
-						edge += WLC_RESIZE_EDGE_LEFT;
-					}
-				}
-			}
-
-			if (dy < 0) {
-				if (!pointer_state.lock.bottom) {
-					if (view->height > min_sane_h) {
-						changed_floating = true;
-						view->height += dy;
-						edge += WLC_RESIZE_EDGE_BOTTOM;
-					}
-				} else if (mouse_origin.y < midway_y && !pointer_state.lock.top) {
-					changed_floating = true;
-					view->y += dy;
-					view->height -= dy;
-					edge += WLC_RESIZE_EDGE_TOP;
-				}
-			} else if (dy > 0) {
-				if (mouse_origin.y > midway_y && !pointer_state.lock.bottom) {
-					changed_floating = true;
-					view->height += dy;
-					edge += WLC_RESIZE_EDGE_BOTTOM;
-				} else if (!pointer_state.lock.top) {
-					if (view->height > min_sane_h) {
-						changed_floating = true;
-						view->y += dy;
-						view->height -= dy;
-						edge += WLC_RESIZE_EDGE_TOP;
-					}
-				}
-			}
-		}
+		changed_floating = resize_floating(prev_pos);
 	} else if (pointer_state.tiling.resize && view) {
-		bool valid = true;
-		double dx = mouse_origin.x - prev_pos.x;
-		double dy = mouse_origin.y - prev_pos.y;
-		if (view != pointer_state.tiling.init_view) {
-			changed_tiling = true;
-			valid = false;
-			if (view->type != C_WORKSPACE) {
-				if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_LEFT) == view) {
-					pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20;
-					pointer_state.lock.temp_left = true;
-				} else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_RIGHT) == view) {
-					pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20;
-					pointer_state.lock.temp_right = true;
-				} else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_UP) == view) {
-					pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
-					pointer_state.lock.temp_up = true;
-				} else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_DOWN) == view) {
-					pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
-					pointer_state.lock.temp_down = true;
-				}
-			}
-		}
-
-		if ((dx < 0 || mouse_origin.x < pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_left) {
-			changed_tiling = true;
-			valid = false;
-		} else if (dx > 0 && pointer_state.lock.temp_left) {
-			pointer_state.lock.temp_left = false;
-			pointer_state.tiling.lock_pos.x = 0;
-		}
-
-		if ((dx > 0 || mouse_origin.x > pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_right) {
-			changed_tiling = true;
-			valid = false;
-		} else if (dx < 0 && pointer_state.lock.temp_right) {
-			pointer_state.lock.temp_right = false;
-			pointer_state.tiling.lock_pos.x = 0;
-		}
-
-		if ((dy < 0 || mouse_origin.y < pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_up) {
-			changed_tiling = true;
-			valid = false;
-		} else if (dy > 0 && pointer_state.lock.temp_up) {
-			pointer_state.lock.temp_up = false;
-			pointer_state.tiling.lock_pos.y = 0;
-		}
-
-		if ((dy > 0 || mouse_origin.y > pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_down) {
-			changed_tiling = true;
-			valid = false;
-		} else if (dy < 0 && pointer_state.lock.temp_down) {
-			pointer_state.lock.temp_down = false;
-			pointer_state.tiling.lock_pos.y = 0;
-		}
-
-		if (!view->is_floating && valid) {
-			// Handle layout resizes -- Find the biggest parent container then apply resizes to that
-			// and its bordering siblings
-			swayc_t *parent = view;
-			if (!pointer_state.lock.bottom) {
-				while (parent->type != C_WORKSPACE) {
-					// TODO: Absolute value is a bad hack here to compensate for rounding. Find a better
-					// way of doing this.
-					if (fabs(parent->parent->y + parent->parent->height - (view->y + view->height)) <= 1) {
-						parent = parent->parent;
-					} else {
-						break;
-					}
-				}
-				if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
-					swayc_t *sibling = get_swayc_in_direction(parent, MOVE_DOWN);
-					if (sibling) {
-						if ((parent->height > min_sane_h || dy > 0) && (sibling->height > min_sane_h || dy < 0)) {
-							recursive_resize(parent, dy, WLC_RESIZE_EDGE_BOTTOM);
-							recursive_resize(sibling, -1 * dy, WLC_RESIZE_EDGE_TOP);
-							changed_tiling = true;
-						} else {
-							if (parent->height < min_sane_h) {
-								//pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
-								pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
-								pointer_state.lock.temp_up = true;
-							} else if (sibling->height < min_sane_h) {
-								pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
-								pointer_state.lock.temp_down = true;
-							}
-						}
-					}
-				}
-			} else if (!pointer_state.lock.top) {
-				while (parent->type != C_WORKSPACE) {
-					if (fabs(parent->parent->y - view->y) <= 1) {
-						parent = parent->parent;
-					} else {
-						break;
-					}
-				}
-				if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
-					swayc_t *sibling = get_swayc_in_direction(parent, MOVE_UP);
-					if (sibling) {
-						if ((parent->height > min_sane_h || dy < 0) && (sibling->height > min_sane_h || dy > 0)) {
-							recursive_resize(parent, -1 * dy, WLC_RESIZE_EDGE_TOP);
-							recursive_resize(sibling, dy, WLC_RESIZE_EDGE_BOTTOM);
-							changed_tiling = true;
-						} else {
-							if (parent->height < min_sane_h) {
-								//pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
-								pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
-								pointer_state.lock.temp_down = true;
-							} else if (sibling->height < min_sane_h) {
-								pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
-								pointer_state.lock.temp_up = true;
-							}
-						}
-					}
-				}
-			}
-
-			parent = view;
-			if (!pointer_state.lock.right) {
-				while (parent->type != C_WORKSPACE) {
-					if (fabs(parent->parent->x + parent->parent->width - (view->x + view->width)) <= 1) {
-						parent = parent->parent;
-					} else {
-						sway_log(L_DEBUG, "view: %f vs parent: %f", view->x + view->width, parent->parent->x + parent->parent->width);
-						break;
-					}
-				}
-				if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
-					swayc_t *sibling = get_swayc_in_direction(parent, MOVE_RIGHT);
-					if (sibling) {
-						if ((parent->width > min_sane_w || dx > 0) && (sibling->width > min_sane_w || dx < 0)) {
-							recursive_resize(parent, dx, WLC_RESIZE_EDGE_RIGHT);
-							recursive_resize(sibling, -1 * dx, WLC_RESIZE_EDGE_LEFT);
-							changed_tiling = true;
-						} else {
-							if (parent->width < min_sane_w) {
-								pointer_state.lock.temp_left = true;
-								pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20;
-							} else if (sibling->width < min_sane_w) {
-								pointer_state.lock.temp_right = true;
-								pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20;
-							}
-						}
-					}
-				}
-			} else if (!pointer_state.lock.left) {
-				while (parent->type != C_WORKSPACE) {
-					if (fabs(parent->parent->x - view->x) <= 1 && parent->parent) {
-						parent = parent->parent;
-					} else {
-						break;
-					}
-				}
-				if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
-					swayc_t *sibling = get_swayc_in_direction(parent, MOVE_LEFT);
-					if (sibling) {
-						if ((parent->width > min_sane_w || dx < 0) && (sibling->width > min_sane_w || dx > 0)) {
-							recursive_resize(parent, -1 * dx, WLC_RESIZE_EDGE_LEFT);
-							recursive_resize(sibling, dx, WLC_RESIZE_EDGE_RIGHT);
-							changed_tiling = true;
-						} else {
-							if (parent->width < min_sane_w) {
-								pointer_state.lock.temp_right = true;
-								pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20;
-							} else if (sibling->width < min_sane_w) {
-								pointer_state.lock.temp_left = true;
-								pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20;
-							}
-						}
-					}
-				}
-			}
-			arrange_windows(swayc_active_workspace(), -1, -1);
-		}
+		changed_tiling = mouse_resize_tiled(prev_pos);
 	}
 	if (config->focus_follows_mouse && prev_handle != handle) {
 		// Dont change focus if fullscreen
@@ -604,21 +378,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
 	}
 	prev_handle = handle;
 	prev_pos = mouse_origin;
-	if (changed_floating) {
-		struct wlc_geometry geometry = {
-			.origin = {
-				.x = view->x,
-				.y = view->y
-			},
-			.size = {
-				.w = view->width,
-				.h = view->height
-			}
-		};
-		wlc_view_set_geometry(view->handle, edge, &geometry);
-		return true;
-	}
-	if (changed_tiling) {
+	if (changed_tiling || changed_floating) {
 		return true;
 	}
 	return false;
diff --git a/sway/layout.c b/sway/layout.c
index 70d9eb21..18ecb1e7 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -10,6 +10,8 @@
 #include "focus.h"
 
 swayc_t root_container;
+int min_sane_h = 60;
+int min_sane_w = 100;
 
 void init_layout(void) {
 	root_container.type = C_ROOT;
diff --git a/sway/resize.c b/sway/resize.c
new file mode 100644
index 00000000..a08ef4a1
--- /dev/null
+++ b/sway/resize.c
@@ -0,0 +1,491 @@
+#include <wlc/wlc.h>
+#include <math.h>
+#include "layout.h"
+#include "focus.h"
+#include "log.h"
+#include "input_state.h"
+#include "handlers.h"
+
+bool mouse_resize_tiled(struct wlc_origin prev_pos) {
+	swayc_t *view = container_under_pointer();
+	bool valid = true;
+	bool changed_tiling = false;
+	double dx = mouse_origin.x - prev_pos.x;
+	double dy = mouse_origin.y - prev_pos.y;
+	if (view != pointer_state.tiling.init_view) {
+		changed_tiling = true;
+		valid = false;
+		if (view->type != C_WORKSPACE) {
+			if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_LEFT) == view) {
+				pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20;
+				pointer_state.lock.temp_left = true;
+			} else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_RIGHT) == view) {
+				pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20;
+				pointer_state.lock.temp_right = true;
+			} else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_UP) == view) {
+				pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
+				pointer_state.lock.temp_up = true;
+			} else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_DOWN) == view) {
+				pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
+				pointer_state.lock.temp_down = true;
+			}
+		}
+	}
+
+	if ((dx < 0 || mouse_origin.x < pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_left) {
+		changed_tiling = true;
+		valid = false;
+	} else if (dx > 0 && pointer_state.lock.temp_left) {
+		pointer_state.lock.temp_left = false;
+		pointer_state.tiling.lock_pos.x = 0;
+	}
+
+	if ((dx > 0 || mouse_origin.x > pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_right) {
+		changed_tiling = true;
+		valid = false;
+	} else if (dx < 0 && pointer_state.lock.temp_right) {
+		pointer_state.lock.temp_right = false;
+		pointer_state.tiling.lock_pos.x = 0;
+	}
+
+	if ((dy < 0 || mouse_origin.y < pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_up) {
+		changed_tiling = true;
+		valid = false;
+	} else if (dy > 0 && pointer_state.lock.temp_up) {
+		pointer_state.lock.temp_up = false;
+		pointer_state.tiling.lock_pos.y = 0;
+	}
+
+	if ((dy > 0 || mouse_origin.y > pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_down) {
+		changed_tiling = true;
+		valid = false;
+	} else if (dy < 0 && pointer_state.lock.temp_down) {
+		pointer_state.lock.temp_down = false;
+		pointer_state.tiling.lock_pos.y = 0;
+	}
+
+	if (!view->is_floating && valid) {
+		// Handle layout resizes -- Find the biggest parent container then apply resizes to that
+		// and its bordering siblings
+		swayc_t *parent = view;
+		if (!pointer_state.lock.bottom) {
+			while (parent->type != C_WORKSPACE) {
+				// TODO: Absolute value is a bad hack here to compensate for rounding. Find a better
+				// way of doing this.
+				if (fabs(parent->parent->y + parent->parent->height - (view->y + view->height)) <= 1) {
+					parent = parent->parent;
+				} else {
+					break;
+				}
+			}
+			if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
+				swayc_t *sibling = get_swayc_in_direction(parent, MOVE_DOWN);
+				if (sibling) {
+					if ((parent->height > min_sane_h || dy > 0) && (sibling->height > min_sane_h || dy < 0)) {
+						recursive_resize(parent, dy, WLC_RESIZE_EDGE_BOTTOM);
+						recursive_resize(sibling, -1 * dy, WLC_RESIZE_EDGE_TOP);
+						changed_tiling = true;
+					} else {
+						if (parent->height < min_sane_h) {
+							//pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
+							pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
+							pointer_state.lock.temp_up = true;
+						} else if (sibling->height < min_sane_h) {
+							pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
+							pointer_state.lock.temp_down = true;
+						}
+					}
+				}
+			}
+		} else if (!pointer_state.lock.top) {
+			while (parent->type != C_WORKSPACE) {
+				if (fabs(parent->parent->y - view->y) <= 1) {
+					parent = parent->parent;
+				} else {
+					break;
+				}
+			}
+			if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
+				swayc_t *sibling = get_swayc_in_direction(parent, MOVE_UP);
+				if (sibling) {
+					if ((parent->height > min_sane_h || dy < 0) && (sibling->height > min_sane_h || dy > 0)) {
+						recursive_resize(parent, -1 * dy, WLC_RESIZE_EDGE_TOP);
+						recursive_resize(sibling, dy, WLC_RESIZE_EDGE_BOTTOM);
+						changed_tiling = true;
+					} else {
+						if (parent->height < min_sane_h) {
+							//pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
+							pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
+							pointer_state.lock.temp_down = true;
+						} else if (sibling->height < min_sane_h) {
+							pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
+							pointer_state.lock.temp_up = true;
+						}
+					}
+				}
+			}
+		}
+
+		parent = view;
+		if (!pointer_state.lock.right) {
+			while (parent->type != C_WORKSPACE) {
+				if (fabs(parent->parent->x + parent->parent->width - (view->x + view->width)) <= 1) {
+					parent = parent->parent;
+				} else {
+					sway_log(L_DEBUG, "view: %f vs parent: %f", view->x + view->width, parent->parent->x + parent->parent->width);
+					break;
+				}
+			}
+			if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
+				swayc_t *sibling = get_swayc_in_direction(parent, MOVE_RIGHT);
+				if (sibling) {
+					if ((parent->width > min_sane_w || dx > 0) && (sibling->width > min_sane_w || dx < 0)) {
+						recursive_resize(parent, dx, WLC_RESIZE_EDGE_RIGHT);
+						recursive_resize(sibling, -1 * dx, WLC_RESIZE_EDGE_LEFT);
+						changed_tiling = true;
+					} else {
+						if (parent->width < min_sane_w) {
+							pointer_state.lock.temp_left = true;
+							pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20;
+						} else if (sibling->width < min_sane_w) {
+							pointer_state.lock.temp_right = true;
+							pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20;
+						}
+					}
+				}
+			}
+		} else if (!pointer_state.lock.left) {
+			while (parent->type != C_WORKSPACE) {
+				if (fabs(parent->parent->x - view->x) <= 1 && parent->parent) {
+					parent = parent->parent;
+				} else {
+					break;
+				}
+			}
+			if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
+				swayc_t *sibling = get_swayc_in_direction(parent, MOVE_LEFT);
+				if (sibling) {
+					if ((parent->width > min_sane_w || dx < 0) && (sibling->width > min_sane_w || dx > 0)) {
+						recursive_resize(parent, -1 * dx, WLC_RESIZE_EDGE_LEFT);
+						recursive_resize(sibling, dx, WLC_RESIZE_EDGE_RIGHT);
+						changed_tiling = true;
+					} else {
+						if (parent->width < min_sane_w) {
+							pointer_state.lock.temp_right = true;
+							pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20;
+						} else if (sibling->width < min_sane_w) {
+							pointer_state.lock.temp_left = true;
+							pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20;
+						}
+					}
+				}
+			}
+		}
+		arrange_windows(swayc_active_workspace(), -1, -1);
+	}
+	return changed_tiling;
+}
+
+bool resize_floating(struct wlc_origin prev_pos) {
+	bool changed = false;
+	swayc_t *view = container_under_pointer();
+	uint32_t edge = 0;
+	int dx = mouse_origin.x - prev_pos.x;
+	int dy = mouse_origin.y - prev_pos.y;
+
+	// Move and resize the view based on the dx/dy and mouse position
+	int midway_x = view->x + view->width/2;
+	int midway_y = view->y + view->height/2;
+	if (dx < 0) {
+		if (!pointer_state.lock.right) {
+			if (view->width > min_sane_w) {
+				changed = true;
+				view->width += dx;
+				edge += WLC_RESIZE_EDGE_RIGHT;
+			}
+		} else if (mouse_origin.x < midway_x && !pointer_state.lock.left) {
+			changed = true;
+			view->x += dx;
+			view->width -= dx;
+			edge += WLC_RESIZE_EDGE_LEFT;
+		}
+	} else if (dx > 0) {
+		if (mouse_origin.x > midway_x && !pointer_state.lock.right) {
+			changed = true;
+			view->width += dx;
+			edge += WLC_RESIZE_EDGE_RIGHT;
+		} else if (!pointer_state.lock.left) {
+			if (view->width > min_sane_w) {
+				changed = true;
+				view->x += dx;
+				view->width -= dx;
+				edge += WLC_RESIZE_EDGE_LEFT;
+			}
+		}
+	}
+
+	if (dy < 0) {
+		if (!pointer_state.lock.bottom) {
+			if (view->height > min_sane_h) {
+				changed = true;
+				view->height += dy;
+				edge += WLC_RESIZE_EDGE_BOTTOM;
+			}
+		} else if (mouse_origin.y < midway_y && !pointer_state.lock.top) {
+			changed = true;
+			view->y += dy;
+			view->height -= dy;
+			edge += WLC_RESIZE_EDGE_TOP;
+		}
+	} else if (dy > 0) {
+		if (mouse_origin.y > midway_y && !pointer_state.lock.bottom) {
+			changed = true;
+			view->height += dy;
+			edge += WLC_RESIZE_EDGE_BOTTOM;
+		} else if (!pointer_state.lock.top) {
+			if (view->height > min_sane_h) {
+				changed = true;
+				view->y += dy;
+				view->height -= dy;
+				edge += WLC_RESIZE_EDGE_TOP;
+			}
+		}
+	}
+	if (changed) {
+		struct wlc_geometry geometry = {
+			.origin = {
+				.x = view->x,
+				.y = view->y
+			},
+			.size = {
+				.w = view->width,
+				.h = view->height
+			}
+		};
+		wlc_view_set_geometry(view->handle, edge, &geometry);
+	}
+	return changed;
+}
+
+bool resize_tiled(int amount, bool use_width) {
+	swayc_t *parent = get_focused_view(swayc_active_workspace());
+	swayc_t *focused = parent;
+	swayc_t *sibling;
+	if (!parent) {
+		return true;
+	}
+	// Find the closest parent container which has siblings of the proper layout.
+	// Then apply the resize to all of them.
+	int i;
+	if (use_width) {
+		int lnumber = 0;
+		int rnumber = 0;
+		while (parent->parent) {
+			if (parent->parent->layout == L_HORIZ) {
+				for (i = 0; i < parent->parent->children->length; i++) {
+					sibling = parent->parent->children->items[i];
+					if (sibling->x != focused->x) {
+						if (sibling->x < parent->x) {
+							lnumber++;
+						} else if (sibling->x > parent->x) {
+							rnumber++;
+						}
+					}
+				}
+				if (rnumber || lnumber) {
+					break;
+				}
+			}
+			parent = parent->parent;
+		}
+		if (parent == &root_container) {
+			return true;
+		}
+		sway_log(L_DEBUG, "Found the proper parent: %p. It has %d l conts, and %d r conts", parent->parent, lnumber, rnumber);
+		//TODO: Ensure rounding is done in such a way that there are NO pixel leaks
+		bool valid = true;
+		for (i = 0; i < parent->parent->children->length; i++) {
+			sibling = parent->parent->children->items[i];
+			if (sibling->x != focused->x) {
+				if (sibling->x < parent->x) {
+					double pixels = -1 * amount;
+					pixels /= lnumber;
+					if (rnumber) {
+						if ((sibling->width + pixels/2) < min_sane_w) {
+							valid = false;
+							break;
+						}
+					} else {
+						if ((sibling->width + pixels) < min_sane_w) {
+							valid = false;
+							break;
+						}
+					}
+				} else if (sibling->x > parent->x) {
+					double pixels = -1 * amount;
+					pixels /= rnumber;
+					if (lnumber) {
+						if ((sibling->width + pixels/2) < min_sane_w) {
+							valid = false;
+							break;
+						}
+					} else {
+						if ((sibling->width + pixels) < min_sane_w) {
+							valid = false;
+							break;
+						}
+					}
+				}
+			} else {
+				double pixels = amount;
+				if (parent->width + pixels < min_sane_w) {
+					valid = false;
+					break;
+				}
+			}
+		}
+		if (valid) {
+			for (i = 0; i < parent->parent->children->length; i++) {
+				sibling = parent->parent->children->items[i];
+				if (sibling->x != focused->x) {
+					if (sibling->x < parent->x) {
+						double pixels = -1 * amount;
+						pixels /= lnumber;
+						if (rnumber) {
+							recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_RIGHT);
+						} else {
+							recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_RIGHT);
+						}
+					} else if (sibling->x > parent->x) {
+						double pixels = -1 * amount;
+						pixels /= rnumber;
+						if (lnumber) {
+							recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_LEFT);
+						} else {
+							recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_LEFT);
+						}
+					}
+				} else {
+					if (rnumber != 0 && lnumber != 0) {
+						double pixels = amount;
+						pixels /= 2;
+						recursive_resize(parent, pixels, WLC_RESIZE_EDGE_LEFT);
+						recursive_resize(parent, pixels, WLC_RESIZE_EDGE_RIGHT);
+					} else if (rnumber) {
+						recursive_resize(parent, amount, WLC_RESIZE_EDGE_RIGHT);
+					} else if (lnumber) {
+						recursive_resize(parent, amount, WLC_RESIZE_EDGE_LEFT);
+					}
+				}
+			}
+			// Recursive resize does not handle positions, let arrange_windows
+			// take care of that.
+			arrange_windows(swayc_active_workspace(), -1, -1);
+		}
+		return true;
+	} else {
+		int tnumber = 0;
+		int bnumber = 0;
+		while (parent->parent) {
+			if (parent->parent->layout == L_VERT) {
+				for (i = 0; i < parent->parent->children->length; i++) {
+					sibling = parent->parent->children->items[i];
+					if (sibling->y != focused->y) {
+						if (sibling->y < parent->y) {
+							bnumber++;
+						} else if (sibling->y > parent->y) {
+							tnumber++;
+						}
+					}
+				}
+				if (bnumber || tnumber) {
+					break;
+				}
+			}
+			parent = parent->parent;
+		}
+		if (parent == &root_container) {
+			return true;
+		}
+		sway_log(L_DEBUG, "Found the proper parent: %p. It has %d b conts, and %d t conts", parent->parent, bnumber, tnumber);
+		//TODO: Ensure rounding is done in such a way that there are NO pixel leaks
+		bool valid = true;
+		for (i = 0; i < parent->parent->children->length; i++) {
+			sibling = parent->parent->children->items[i];
+			if (sibling->y != focused->y) {
+				if (sibling->y < parent->y) {
+					double pixels = -1 * amount;
+					pixels /= bnumber;
+					if (tnumber) {
+						if ((sibling->height + pixels/2) < min_sane_h) {
+							valid = false;
+							break;
+						}
+					} else {
+						if ((sibling->height + pixels) < min_sane_h) {
+							valid = false;
+							break;
+						}
+					}
+				} else if (sibling->y > parent->y) {
+					double pixels = -1 * amount;
+					pixels /= tnumber;
+					if (bnumber) {
+						if ((sibling->height + pixels/2) < min_sane_h) {
+							valid = false;
+							break;
+						}
+					} else {
+						if ((sibling->height + pixels) < min_sane_h) {
+							valid = false;
+							break;
+						}
+					}
+				}
+			} else {
+				double pixels = amount;
+				if (parent->height + pixels < min_sane_h) {
+					valid = false;
+					break;
+				}
+			}
+		}
+		if (valid) {
+			for (i = 0; i < parent->parent->children->length; i++) {
+				sibling = parent->parent->children->items[i];
+				if (sibling->y != focused->y) {
+					if (sibling->y < parent->y) {
+						double pixels = -1 * amount;
+						pixels /= bnumber;
+						if (tnumber) {
+							recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_BOTTOM);
+						} else {
+							recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_BOTTOM);
+						}
+					} else if (sibling->x > parent->x) {
+						double pixels = -1 * amount;
+						pixels /= tnumber;
+						if (bnumber) {
+							recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_TOP);
+						} else {
+							recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_TOP);
+						}
+					}
+				} else {
+					if (bnumber != 0 && tnumber != 0) {
+						double pixels = amount/2;
+						recursive_resize(parent, pixels, WLC_RESIZE_EDGE_TOP);
+						recursive_resize(parent, pixels, WLC_RESIZE_EDGE_BOTTOM);
+					} else if (tnumber) {
+						recursive_resize(parent, amount, WLC_RESIZE_EDGE_TOP);
+					} else if (bnumber) {
+						recursive_resize(parent, amount, WLC_RESIZE_EDGE_BOTTOM);
+					}
+				}
+			}
+			arrange_windows(swayc_active_workspace(), -1, -1);
+		}
+		return true;
+	}
+	return true;
+}