aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/arrange.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-30 21:00:10 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-09-05 18:01:43 +1000
commit7586f150c058997d9dde387ea7c091ffa7a3c3c7 (patch)
tree63d19027974c1db62ce3a74ca1d2314eb6d5049b /sway/tree/arrange.c
parentMerge pull request #2569 from RyanDwyer/deny-reload-repeat (diff)
downloadsway-7586f150c058997d9dde387ea7c091ffa7a3c3c7.tar.gz
sway-7586f150c058997d9dde387ea7c091ffa7a3c3c7.tar.zst
sway-7586f150c058997d9dde387ea7c091ffa7a3c3c7.zip
Implement type safe arguments and demote sway_container
This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
Diffstat (limited to 'sway/tree/arrange.c')
-rw-r--r--sway/tree/arrange.c110
1 files changed, 43 insertions, 67 deletions
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c
index 92f20fcc..f86d4a74 100644
--- a/sway/tree/arrange.c
+++ b/sway/tree/arrange.c
@@ -166,29 +166,23 @@ void arrange_container(struct sway_container *container) {
166 if (config->reloading) { 166 if (config->reloading) {
167 return; 167 return;
168 } 168 }
169 if (container->type == C_VIEW) { 169 if (container->view) {
170 view_autoconfigure(container->sway_view); 170 view_autoconfigure(container->view);
171 container_set_dirty(container); 171 node_set_dirty(&container->node);
172 return;
173 }
174 if (!sway_assert(container->type == C_CONTAINER, "Expected a container")) {
175 return; 172 return;
176 } 173 }
177 struct wlr_box box; 174 struct wlr_box box;
178 container_get_box(container, &box); 175 container_get_box(container, &box);
179 arrange_children(container->children, container->layout, &box); 176 arrange_children(container->children, container->layout, &box);
180 container_set_dirty(container); 177 node_set_dirty(&container->node);
181} 178}
182 179
183void arrange_workspace(struct sway_container *workspace) { 180void arrange_workspace(struct sway_workspace *workspace) {
184 if (config->reloading) { 181 if (config->reloading) {
185 return; 182 return;
186 } 183 }
187 if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) { 184 struct sway_output *output = workspace->output;
188 return; 185 struct wlr_box *area = &output->usable_area;
189 }
190 struct sway_container *output = workspace->parent;
191 struct wlr_box *area = &output->sway_output->usable_area;
192 wlr_log(WLR_DEBUG, "Usable area for ws: %dx%d@%d,%d", 186 wlr_log(WLR_DEBUG, "Usable area for ws: %dx%d@%d,%d",
193 area->width, area->height, area->x, area->y); 187 area->width, area->height, area->x, area->y);
194 workspace_remove_gaps(workspace); 188 workspace_remove_gaps(workspace);
@@ -197,21 +191,20 @@ void arrange_workspace(struct sway_container *workspace) {
197 double prev_y = workspace->y; 191 double prev_y = workspace->y;
198 workspace->width = area->width; 192 workspace->width = area->width;
199 workspace->height = area->height; 193 workspace->height = area->height;
200 workspace->x = output->x + area->x; 194 workspace->x = output->wlr_output->lx + area->x;
201 workspace->y = output->y + area->y; 195 workspace->y = output->wlr_output->ly + area->y;
202 196
203 // Adjust any floating containers 197 // Adjust any floating containers
204 double diff_x = workspace->x - prev_x; 198 double diff_x = workspace->x - prev_x;
205 double diff_y = workspace->y - prev_y; 199 double diff_y = workspace->y - prev_y;
206 if (diff_x != 0 || diff_y != 0) { 200 if (diff_x != 0 || diff_y != 0) {
207 for (int i = 0; i < workspace->sway_workspace->floating->length; ++i) { 201 for (int i = 0; i < workspace->floating->length; ++i) {
208 struct sway_container *floater = 202 struct sway_container *floater = workspace->floating->items[i];
209 workspace->sway_workspace->floating->items[i];
210 container_floating_translate(floater, diff_x, diff_y); 203 container_floating_translate(floater, diff_x, diff_y);
211 double center_x = floater->x + floater->width / 2; 204 double center_x = floater->x + floater->width / 2;
212 double center_y = floater->y + floater->height / 2; 205 double center_y = floater->y + floater->height / 2;
213 struct wlr_box workspace_box; 206 struct wlr_box workspace_box;
214 container_get_box(workspace, &workspace_box); 207 workspace_get_box(workspace, &workspace_box);
215 if (!wlr_box_contains_point(&workspace_box, center_x, center_y)) { 208 if (!wlr_box_contains_point(&workspace_box, center_x, center_y)) {
216 container_floating_move_to_center(floater); 209 container_floating_move_to_center(floater);
217 } 210 }
@@ -219,43 +212,32 @@ void arrange_workspace(struct sway_container *workspace) {
219 } 212 }
220 213
221 workspace_add_gaps(workspace); 214 workspace_add_gaps(workspace);
222 container_set_dirty(workspace); 215 node_set_dirty(&workspace->node);
223 wlr_log(WLR_DEBUG, "Arranging workspace '%s' at %f, %f", workspace->name, 216 wlr_log(WLR_DEBUG, "Arranging workspace '%s' at %f, %f", workspace->name,
224 workspace->x, workspace->y); 217 workspace->x, workspace->y);
225 if (workspace->sway_workspace->fullscreen) { 218 if (workspace->fullscreen) {
226 struct sway_container *fs = workspace->sway_workspace->fullscreen; 219 struct sway_container *fs = workspace->fullscreen;
227 fs->x = workspace->parent->x; 220 fs->x = output->wlr_output->lx;
228 fs->y = workspace->parent->y; 221 fs->y = output->wlr_output->ly;
229 fs->width = workspace->parent->width; 222 fs->width = output->wlr_output->width;
230 fs->height = workspace->parent->height; 223 fs->height = output->wlr_output->height;
231 arrange_container(fs); 224 arrange_container(fs);
232 } else { 225 } else {
233 struct wlr_box box; 226 struct wlr_box box;
234 container_get_box(workspace, &box); 227 workspace_get_box(workspace, &box);
235 arrange_children(workspace->children, workspace->layout, &box); 228 arrange_children(workspace->tiling, workspace->layout, &box);
236 arrange_floating(workspace->sway_workspace->floating); 229 arrange_floating(workspace->floating);
237 } 230 }
238} 231}
239 232
240void arrange_output(struct sway_container *output) { 233void arrange_output(struct sway_output *output) {
241 if (config->reloading) { 234 if (config->reloading) {
242 return; 235 return;
243 } 236 }
244 if (!sway_assert(output->type == C_OUTPUT, "Expected an output")) { 237 // Outputs have no pending x/y/width/height,
245 return; 238 // so all we do here is arrange the workspaces.
246 } 239 for (int i = 0; i < output->workspaces->length; ++i) {
247 const struct wlr_box *output_box = wlr_output_layout_get_box( 240 struct sway_workspace *workspace = output->workspaces->items[i];
248 root_container.sway_root->output_layout,
249 output->sway_output->wlr_output);
250 output->x = output_box->x;
251 output->y = output_box->y;
252 output->width = output_box->width;
253 output->height = output_box->height;
254 container_set_dirty(output);
255 wlr_log(WLR_DEBUG, "Arranging output '%s' at %f,%f",
256 output->name, output->x, output->y);
257 for (int i = 0; i < output->children->length; ++i) {
258 struct sway_container *workspace = output->children->items[i];
259 arrange_workspace(workspace); 241 arrange_workspace(workspace);
260 } 242 }
261} 243}
@@ -264,37 +246,31 @@ void arrange_root(void) {
264 if (config->reloading) { 246 if (config->reloading) {
265 return; 247 return;
266 } 248 }
267 struct wlr_output_layout *output_layout =
268 root_container.sway_root->output_layout;
269 const struct wlr_box *layout_box = 249 const struct wlr_box *layout_box =
270 wlr_output_layout_get_box(output_layout, NULL); 250 wlr_output_layout_get_box(root->output_layout, NULL);
271 root_container.x = layout_box->x; 251 root->x = layout_box->x;
272 root_container.y = layout_box->y; 252 root->y = layout_box->y;
273 root_container.width = layout_box->width; 253 root->width = layout_box->width;
274 root_container.height = layout_box->height; 254 root->height = layout_box->height;
275 container_set_dirty(&root_container); 255 for (int i = 0; i < root->outputs->length; ++i) {
276 for (int i = 0; i < root_container.children->length; ++i) { 256 struct sway_output *output = root->outputs->items[i];
277 struct sway_container *output = root_container.children->items[i];
278 arrange_output(output); 257 arrange_output(output);
279 } 258 }
280} 259}
281 260
282void arrange_windows(struct sway_container *container) { 261void arrange_node(struct sway_node *node) {
283 switch (container->type) { 262 switch (node->type) {
284 case C_ROOT: 263 case N_ROOT:
285 arrange_root(); 264 arrange_root();
286 break; 265 break;
287 case C_OUTPUT: 266 case N_OUTPUT:
288 arrange_output(container); 267 arrange_output(node->sway_output);
289 break;
290 case C_WORKSPACE:
291 arrange_workspace(container);
292 break; 268 break;
293 case C_CONTAINER: 269 case N_WORKSPACE:
294 case C_VIEW: 270 arrange_workspace(node->sway_workspace);
295 arrange_container(container);
296 break; 271 break;
297 case C_TYPES: 272 case N_CONTAINER:
273 arrange_container(node->sway_container);
298 break; 274 break;
299 } 275 }
300} 276}