From 15d9f1edcb69fec18104fc5d40780cf1306731ef Mon Sep 17 00:00:00 2001 From: Luminarys Date: Thu, 20 Aug 2015 11:30:11 -0500 Subject: [PATCH 1/7] Added in basic resize command --- include/layout.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/layout.h b/include/layout.h index 75e72d2fe..4dff81b7e 100644 --- a/include/layout.h +++ b/include/layout.h @@ -29,4 +29,6 @@ swayc_t *get_focused_container(swayc_t *parent); swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent); swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir); +void recursive_resize(swayc_t *container, double amount, enum movement_direction dir); + #endif From bc3babf566f1f8ad9db4d1f7b70a859f54ba6c48 Mon Sep 17 00:00:00 2001 From: Luminarys Date: Thu, 20 Aug 2015 11:30:32 -0500 Subject: [PATCH 2/7] Added in basic resize command --- include/ipc.h | 12 ++-- sway/commands.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++ sway/layout.c | 32 +++++++++++ 3 files changed, 183 insertions(+), 6 deletions(-) diff --git a/include/ipc.h b/include/ipc.h index 0b6441f66..2d71c666b 100644 --- a/include/ipc.h +++ b/include/ipc.h @@ -2,14 +2,14 @@ #define _SWAY_IPC_H enum ipc_command_type { - IPC_COMMAND = 0, + IPC_COMMAND = 0, IPC_GET_WORKSPACES = 1, - IPC_SUBSCRIBE = 2, - IPC_GET_OUTPUTS = 3, - IPC_GET_TREE = 4, - IPC_GET_MARKS = 5, + IPC_SUBSCRIBE = 2, + IPC_GET_OUTPUTS = 3, + IPC_GET_TREE = 4, + IPC_GET_MARKS = 5, IPC_GET_BAR_CONFIG = 6, - IPC_GET_VERSION = 7, + IPC_GET_VERSION = 7, }; void ipc_init(void); diff --git a/sway/commands.c b/sway/commands.c index 644b80050..cdc80a0bf 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -422,6 +422,150 @@ static bool cmd_reload(struct sway_config *config, int argc, char **argv) { return true; } +static bool cmd_resize(struct sway_config *config, int argc, char **argv) { + if (!checkarg(argc, "resize", EXPECTED_AT_LEAST, 3)) { + return false; + } + char *end; + 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(active_workspace); + swayc_t *focused = parent; + swayc_t *sibling; + if (!parent) { + return true; + } + // Find the closest possible sibling and resize using that edge + 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 + 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/lnumber); + if (lnumber) { + recursive_resize(sibling, pixels/2, MOVE_RIGHT); + } else { + recursive_resize(sibling, pixels, MOVE_RIGHT); + } + } else if (sibling->x > parent->x) { + double pixels = -1 * (amount/rnumber); + if (rnumber) { + recursive_resize(sibling, pixels/2, MOVE_LEFT); + } else { + recursive_resize(sibling, pixels, MOVE_LEFT); + } + } + } else { + if (rnumber != 0 && lnumber != 0) { + recursive_resize(parent, amount/2, MOVE_LEFT); + recursive_resize(parent, amount/2, MOVE_RIGHT); + } else if (rnumber) { + recursive_resize(parent, amount, MOVE_RIGHT); + } else if (lnumber) { + recursive_resize(parent, amount, MOVE_LEFT); + } + } + } + arrange_windows(active_workspace, -1, -1); + return 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 + 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/bnumber); + if (tnumber) { + recursive_resize(sibling, pixels/2, MOVE_UP); + } else { + recursive_resize(sibling, pixels, MOVE_UP); + } + } else if (sibling->x > parent->x) { + double pixels = -1 * (amount/tnumber); + if (bnumber) { + recursive_resize(sibling, pixels/2, MOVE_DOWN); + } else { + recursive_resize(sibling, pixels, MOVE_DOWN); + } + } + } else { + if (bnumber != 0 && tnumber != 0) { + recursive_resize(parent, amount/2, MOVE_UP); + recursive_resize(parent, amount/2, MOVE_DOWN); + } else if (tnumber) { + recursive_resize(parent, amount, MOVE_UP); + } else if (bnumber) { + recursive_resize(parent, amount, MOVE_DOWN); + } + } + } + arrange_windows(active_workspace, -1, -1); + return true; + } + sway_log(L_INFO, "Done with resize"); + return true; +} + static bool cmd_set(struct sway_config *config, int argc, char **argv) { if (!checkarg(argc, "set", EXPECTED_EQUAL_TO, 2)) { return false; @@ -587,6 +731,7 @@ static struct cmd_handler handlers[] = { { "layout", cmd_layout }, { "log_colors", cmd_log_colors }, { "reload", cmd_reload }, + { "resize", cmd_resize }, { "set", cmd_set }, { "split", cmd_split }, { "splith", cmd_splith }, diff --git a/sway/layout.c b/sway/layout.c index 78b3dd279..b70e10415 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -370,3 +370,35 @@ swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir) } } } + +void recursive_resize(swayc_t *container, double amount, enum movement_direction dir) { + int i; + bool layout_match = true; + if (dir == MOVE_LEFT) { + container->x += (int) amount; + container->width += (int) amount; + layout_match = container->layout == L_HORIZ; + } else if(dir == MOVE_RIGHT) { + container->width += (int) amount; + layout_match = container->layout == L_HORIZ; + } else if(dir == MOVE_UP) { + container->y += (int) amount; + container->height += (int) amount; + layout_match = container->layout == L_VERT; + } else if(dir == MOVE_DOWN) { + container->height += (int) amount; + layout_match = container->layout == L_VERT; + } + if (container->type == C_VIEW) { + return; + } + if (layout_match) { + for (i = 0; i < container->children->length; i++) { + recursive_resize(container->children->items[i], amount/container->children->length, dir); + } + } else { + for (i = 0; i < container->children->length; i++) { + recursive_resize(container->children->items[i], amount, dir); + } + } +} From d06732e1a8c2df4d1523c1c0efeff5534156e387 Mon Sep 17 00:00:00 2001 From: Luminarys Date: Thu, 20 Aug 2015 11:35:01 -0500 Subject: [PATCH 3/7] Altered incorrect comment --- sway/commands.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sway/commands.c b/sway/commands.c index cdc80a0bf..be6bc8cff 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -445,7 +445,8 @@ static bool cmd_resize(struct sway_config *config, int argc, char **argv) { if (!parent) { return true; } - // Find the closest possible sibling and resize using that edge + // 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; From c9935507f2bc8e2471f6642e99a2fb52ab1310f0 Mon Sep 17 00:00:00 2001 From: Luminarys Date: Thu, 20 Aug 2015 11:42:01 -0500 Subject: [PATCH 4/7] Style fixes --- sway/commands.c | 1 - sway/layout.c | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/sway/commands.c b/sway/commands.c index be6bc8cff..27dbb44b3 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -563,7 +563,6 @@ static bool cmd_resize(struct sway_config *config, int argc, char **argv) { arrange_windows(active_workspace, -1, -1); return true; } - sway_log(L_INFO, "Done with resize"); return true; } diff --git a/sway/layout.c b/sway/layout.c index b70e10415..c9c8fa7f7 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -378,14 +378,14 @@ void recursive_resize(swayc_t *container, double amount, enum movement_direction container->x += (int) amount; container->width += (int) amount; layout_match = container->layout == L_HORIZ; - } else if(dir == MOVE_RIGHT) { + } else if (dir == MOVE_RIGHT) { container->width += (int) amount; layout_match = container->layout == L_HORIZ; - } else if(dir == MOVE_UP) { + } else if (dir == MOVE_UP) { container->y += (int) amount; container->height += (int) amount; layout_match = container->layout == L_VERT; - } else if(dir == MOVE_DOWN) { + } else if (dir == MOVE_DOWN) { container->height += (int) amount; layout_match = container->layout == L_VERT; } From f589731f2912660bab6fdffc14ddcdbac3edd41c Mon Sep 17 00:00:00 2001 From: Luminarys Date: Thu, 20 Aug 2015 21:37:59 -0500 Subject: [PATCH 5/7] Rewrite of resize command to make it more sane --- include/container.h | 4 ++-- include/layout.h | 2 +- sway/commands.c | 53 ++++++++++++++++++++++++++------------------- sway/layout.c | 44 ++++++++++++++++++++----------------- sway/log.c | 4 ++-- 5 files changed, 60 insertions(+), 47 deletions(-) diff --git a/include/container.h b/include/container.h index bd92058d6..d3026011a 100644 --- a/include/container.h +++ b/include/container.h @@ -33,12 +33,12 @@ struct sway_container { enum swayc_layouts layout; // Not including borders or margins - int width, height; + double width, height; // Used for setting floating geometry int desired_width, desired_height; - int x, y; + double x, y; bool visible; bool is_floating; diff --git a/include/layout.h b/include/layout.h index 4dff81b7e..566e32465 100644 --- a/include/layout.h +++ b/include/layout.h @@ -29,6 +29,6 @@ swayc_t *get_focused_container(swayc_t *parent); swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent); swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir); -void recursive_resize(swayc_t *container, double amount, enum movement_direction dir); +void recursive_resize(swayc_t *container, double amount, enum wlc_resize_edge edge); #endif diff --git a/sway/commands.c b/sway/commands.c index 27dbb44b3..0f743b4e3 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -478,31 +478,37 @@ static bool cmd_resize(struct sway_config *config, int argc, char **argv) { sibling = parent->parent->children->items[i]; if (sibling->x != focused->x) { if (sibling->x < parent->x) { - double pixels = -1 * (amount/lnumber); - if (lnumber) { - recursive_resize(sibling, pixels/2, MOVE_RIGHT); + double pixels = -1 * amount; + pixels /= lnumber; + if (rnumber) { + recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_RIGHT); } else { - recursive_resize(sibling, pixels, MOVE_RIGHT); + recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_RIGHT); } } else if (sibling->x > parent->x) { - double pixels = -1 * (amount/rnumber); - if (rnumber) { - recursive_resize(sibling, pixels/2, MOVE_LEFT); + double pixels = -1 * amount; + pixels /= rnumber; + if (lnumber) { + recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_LEFT); } else { - recursive_resize(sibling, pixels, MOVE_LEFT); + recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_LEFT); } } } else { if (rnumber != 0 && lnumber != 0) { - recursive_resize(parent, amount/2, MOVE_LEFT); - recursive_resize(parent, amount/2, MOVE_RIGHT); + 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, MOVE_RIGHT); + recursive_resize(parent, amount, WLC_RESIZE_EDGE_RIGHT); } else if (lnumber) { - recursive_resize(parent, amount, MOVE_LEFT); + recursive_resize(parent, amount, WLC_RESIZE_EDGE_LEFT); } } } + // Recursive resize does not handle positions, let arrange_windows + // take care of that. arrange_windows(active_workspace, -1, -1); return true; } else if (strcmp(argv[1], "height") == 0) { @@ -535,28 +541,31 @@ static bool cmd_resize(struct sway_config *config, int argc, char **argv) { sibling = parent->parent->children->items[i]; if (sibling->y != focused->y) { if (sibling->y < parent->y) { - double pixels = -1 * (amount/bnumber); + double pixels = -1 * amount; + pixels /= bnumber; if (tnumber) { - recursive_resize(sibling, pixels/2, MOVE_UP); + recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_BOTTOM); } else { - recursive_resize(sibling, pixels, MOVE_UP); + recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_BOTTOM); } } else if (sibling->x > parent->x) { - double pixels = -1 * (amount/tnumber); + double pixels = -1 * amount; + pixels /= tnumber; if (bnumber) { - recursive_resize(sibling, pixels/2, MOVE_DOWN); + recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_TOP); } else { - recursive_resize(sibling, pixels, MOVE_DOWN); + recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_TOP); } } } else { if (bnumber != 0 && tnumber != 0) { - recursive_resize(parent, amount/2, MOVE_UP); - recursive_resize(parent, amount/2, MOVE_DOWN); + 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, MOVE_UP); + recursive_resize(parent, amount, WLC_RESIZE_EDGE_TOP); } else if (bnumber) { - recursive_resize(parent, amount, MOVE_DOWN); + recursive_resize(parent, amount, WLC_RESIZE_EDGE_BOTTOM); } } } diff --git a/sway/layout.c b/sway/layout.c index c9c8fa7f7..50e7b5925 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -29,7 +29,7 @@ static int index_child(swayc_t *parent, swayc_t *child) { } void add_child(swayc_t *parent, swayc_t *child) { - sway_log(L_DEBUG, "Adding %p (%d, %dx%d) to %p (%d, %dx%d)", child, child->type, + sway_log(L_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)", child, child->type, child->width, child->height, parent, parent->type, parent->width, parent->height); list_add(parent->children, child); child->parent = parent; @@ -40,7 +40,7 @@ void add_child(swayc_t *parent, swayc_t *child) { } void add_floating(swayc_t *ws, swayc_t *child) { - sway_log(L_DEBUG, "Adding %p (%d, %dx%d) to %p (%d, %dx%d)", child, child->type, + sway_log(L_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)", child, child->type, child->width, child->height, ws, ws->type, ws->width, ws->height); list_add(ws->floating, child); child->parent = ws; @@ -144,7 +144,7 @@ void arrange_windows(swayc_t *container, int width, int height) { child->y = y + container->gaps; child->width = width - container->gaps * 2; child->height = height - container->gaps * 2; - sway_log(L_DEBUG, "Arranging workspace #%d at %d, %d", i, child->x, child->y); + sway_log(L_DEBUG, "Arranging workspace #%d at %f, %f", i, child->x, child->y); arrange_windows(child, -1, -1); } return; @@ -193,7 +193,7 @@ void arrange_windows(swayc_t *container, int width, int height) { default: // Calculate total width for (i = 0; i < container->children->length; ++i) { - int *old_width = &((swayc_t *)container->children->items[i])->width; + double *old_width = &((swayc_t *)container->children->items[i])->width; if (*old_width <= 0) { if (container->children->length > 1) { *old_width = width / (container->children->length - 1); @@ -220,7 +220,7 @@ void arrange_windows(swayc_t *container, int width, int height) { case L_VERT: // Calculate total height for (i = 0; i < container->children->length; ++i) { - int *old_height = &((swayc_t *)container->children->items[i])->height; + double *old_height = &((swayc_t *)container->children->items[i])->height; if (*old_height <= 0) { if (container->children->length > 1) { *old_height = height / (container->children->length - 1); @@ -371,34 +371,38 @@ swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir) } } -void recursive_resize(swayc_t *container, double amount, enum movement_direction dir) { +void recursive_resize(swayc_t *container, double amount, enum wlc_resize_edge edge) { int i; bool layout_match = true; - if (dir == MOVE_LEFT) { - container->x += (int) amount; - container->width += (int) amount; + sway_log(L_DEBUG, "Resizing %p with amount: %f", container, amount); + if (edge == WLC_RESIZE_EDGE_LEFT || edge == WLC_RESIZE_EDGE_RIGHT) { + container->width += amount; layout_match = container->layout == L_HORIZ; - } else if (dir == MOVE_RIGHT) { - container->width += (int) amount; - layout_match = container->layout == L_HORIZ; - } else if (dir == MOVE_UP) { - container->y += (int) amount; - container->height += (int) amount; - layout_match = container->layout == L_VERT; - } else if (dir == MOVE_DOWN) { - container->height += (int) amount; + } else if (edge == WLC_RESIZE_EDGE_TOP || edge == WLC_RESIZE_EDGE_BOTTOM) { + container->height += amount; layout_match = container->layout == L_VERT; } if (container->type == C_VIEW) { + struct wlc_geometry geometry = { + .origin = { + .x = container->x + container->gaps / 2, + .y = container->y + container->gaps / 2 + }, + .size = { + .w = container->width - container->gaps, + .h = container->height - container->gaps + } + }; + wlc_view_set_geometry(container->handle, edge, &geometry); return; } if (layout_match) { for (i = 0; i < container->children->length; i++) { - recursive_resize(container->children->items[i], amount/container->children->length, dir); + recursive_resize(container->children->items[i], amount/container->children->length, edge); } } else { for (i = 0; i < container->children->length; i++) { - recursive_resize(container->children->items[i], amount, dir); + recursive_resize(container->children->items[i], amount, edge); } } } diff --git a/sway/log.c b/sway/log.c index 6e01421bc..eda0c88ee 100644 --- a/sway/log.c +++ b/sway/log.c @@ -142,8 +142,8 @@ static void container_log(const swayc_t *c) { c->layout == L_STACKED ? "Stacked|": c->layout == L_FLOATING ? "Floating|": "Unknown|"); - fprintf(stderr, "w:%d|h:%d|", c->width, c->height); - fprintf(stderr, "x:%d|y:%d|", c->x, c->y); + fprintf(stderr, "w:%f|h:%f|", c->width, c->height); + fprintf(stderr, "x:%f|y:%f|", c->x, c->y); fprintf(stderr, "vis:%c|", c->visible?'t':'f'); fprintf(stderr, "name:%.16s|", c->name); fprintf(stderr, "children:%d\n",c->children?c->children->length:0); From 461da7f87fa970ce4ba1a124e6197554c85d42e5 Mon Sep 17 00:00:00 2001 From: Luminarys Date: Fri, 21 Aug 2015 00:17:26 -0500 Subject: [PATCH 6/7] Added in bspwm like mouse resizing --- include/input_state.h | 3 ++ include/layout.h | 2 +- sway/handlers.c | 109 ++++++++++++++++++++++++++++++++++++---- sway/input_state.c | 3 +- sway/layout.c | 6 +-- sway/type | 113 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 221 insertions(+), 15 deletions(-) create mode 100644 sway/type diff --git a/include/input_state.h b/include/input_state.h index 782b4b19c..711ad6338 100644 --- a/include/input_state.h +++ b/include/input_state.h @@ -34,6 +34,9 @@ extern struct pointer_state { bool drag; bool resize; } floating; + struct pointer_tiling { + bool resize; + } tiling; struct pointer_lock { bool left; bool right; diff --git a/include/layout.h b/include/layout.h index 566e32465..20044b953 100644 --- a/include/layout.h +++ b/include/layout.h @@ -18,7 +18,7 @@ swayc_t *replace_child(swayc_t *child, swayc_t *new_child); swayc_t *remove_child(swayc_t *child); // Layout -void arrange_windows(swayc_t *container, int width, int height); +void arrange_windows(swayc_t *container, double width, double height); // Focus void unfocus_all(swayc_t *container); diff --git a/sway/handlers.c b/sway/handlers.c index 5993223d3..a71328e3d 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -351,7 +352,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct return false; } // Do checks to determine if proper keys are being held - swayc_t *view = get_focused_view(active_workspace); + swayc_t *view = container_under_pointer(); uint32_t edge = 0; if (pointer_state.floating.drag && view) { if (view->is_floating) { @@ -426,6 +427,91 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct } } } + } + } else if (pointer_state.tiling.resize && view) { + if (!view->is_floating) { + // Handle layout resizes -- Find the biggest parent container then apply resizes to that + // and its bordering siblings + swayc_t *parent = view; + double dx = mouse_origin.x - prev_pos.x; + double dy = mouse_origin.y - prev_pos.y; + if (pointer_state.lock.top) { + 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) { + sway_log(L_DEBUG, "Top is locked, found biggest valid parent at: %p", parent); + swayc_t *sibling = get_swayc_in_direction(parent, MOVE_DOWN); + if (sibling) { + sway_log(L_DEBUG, "Found sibling at: %p", sibling); + recursive_resize(parent, dy, WLC_RESIZE_EDGE_BOTTOM); + recursive_resize(sibling, -1 * dy, WLC_RESIZE_EDGE_TOP); + } + } + } else { + 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) { + sway_log(L_DEBUG, "Bot is locked, found biggest valid parent at: %p", parent); + swayc_t *sibling = get_swayc_in_direction(parent, MOVE_UP); + if (sibling) { + sway_log(L_DEBUG, "Found sibling at: %p", sibling); + recursive_resize(parent, -1 * dy, WLC_RESIZE_EDGE_TOP); + recursive_resize(sibling, dy, WLC_RESIZE_EDGE_BOTTOM); + } + } + } + + parent = view; + if (pointer_state.lock.left) { + 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; + } + } + sway_log(L_DEBUG, "Left is locked, found biggest valid parent at: %p", parent); + if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) { + sway_log(L_DEBUG, "Left is locked, found biggest valid parent at: %p", parent); + swayc_t *sibling = get_swayc_in_direction(parent, MOVE_RIGHT); + if (sibling) { + sway_log(L_DEBUG, "Found sibling at: %p", sibling); + recursive_resize(parent, dx, WLC_RESIZE_EDGE_RIGHT); + recursive_resize(sibling, -1 * dx, WLC_RESIZE_EDGE_LEFT); + } + } + } else { + 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) { + sway_log(L_DEBUG, "Right is locked, found biggest valid parent at: %p", parent); + swayc_t *sibling = get_swayc_in_direction(parent, MOVE_LEFT); + if (sibling) { + sway_log(L_DEBUG, "Found sibling at: %p", sibling); + recursive_resize(parent, -1 * dx, WLC_RESIZE_EDGE_LEFT); + recursive_resize(sibling, dx, WLC_RESIZE_EDGE_RIGHT); + } + } + } + arrange_windows(active_workspace, -1, -1); } } if (config->focus_follows_mouse && prev_handle != handle) { @@ -472,7 +558,16 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w pointer_state.r_held = true; } swayc_t *pointer = container_under_pointer(); - set_focused_container(pointer); + if (pointer) { + set_focused_container(pointer); + int midway_x = pointer->x + pointer->width/2; + int midway_y = pointer->y + pointer->height/2; + pointer_state.lock.bottom = origin->y < midway_y; + pointer_state.lock.top = !pointer_state.lock.bottom; + pointer_state.lock.right = origin->x < midway_x; + pointer_state.lock.left = !pointer_state.lock.right; + } + if (pointer->is_floating) { int i; for (i = 0; i < pointer->parent->floating->length; i++) { @@ -484,19 +579,14 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w } arrange_windows(pointer->parent, -1, -1); if (modifiers->mods & config->floating_mod) { - int midway_x = pointer->x + pointer->width/2; - int midway_y = pointer->y + pointer->height/2; - pointer_state.floating.drag = pointer_state.l_held; pointer_state.floating.resize = pointer_state.r_held; - pointer_state.lock.bottom = origin->y < midway_y; - pointer_state.lock.top = !pointer_state.lock.bottom; - pointer_state.lock.right = origin->x < midway_x; - pointer_state.lock.left = !pointer_state.lock.right; start_floating(pointer); } // Dont want pointer sent to window while dragging or resizing return (pointer_state.floating.drag || pointer_state.floating.resize); + } else { + pointer_state.tiling.resize = pointer_state.r_held; } return (pointer && pointer != focused); } else { @@ -508,6 +598,7 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w if (button == M_RIGHT_CLICK) { pointer_state.r_held = false; pointer_state.floating.resize = false; + pointer_state.tiling.resize = false; pointer_state.lock = (struct pointer_lock){false ,false ,false ,false}; } } diff --git a/sway/input_state.c b/sway/input_state.c index a7f88d4a6..e592cfc15 100644 --- a/sway/input_state.c +++ b/sway/input_state.c @@ -41,7 +41,7 @@ void release_key(keycode key) { } } -struct pointer_state pointer_state = {0, 0, {0, 0}, {0, 0, 0, 0}}; +struct pointer_state pointer_state = {0, 0, {0, 0}, {0}, {0, 0, 0, 0}}; static struct wlc_geometry saved_floating; @@ -65,4 +65,3 @@ void reset_floating(swayc_t *view) { pointer_state.floating = (struct pointer_floating){0,0}; pointer_state.lock = (struct pointer_lock){0,0,0,0}; } - diff --git a/sway/layout.c b/sway/layout.c index 50e7b5925..12b279876 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -109,7 +109,7 @@ swayc_t *remove_child(swayc_t *child) { } -void arrange_windows(swayc_t *container, int width, int height) { +void arrange_windows(swayc_t *container, double width, double height) { int i; if (width == -1 || height == -1) { sway_log(L_DEBUG, "Arranging layout for %p", container); @@ -209,7 +209,7 @@ void arrange_windows(swayc_t *container, int width, int height) { sway_log(L_DEBUG, "Arranging %p horizontally", container); for (i = 0; i < container->children->length; ++i) { swayc_t *child = container->children->items[i]; - sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %d by %f)", child, child->type, width, scale); + sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, width, scale); child->x = x + container->x; child->y = y + container->y; arrange_windows(child, child->width * scale, height); @@ -236,7 +236,7 @@ void arrange_windows(swayc_t *container, int width, int height) { sway_log(L_DEBUG, "Arranging %p vertically", container); for (i = 0; i < container->children->length; ++i) { swayc_t *child = container->children->items[i]; - sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %d by %f)", child, child->type, height, scale); + sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, height, scale); child->x = x + container->x; child->y = y + container->y; arrange_windows(child, width, child->height * scale); diff --git a/sway/type b/sway/type new file mode 100644 index 000000000..c7bebe5e4 --- /dev/null +++ b/sway/type @@ -0,0 +1,113 @@ +workspace.c:78:9: while (parent->type != C_OUTPUT) { +workspace.c:79:12: parent = parent->parent; + +focus.c:16:6: if (parent->focused != c) { +focus.c:30:8: if (parent->focused) { +focus.c:31:19: swayc_t *ws = parent->focused; +focus.c:38:25: wlc_output_set_mask(parent->handle, 2); +focus.c:39:8: c->parent->focused = c; +focus.c:53:5: c->parent->focused = c; +focus.c:71:20: while (parent && !parent->is_focused) { +focus.c:72:12: parent = parent->focused; +focus.c:143:13: if (find->parent->focused != find) { +focus.c:167:19: while (parent && parent->type != C_VIEW) { +focus.c:168:7: if (parent->type == C_WORKSPACE && parent->focused == NULL) { +focus.c:171:12: parent = parent->focused; + +handlers.c:24:9: while (parent->type != C_OUTPUT) { +handlers.c:25:12: parent = parent->parent; +handlers.c:436:18: while (parent->parent && parent->y + parent->height == view->y + view->height && parent->type != L_WORKSPACE) { +handlers.c:437:30: parent = parent->parent; +handlers.c:440:50: if (parent == &root_container || parent->children->length == 1) { +handlers.c:444:18: while (parent->parent && parent->y == view->y) { +handlers.c:445:30: parent = parent->parent; +handlers.c:448:50: if (parent == &root_container || parent->children->length == 1) { +handlers.c:454:18: while (parent->parent && parent->x + parent->width == view->x + view->width) { +handlers.c:455:30: parent = parent->parent; +handlers.c:458:50: if (parent == &root_container || parent->children->length == 1) { +handlers.c:462:18: while (parent->parent && parent->x + parent->width == view->x) { +handlers.c:463:30: parent = parent->parent; +handlers.c:466:50: if (parent == &root_container || parent->children->length == 1) { +handlers.c:528:29: for (i = 0; i < pointer->parent->floating->length; i++) { +handlers.c:529:18: if (pointer->parent->floating->items[i] == pointer) { +handlers.c:530:24: list_del(pointer->parent->floating, i); +handlers.c:531:24: list_add(pointer->parent->floating, pointer); + +container.c:284:6: if (parent->type == C_CONTAINER) { + +layout.c:23:18: for (i = 0; i < parent->children->length; ++i) { +layout.c:24:7: if (parent->children->items[i] == child) { +layout.c:33:40: child->width, child->height, parent, parent->type, parent->width, parent->height); +layout.c:34:11: list_add(parent->children, child); +layout.c:37:6: if (parent->children->length == 1) { +layout.c:56:11: if (i == parent->children->length) { +layout.c:59:14: list_insert(parent->children, i+1, child); +layout.c:70:2: parent->children->items[i] = new_child; +layout.c:73:13: if (child->parent->focused == child) { +layout.c:85:19: for (i = 0; i < parent->floating->length; ++i) { +layout.c:86:8: if (parent->floating->items[i] == child) { +layout.c:87:14: list_del(parent->floating, i); +layout.c:93:19: for (i = 0; i < parent->children->length; ++i) { +layout.c:94:8: if (parent->children->items[i] == child) { +layout.c:95:14: list_del(parent->children, i); +layout.c:101:6: if (parent->focused == child) { +layout.c:102:7: if (parent->children->length > 0) { +layout.c:103:38: set_focused_container_for(parent, parent->children->items[i?i-1:0]); +layout.c:105:4: parent->focused = NULL; +layout.c:165:12: while (parent->type != C_OUTPUT) { +layout.c:166:15: parent = parent->parent; +layout.c:170:23: geometry.size.w = parent->width; +layout.c:171:23: geometry.size.h = parent->height; +layout.c:267:13: while (parent->type != C_OUTPUT) { +layout.c:268:16: parent = parent->parent; +layout.c:272:24: geometry.size.w = parent->width; +layout.c:273:24: geometry.size.h = parent->height; +layout.c:294:6: if (parent->children == NULL) { +layout.c:300:6: if (parent->type == C_WORKSPACE) { +layout.c:301:19: for (i = 0; i < parent->floating->length; ++i) { +layout.c:302:21: swayc_t *child = parent->floating->items[i]; +layout.c:309:18: for (i = 0; i < parent->children->length; ++i) { +layout.c:310:20: swayc_t *child = parent->children->items[i]; +layout.c:327:7: if (parent->type == C_OUTPUT) { +layout.c:338:8: if (parent->layout == L_HORIZ || parent->type == C_ROOT) { +layout.c:343:8: if (parent->layout == L_VERT) { +layout.c:350:20: for (i = 0; i < parent->children->length; ++i) { +layout.c:351:22: swayc_t *child = parent->children->items[i]; +layout.c:357:34: if (desired < 0 || desired >= parent->children->length) { +layout.c:360:12: return parent->children->items[desired]; +layout.c:365:13: parent = parent->parent; + +commands.c:394:9: while (parent->type == C_VIEW) { +commands.c:395:12: parent = parent->parent; +commands.c:399:3: parent->layout = L_HORIZ; +commands.c:401:3: parent->layout = L_VERT; +commands.c:403:7: if (parent->layout == L_VERT) { +commands.c:404:4: parent->layout = L_HORIZ; +commands.c:406:4: parent->layout = L_VERT; +commands.c:409:26: arrange_windows(parent, parent->width, parent->height); +commands.c:454:10: while (parent->parent) { +commands.c:455:8: if (parent->parent->layout == L_HORIZ) { +commands.c:456:21: for (i = 0; i < parent->parent->children->length; i++) { +commands.c:457:16: sibling = parent->parent->children->items[i]; +commands.c:459:24: if (sibling->x < parent->x) { +commands.c:461:31: } else if (sibling->x > parent->x) { +commands.c:470:13: parent = parent->parent; +commands.c:475:87: sway_log(L_DEBUG, "Found the proper parent: %p. It has %d l conts, and %d r conts", parent->parent, lnumber, rnumber); +commands.c:477:19: for (i = 0; i < parent->parent->children->length; i++) { +commands.c:478:14: sibling = parent->parent->children->items[i]; +commands.c:480:22: if (sibling->x < parent->x) { +commands.c:488:29: } else if (sibling->x > parent->x) { +commands.c:517:10: while (parent->parent) { +commands.c:518:8: if (parent->parent->layout == L_VERT) { +commands.c:519:21: for (i = 0; i < parent->parent->children->length; i++) { +commands.c:520:16: sibling = parent->parent->children->items[i]; +commands.c:522:24: if (sibling->y < parent->y) { +commands.c:524:31: } else if (sibling->y > parent->y) { +commands.c:533:13: parent = parent->parent; +commands.c:538:87: sway_log(L_DEBUG, "Found the proper parent: %p. It has %d b conts, and %d t conts", parent->parent, bnumber, tnumber); +commands.c:540:19: for (i = 0; i < parent->parent->children->length; i++) { +commands.c:541:14: sibling = parent->parent->children->items[i]; +commands.c:543:22: if (sibling->y < parent->y) { +commands.c:551:29: } else if (sibling->x > parent->x) { +commands.c:603:54: } else if (focused->type != C_WORKSPACE && focused->parent->children->length == 1) { +commands.c:606:12: focused->parent->layout = layout; From 96ab21b2766096bdb42d79a0169d42b9ff00e2fb Mon Sep 17 00:00:00 2001 From: Luminarys Date: Fri, 21 Aug 2015 00:49:47 -0500 Subject: [PATCH 7/7] Fixes to resizing and added in resize lock once boundaries are exceeded --- include/input_state.h | 1 + sway/handlers.c | 45 +++++++++++++++++++++++++++++++------------ sway/log.c | 1 + 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/include/input_state.h b/include/input_state.h index 711ad6338..7119c68b9 100644 --- a/include/input_state.h +++ b/include/input_state.h @@ -36,6 +36,7 @@ extern struct pointer_state { } floating; struct pointer_tiling { bool resize; + swayc_t *init_view; } tiling; struct pointer_lock { bool left; diff --git a/sway/handlers.c b/sway/handlers.c index a71328e3d..571dd2a69 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -348,6 +348,9 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct static wlc_handle prev_handle = 0; mouse_origin = *origin; bool changed_floating = false; + bool changed_tiling = false; + int min_sane_w = 100; + int min_sane_h = 60; if (!active_workspace) { return false; } @@ -366,8 +369,6 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct if (view->is_floating) { int dx = mouse_origin.x - prev_pos.x; int dy = mouse_origin.y - prev_pos.y; - int min_sane_w = 100; - int min_sane_h = 60; // Move and resize the view based on the dx/dy and mouse position int midway_x = view->x + view->width/2; @@ -429,7 +430,11 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct } } } else if (pointer_state.tiling.resize && view) { - if (!view->is_floating) { + if (view != pointer_state.tiling.init_view) { + // Quit out of the resize + pointer_state.tiling.init_view = NULL; + } + if (!view->is_floating && view == pointer_state.tiling.init_view) { // Handle layout resizes -- Find the biggest parent container then apply resizes to that // and its bordering siblings swayc_t *parent = view; @@ -450,8 +455,11 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct swayc_t *sibling = get_swayc_in_direction(parent, MOVE_DOWN); if (sibling) { sway_log(L_DEBUG, "Found sibling at: %p", sibling); - recursive_resize(parent, dy, WLC_RESIZE_EDGE_BOTTOM); - recursive_resize(sibling, -1 * dy, WLC_RESIZE_EDGE_TOP); + 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 { @@ -467,8 +475,11 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct swayc_t *sibling = get_swayc_in_direction(parent, MOVE_UP); if (sibling) { sway_log(L_DEBUG, "Found sibling at: %p", sibling); - recursive_resize(parent, -1 * dy, WLC_RESIZE_EDGE_TOP); - recursive_resize(sibling, dy, WLC_RESIZE_EDGE_BOTTOM); + 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; + } } } } @@ -483,14 +494,16 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct break; } } - sway_log(L_DEBUG, "Left is locked, found biggest valid parent at: %p", parent); if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) { sway_log(L_DEBUG, "Left is locked, found biggest valid parent at: %p", parent); swayc_t *sibling = get_swayc_in_direction(parent, MOVE_RIGHT); if (sibling) { sway_log(L_DEBUG, "Found sibling at: %p", sibling); - recursive_resize(parent, dx, WLC_RESIZE_EDGE_RIGHT); - recursive_resize(sibling, -1 * dx, WLC_RESIZE_EDGE_LEFT); + 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 { @@ -506,8 +519,11 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct swayc_t *sibling = get_swayc_in_direction(parent, MOVE_LEFT); if (sibling) { sway_log(L_DEBUG, "Found sibling at: %p", sibling); - recursive_resize(parent, -1 * dx, WLC_RESIZE_EDGE_LEFT); - recursive_resize(sibling, dx, WLC_RESIZE_EDGE_RIGHT); + 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; + } } } } @@ -538,6 +554,9 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_view_set_geometry(view->handle, edge, &geometry); return true; } + if (changed_tiling) { + return true; + } return false; } @@ -587,6 +606,7 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w return (pointer_state.floating.drag || pointer_state.floating.resize); } else { pointer_state.tiling.resize = pointer_state.r_held; + pointer_state.tiling.init_view = pointer; } return (pointer && pointer != focused); } else { @@ -599,6 +619,7 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w pointer_state.r_held = false; pointer_state.floating.resize = false; pointer_state.tiling.resize = false; + pointer_state.tiling.init_view = NULL; pointer_state.lock = (struct pointer_lock){false ,false ,false ,false}; } } diff --git a/sway/log.c b/sway/log.c index eda0c88ee..21aa9b8e3 100644 --- a/sway/log.c +++ b/sway/log.c @@ -149,6 +149,7 @@ static void container_log(const swayc_t *c) { fprintf(stderr, "children:%d\n",c->children?c->children->length:0); } void layout_log(const swayc_t *c, int depth) { + if (L_DEBUG > v) return; int i, d; int e = c->children ? c->children->length : 0; container_log(c);