diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-08-03 23:06:01 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-08-04 14:01:20 +1000 |
commit | 04489ff4209dc073027419d90961367cfb998fe8 (patch) | |
tree | d6f6213d2374e10a875e8ced872511e6e656ae3e /sway/tree | |
parent | 5de2223c6df480759ee6d8f4422c2643491595d0 (diff) |
Separate root-related code
This creates a root.c and moves bits and pieces from elsewhere into it.
* layout_init has been renamed to root_create and moved into root.c
* root_destroy has been created and is called on shutdown
* scratchpad code has been moved into root.c, because hidden scratchpad
containers are stored in the root struct
Diffstat (limited to 'sway/tree')
-rw-r--r-- | sway/tree/arrange.c | 2 | ||||
-rw-r--r-- | sway/tree/container.c | 6 | ||||
-rw-r--r-- | sway/tree/layout.c | 34 | ||||
-rw-r--r-- | sway/tree/root.c | 147 |
4 files changed, 149 insertions, 40 deletions
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c index 5452b13c..494a8461 100644 --- a/sway/tree/arrange.c +++ b/sway/tree/arrange.c @@ -14,8 +14,6 @@ #include "list.h" #include "log.h" -struct sway_container root_container; - static void apply_horiz_layout(struct sway_container *parent) { size_t num_children = parent->children->length; if (!num_children) { diff --git a/sway/tree/container.c b/sway/tree/container.c index 4a503652..6da5ac3c 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -17,7 +17,6 @@ #include "sway/input/seat.h" #include "sway/ipc-server.h" #include "sway/output.h" -#include "sway/scratchpad.h" #include "sway/server.h" #include "sway/tree/arrange.h" #include "sway/tree/layout.h" @@ -336,7 +335,6 @@ static struct sway_container *container_destroy_noreaping( // Workspaces will refuse to be destroyed if they're the last workspace // on their output. if (!container_workspace_destroy(con)) { - wlr_log(WLR_ERROR, "workspace doesn't want to destroy"); return NULL; } } @@ -347,7 +345,7 @@ static struct sway_container *container_destroy_noreaping( container_set_dirty(con); if (con->scratchpad) { - scratchpad_remove_container(con); + root_scratchpad_remove_container(con); } if (!con->parent) { @@ -1097,7 +1095,7 @@ void container_set_floating(struct sway_container *container, bool enable) { } else { // Returning to tiled if (container->scratchpad) { - scratchpad_remove_container(container); + root_scratchpad_remove_container(container); } container_remove_child(container); struct sway_container *reference = diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 1f82e534..07de9664 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -19,40 +19,6 @@ #include "list.h" #include "log.h" -struct sway_container root_container; - -static void output_layout_handle_change(struct wl_listener *listener, - void *data) { - arrange_windows(&root_container); - transaction_commit_dirty(); -} - -void layout_init(void) { - root_container.id = 0; // normally assigned in new_swayc() - root_container.type = C_ROOT; - root_container.layout = L_NONE; - root_container.name = strdup("root"); - root_container.instructions = create_list(); - root_container.children = create_list(); - root_container.current.children = create_list(); - wl_signal_init(&root_container.events.destroy); - - root_container.sway_root = calloc(1, sizeof(*root_container.sway_root)); - root_container.sway_root->output_layout = wlr_output_layout_create(); - wl_list_init(&root_container.sway_root->outputs); -#ifdef HAVE_XWAYLAND - wl_list_init(&root_container.sway_root->xwayland_unmanaged); -#endif - wl_list_init(&root_container.sway_root->drag_icons); - wl_signal_init(&root_container.sway_root->events.new_container); - root_container.sway_root->scratchpad = create_list(); - - root_container.sway_root->output_layout_change.notify = - output_layout_handle_change; - wl_signal_add(&root_container.sway_root->output_layout->events.change, - &root_container.sway_root->output_layout_change); -} - static int index_child(const struct sway_container *child) { struct sway_container *parent = child->parent; for (int i = 0; i < parent->children->length; ++i) { diff --git a/sway/tree/root.c b/sway/tree/root.c new file mode 100644 index 00000000..9f3965be --- /dev/null +++ b/sway/tree/root.c @@ -0,0 +1,147 @@ +#define _POSIX_C_SOURCE 200809L +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <wlr/types/wlr_output_layout.h> +#include "sway/input/seat.h" +#include "sway/tree/arrange.h" +#include "sway/tree/container.h" +#include "sway/tree/root.h" +#include "sway/tree/workspace.h" +#include "list.h" +#include "log.h" + +struct sway_container root_container; + +static void output_layout_handle_change(struct wl_listener *listener, + void *data) { + arrange_windows(&root_container); + transaction_commit_dirty(); +} + +void root_create(void) { + root_container.id = 0; // normally assigned in new_swayc() + root_container.type = C_ROOT; + root_container.layout = L_NONE; + root_container.name = strdup("root"); + root_container.instructions = create_list(); + root_container.children = create_list(); + root_container.current.children = create_list(); + wl_signal_init(&root_container.events.destroy); + + root_container.sway_root = calloc(1, sizeof(*root_container.sway_root)); + root_container.sway_root->output_layout = wlr_output_layout_create(); + wl_list_init(&root_container.sway_root->outputs); +#ifdef HAVE_XWAYLAND + wl_list_init(&root_container.sway_root->xwayland_unmanaged); +#endif + wl_list_init(&root_container.sway_root->drag_icons); + wl_signal_init(&root_container.sway_root->events.new_container); + root_container.sway_root->scratchpad = create_list(); + + root_container.sway_root->output_layout_change.notify = + output_layout_handle_change; + wl_signal_add(&root_container.sway_root->output_layout->events.change, + &root_container.sway_root->output_layout_change); +} + +void root_destroy(void) { + // sway_root + wl_list_remove(&root_container.sway_root->output_layout_change.link); + list_free(root_container.sway_root->scratchpad); + wlr_output_layout_destroy(root_container.sway_root->output_layout); + free(root_container.sway_root); + + // root_container + list_free(root_container.instructions); + list_free(root_container.children); + list_free(root_container.current.children); + free(root_container.name); + + memset(&root_container, 0, sizeof(root_container)); +} + +void root_scratchpad_add_container(struct sway_container *con) { + if (!sway_assert(!con->scratchpad, "Container is already in scratchpad")) { + return; + } + con->scratchpad = true; + list_add(root_container.sway_root->scratchpad, con); + + struct sway_container *parent = con->parent; + container_set_floating(con, true); + container_remove_child(con); + arrange_windows(parent); + + struct sway_seat *seat = input_manager_current_seat(input_manager); + seat_set_focus(seat, seat_get_focus_inactive(seat, parent)); +} + +void root_scratchpad_remove_container(struct sway_container *con) { + if (!sway_assert(con->scratchpad, "Container is not in scratchpad")) { + return; + } + con->scratchpad = false; + for (int i = 0; i < root_container.sway_root->scratchpad->length; ++i) { + if (root_container.sway_root->scratchpad->items[i] == con) { + list_del(root_container.sway_root->scratchpad, i); + break; + } + } +} + +void root_scratchpad_show(struct sway_container *con) { + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *ws = seat_get_focus(seat); + if (ws->type != C_WORKSPACE) { + ws = container_parent(ws, C_WORKSPACE); + } + + // If the current con or any of its parents are in fullscreen mode, we + // first need to disable it before showing the scratchpad con. + if (ws->sway_workspace->fullscreen) { + container_set_fullscreen(ws->sway_workspace->fullscreen, false); + } + + // Show the container + if (con->parent) { + container_remove_child(con); + } + container_add_child(ws->sway_workspace->floating, con); + + // Make sure the container's center point overlaps this workspace + double center_lx = con->x + con->width / 2; + double center_ly = con->y + con->height / 2; + + struct wlr_box workspace_box; + container_get_box(ws, &workspace_box); + if (!wlr_box_contains_point(&workspace_box, center_lx, center_ly)) { + // Maybe resize it + if (con->width > ws->width || con->height > ws->height) { + container_init_floating(con); + } + + // Center it + double new_lx = ws->x + (ws->width - con->width) / 2; + double new_ly = ws->y + (ws->height - con->height) / 2; + container_floating_move_to(con, new_lx, new_ly); + } + + arrange_windows(ws); + seat_set_focus(seat, seat_get_focus_inactive(seat, con)); + + container_set_dirty(con->parent); +} + +void root_scratchpad_hide(struct sway_container *con) { + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = seat_get_focus(seat); + struct sway_container *ws = container_parent(con, C_WORKSPACE); + + container_remove_child(con); + arrange_windows(ws); + if (con == focus) { + seat_set_focus(seat, seat_get_focus_inactive(seat, ws)); + } + list_move_to_end(root_container.sway_root->scratchpad, con); +} |