From f2d1cf3ceb9ca7198aba89245fafad42f16edb8e Mon Sep 17 00:00:00 2001
From: Ryan Dwyer <ryandwyer1@gmail.com>
Date: Wed, 11 Jul 2018 22:16:48 +1000
Subject: Implement floating_minimum_size and floating_maximum_size

---
 sway/commands.c                      |  4 ++-
 sway/commands/floating_minmax_size.c | 53 ++++++++++++++++++++++++++++++++++++
 sway/meson.build                     |  1 +
 sway/tree/view.c                     | 43 +++++++++++++++++++++++++----
 4 files changed, 94 insertions(+), 7 deletions(-)
 create mode 100644 sway/commands/floating_minmax_size.c

(limited to 'sway')

diff --git a/sway/commands.c b/sway/commands.c
index 6c5bea37..addd64a6 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -100,6 +100,8 @@ static struct cmd_handler handlers[] = {
 	{ "default_border", cmd_default_border },
 	{ "exec", cmd_exec },
 	{ "exec_always", cmd_exec_always },
+	{ "floating_maximum_size", cmd_floating_maximum_size },
+	{ "floating_minimum_size", cmd_floating_minimum_size },
 	{ "focus_follows_mouse", cmd_focus_follows_mouse },
 	{ "focus_wrapping", cmd_focus_wrapping },
 	{ "font", cmd_font },
@@ -344,7 +346,7 @@ struct cmd_results *config_command(char *exec) {
 
 	// Start block
 	if (argc > 1 && strcmp(argv[argc - 1], "{") == 0) {
-		char *block = join_args(argv, argc - 1); 
+		char *block = join_args(argv, argc - 1);
 		results = cmd_results_new(CMD_BLOCK, block, NULL);
 		free(block);
 		goto cleanup;
diff --git a/sway/commands/floating_minmax_size.c b/sway/commands/floating_minmax_size.c
new file mode 100644
index 00000000..0af78908
--- /dev/null
+++ b/sway/commands/floating_minmax_size.c
@@ -0,0 +1,53 @@
+#include <errno.h>
+#include <math.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <wlr/util/log.h>
+#include "sway/commands.h"
+#include "log.h"
+
+static const char* min_usage =
+	"Expected 'floating_minimum_size <width> x <height>'";
+
+static const char* max_usage =
+	"Expected 'floating_maximum_size <width> x <height>'";
+
+static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name,
+		const char *usage, int *config_width, int *config_height) {
+	struct cmd_results *error;
+	if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 3))) {
+		return error;
+	}
+
+	char *err;
+	int width = (int)strtol(argv[0], &err, 10);
+	if (*err) {
+		return cmd_results_new(CMD_INVALID, cmd_name, usage);
+	}
+
+	if (strcmp(argv[1], "x") != 0) {
+		return cmd_results_new(CMD_INVALID, cmd_name, usage);
+	}
+
+	int height = (int)strtol(argv[2], &err, 10);
+	if (*err) {
+		return cmd_results_new(CMD_INVALID, cmd_name, usage);
+	}
+
+	*config_width = width;
+	*config_height = height;
+
+	return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+}
+
+struct cmd_results *cmd_floating_minimum_size(int argc, char **argv) {
+	return handle_command(argc, argv, "floating_minimum_size", min_usage,
+			&config->floating_minimum_width, &config->floating_minimum_height);
+}
+
+struct cmd_results *cmd_floating_maximum_size(int argc, char **argv) {
+	return handle_command(argc, argv, "floating_maximum_size", max_usage,
+			&config->floating_maximum_width, &config->floating_maximum_height);
+}
diff --git a/sway/meson.build b/sway/meson.build
index e492aeee..72192917 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -40,6 +40,7 @@ sway_sources = files(
 	'commands/exec.c',
 	'commands/exec_always.c',
 	'commands/floating.c',
+	'commands/floating_minmax_size.c',
 	'commands/focus.c',
 	'commands/focus_follows_mouse.c',
 	'commands/focus_wrapping.c',
diff --git a/sway/tree/view.c b/sway/tree/view.c
index c96b6a97..f99def6c 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -150,12 +150,43 @@ uint32_t view_configure(struct sway_view *view, double lx, double ly, int width,
 
 void view_init_floating(struct sway_view *view) {
 	struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
-	int max_width = ws->width * 0.6666;
-	int max_height = ws->height * 0.6666;
-	view->width =
-		view->natural_width > max_width ? max_width : view->natural_width;
-	view->height =
-		view->natural_height > max_height ? max_height : view->natural_height;
+	int min_width, min_height;
+	int max_width, max_height;
+
+	if (config->floating_minimum_width == -1) { // no minimum
+		min_width = 0;
+	} else if (config->floating_minimum_width == 0) { // automatic
+		min_width = 75;
+	} else {
+		min_width = config->floating_minimum_width;
+	}
+
+	if (config->floating_minimum_height == -1) { // no minimum
+		min_height = 0;
+	} else if (config->floating_minimum_height == 0) { // automatic
+		min_height = 50;
+	} else {
+		min_height = config->floating_minimum_height;
+	}
+
+	if (config->floating_maximum_width == -1) { // no maximum
+		max_width = INT_MAX;
+	} else if (config->floating_maximum_width == 0) { // automatic
+		max_width = ws->width * 0.6666;
+	} else {
+		max_width = config->floating_maximum_width;
+	}
+
+	if (config->floating_maximum_height == -1) { // no maximum
+		max_height = INT_MAX;
+	} else if (config->floating_maximum_height == 0) { // automatic
+		max_height = ws->height * 0.6666;
+	} else {
+		max_height = config->floating_maximum_height;
+	}
+
+	view->width = fmax(min_width, fmin(view->natural_width, max_width));
+	view->height = fmax(min_height, fmin(view->natural_height, max_height));
 	view->x = ws->x + (ws->width - view->width) / 2;
 	view->y = ws->y + (ws->height - view->height) / 2;
 
-- 
cgit v1.2.3