aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/output.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/output.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/output.c')
-rw-r--r--sway/tree/output.c348
1 files changed, 208 insertions, 140 deletions
diff --git a/sway/tree/output.c b/sway/tree/output.c
index 6601220b..d72eb1a1 100644
--- a/sway/tree/output.c
+++ b/sway/tree/output.c
@@ -2,28 +2,31 @@
2#include <ctype.h> 2#include <ctype.h>
3#include <string.h> 3#include <string.h>
4#include <strings.h> 4#include <strings.h>
5#include <wlr/types/wlr_output_damage.h>
5#include "sway/ipc-server.h" 6#include "sway/ipc-server.h"
7#include "sway/layers.h"
6#include "sway/output.h" 8#include "sway/output.h"
7#include "sway/tree/arrange.h" 9#include "sway/tree/arrange.h"
8#include "sway/tree/output.h" 10#include "sway/tree/output.h"
9#include "sway/tree/workspace.h" 11#include "sway/tree/workspace.h"
10#include "log.h" 12#include "log.h"
13#include "util.h"
11 14
12static void restore_workspaces(struct sway_container *output) { 15static void restore_workspaces(struct sway_output *output) {
13 // Workspace output priority 16 // Workspace output priority
14 for (int i = 0; i < root_container.children->length; i++) { 17 for (int i = 0; i < root->outputs->length; i++) {
15 struct sway_container *other = root_container.children->items[i]; 18 struct sway_output *other = root->outputs->items[i];
16 if (other == output) { 19 if (other == output) {
17 continue; 20 continue;
18 } 21 }
19 22
20 for (int j = 0; j < other->children->length; j++) { 23 for (int j = 0; j < other->workspaces->length; j++) {
21 struct sway_container *ws = other->children->items[j]; 24 struct sway_workspace *ws = other->workspaces->items[j];
22 struct sway_container *highest = 25 struct sway_output *highest =
23 workspace_output_get_highest_available(ws, NULL); 26 workspace_output_get_highest_available(ws, NULL);
24 if (highest == output) { 27 if (highest == output) {
25 container_remove_child(ws); 28 workspace_detach(ws);
26 container_add_child(output, ws); 29 output_add_workspace(output, ws);
27 ipc_event_workspace(NULL, ws, "move"); 30 ipc_event_workspace(NULL, ws, "move");
28 j--; 31 j--;
29 } 32 }
@@ -31,111 +34,111 @@ static void restore_workspaces(struct sway_container *output) {
31 } 34 }
32 35
33 // Saved workspaces 36 // Saved workspaces
34 list_t *saved = root_container.sway_root->saved_workspaces; 37 for (int i = 0; i < root->saved_workspaces->length; ++i) {
35 for (int i = 0; i < saved->length; ++i) { 38 struct sway_workspace *ws = root->saved_workspaces->items[i];
36 struct sway_container *ws = saved->items[i]; 39 output_add_workspace(output, ws);
37 container_add_child(output, ws);
38 ipc_event_workspace(NULL, ws, "move"); 40 ipc_event_workspace(NULL, ws, "move");
39 } 41 }
40 saved->length = 0; 42 root->saved_workspaces->length = 0;
41 43
42 output_sort_workspaces(output); 44 output_sort_workspaces(output);
43} 45}
44 46
45struct sway_container *output_create( 47struct sway_output *output_create(struct wlr_output *wlr_output) {
46 struct sway_output *sway_output) { 48 struct sway_output *output = calloc(1, sizeof(struct sway_output));
47 const char *name = sway_output->wlr_output->name; 49 node_init(&output->node, N_OUTPUT, output);
48 char identifier[128]; 50 output->wlr_output = wlr_output;
49 output_get_identifier(identifier, sizeof(identifier), sway_output); 51 wlr_output->data = output;
50 52
51 struct output_config *oc = NULL, *all = NULL; 53 wl_signal_add(&wlr_output->events.destroy, &output->destroy);
52 for (int i = 0; i < config->output_configs->length; ++i) {
53 struct output_config *cur = config->output_configs->items[i];
54 54
55 if (strcasecmp(name, cur->name) == 0 || 55 wl_list_insert(&root->all_outputs, &output->link);
56 strcasecmp(identifier, cur->name) == 0) {
57 wlr_log(WLR_DEBUG, "Matched output config for %s", name);
58 oc = cur;
59 }
60 if (strcasecmp("*", cur->name) == 0) {
61 wlr_log(WLR_DEBUG, "Matched wildcard output config for %s", name);
62 all = cur;
63 }
64 56
65 if (oc && all) { 57 if (!wl_list_empty(&wlr_output->modes)) {
66 break; 58 struct wlr_output_mode *mode =
67 } 59 wl_container_of(wlr_output->modes.prev, mode, link);
68 } 60 wlr_output_set_mode(wlr_output, mode);
69 if (!oc) {
70 oc = all;
71 } 61 }
72 62
73 if (oc && !oc->enabled) { 63 output->workspaces = create_list();
74 return NULL; 64 output->current.workspaces = create_list();
75 }
76 65
77 struct sway_container *output = container_create(C_OUTPUT); 66 return output;
78 output->sway_output = sway_output; 67}
79 output->name = strdup(name);
80 if (output->name == NULL) {
81 output_begin_destroy(output);
82 return NULL;
83 }
84 68
69void output_enable(struct sway_output *output, struct output_config *oc) {
70 if (!sway_assert(!output->enabled, "output is already enabled")) {
71 return;
72 }
73 struct wlr_output *wlr_output = output->wlr_output;
74 output->enabled = true;
85 apply_output_config(oc, output); 75 apply_output_config(oc, output);
86 container_add_child(&root_container, output); 76 list_add(root->outputs, output);
87 load_swaybars();
88
89 struct wlr_box size;
90 wlr_output_effective_resolution(sway_output->wlr_output, &size.width,
91 &size.height);
92 output->width = size.width;
93 output->height = size.height;
94 77
95 restore_workspaces(output); 78 restore_workspaces(output);
96 79
97 if (!output->children->length) { 80 if (!output->workspaces->length) {
98 // Create workspace 81 // Create workspace
99 char *ws_name = workspace_next_name(output->name); 82 char *ws_name = workspace_next_name(wlr_output->name);
100 wlr_log(WLR_DEBUG, "Creating default workspace %s", ws_name); 83 wlr_log(WLR_DEBUG, "Creating default workspace %s", ws_name);
101 struct sway_container *ws = workspace_create(output, ws_name); 84 struct sway_workspace *ws = workspace_create(output, ws_name);
102 // Set each seat's focus if not already set 85 // Set each seat's focus if not already set
103 struct sway_seat *seat = NULL; 86 struct sway_seat *seat = NULL;
104 wl_list_for_each(seat, &input_manager->seats, link) { 87 wl_list_for_each(seat, &input_manager->seats, link) {
105 if (!seat->has_focus) { 88 if (!seat->has_focus) {
106 seat_set_focus(seat, ws); 89 seat_set_focus(seat, &ws->node);
107 } 90 }
108 } 91 }
109 free(ws_name); 92 free(ws_name);
110 } 93 }
111 94
112 container_create_notify(output); 95 size_t len = sizeof(output->layers) / sizeof(output->layers[0]);
113 return output; 96 for (size_t i = 0; i < len; ++i) {
97 wl_list_init(&output->layers[i]);
98 }
99 wl_signal_init(&output->events.destroy);
100
101 input_manager_configure_xcursor(input_manager);
102
103 wl_signal_add(&wlr_output->events.mode, &output->mode);
104 wl_signal_add(&wlr_output->events.transform, &output->transform);
105 wl_signal_add(&wlr_output->events.scale, &output->scale);
106 wl_signal_add(&output->damage->events.frame, &output->damage_frame);
107 wl_signal_add(&output->damage->events.destroy, &output->damage_destroy);
108
109 output_add_listeners(output);
110
111 wl_signal_emit(&root->events.new_node, &output->node);
112
113 load_swaybars();
114
115 arrange_layers(output);
116 arrange_root();
114} 117}
115 118
116static void output_evacuate(struct sway_container *output) { 119static void output_evacuate(struct sway_output *output) {
117 if (!output->children->length) { 120 if (!output->workspaces->length) {
118 return; 121 return;
119 } 122 }
120 struct sway_container *fallback_output = NULL; 123 struct sway_output *fallback_output = NULL;
121 if (root_container.children->length > 1) { 124 if (root->outputs->length > 1) {
122 fallback_output = root_container.children->items[0]; 125 fallback_output = root->outputs->items[0];
123 if (fallback_output == output) { 126 if (fallback_output == output) {
124 fallback_output = root_container.children->items[1]; 127 fallback_output = root->outputs->items[1];
125 } 128 }
126 } 129 }
127 130
128 while (output->children->length) { 131 while (output->workspaces->length) {
129 struct sway_container *workspace = output->children->items[0]; 132 struct sway_workspace *workspace = output->workspaces->items[0];
130 133
131 container_remove_child(workspace); 134 workspace_detach(workspace);
132 135
133 if (workspace_is_empty(workspace)) { 136 if (workspace_is_empty(workspace)) {
134 workspace_begin_destroy(workspace); 137 workspace_begin_destroy(workspace);
135 continue; 138 continue;
136 } 139 }
137 140
138 struct sway_container *new_output = 141 struct sway_output *new_output =
139 workspace_output_get_highest_available(workspace, output); 142 workspace_output_get_highest_available(workspace, output);
140 if (!new_output) { 143 if (!new_output) {
141 new_output = fallback_output; 144 new_output = fallback_output;
@@ -143,39 +146,31 @@ static void output_evacuate(struct sway_container *output) {
143 146
144 if (new_output) { 147 if (new_output) {
145 workspace_output_add_priority(workspace, new_output); 148 workspace_output_add_priority(workspace, new_output);
146 container_add_child(new_output, workspace); 149 output_add_workspace(new_output, workspace);
147 output_sort_workspaces(new_output); 150 output_sort_workspaces(new_output);
148 ipc_event_workspace(NULL, workspace, "move"); 151 ipc_event_workspace(NULL, workspace, "move");
149 } else { 152 } else {
150 list_add(root_container.sway_root->saved_workspaces, workspace); 153 list_add(root->saved_workspaces, workspace);
151 } 154 }
152 } 155 }
153} 156}
154 157
155void output_destroy(struct sway_container *output) { 158void output_destroy(struct sway_output *output) {
156 if (!sway_assert(output->type == C_OUTPUT, "Expected an output")) { 159 if (!sway_assert(output->node.destroying,
160 "Tried to free output which wasn't marked as destroying")) {
157 return; 161 return;
158 } 162 }
159 if (!sway_assert(output->destroying, 163 if (!sway_assert(output->wlr_output == NULL,
160 "Tried to free output which wasn't marked as destroying")) { 164 "Tried to free output which still had a wlr_output")) {
161 return; 165 return;
162 } 166 }
163 if (!sway_assert(output->ntxnrefs == 0, "Tried to free output " 167 if (!sway_assert(output->node.ntxnrefs == 0, "Tried to free output "
164 "which is still referenced by transactions")) { 168 "which is still referenced by transactions")) {
165 return; 169 return;
166 } 170 }
167 free(output->name); 171 list_free(output->workspaces);
168 free(output->formatted_title); 172 list_free(output->current.workspaces);
169 wlr_texture_destroy(output->title_focused);
170 wlr_texture_destroy(output->title_focused_inactive);
171 wlr_texture_destroy(output->title_unfocused);
172 wlr_texture_destroy(output->title_urgent);
173 list_free(output->children);
174 list_free(output->current.children);
175 list_free(output->outputs);
176 free(output); 173 free(output);
177
178 // NOTE: We don't actually destroy the sway_output here
179} 174}
180 175
181static void untrack_output(struct sway_container *con, void *data) { 176static void untrack_output(struct sway_container *con, void *data) {
@@ -186,76 +181,131 @@ static void untrack_output(struct sway_container *con, void *data) {
186 } 181 }
187} 182}
188 183
189void output_begin_destroy(struct sway_container *output) { 184void output_disable(struct sway_output *output) {
190 if (!sway_assert(output->type == C_OUTPUT, "Expected an output")) { 185 if (!sway_assert(output->enabled, "Expected an enabled output")) {
191 return; 186 return;
192 } 187 }
193 wlr_log(WLR_DEBUG, "OUTPUT: Destroying output '%s'", output->name); 188 wlr_log(WLR_DEBUG, "Disabling output '%s'", output->wlr_output->name);
194 wl_signal_emit(&output->events.destroy, output); 189 wl_signal_emit(&output->events.destroy, output);
195 190
196 output_evacuate(output); 191 output_evacuate(output);
197 192
198 output->destroying = true; 193 root_for_each_container(untrack_output, output);
199 container_set_dirty(output); 194
195 int index = list_find(root->outputs, output);
196 list_del(root->outputs, index);
200 197
201 root_for_each_container(untrack_output, output->sway_output); 198 wl_list_remove(&output->mode.link);
199 wl_list_remove(&output->transform.link);
200 wl_list_remove(&output->scale.link);
201 wl_list_remove(&output->damage_destroy.link);
202 wl_list_remove(&output->damage_frame.link);
202 203
203 wl_list_remove(&output->sway_output->mode.link); 204 output->enabled = false;
204 wl_list_remove(&output->sway_output->transform.link);
205 wl_list_remove(&output->sway_output->scale.link);
206 wl_list_remove(&output->sway_output->damage_destroy.link);
207 wl_list_remove(&output->sway_output->damage_frame.link);
208 205
209 output->sway_output->swayc = NULL; 206 arrange_root();
210 output->sway_output = NULL; 207}
211 208
212 if (output->parent) { 209void output_begin_destroy(struct sway_output *output) {
213 container_remove_child(output); 210 if (!sway_assert(!output->enabled, "Expected a disabled output")) {
211 return;
214 } 212 }
213 wlr_log(WLR_DEBUG, "Destroying output '%s'", output->wlr_output->name);
214
215 output->node.destroying = true;
216 node_set_dirty(&output->node);
217
218 wl_list_remove(&output->link);
219 wl_list_remove(&output->destroy.link);
220 output->wlr_output->data = NULL;
221 output->wlr_output = NULL;
215} 222}
216 223
217struct sway_container *output_from_wlr_output(struct wlr_output *output) { 224struct output_config *output_find_config(struct sway_output *output) {
218 if (output == NULL) { 225 const char *name = output->wlr_output->name;
226 char identifier[128];
227 output_get_identifier(identifier, sizeof(identifier), output);
228
229 struct output_config *oc = NULL, *all = NULL;
230 for (int i = 0; i < config->output_configs->length; ++i) {
231 struct output_config *cur = config->output_configs->items[i];
232
233 if (strcasecmp(name, cur->name) == 0 ||
234 strcasecmp(identifier, cur->name) == 0) {
235 wlr_log(WLR_DEBUG, "Matched output config for %s", name);
236 oc = cur;
237 }
238 if (strcasecmp("*", cur->name) == 0) {
239 wlr_log(WLR_DEBUG, "Matched wildcard output config for %s", name);
240 all = cur;
241 }
242
243 if (oc && all) {
244 break;
245 }
246 }
247 if (!oc) {
248 oc = all;
249 }
250
251 if (oc && !oc->enabled) {
219 return NULL; 252 return NULL;
220 } 253 }
221 for (int i = 0; i < root_container.children->length; ++i) { 254 return oc;
222 struct sway_container *o = root_container.children->items[i]; 255}
223 if (o->type == C_OUTPUT && o->sway_output->wlr_output == output) { 256
224 return o; 257struct sway_output *output_from_wlr_output(struct wlr_output *output) {
225 } 258 return output->data;
259}
260
261struct sway_output *output_get_in_direction(struct sway_output *reference,
262 enum movement_direction direction) {
263 enum wlr_direction wlr_dir = 0;
264 if (!sway_assert(sway_dir_to_wlr(direction, &wlr_dir),
265 "got invalid direction: %d", direction)) {
266 return NULL;
226 } 267 }
227 return NULL; 268 int lx = reference->wlr_output->lx + reference->wlr_output->width / 2;
269 int ly = reference->wlr_output->ly + reference->wlr_output->height / 2;
270 struct wlr_output *wlr_adjacent = wlr_output_layout_adjacent_output(
271 root->output_layout, wlr_dir, reference->wlr_output, lx, ly);
272 if (!wlr_adjacent) {
273 return NULL;
274 }
275 return output_from_wlr_output(wlr_adjacent);
228} 276}
229 277
230void output_for_each_workspace(struct sway_container *output, 278void output_add_workspace(struct sway_output *output,
231 void (*f)(struct sway_container *con, void *data), void *data) { 279 struct sway_workspace *workspace) {
232 if (!sway_assert(output->type == C_OUTPUT, "Expected an output")) { 280 if (workspace->output) {
233 return; 281 workspace_detach(workspace);
234 } 282 }
235 for (int i = 0; i < output->children->length; ++i) { 283 list_add(output->workspaces, workspace);
236 struct sway_container *workspace = output->children->items[i]; 284 workspace->output = output;
285 node_set_dirty(&output->node);
286 node_set_dirty(&workspace->node);
287}
288
289void output_for_each_workspace(struct sway_output *output,
290 void (*f)(struct sway_workspace *ws, void *data), void *data) {
291 for (int i = 0; i < output->workspaces->length; ++i) {
292 struct sway_workspace *workspace = output->workspaces->items[i];
237 f(workspace, data); 293 f(workspace, data);
238 } 294 }
239} 295}
240 296
241void output_for_each_container(struct sway_container *output, 297void output_for_each_container(struct sway_output *output,
242 void (*f)(struct sway_container *con, void *data), void *data) { 298 void (*f)(struct sway_container *con, void *data), void *data) {
243 if (!sway_assert(output->type == C_OUTPUT, "Expected an output")) { 299 for (int i = 0; i < output->workspaces->length; ++i) {
244 return; 300 struct sway_workspace *workspace = output->workspaces->items[i];
245 }
246 for (int i = 0; i < output->children->length; ++i) {
247 struct sway_container *workspace = output->children->items[i];
248 workspace_for_each_container(workspace, f, data); 301 workspace_for_each_container(workspace, f, data);
249 } 302 }
250} 303}
251 304
252struct sway_container *output_find_workspace(struct sway_container *output, 305struct sway_workspace *output_find_workspace(struct sway_output *output,
253 bool (*test)(struct sway_container *con, void *data), void *data) { 306 bool (*test)(struct sway_workspace *ws, void *data), void *data) {
254 if (!sway_assert(output->type == C_OUTPUT, "Expected an output")) { 307 for (int i = 0; i < output->workspaces->length; ++i) {
255 return NULL; 308 struct sway_workspace *workspace = output->workspaces->items[i];
256 }
257 for (int i = 0; i < output->children->length; ++i) {
258 struct sway_container *workspace = output->children->items[i];
259 if (test(workspace, data)) { 309 if (test(workspace, data)) {
260 return workspace; 310 return workspace;
261 } 311 }
@@ -263,14 +313,11 @@ struct sway_container *output_find_workspace(struct sway_container *output,
263 return NULL; 313 return NULL;
264} 314}
265 315
266struct sway_container *output_find_container(struct sway_container *output, 316struct sway_container *output_find_container(struct sway_output *output,
267 bool (*test)(struct sway_container *con, void *data), void *data) { 317 bool (*test)(struct sway_container *con, void *data), void *data) {
268 if (!sway_assert(output->type == C_OUTPUT, "Expected an output")) {
269 return NULL;
270 }
271 struct sway_container *result = NULL; 318 struct sway_container *result = NULL;
272 for (int i = 0; i < output->children->length; ++i) { 319 for (int i = 0; i < output->workspaces->length; ++i) {
273 struct sway_container *workspace = output->children->items[i]; 320 struct sway_workspace *workspace = output->workspaces->items[i];
274 if ((result = workspace_find_container(workspace, test, data))) { 321 if ((result = workspace_find_container(workspace, test, data))) {
275 return result; 322 return result;
276 } 323 }
@@ -279,8 +326,8 @@ struct sway_container *output_find_container(struct sway_container *output,
279} 326}
280 327
281static int sort_workspace_cmp_qsort(const void *_a, const void *_b) { 328static int sort_workspace_cmp_qsort(const void *_a, const void *_b) {
282 struct sway_container *a = *(void **)_a; 329 struct sway_workspace *a = *(void **)_a;
283 struct sway_container *b = *(void **)_b; 330 struct sway_workspace *b = *(void **)_b;
284 331
285 if (isdigit(a->name[0]) && isdigit(b->name[0])) { 332 if (isdigit(a->name[0]) && isdigit(b->name[0])) {
286 int a_num = strtol(a->name, NULL, 10); 333 int a_num = strtol(a->name, NULL, 10);
@@ -294,6 +341,27 @@ static int sort_workspace_cmp_qsort(const void *_a, const void *_b) {
294 return 0; 341 return 0;
295} 342}
296 343
297void output_sort_workspaces(struct sway_container *output) { 344void output_sort_workspaces(struct sway_output *output) {
298 list_stable_sort(output->children, sort_workspace_cmp_qsort); 345 list_stable_sort(output->workspaces, sort_workspace_cmp_qsort);
346}
347
348void output_get_box(struct sway_output *output, struct wlr_box *box) {
349 box->x = output->wlr_output->lx;
350 box->y = output->wlr_output->ly;
351 box->width = output->wlr_output->width;
352 box->height = output->wlr_output->height;
353}
354
355enum sway_container_layout output_get_default_layout(
356 struct sway_output *output) {
357 if (config->default_layout != L_NONE) {
358 return config->default_layout;
359 }
360 if (config->default_orientation != L_NONE) {
361 return config->default_orientation;
362 }
363 if (output->wlr_output->height > output->wlr_output->width) {
364 return L_VERT;
365 }
366 return L_HORIZ;
299} 367}