diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-08-20 15:54:30 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-08-24 22:17:28 +1000 |
commit | b6058703fa240780d66fac8ef96982c66b2b0263 (patch) | |
tree | 5e056a7859751c68c0cfb425fc6f37599c3f7400 /sway/tree/workspace.c | |
parent | Merge pull request #2470 from ianyfan/completions (diff) | |
download | sway-b6058703fa240780d66fac8ef96982c66b2b0263.tar.gz sway-b6058703fa240780d66fac8ef96982c66b2b0263.tar.zst sway-b6058703fa240780d66fac8ef96982c66b2b0263.zip |
Refactor destroy functions and save workspaces when there's no outputs
This changes the destroy functions to the following:
* output_begin_destroy
* output_destroy
* workspace_begin_destroy
* workspace_destroy
* container_begin_destroy
* container_destroy
* view_begin_destroy
* view_destroy
The terminology was `destroy` and `free`, and it has been changed to
`begin_destroy` and `destroy` respectively.
When the last output is disconnected, its workspaces will now be stashed
in the root. Upon connection of a new output they will be restored.
There is a new function `workspace_consider_destroy` which decides
whether the given workspace should be destroyed or not (ie. empty and
not visible).
Calling container_begin_destroy will no longer automatically reap the
parents. In some places we want to reap the parents and in some we
don't, so this is left to the caller.
container_reap_empty_recursive and container_reap_empty have been
combined into one function and it will recurse up the tree.
Diffstat (limited to 'sway/tree/workspace.c')
-rw-r--r-- | sway/tree/workspace.c | 63 |
1 files changed, 60 insertions, 3 deletions
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index cf50ee09..93c4b3d3 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c | |||
@@ -79,6 +79,65 @@ struct sway_container *workspace_create(struct sway_container *output, | |||
79 | return workspace; | 79 | return workspace; |
80 | } | 80 | } |
81 | 81 | ||
82 | void workspace_destroy(struct sway_container *workspace) { | ||
83 | if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) { | ||
84 | return; | ||
85 | } | ||
86 | if (!sway_assert(workspace->destroying, | ||
87 | "Tried to free workspace which wasn't marked as destroying")) { | ||
88 | return; | ||
89 | } | ||
90 | if (!sway_assert(workspace->ntxnrefs == 0, "Tried to free workspace " | ||
91 | "which is still referenced by transactions")) { | ||
92 | return; | ||
93 | } | ||
94 | // sway_workspace | ||
95 | struct sway_workspace *ws = workspace->sway_workspace; | ||
96 | list_foreach(ws->output_priority, free); | ||
97 | list_free(ws->output_priority); | ||
98 | list_free(ws->floating); | ||
99 | free(ws); | ||
100 | |||
101 | // swayc | ||
102 | free(workspace->name); | ||
103 | free(workspace->formatted_title); | ||
104 | wlr_texture_destroy(workspace->title_focused); | ||
105 | wlr_texture_destroy(workspace->title_focused_inactive); | ||
106 | wlr_texture_destroy(workspace->title_unfocused); | ||
107 | wlr_texture_destroy(workspace->title_urgent); | ||
108 | list_free(workspace->children); | ||
109 | list_free(workspace->current.children); | ||
110 | list_free(workspace->outputs); | ||
111 | free(workspace); | ||
112 | } | ||
113 | |||
114 | void workspace_begin_destroy(struct sway_container *workspace) { | ||
115 | if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) { | ||
116 | return; | ||
117 | } | ||
118 | wlr_log(WLR_DEBUG, "Destroying workspace '%s'", workspace->name); | ||
119 | wl_signal_emit(&workspace->events.destroy, workspace); | ||
120 | ipc_event_workspace(NULL, workspace, "empty"); // intentional | ||
121 | |||
122 | workspace->destroying = true; | ||
123 | container_set_dirty(workspace); | ||
124 | |||
125 | if (workspace->parent) { | ||
126 | container_remove_child(workspace); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | void workspace_consider_destroy(struct sway_container *ws) { | ||
131 | if (!sway_assert(ws->type == C_WORKSPACE, "Expected a workspace")) { | ||
132 | return; | ||
133 | } | ||
134 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
135 | if (ws->children->length == 0 && ws->sway_workspace->floating->length == 0 | ||
136 | && seat_get_active_child(seat, ws->parent) != ws) { | ||
137 | workspace_begin_destroy(ws); | ||
138 | } | ||
139 | } | ||
140 | |||
82 | char *prev_workspace_name = NULL; | 141 | char *prev_workspace_name = NULL; |
83 | 142 | ||
84 | void next_name_map(struct sway_container *ws, void *data) { | 143 | void next_name_map(struct sway_container *ws, void *data) { |
@@ -421,9 +480,7 @@ bool workspace_switch(struct sway_container *workspace, | |||
421 | // no op. We therefore need to send the IPC event and clean up the old | 480 | // no op. We therefore need to send the IPC event and clean up the old |
422 | // workspace here. | 481 | // workspace here. |
423 | ipc_event_workspace(active_ws, workspace, "focus"); | 482 | ipc_event_workspace(active_ws, workspace, "focus"); |
424 | if (!workspace_is_visible(active_ws) && workspace_is_empty(active_ws)) { | 483 | workspace_consider_destroy(active_ws); |
425 | container_destroy(active_ws); | ||
426 | } | ||
427 | } | 484 | } |
428 | seat_set_focus(seat, next); | 485 | seat_set_focus(seat, next); |
429 | struct sway_container *output = container_parent(workspace, C_OUTPUT); | 486 | struct sway_container *output = container_parent(workspace, C_OUTPUT); |