From d6cd79c342495738fc23fbfbf19a01e73cdc42dc Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Fri, 17 Aug 2018 19:48:34 +1000 Subject: Implement iterators per container type This introduces the following `for_each` functions: * root_for_each_workspace * root_for_each_container * output_for_each_workspace * output_for_each_container * workspace_for_each_container And introduces the following `find` functions: * root_find_output * root_find_workspace * root_find_container * output_find_workspace * output_find_container * workspace_find_container * container_find_child And removes the following functions: * container_descendants * container_for_each_descendant * container_find This change is preparing the way for demoting sway_container. Eventually these functions will accept and return sway_outputs, sway_workspaces and sway_containers (meaning a C_CONTAINER or C_VIEW). This change also makes it easy to handle abnormalities like the workspace floating list, root's scratchpad list and (once implemented) root's saved workspaces list for when there's no connected outputs. --- sway/tree/root.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) (limited to 'sway/tree/root.c') diff --git a/sway/tree/root.c b/sway/tree/root.c index fc908cc1..8d8f42dc 100644 --- a/sway/tree/root.c +++ b/sway/tree/root.c @@ -256,3 +256,81 @@ void root_record_workspace_pid(pid_t pid) { &pw->output_destroy); wl_list_insert(&pid_workspaces, &pw->link); } + +void root_for_each_workspace(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]; + 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]; + 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]; + // 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. + if (!container->parent) { + f(container, data); + container_for_each_child(container, f, 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]; + if (test(output, data)) { + return 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]; + if ((result = output_find_workspace(output, test, data))) { + return result; + } + } + return NULL; +} + +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]; + 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]; + if (!container->parent) { + if (test(container, data)) { + return container; + } + if ((result = container_find_child(container, test, data))) { + return result; + } + } + } + return NULL; +} -- cgit v1.2.3