aboutsummaryrefslogtreecommitdiff
path: root/sway/tree/root.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree/root.c')
-rw-r--r--sway/tree/root.c186
1 files changed, 89 insertions, 97 deletions
diff --git a/sway/tree/root.c b/sway/tree/root.c
index b42371de..ecc04ddb 100644
--- a/sway/tree/root.c
+++ b/sway/tree/root.c
@@ -14,54 +14,45 @@
#include "log.h"
#include "util.h"
-struct sway_container root_container;
+struct sway_root *root;
static void output_layout_handle_change(struct wl_listener *listener,
void *data) {
- arrange_windows(&root_container);
+ arrange_root();
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.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->all_outputs);
+struct sway_root *root_create(void) {
+ struct sway_root *root = calloc(1, sizeof(struct sway_root));
+ if (!root) {
+ wlr_log(WLR_ERROR, "Unable to allocate sway_root");
+ return NULL;
+ }
+ node_init(&root->node, N_ROOT, root);
+ root->output_layout = wlr_output_layout_create();
+ wl_list_init(&root->all_outputs);
#ifdef HAVE_XWAYLAND
- wl_list_init(&root_container.sway_root->xwayland_unmanaged);
+ wl_list_init(&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->saved_workspaces = 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);
+ wl_list_init(&root->drag_icons);
+ wl_signal_init(&root->events.new_node);
+ root->outputs = create_list();
+ root->scratchpad = create_list();
+ root->saved_workspaces = create_list();
+
+ root->output_layout_change.notify = output_layout_handle_change;
+ wl_signal_add(&root->output_layout->events.change,
+ &root->output_layout_change);
+ return root;
}
-void root_destroy(void) {
- // sway_root
- wl_list_remove(&root_container.sway_root->output_layout_change.link);
- list_free(root_container.sway_root->scratchpad);
- list_free(root_container.sway_root->saved_workspaces);
- wlr_output_layout_destroy(root_container.sway_root->output_layout);
- free(root_container.sway_root);
-
- // root_container
- list_free(root_container.children);
- list_free(root_container.current.children);
- free(root_container.name);
-
- memset(&root_container, 0, sizeof(root_container));
+void root_destroy(struct sway_root *root) {
+ wl_list_remove(&root->output_layout_change.link);
+ list_free(root->scratchpad);
+ list_free(root->saved_workspaces);
+ list_free(root->outputs);
+ wlr_output_layout_destroy(root->output_layout);
+ free(root);
}
void root_scratchpad_add_container(struct sway_container *con) {
@@ -69,15 +60,21 @@ void root_scratchpad_add_container(struct sway_container *con) {
return;
}
con->scratchpad = true;
- list_add(root_container.sway_root->scratchpad, con);
+ list_add(root->scratchpad, con);
struct sway_container *parent = con->parent;
+ struct sway_workspace *workspace = con->workspace;
container_set_floating(con, true);
- container_remove_child(con);
- arrange_windows(parent);
+ container_detach(con);
struct sway_seat *seat = input_manager_current_seat(input_manager);
- seat_set_focus(seat, seat_get_focus_inactive(seat, parent));
+ if (parent) {
+ arrange_container(parent);
+ seat_set_focus(seat, seat_get_focus_inactive(seat, &parent->node));
+ } else {
+ arrange_workspace(workspace);
+ seat_set_focus(seat, seat_get_focus_inactive(seat, &workspace->node));
+ }
}
void root_scratchpad_remove_container(struct sway_container *con) {
@@ -85,28 +82,25 @@ void root_scratchpad_remove_container(struct sway_container *con) {
return;
}
con->scratchpad = false;
- int index = list_find(root_container.sway_root->scratchpad, con);
+ int index = list_find(root->scratchpad, con);
if (index != -1) {
- list_del(root_container.sway_root->scratchpad, index);
+ list_del(root->scratchpad, index);
}
}
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);
- }
+ struct sway_workspace *ws = seat_get_focused_workspace(seat);
// 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);
+ if (ws->fullscreen) {
+ container_set_fullscreen(ws->fullscreen, false);
}
// Show the container
- if (con->parent) {
- container_remove_child(con);
+ if (con->workspace) {
+ container_detach(con);
}
workspace_add_floating(ws, con);
@@ -115,7 +109,7 @@ void root_scratchpad_show(struct sway_container *con) {
double center_ly = con->y + con->height / 2;
struct wlr_box workspace_box;
- container_get_box(ws, &workspace_box);
+ workspace_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) {
@@ -128,23 +122,21 @@ void root_scratchpad_show(struct sway_container *con) {
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);
+ arrange_workspace(ws);
+ seat_set_focus(seat, seat_get_focus_inactive(seat, &con->node));
}
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);
+ struct sway_node *focus = seat_get_focus(seat);
+ struct sway_workspace *ws = con->workspace;
- container_remove_child(con);
- arrange_windows(ws);
- if (con == focus) {
- seat_set_focus(seat, seat_get_focus_inactive(seat, ws));
+ container_detach(con);
+ arrange_workspace(ws);
+ if (&con->node == focus) {
+ seat_set_focus(seat, seat_get_focus_inactive(seat, &ws->node));
}
- list_move_to_end(root_container.sway_root->scratchpad, con);
+ list_move_to_end(root->scratchpad, con);
}
struct pid_workspace {
@@ -152,7 +144,7 @@ struct pid_workspace {
char *workspace;
struct timespec time_added;
- struct sway_container *output;
+ struct sway_output *output;
struct wl_listener output_destroy;
struct wl_list link;
@@ -160,13 +152,13 @@ struct pid_workspace {
static struct wl_list pid_workspaces;
-struct sway_container *root_workspace_for_pid(pid_t pid) {
+struct sway_workspace *root_workspace_for_pid(pid_t pid) {
if (!pid_workspaces.prev && !pid_workspaces.next) {
wl_list_init(&pid_workspaces);
return NULL;
}
- struct sway_container *ws = NULL;
+ struct sway_workspace *ws = NULL;
struct pid_workspace *pw = NULL;
wlr_log(WLR_DEBUG, "Looking up workspace for pid %d", pid);
@@ -219,16 +211,12 @@ void root_record_workspace_pid(pid_t pid) {
}
struct sway_seat *seat = input_manager_current_seat(input_manager);
- struct sway_container *ws =
- seat_get_focus_inactive(seat, &root_container);
- if (ws && ws->type != C_WORKSPACE) {
- ws = container_parent(ws, C_WORKSPACE);
- }
+ struct sway_workspace *ws = seat_get_focused_workspace(seat);
if (!ws) {
wlr_log(WLR_DEBUG, "Bailing out, no workspace");
return;
}
- struct sway_container *output = ws->parent;
+ struct sway_output *output = ws->output;
if (!output) {
wlr_log(WLR_DEBUG, "Bailing out, no output");
return;
@@ -255,30 +243,28 @@ void root_record_workspace_pid(pid_t pid) {
pw->pid = pid;
memcpy(&pw->time_added, &now, sizeof(struct timespec));
pw->output_destroy.notify = pw_handle_output_destroy;
- wl_signal_add(&output->sway_output->wlr_output->events.destroy,
- &pw->output_destroy);
+ wl_signal_add(&output->wlr_output->events.destroy, &pw->output_destroy);
wl_list_insert(&pid_workspaces, &pw->link);
}
-void root_for_each_workspace(void (*f)(struct sway_container *con, void *data),
+void root_for_each_workspace(void (*f)(struct sway_workspace *ws, void *data),
void *data) {
- for (int i = 0; i < root_container.children->length; ++i) {
- struct sway_container *output = root_container.children->items[i];
+ for (int i = 0; i < root->outputs->length; ++i) {
+ struct sway_output *output = root->outputs->items[i];
output_for_each_workspace(output, f, data);
}
}
void root_for_each_container(void (*f)(struct sway_container *con, void *data),
void *data) {
- for (int i = 0; i < root_container.children->length; ++i) {
- struct sway_container *output = root_container.children->items[i];
+ for (int i = 0; i < root->outputs->length; ++i) {
+ struct sway_output *output = root->outputs->items[i];
output_for_each_container(output, f, data);
}
// Scratchpad
- for (int i = 0; i < root_container.sway_root->scratchpad->length; ++i) {
- struct sway_container *container =
- root_container.sway_root->scratchpad->items[i];
+ for (int i = 0; i < root->scratchpad->length; ++i) {
+ struct sway_container *container = root->scratchpad->items[i];
// If the container has a parent then it's visible on a workspace
// and will have been iterated in the previous for loop. So we only
// iterate the hidden scratchpad containers here.
@@ -289,10 +275,10 @@ void root_for_each_container(void (*f)(struct sway_container *con, void *data),
}
}
-struct sway_container *root_find_output(
- bool (*test)(struct sway_container *con, void *data), void *data) {
- for (int i = 0; i < root_container.children->length; ++i) {
- struct sway_container *output = root_container.children->items[i];
+struct sway_output *root_find_output(
+ bool (*test)(struct sway_output *output, void *data), void *data) {
+ for (int i = 0; i < root->outputs->length; ++i) {
+ struct sway_output *output = root->outputs->items[i];
if (test(output, data)) {
return output;
}
@@ -300,11 +286,11 @@ struct sway_container *root_find_output(
return NULL;
}
-struct sway_container *root_find_workspace(
- bool (*test)(struct sway_container *con, void *data), void *data) {
- struct sway_container *result = NULL;
- for (int i = 0; i < root_container.children->length; ++i) {
- struct sway_container *output = root_container.children->items[i];
+struct sway_workspace *root_find_workspace(
+ bool (*test)(struct sway_workspace *ws, void *data), void *data) {
+ struct sway_workspace *result = NULL;
+ for (int i = 0; i < root->outputs->length; ++i) {
+ struct sway_output *output = root->outputs->items[i];
if ((result = output_find_workspace(output, test, data))) {
return result;
}
@@ -315,17 +301,16 @@ struct sway_container *root_find_workspace(
struct sway_container *root_find_container(
bool (*test)(struct sway_container *con, void *data), void *data) {
struct sway_container *result = NULL;
- for (int i = 0; i < root_container.children->length; ++i) {
- struct sway_container *output = root_container.children->items[i];
+ for (int i = 0; i < root->outputs->length; ++i) {
+ struct sway_output *output = root->outputs->items[i];
if ((result = output_find_container(output, test, data))) {
return result;
}
}
// Scratchpad
- for (int i = 0; i < root_container.sway_root->scratchpad->length; ++i) {
- struct sway_container *container =
- root_container.sway_root->scratchpad->items[i];
+ for (int i = 0; i < root->scratchpad->length; ++i) {
+ struct sway_container *container = root->scratchpad->items[i];
if (!container->parent) {
if (test(container, data)) {
return container;
@@ -337,3 +322,10 @@ struct sway_container *root_find_container(
}
return NULL;
}
+
+void root_get_box(struct sway_root *root, struct wlr_box *box) {
+ box->x = root->x;
+ box->y = root->y;
+ box->width = root->width;
+ box->height = root->height;
+}