From 5dbbab7bdc56fc513eea2f9a39d722859a3b0c2e Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 26 Aug 2018 12:05:16 +1000 Subject: [PATCH] Remove layout.c When we have type safety we'll need to have functions for workspace_add_tiling and so on. This means the existing container functions will be just for containers, so they are being moved to container.c. At this point layout.c doesn't contain much else, so I've relocated everything and removed the file. * container_swap and its static functions have been moved to the swap command and made static. * container_recursive_resize has been moved to the resize command and made static. * The following have been moved to container.c: * container_handle_fullscreen_reparent * container_insert_child * container_add_sibling * container_add_child * container_remove_child * container_replace_child * container_split * enum movement_direction and sway_dir_to_wlr have been moved to util.c. Side note: Several commands included layout.h which then included root.h. With layout.h gone, root.h has to be included by those commands. --- common/util.c | 21 ++ include/sway/config.h | 2 +- include/sway/tree/container.h | 28 +++ include/sway/tree/layout.h | 52 ---- include/util.h | 14 +- sway/commands/exec_always.c | 1 + sway/commands/floating.c | 1 - sway/commands/focus.c | 2 + sway/commands/fullscreen.c | 1 - sway/commands/hide_edge_borders.c | 1 + sway/commands/move.c | 1 + sway/commands/output.c | 1 - sway/commands/resize.c | 21 ++ sway/commands/show_marks.c | 1 + sway/commands/sticky.c | 1 - sway/commands/swap.c | 128 +++++++++- sway/commands/unmark.c | 1 + sway/commands/urgent.c | 1 - sway/config.c | 2 +- sway/config/output.c | 1 + sway/criteria.c | 1 + sway/debug-tree.c | 2 +- sway/desktop/layer_shell.c | 1 - sway/desktop/output.c | 2 +- sway/desktop/render.c | 2 +- sway/desktop/xdg_shell.c | 1 - sway/desktop/xdg_shell_v6.c | 1 - sway/desktop/xwayland.c | 1 - sway/input/cursor.c | 1 + sway/input/seat.c | 3 +- sway/ipc-server.c | 1 + sway/main.c | 2 +- sway/meson.build | 1 - sway/server.c | 2 +- sway/tree/arrange.c | 1 - sway/tree/container.c | 221 +++++++++++++++- sway/tree/layout.c | 403 ------------------------------ sway/tree/view.c | 1 - 38 files changed, 449 insertions(+), 479 deletions(-) delete mode 100644 include/sway/tree/layout.h delete mode 100644 sway/tree/layout.c 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 #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 -#include -#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 #include #include -#include +#include +#include #include +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 <[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 #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 #include #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 '"; +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 #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 #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 #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 -#include -#include -#include -#include -#include -#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"