aboutsummaryrefslogtreecommitdiff
path: root/sway/commands
diff options
context:
space:
mode:
Diffstat (limited to 'sway/commands')
-rw-r--r--sway/commands/exec_always.c1
-rw-r--r--sway/commands/floating.c1
-rw-r--r--sway/commands/focus.c2
-rw-r--r--sway/commands/fullscreen.c1
-rw-r--r--sway/commands/hide_edge_borders.c1
-rw-r--r--sway/commands/move.c49
-rw-r--r--sway/commands/output.c1
-rw-r--r--sway/commands/resize.c21
-rw-r--r--sway/commands/show_marks.c1
-rw-r--r--sway/commands/sticky.c1
-rw-r--r--sway/commands/swap.c128
-rw-r--r--sway/commands/unmark.c1
-rw-r--r--sway/commands/urgent.c1
13 files changed, 193 insertions, 16 deletions
diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c
index 5ce7919b..bc07c2aa 100644
--- a/sway/commands/exec_always.c
+++ b/sway/commands/exec_always.c
@@ -8,6 +8,7 @@
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/tree/container.h"
+#include "sway/tree/root.h"
#include "sway/tree/workspace.h"
#include "log.h"
#include "stringop.h"
diff --git a/sway/commands/floating.c b/sway/commands/floating.c
index beafd9fb..436376e3 100644
--- a/sway/commands/floating.c
+++ b/sway/commands/floating.c
@@ -6,7 +6,6 @@
#include "sway/output.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
-#include "sway/tree/layout.h"
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
#include "list.h"
diff --git a/sway/commands/focus.c b/sway/commands/focus.c
index a9fa9a0f..f342e524 100644
--- a/sway/commands/focus.c
+++ b/sway/commands/focus.c
@@ -6,9 +6,11 @@
#include "sway/input/seat.h"
#include "sway/output.h"
#include "sway/tree/arrange.h"
+#include "sway/tree/root.h"
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
#include "stringop.h"
+#include "util.h"
static bool parse_movement_direction(const char *name,
enum movement_direction *out) {
diff --git a/sway/commands/fullscreen.c b/sway/commands/fullscreen.c
index a0661200..ac65dffb 100644
--- a/sway/commands/fullscreen.c
+++ b/sway/commands/fullscreen.c
@@ -5,7 +5,6 @@
#include "sway/tree/container.h"
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
-#include "sway/tree/layout.h"
#include "util.h"
struct cmd_results *cmd_fullscreen(int argc, char **argv) {
diff --git a/sway/commands/hide_edge_borders.c b/sway/commands/hide_edge_borders.c
index d59c9fdb..e494f6aa 100644
--- a/sway/commands/hide_edge_borders.c
+++ b/sway/commands/hide_edge_borders.c
@@ -1,6 +1,7 @@
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/tree/container.h"
+#include "sway/tree/root.h"
#include "sway/tree/view.h"
static void _configure_view(struct sway_container *con, void *data) {
diff --git a/sway/commands/move.c b/sway/commands/move.c
index a4eedf7f..d0f6b9ea 100644
--- a/sway/commands/move.c
+++ b/sway/commands/move.c
@@ -19,6 +19,7 @@
#include "stringop.h"
#include "list.h"
#include "log.h"
+#include "util.h"
static const char *expected_syntax =
"Expected 'move <left|right|up|down> <[px] px>' or "
@@ -26,7 +27,20 @@ static const char *expected_syntax =
"'move <container|window|workspace> [to] output <name|direction>' or "
"'move <container|window> [to] mark <mark>'";
-static struct sway_container *output_in_direction(const char *direction,
+enum wlr_direction opposite_direction(enum wlr_direction d) {
+ switch (d) {
+ case WLR_DIRECTION_UP:
+ return WLR_DIRECTION_DOWN;
+ case WLR_DIRECTION_DOWN:
+ return WLR_DIRECTION_UP;
+ case WLR_DIRECTION_RIGHT:
+ return WLR_DIRECTION_LEFT;
+ default:
+ return WLR_DIRECTION_RIGHT;
+ }
+}
+
+static struct sway_container *output_in_direction(const char *direction_string,
struct wlr_output *reference, int ref_lx, int ref_ly) {
struct {
char *name;
@@ -37,19 +51,34 @@ static struct sway_container *output_in_direction(const char *direction,
{ "left", WLR_DIRECTION_LEFT },
{ "right", WLR_DIRECTION_RIGHT },
};
+
+ enum wlr_direction direction;
+
for (size_t i = 0; i < sizeof(names) / sizeof(names[0]); ++i) {
- if (strcasecmp(names[i].name, direction) == 0) {
- struct wlr_output *adjacent = wlr_output_layout_adjacent_output(
- root_container.sway_root->output_layout,
- names[i].direction, reference, ref_lx, ref_ly);
- if (adjacent) {
- struct sway_output *sway_output = adjacent->data;
- return sway_output->swayc;
- }
+ if (strcasecmp(names[i].name, direction_string) == 0) {
+ direction = names[i].direction;
break;
}
}
- return output_by_name(direction);
+
+ if (direction) {
+ struct wlr_output *target = wlr_output_layout_adjacent_output(
+ root_container.sway_root->output_layout,
+ direction, reference, ref_lx, ref_ly);
+
+ if (!target) {
+ target = wlr_output_layout_farthest_output(
+ root_container.sway_root->output_layout,
+ opposite_direction(direction), reference, ref_lx, ref_ly);
+ }
+
+ if (target) {
+ struct sway_output *sway_output = target->data;
+ return sway_output->swayc;
+ }
+ }
+
+ return output_by_name(direction_string);
}
static void container_move_to(struct sway_container *container,
diff --git a/sway/commands/output.c b/sway/commands/output.c
index ef1b7a69..00910843 100644
--- a/sway/commands/output.c
+++ b/sway/commands/output.c
@@ -1,7 +1,6 @@
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/output.h"
-#include "sway/tree/layout.h"
#include "list.h"
#include "log.h"
diff --git a/sway/commands/resize.c b/sway/commands/resize.c
index ea1e36ff..ad659ef5 100644
--- a/sway/commands/resize.c
+++ b/sway/commands/resize.c
@@ -159,6 +159,27 @@ static int parallel_size(struct sway_container *c, enum resize_axis a) {
return normalize_axis(a) == RESIZE_AXIS_HORIZONTAL ? c->width : c->height;
}
+static void container_recursive_resize(struct sway_container *container,
+ double amount, enum wlr_edges edge) {
+ bool layout_match = true;
+ wlr_log(WLR_DEBUG, "Resizing %p with amount: %f", container, amount);
+ if (edge == WLR_EDGE_LEFT || edge == WLR_EDGE_RIGHT) {
+ container->width += amount;
+ layout_match = container->layout == L_HORIZ;
+ } else if (edge == WLR_EDGE_TOP || edge == WLR_EDGE_BOTTOM) {
+ container->height += amount;
+ layout_match = container->layout == L_VERT;
+ }
+ if (container->children) {
+ for (int i = 0; i < container->children->length; i++) {
+ struct sway_container *child = container->children->items[i];
+ double amt = layout_match ?
+ amount / container->children->length : amount;
+ container_recursive_resize(child, amt, edge);
+ }
+ }
+}
+
static void resize_tiled(struct sway_container *parent, int amount,
enum resize_axis axis) {
struct sway_container *focused = parent;
diff --git a/sway/commands/show_marks.c b/sway/commands/show_marks.c
index dd7d170c..1844e917 100644
--- a/sway/commands/show_marks.c
+++ b/sway/commands/show_marks.c
@@ -2,6 +2,7 @@
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"
+#include "sway/tree/root.h"
#include "sway/tree/view.h"
#include "sway/output.h"
#include "list.h"
diff --git a/sway/commands/sticky.c b/sway/commands/sticky.c
index 72ef4282..8692e08d 100644
--- a/sway/commands/sticky.c
+++ b/sway/commands/sticky.c
@@ -6,7 +6,6 @@
#include "sway/output.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
-#include "sway/tree/layout.h"
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
#include "list.h"
diff --git a/sway/commands/swap.c b/sway/commands/swap.c
index f881a002..f25c43a1 100644
--- a/sway/commands/swap.c
+++ b/sway/commands/swap.c
@@ -1,15 +1,141 @@
+#define _POSIX_C_SOURCE 200809L
#include <strings.h>
#include <wlr/util/log.h>
#include "config.h"
+#include "log.h"
#include "sway/commands.h"
#include "sway/tree/arrange.h"
-#include "sway/tree/layout.h"
+#include "sway/tree/root.h"
#include "sway/tree/view.h"
+#include "sway/tree/workspace.h"
#include "stringop.h"
static const char* EXPECTED_SYNTAX =
"Expected 'swap container with id|con_id|mark <arg>'";
+static void swap_places(struct sway_container *con1,
+ struct sway_container *con2) {
+ struct sway_container *temp = malloc(sizeof(struct sway_container));
+ temp->x = con1->x;
+ temp->y = con1->y;
+ temp->width = con1->width;
+ temp->height = con1->height;
+ temp->parent = con1->parent;
+
+ con1->x = con2->x;
+ con1->y = con2->y;
+ con1->width = con2->width;
+ con1->height = con2->height;
+
+ con2->x = temp->x;
+ con2->y = temp->y;
+ con2->width = temp->width;
+ con2->height = temp->height;
+
+ int temp_index = container_sibling_index(con1);
+ container_insert_child(con2->parent, con1, container_sibling_index(con2));
+ container_insert_child(temp->parent, con2, temp_index);
+
+ free(temp);
+}
+
+static void swap_focus(struct sway_container *con1,
+ struct sway_container *con2, struct sway_seat *seat,
+ struct sway_container *focus) {
+ if (focus == con1 || focus == con2) {
+ struct sway_container *ws1 = container_parent(con1, C_WORKSPACE);
+ struct sway_container *ws2 = container_parent(con2, C_WORKSPACE);
+ if (focus == con1 && (con2->parent->layout == L_TABBED
+ || con2->parent->layout == L_STACKED)) {
+ if (workspace_is_visible(ws2)) {
+ seat_set_focus_warp(seat, con2, false, true);
+ }
+ seat_set_focus(seat, ws1 != ws2 ? con2 : con1);
+ } else if (focus == con2 && (con1->parent->layout == L_TABBED
+ || con1->parent->layout == L_STACKED)) {
+ if (workspace_is_visible(ws1)) {
+ seat_set_focus_warp(seat, con1, false, true);
+ }
+ seat_set_focus(seat, ws1 != ws2 ? con1 : con2);
+ } else if (ws1 != ws2) {
+ seat_set_focus(seat, focus == con1 ? con2 : con1);
+ } else {
+ seat_set_focus(seat, focus);
+ }
+ } else {
+ seat_set_focus(seat, focus);
+ }
+}
+
+static void container_swap(struct sway_container *con1,
+ struct sway_container *con2) {
+ if (!sway_assert(con1 && con2, "Cannot swap with nothing")) {
+ return;
+ }
+ if (!sway_assert(con1->type >= C_CONTAINER && con2->type >= C_CONTAINER,
+ "Can only swap containers and views")) {
+ return;
+ }
+ if (!sway_assert(!container_has_ancestor(con1, con2)
+ && !container_has_ancestor(con2, con1),
+ "Cannot swap ancestor and descendant")) {
+ return;
+ }
+ if (!sway_assert(!container_is_floating(con1)
+ && !container_is_floating(con2),
+ "Swapping with floating containers is not supported")) {
+ return;
+ }
+
+ wlr_log(WLR_DEBUG, "Swapping containers %zu and %zu", con1->id, con2->id);
+
+ int fs1 = con1->is_fullscreen;
+ int fs2 = con2->is_fullscreen;
+ if (fs1) {
+ container_set_fullscreen(con1, false);
+ }
+ if (fs2) {
+ container_set_fullscreen(con2, false);
+ }
+
+ struct sway_seat *seat = input_manager_get_default_seat(input_manager);
+ struct sway_container *focus = seat_get_focus(seat);
+ struct sway_container *vis1 = container_parent(
+ seat_get_focus_inactive(seat, container_parent(con1, C_OUTPUT)),
+ C_WORKSPACE);
+ struct sway_container *vis2 = container_parent(
+ seat_get_focus_inactive(seat, container_parent(con2, C_OUTPUT)),
+ C_WORKSPACE);
+
+ char *stored_prev_name = NULL;
+ if (prev_workspace_name) {
+ stored_prev_name = strdup(prev_workspace_name);
+ }
+
+ swap_places(con1, con2);
+
+ if (!workspace_is_visible(vis1)) {
+ seat_set_focus(seat, seat_get_focus_inactive(seat, vis1));
+ }
+ if (!workspace_is_visible(vis2)) {
+ seat_set_focus(seat, seat_get_focus_inactive(seat, vis2));
+ }
+
+ swap_focus(con1, con2, seat, focus);
+
+ if (stored_prev_name) {
+ free(prev_workspace_name);
+ prev_workspace_name = stored_prev_name;
+ }
+
+ if (fs1) {
+ container_set_fullscreen(con2, true);
+ }
+ if (fs2) {
+ container_set_fullscreen(con1, true);
+ }
+}
+
static bool test_con_id(struct sway_container *container, void *con_id) {
return container->id == (size_t)con_id;
}
diff --git a/sway/commands/unmark.c b/sway/commands/unmark.c
index c183785b..62127c97 100644
--- a/sway/commands/unmark.c
+++ b/sway/commands/unmark.c
@@ -2,6 +2,7 @@
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"
+#include "sway/tree/root.h"
#include "sway/tree/view.h"
#include "list.h"
#include "log.h"
diff --git a/sway/commands/urgent.c b/sway/commands/urgent.c
index 51c497c4..bccb33fe 100644
--- a/sway/commands/urgent.c
+++ b/sway/commands/urgent.c
@@ -4,7 +4,6 @@
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
#include "sway/tree/view.h"
-#include "sway/tree/layout.h"
#include "util.h"
struct cmd_results *cmd_urgent(int argc, char **argv) {