aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/util.c21
-rw-r--r--include/sway/config.h2
-rw-r--r--include/sway/tree/container.h28
-rw-r--r--include/sway/tree/layout.h52
-rw-r--r--include/util.h14
-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.c1
-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
-rw-r--r--sway/config.c2
-rw-r--r--sway/config/output.c1
-rw-r--r--sway/criteria.c1
-rw-r--r--sway/debug-tree.c2
-rw-r--r--sway/desktop/layer_shell.c1
-rw-r--r--sway/desktop/output.c2
-rw-r--r--sway/desktop/render.c2
-rw-r--r--sway/desktop/xdg_shell.c1
-rw-r--r--sway/desktop/xdg_shell_v6.c1
-rw-r--r--sway/desktop/xwayland.c1
-rw-r--r--sway/input/cursor.c1
-rw-r--r--sway/input/seat.c3
-rw-r--r--sway/ipc-server.c1
-rw-r--r--sway/main.c2
-rw-r--r--sway/meson.build1
-rw-r--r--sway/server.c2
-rw-r--r--sway/tree/arrange.c1
-rw-r--r--sway/tree/container.c221
-rw-r--r--sway/tree/layout.c403
-rw-r--r--sway/tree/view.c1
38 files changed, 449 insertions, 479 deletions
diff --git a/common/util.c b/common/util.c
index 467aa4b5..561b3804 100644
--- a/common/util.c
+++ b/common/util.c
@@ -175,3 +175,24 @@ failed:
free(current);
return NULL;
}
+
+bool sway_dir_to_wlr(enum movement_direction dir, enum wlr_direction *out) {
+ switch (dir) {
+ case MOVE_UP:
+ *out = WLR_DIRECTION_UP;
+ break;
+ case MOVE_DOWN:
+ *out = WLR_DIRECTION_DOWN;
+ break;
+ case MOVE_LEFT:
+ *out = WLR_DIRECTION_LEFT;
+ break;
+ case MOVE_RIGHT:
+ *out = WLR_DIRECTION_RIGHT;
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
diff --git a/include/sway/config.h b/include/sway/config.h
index c2eaea1b..18d10faa 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -8,8 +8,8 @@
#include <xkbcommon/xkbcommon.h>
#include "list.h"
#include "swaynag.h"
-#include "tree/layout.h"
#include "tree/container.h"
+#include "sway/tree/root.h"
#include "wlr-layer-shell-unstable-v1-protocol.h"
// TODO: Refactor this shit
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index 2b6e6e0c..e4071cfe 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -53,6 +53,9 @@ struct sway_output;
struct sway_workspace;
struct sway_view;
+enum movement_direction;
+enum wlr_direction;
+
struct sway_container_state {
// Container/swayc properties
enum sway_container_layout layout;
@@ -341,4 +344,29 @@ void container_add_gaps(struct sway_container *container);
int container_sibling_index(const struct sway_container *child);
+void container_handle_fullscreen_reparent(struct sway_container *con,
+ struct sway_container *old_parent);
+
+void container_add_child(struct sway_container *parent,
+ struct sway_container *child);
+
+void container_insert_child(struct sway_container *parent,
+ struct sway_container *child, int i);
+
+struct sway_container *container_add_sibling(struct sway_container *parent,
+ struct sway_container *child);
+
+struct sway_container *container_remove_child(struct sway_container *child);
+
+struct sway_container *container_replace_child(struct sway_container *child,
+ struct sway_container *new_child);
+
+bool sway_dir_to_wlr(enum movement_direction dir, enum wlr_direction *out);
+
+enum sway_container_layout container_get_default_layout(
+ struct sway_container *con);
+
+struct sway_container *container_split(struct sway_container *child,
+ enum sway_container_layout layout);
+
#endif
diff --git a/include/sway/tree/layout.h b/include/sway/tree/layout.h
deleted file mode 100644
index 5c834ad2..00000000
--- a/include/sway/tree/layout.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef _SWAY_LAYOUT_H
-#define _SWAY_LAYOUT_H
-#include <wlr/types/wlr_output_layout.h>
-#include <wlr/render/wlr_texture.h>
-#include "sway/tree/container.h"
-#include "sway/tree/root.h"
-#include "config.h"
-
-enum movement_direction {
- MOVE_LEFT,
- MOVE_RIGHT,
- MOVE_UP,
- MOVE_DOWN,
- MOVE_PARENT,
- MOVE_CHILD,
-};
-
-enum wlr_edges;
-
-struct sway_container;
-
-void container_handle_fullscreen_reparent(struct sway_container *con,
- struct sway_container *old_parent);
-
-void container_add_child(struct sway_container *parent,
- struct sway_container *child);
-
-void container_insert_child(struct sway_container *parent,
- struct sway_container *child, int i);
-
-struct sway_container *container_add_sibling(struct sway_container *parent,
- struct sway_container *child);
-
-struct sway_container *container_remove_child(struct sway_container *child);
-
-struct sway_container *container_replace_child(struct sway_container *child,
- struct sway_container *new_child);
-
-bool sway_dir_to_wlr(enum movement_direction dir, enum wlr_direction *out);
-
-enum sway_container_layout container_get_default_layout(
- struct sway_container *con);
-
-struct sway_container *container_split(struct sway_container *child,
- enum sway_container_layout layout);
-
-void container_recursive_resize(struct sway_container *container,
- double amount, enum wlr_edges edge);
-
-void container_swap(struct sway_container *con1, struct sway_container *con2);
-
-#endif
diff --git a/include/util.h b/include/util.h
index 9277fa6e..46ed1533 100644
--- a/include/util.h
+++ b/include/util.h
@@ -4,9 +4,19 @@
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
-#include <sys/types.h>
+#include <sys/types.h>
+#include <wlr/types/wlr_output_layout.h>
#include <xkbcommon/xkbcommon.h>
+enum movement_direction {
+ MOVE_LEFT,
+ MOVE_RIGHT,
+ MOVE_UP,
+ MOVE_DOWN,
+ MOVE_PARENT,
+ MOVE_CHILD,
+};
+
/**
* Wrap i into the range [0, max[
*/
@@ -71,4 +81,6 @@ char* resolve_path(const char* path);
char *b64_encode(const char* binaryData, size_t len, size_t *flen);
unsigned char *b64_decode(const char *ascii, size_t len, size_t *flen);
+bool sway_dir_to_wlr(enum movement_direction dir, enum wlr_direction *out);
+
#endif
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 2744b354..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 "
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) {
diff --git a/sway/config.c b/sway/config.c
index 642abbac..8105722a 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -27,7 +27,7 @@
#include "sway/criteria.h"
#include "sway/swaynag.h"
#include "sway/tree/arrange.h"
-#include "sway/tree/layout.h"
+#include "sway/tree/root.h"
#include "sway/tree/workspace.h"
#include "cairo.h"
#include "pango.h"
diff --git a/sway/config/output.c b/sway/config/output.c
index 7f9b1007..199267bf 100644
--- a/sway/config/output.c
+++ b/sway/config/output.c
@@ -9,6 +9,7 @@
#include <wlr/types/wlr_output_layout.h>
#include "sway/config.h"
#include "sway/output.h"
+#include "sway/tree/root.h"
#include "log.h"
int output_name_cmp(const void *item, const void *data) {
diff --git a/sway/criteria.c b/sway/criteria.c
index 81c2325a..5452c4ee 100644
--- a/sway/criteria.c
+++ b/sway/criteria.c
@@ -6,6 +6,7 @@
#include "sway/criteria.h"
#include "sway/tree/container.h"
#include "sway/config.h"
+#include "sway/tree/root.h"
#include "sway/tree/view.h"
#include "stringop.h"
#include "list.h"
diff --git a/sway/debug-tree.c b/sway/debug-tree.c
index ea0826b9..2768cf58 100644
--- a/sway/debug-tree.c
+++ b/sway/debug-tree.c
@@ -9,7 +9,7 @@
#include "sway/output.h"
#include "sway/server.h"
#include "sway/tree/container.h"
-#include "sway/tree/layout.h"
+#include "sway/tree/root.h"
#include "cairo.h"
#include "config.h"
#include "pango.h"
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c
index a2935883..1fae5db2 100644
--- a/sway/desktop/layer_shell.c
+++ b/sway/desktop/layer_shell.c
@@ -14,7 +14,6 @@
#include "sway/output.h"
#include "sway/server.h"
#include "sway/tree/arrange.h"
-#include "sway/tree/layout.h"
#include "log.h"
static void apply_exclusive(struct wlr_box *usable_area,
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 401d3c44..35fce1a6 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -23,7 +23,7 @@
#include "sway/server.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
-#include "sway/tree/layout.h"
+#include "sway/tree/root.h"
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index 5cf8abc0..b5a10370 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -24,7 +24,7 @@
#include "sway/server.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
-#include "sway/tree/layout.h"
+#include "sway/tree/root.h"
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c
index f5aaa575..7d1824f1 100644
--- a/sway/desktop/xdg_shell.c
+++ b/sway/desktop/xdg_shell.c
@@ -13,7 +13,6 @@
#include "sway/server.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
-#include "sway/tree/layout.h"
#include "sway/tree/view.h"
static const struct sway_view_child_impl popup_impl;
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c
index f623b77b..522fddca 100644
--- a/sway/desktop/xdg_shell_v6.c
+++ b/sway/desktop/xdg_shell_v6.c
@@ -12,7 +12,6 @@
#include "sway/server.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
-#include "sway/tree/layout.h"
#include "sway/tree/view.h"
static const struct sway_view_child_impl popup_impl;
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 6fcc850d..4e401008 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -14,7 +14,6 @@
#include "sway/server.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
-#include "sway/tree/layout.h"
#include "sway/tree/view.h"
static const char *atom_map[ATOM_LAST] = {
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index ba5e0400..00240e84 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -20,6 +20,7 @@
#include "sway/layers.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 "wlr-layer-shell-unstable-v1-protocol.h"
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 997d7815..269823ee 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -25,10 +25,9 @@
#include "sway/output.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
-#include "sway/tree/container.h"
+#include "sway/tree/root.h"
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
-#include "sway/tree/workspace.h"
static void seat_device_destroy(struct sway_seat_device *seat_device) {
if (!seat_device) {
diff --git a/sway/ipc-server.c b/sway/ipc-server.c
index 34e940ad..1ac0521e 100644
--- a/sway/ipc-server.c
+++ b/sway/ipc-server.c
@@ -31,6 +31,7 @@
#include "sway/server.h"
#include "sway/input/input-manager.h"
#include "sway/input/seat.h"
+#include "sway/tree/root.h"
#include "sway/tree/view.h"
#include "list.h"
#include "log.h"
diff --git a/sway/main.c b/sway/main.c
index 3ba4ba75..7ed10c86 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -23,7 +23,7 @@
#include "sway/desktop/transaction.h"
#include "sway/server.h"
#include "sway/swaynag.h"
-#include "sway/tree/layout.h"
+#include "sway/tree/root.h"
#include "sway/ipc-server.h"
#include "ipc-client.h"
#include "readline.h"
diff --git a/sway/meson.build b/sway/meson.build
index 676422d0..bcb44e8b 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -150,7 +150,6 @@ sway_sources = files(
'tree/arrange.c',
'tree/container.c',
- 'tree/layout.c',
'tree/root.c',
'tree/view.c',
'tree/workspace.c',
diff --git a/sway/server.c b/sway/server.c
index 00acaa01..7fa6007e 100644
--- a/sway/server.c
+++ b/sway/server.c
@@ -24,7 +24,7 @@
#include "sway/desktop/idle_inhibit_v1.h"
#include "sway/input/input-manager.h"
#include "sway/server.h"
-#include "sway/tree/layout.h"
+#include "sway/tree/root.h"
#include "config.h"
#ifdef HAVE_XWAYLAND
#include "sway/xwayland.h"
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c
index 0da61a4c..60e5b951 100644
--- a/sway/tree/arrange.c
+++ b/sway/tree/arrange.c
@@ -7,7 +7,6 @@
#include <wlr/types/wlr_output_layout.h>
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
-#include "sway/tree/layout.h"
#include "sway/output.h"
#include "sway/tree/workspace.h"
#include "sway/tree/view.h"
diff --git a/sway/tree/container.c b/sway/tree/container.c
index f9611342..f13e2e96 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -19,7 +19,6 @@
#include "sway/output.h"
#include "sway/server.h"
#include "sway/tree/arrange.h"
-#include "sway/tree/layout.h"
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
#include "log.h"
@@ -1159,3 +1158,223 @@ void container_add_gaps(struct sway_container *c) {
int container_sibling_index(const struct sway_container *child) {
return list_find(child->parent->children, child);
}
+
+void container_handle_fullscreen_reparent(struct sway_container *con,
+ struct sway_container *old_parent) {
+ if (!con->is_fullscreen) {
+ return;
+ }
+ struct sway_container *old_workspace = old_parent;
+ if (old_workspace && old_workspace->type != C_WORKSPACE) {
+ old_workspace = container_parent(old_workspace, C_WORKSPACE);
+ }
+ struct sway_container *new_workspace = container_parent(con, C_WORKSPACE);
+ if (old_workspace == new_workspace) {
+ return;
+ }
+ // Unmark the old workspace as fullscreen
+ if (old_workspace) {
+ old_workspace->sway_workspace->fullscreen = NULL;
+ }
+
+ // Mark the new workspace as fullscreen
+ if (new_workspace->sway_workspace->fullscreen) {
+ container_set_fullscreen(
+ new_workspace->sway_workspace->fullscreen, false);
+ }
+ new_workspace->sway_workspace->fullscreen = con;
+
+ // Resize container to new output dimensions
+ struct sway_container *output = new_workspace->parent;
+ con->x = output->x;
+ con->y = output->y;
+ con->width = output->width;
+ con->height = output->height;
+
+ if (con->type == C_VIEW) {
+ struct sway_view *view = con->sway_view;
+ view->x = output->x;
+ view->y = output->y;
+ view->width = output->width;
+ view->height = output->height;
+ } else {
+ arrange_windows(new_workspace);
+ }
+}
+
+void container_insert_child(struct sway_container *parent,
+ struct sway_container *child, int i) {
+ struct sway_container *old_parent = child->parent;
+ if (old_parent) {
+ container_remove_child(child);
+ }
+ wlr_log(WLR_DEBUG, "Inserting id:%zd at index %d", child->id, i);
+ list_insert(parent->children, i, child);
+ child->parent = parent;
+ container_handle_fullscreen_reparent(child, old_parent);
+}
+
+struct sway_container *container_add_sibling(struct sway_container *fixed,
+ struct sway_container *active) {
+ // TODO handle floating
+ struct sway_container *old_parent = NULL;
+ if (active->parent) {
+ old_parent = active->parent;
+ container_remove_child(active);
+ }
+ struct sway_container *parent = fixed->parent;
+ int i = container_sibling_index(fixed);
+ list_insert(parent->children, i + 1, active);
+ active->parent = parent;
+ container_handle_fullscreen_reparent(active, old_parent);
+ return active->parent;
+}
+
+void container_add_child(struct sway_container *parent,
+ struct sway_container *child) {
+ wlr_log(WLR_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);
+ struct sway_container *old_parent = child->parent;
+ list_add(parent->children, child);
+ child->parent = parent;
+ container_handle_fullscreen_reparent(child, old_parent);
+ if (old_parent) {
+ container_set_dirty(old_parent);
+ }
+ container_set_dirty(child);
+}
+
+struct sway_container *container_remove_child(struct sway_container *child) {
+ if (child->is_fullscreen) {
+ struct sway_container *workspace = container_parent(child, C_WORKSPACE);
+ workspace->sway_workspace->fullscreen = NULL;
+ }
+
+ struct sway_container *parent = child->parent;
+ list_t *list = container_is_floating(child) ?
+ parent->sway_workspace->floating : parent->children;
+ int index = list_find(list, child);
+ if (index != -1) {
+ list_del(list, index);
+ }
+ child->parent = NULL;
+ container_notify_subtree_changed(parent);
+
+ container_set_dirty(parent);
+ container_set_dirty(child);
+
+ return parent;
+}
+
+enum sway_container_layout container_get_default_layout(
+ struct sway_container *con) {
+ if (con->type != C_OUTPUT) {
+ con = container_parent(con, C_OUTPUT);
+ }
+
+ if (!sway_assert(con != NULL,
+ "container_get_default_layout must be called on an attached"
+ " container below the root container")) {
+ return 0;
+ }
+
+ if (config->default_layout != L_NONE) {
+ return config->default_layout;
+ } else if (config->default_orientation != L_NONE) {
+ return config->default_orientation;
+ } else if (con->width >= con->height) {
+ return L_HORIZ;
+ } else {
+ return L_VERT;
+ }
+}
+
+struct sway_container *container_replace_child(struct sway_container *child,
+ struct sway_container *new_child) {
+ struct sway_container *parent = child->parent;
+ if (parent == NULL) {
+ return NULL;
+ }
+
+ list_t *list = container_is_floating(child) ?
+ parent->sway_workspace->floating : parent->children;
+ int i = list_find(list, child);
+
+ if (new_child->parent) {
+ container_remove_child(new_child);
+ }
+ list->items[i] = new_child;
+ new_child->parent = parent;
+ child->parent = NULL;
+
+ // Set geometry for new child
+ new_child->x = child->x;
+ new_child->y = child->y;
+ new_child->width = child->width;
+ new_child->height = child->height;
+
+ // reset geometry for child
+ child->width = 0;
+ child->height = 0;
+
+ return parent;
+}
+
+struct sway_container *container_split(struct sway_container *child,
+ enum sway_container_layout layout) {
+ // TODO floating: cannot split a floating container
+ if (!sway_assert(child, "child cannot be null")) {
+ return NULL;
+ }
+ if (child->type == C_WORKSPACE && child->children->length == 0) {
+ // Special case: this just behaves like splitt
+ child->prev_split_layout = child->layout;
+ child->layout = layout;
+ return child;
+ }
+
+ struct sway_container *cont = container_create(C_CONTAINER);
+
+ wlr_log(WLR_DEBUG, "creating container %p around %p", cont, child);
+
+ child->type == C_WORKSPACE ? workspace_remove_gaps(child)
+ : container_remove_gaps(child);
+
+ cont->prev_split_layout = L_NONE;
+ cont->width = child->width;
+ cont->height = child->height;
+ cont->x = child->x;
+ cont->y = child->y;
+
+ struct sway_seat *seat = input_manager_get_default_seat(input_manager);
+ bool set_focus = (seat_get_focus(seat) == child);
+
+ container_add_gaps(cont);
+
+ if (child->type == C_WORKSPACE) {
+ struct sway_container *workspace = child;
+ while (workspace->children->length) {
+ struct sway_container *ws_child = workspace->children->items[0];
+ container_remove_child(ws_child);
+ container_add_child(cont, ws_child);
+ }
+
+ container_add_child(workspace, cont);
+ enum sway_container_layout old_layout = workspace->layout;
+ workspace->layout = layout;
+ cont->layout = old_layout;
+ } else {
+ cont->layout = layout;
+ container_replace_child(child, cont);
+ container_add_child(cont, child);
+ }
+
+ if (set_focus) {
+ seat_set_focus(seat, cont);
+ seat_set_focus(seat, child);
+ }
+
+ container_notify_subtree_changed(cont);
+ return cont;
+}
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
deleted file mode 100644
index 85fe7643..00000000
--- a/sway/tree/layout.c
+++ /dev/null
@@ -1,403 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-#include <math.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include <wlr/types/wlr_output.h>
-#include <wlr/types/wlr_output_layout.h>
-#include "config.h"
-#include "sway/debug.h"
-#include "sway/tree/arrange.h"
-#include "sway/tree/container.h"
-#include "sway/tree/layout.h"
-#include "sway/output.h"
-#include "sway/tree/workspace.h"
-#include "sway/tree/view.h"
-#include "sway/input/seat.h"
-#include "sway/ipc-server.h"
-#include "list.h"
-#include "log.h"
-
-void container_handle_fullscreen_reparent(struct sway_container *con,
- struct sway_container *old_parent) {
- if (!con->is_fullscreen) {
- return;
- }
- struct sway_container *old_workspace = old_parent;
- if (old_workspace && old_workspace->type != C_WORKSPACE) {
- old_workspace = container_parent(old_workspace, C_WORKSPACE);
- }
- struct sway_container *new_workspace = container_parent(con, C_WORKSPACE);
- if (old_workspace == new_workspace) {
- return;
- }
- // Unmark the old workspace as fullscreen
- if (old_workspace) {
- old_workspace->sway_workspace->fullscreen = NULL;
- }
-
- // Mark the new workspace as fullscreen
- if (new_workspace->sway_workspace->fullscreen) {
- container_set_fullscreen(
- new_workspace->sway_workspace->fullscreen, false);
- }
- new_workspace->sway_workspace->fullscreen = con;
-
- // Resize container to new output dimensions
- struct sway_container *output = new_workspace->parent;
- con->x = output->x;
- con->y = output->y;
- con->width = output->width;
- con->height = output->height;
-
- if (con->type == C_VIEW) {
- struct sway_view *view = con->sway_view;
- view->x = output->x;
- view->y = output->y;
- view->width = output->width;
- view->height = output->height;
- } else {
- arrange_windows(new_workspace);
- }
-}
-
-void container_insert_child(struct sway_container *parent,
- struct sway_container *child, int i) {
- struct sway_container *old_parent = child->parent;
- if (old_parent) {
- container_remove_child(child);
- }
- wlr_log(WLR_DEBUG, "Inserting id:%zd at index %d", child->id, i);
- list_insert(parent->children, i, child);
- child->parent = parent;
- container_handle_fullscreen_reparent(child, old_parent);
-}
-
-struct sway_container *container_add_sibling(struct sway_container *fixed,
- struct sway_container *active) {
- // TODO handle floating
- struct sway_container *old_parent = NULL;
- if (active->parent) {
- old_parent = active->parent;
- container_remove_child(active);
- }
- struct sway_container *parent = fixed->parent;
- int i = container_sibling_index(fixed);
- list_insert(parent->children, i + 1, active);
- active->parent = parent;
- container_handle_fullscreen_reparent(active, old_parent);
- return active->parent;
-}
-
-void container_add_child(struct sway_container *parent,
- struct sway_container *child) {
- wlr_log(WLR_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);
- struct sway_container *old_parent = child->parent;
- list_add(parent->children, child);
- child->parent = parent;
- container_handle_fullscreen_reparent(child, old_parent);
- if (old_parent) {
- container_set_dirty(old_parent);
- }
- container_set_dirty(child);
-}
-
-struct sway_container *container_remove_child(struct sway_container *child) {
- if (child->is_fullscreen) {
- struct sway_container *workspace = container_parent(child, C_WORKSPACE);
- workspace->sway_workspace->fullscreen = NULL;
- }
-
- struct sway_container *parent = child->parent;
- list_t *list = container_is_floating(child) ?
- parent->sway_workspace->floating : parent->children;
- int index = list_find(list, child);
- if (index != -1) {
- list_del(list, index);
- }
- child->parent = NULL;
- container_notify_subtree_changed(parent);
-
- container_set_dirty(parent);
- container_set_dirty(child);
-
- return parent;
-}
-
-bool sway_dir_to_wlr(enum movement_direction dir, enum wlr_direction *out) {
- switch (dir) {
- case MOVE_UP:
- *out = WLR_DIRECTION_UP;
- break;
- case MOVE_DOWN:
- *out = WLR_DIRECTION_DOWN;
- break;
- case MOVE_LEFT:
- *out = WLR_DIRECTION_LEFT;
- break;
- case MOVE_RIGHT:
- *out = WLR_DIRECTION_RIGHT;
- break;
- default:
- return false;
- }
-
- return true;
-}
-
-enum sway_container_layout container_get_default_layout(
- struct sway_container *con) {
- if (con->type != C_OUTPUT) {
- con = container_parent(con, C_OUTPUT);
- }
-
- if (!sway_assert(con != NULL,
- "container_get_default_layout must be called on an attached"
- " container below the root container")) {
- return 0;
- }
-
- if (config->default_layout != L_NONE) {
- return config->default_layout;
- } else if (config->default_orientation != L_NONE) {
- return config->default_orientation;
- } else if (con->width >= con->height) {
- return L_HORIZ;
- } else {
- return L_VERT;
- }
-}
-
-struct sway_container *container_replace_child(struct sway_container *child,
- struct sway_container *new_child) {
- struct sway_container *parent = child->parent;
- if (parent == NULL) {
- return NULL;
- }
-
- list_t *list = container_is_floating(child) ?
- parent->sway_workspace->floating : parent->children;
- int i = list_find(list, child);
-
- if (new_child->parent) {
- container_remove_child(new_child);
- }
- list->items[i] = new_child;
- new_child->parent = parent;
- child->parent = NULL;
-
- // Set geometry for new child
- new_child->x = child->x;
- new_child->y = child->y;
- new_child->width = child->width;
- new_child->height = child->height;
-
- // reset geometry for child
- child->width = 0;
- child->height = 0;
-
- return parent;
-}
-
-struct sway_container *container_split(struct sway_container *child,
- enum sway_container_layout layout) {
- // TODO floating: cannot split a floating container
- if (!sway_assert(child, "child cannot be null")) {
- return NULL;
- }
- if (child->type == C_WORKSPACE && child->children->length == 0) {
- // Special case: this just behaves like splitt
- child->prev_split_layout = child->layout;
- child->layout = layout;
- return child;
- }
-
- struct sway_container *cont = container_create(C_CONTAINER);
-
- wlr_log(WLR_DEBUG, "creating container %p around %p", cont, child);
-
- child->type == C_WORKSPACE ? workspace_remove_gaps(child)
- : container_remove_gaps(child);
-
- cont->prev_split_layout = L_NONE;
- cont->width = child->width;
- cont->height = child->height;
- cont->x = child->x;
- cont->y = child->y;
-
- struct sway_seat *seat = input_manager_get_default_seat(input_manager);
- bool set_focus = (seat_get_focus(seat) == child);
-
- container_add_gaps(cont);
-
- if (child->type == C_WORKSPACE) {
- struct sway_container *workspace = child;
- while (workspace->children->length) {
- struct sway_container *ws_child = workspace->children->items[0];
- container_remove_child(ws_child);
- container_add_child(cont, ws_child);
- }
-
- container_add_child(workspace, cont);
- enum sway_container_layout old_layout = workspace->layout;
- workspace->layout = layout;
- cont->layout = old_layout;
- } else {
- cont->layout = layout;
- container_replace_child(child, cont);
- container_add_child(cont, child);
- }
-
- if (set_focus) {
- seat_set_focus(seat, cont);
- seat_set_focus(seat, child);
- }
-
- container_notify_subtree_changed(cont);
- return cont;
-}
-
-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 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);
- }
-}
-
-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);
- }
-}
diff --git a/sway/tree/view.c b/sway/tree/view.c
index ba4a880f..2870d4f5 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -18,7 +18,6 @@
#include "sway/input/seat.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 "sway/config.h"