aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-06-03 16:35:06 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-06-09 10:08:43 +1000
commit59c94887018bdfa578c4371c4275061ca6e71b3e (patch)
tree62bdaa6ac4777d1fcb292013bddd2043dad7765a /sway/tree
parentMerge pull request #2115 from RedSoxFan/restore-workspaces (diff)
downloadsway-59c94887018bdfa578c4371c4275061ca6e71b3e.tar.gz
sway-59c94887018bdfa578c4371c4275061ca6e71b3e.tar.zst
sway-59c94887018bdfa578c4371c4275061ca6e71b3e.zip
WIP: Atomic layout updates ground work
Diffstat (limited to 'sway/tree')
-rw-r--r--sway/tree/arrange.c321
-rw-r--r--sway/tree/container.c11
-rw-r--r--sway/tree/layout.c4
-rw-r--r--sway/tree/view.c98
-rw-r--r--sway/tree/workspace.c6
5 files changed, 252 insertions, 188 deletions
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c
index 721b557e..d8b3aec1 100644
--- a/sway/tree/arrange.c
+++ b/sway/tree/arrange.c
@@ -5,7 +5,6 @@
5#include <string.h> 5#include <string.h>
6#include <wlr/types/wlr_output.h> 6#include <wlr/types/wlr_output.h>
7#include <wlr/types/wlr_output_layout.h> 7#include <wlr/types/wlr_output_layout.h>
8#include "sway/debug.h"
9#include "sway/tree/arrange.h" 8#include "sway/tree/arrange.h"
10#include "sway/tree/container.h" 9#include "sway/tree/container.h"
11#include "sway/tree/layout.h" 10#include "sway/tree/layout.h"
@@ -17,116 +16,56 @@
17 16
18struct sway_container root_container; 17struct sway_container root_container;
19 18
20void arrange_root() {
21 if (config->reloading) {
22 return;
23 }
24 struct wlr_output_layout *output_layout =
25 root_container.sway_root->output_layout;
26 const struct wlr_box *layout_box =
27 wlr_output_layout_get_box(output_layout, NULL);
28 root_container.x = layout_box->x;
29 root_container.y = layout_box->y;
30 root_container.width = layout_box->width;
31 root_container.height = layout_box->height;
32 for (int i = 0; i < root_container.children->length; ++i) {
33 struct sway_container *output = root_container.children->items[i];
34 arrange_output(output);
35 }
36}
37
38void arrange_output(struct sway_container *output) {
39 if (config->reloading) {
40 return;
41 }
42 if (!sway_assert(output->type == C_OUTPUT,
43 "called arrange_output() on non-output container")) {
44 return;
45 }
46 const struct wlr_box *output_box = wlr_output_layout_get_box(
47 root_container.sway_root->output_layout,
48 output->sway_output->wlr_output);
49 output->x = output_box->x;
50 output->y = output_box->y;
51 output->width = output_box->width;
52 output->height = output_box->height;
53 wlr_log(L_DEBUG, "Arranging output '%s' at %f,%f",
54 output->name, output->x, output->y);
55 for (int i = 0; i < output->children->length; ++i) {
56 struct sway_container *workspace = output->children->items[i];
57 arrange_workspace(workspace);
58 }
59 container_damage_whole(output);
60}
61
62void arrange_workspace(struct sway_container *workspace) {
63 if (config->reloading) {
64 return;
65 }
66 if (!sway_assert(workspace->type == C_WORKSPACE,
67 "called arrange_workspace() on non-workspace container")) {
68 return;
69 }
70 struct sway_container *output = workspace->parent;
71 struct wlr_box *area = &output->sway_output->usable_area;
72 wlr_log(L_DEBUG, "Usable area for ws: %dx%d@%d,%d",
73 area->width, area->height, area->x, area->y);
74 workspace->width = area->width;
75 workspace->height = area->height;
76 workspace->x = output->x + area->x;
77 workspace->y = output->y + area->y;
78 wlr_log(L_DEBUG, "Arranging workspace '%s' at %f, %f",
79 workspace->name, workspace->x, workspace->y);
80 arrange_children_of(workspace);
81 container_damage_whole(workspace);
82}
83
84static void apply_horiz_layout(struct sway_container *parent) { 19static void apply_horiz_layout(struct sway_container *parent) {
85 size_t num_children = parent->children->length; 20 size_t num_children = parent->children->length;
86 if (!num_children) { 21 if (!num_children) {
87 return; 22 return;
88 } 23 }
89 size_t parent_offset = 0; 24 size_t parent_offset = 0;
90 if (parent->parent->layout == L_TABBED) { 25 if (parent->parent->pending.layout == L_TABBED) {
91 parent_offset = container_titlebar_height(); 26 parent_offset = container_titlebar_height();
92 } else if (parent->parent->layout == L_STACKED) { 27 } else if (parent->parent->pending.layout == L_STACKED) {
93 parent_offset = 28 parent_offset = container_titlebar_height() *
94 container_titlebar_height() * parent->parent->children->length; 29 parent->parent->children->length;
95 } 30 }
96 size_t parent_height = parent->height - parent_offset; 31 size_t parent_height = parent->pending.swayc_height - parent_offset;
97 32
98 // Calculate total width of children 33 // Calculate total width of children
99 double total_width = 0; 34 double total_width = 0;
100 for (size_t i = 0; i < num_children; ++i) { 35 for (size_t i = 0; i < num_children; ++i) {
101 struct sway_container *child = parent->children->items[i]; 36 struct sway_container *child = parent->children->items[i];
102 if (child->width <= 0) { 37 if (child->pending.swayc_width <= 0) {
103 if (num_children > 1) { 38 if (num_children > 1) {
104 child->width = parent->width / (num_children - 1); 39 child->pending.swayc_width =
40 parent->pending.swayc_width / (num_children - 1);
105 } else { 41 } else {
106 child->width = parent->width; 42 child->pending.swayc_width = parent->pending.swayc_width;
107 } 43 }
108 } 44 }
109 total_width += child->width; 45 total_width += child->pending.swayc_width;
110 } 46 }
111 double scale = parent->width / total_width; 47 double scale = parent->pending.swayc_width / total_width;
112 48
113 // Resize windows 49 // Resize windows
114 wlr_log(L_DEBUG, "Arranging %p horizontally", parent); 50 wlr_log(L_DEBUG, "Arranging %p horizontally", parent);
115 double child_x = parent->x; 51 double child_x = parent->pending.swayc_x;
116 struct sway_container *child;
117 for (size_t i = 0; i < num_children; ++i) { 52 for (size_t i = 0; i < num_children; ++i) {
118 child = parent->children->items[i]; 53 struct sway_container *child = parent->children->items[i];
119 wlr_log(L_DEBUG, 54 wlr_log(L_DEBUG,
120 "Calculating arrangement for %p:%d (will scale %f by %f)", 55 "Calculating arrangement for %p:%d (will scale %f by %f)",
121 child, child->type, child->width, scale); 56 child, child->type, child->pending.swayc_width, scale);
122 child->x = child_x; 57 child->pending.swayc_x = child_x;
123 child->y = parent->y + parent_offset; 58 child->pending.swayc_y = parent->pending.swayc_y + parent_offset;
124 child->width = floor(child->width * scale); 59 child->pending.swayc_width = floor(child->pending.swayc_width * scale);
125 child->height = parent_height; 60 child->pending.swayc_height = parent_height;
126 child_x += child->width; 61 child_x += child->pending.swayc_width;
62
63 // Make last child use remaining width of parent
64 if (i == num_children - 1) {
65 child->pending.swayc_width = parent->pending.swayc_x +
66 parent->pending.swayc_width - child->pending.swayc_x;
67 }
127 } 68 }
128 // Make last child use remaining width of parent
129 child->width = parent->x + parent->width - child->x;
130} 69}
131 70
132static void apply_vert_layout(struct sway_container *parent) { 71static void apply_vert_layout(struct sway_container *parent) {
@@ -135,46 +74,51 @@ static void apply_vert_layout(struct sway_container *parent) {
135 return; 74 return;
136 } 75 }
137 size_t parent_offset = 0; 76 size_t parent_offset = 0;
138 if (parent->parent->layout == L_TABBED) { 77 if (parent->parent->pending.layout == L_TABBED) {
139 parent_offset = container_titlebar_height(); 78 parent_offset = container_titlebar_height();
140 } else if (parent->parent->layout == L_STACKED) { 79 } else if (parent->parent->pending.layout == L_STACKED) {
141 parent_offset = 80 parent_offset =
142 container_titlebar_height() * parent->parent->children->length; 81 container_titlebar_height() * parent->parent->children->length;
143 } 82 }
144 size_t parent_height = parent->height - parent_offset; 83 size_t parent_height = parent->pending.swayc_height - parent_offset;
145 84
146 // Calculate total height of children 85 // Calculate total height of children
147 double total_height = 0; 86 double total_height = 0;
148 for (size_t i = 0; i < num_children; ++i) { 87 for (size_t i = 0; i < num_children; ++i) {
149 struct sway_container *child = parent->children->items[i]; 88 struct sway_container *child = parent->children->items[i];
150 if (child->height <= 0) { 89 if (child->pending.swayc_height <= 0) {
151 if (num_children > 1) { 90 if (num_children > 1) {
152 child->height = parent_height / (num_children - 1); 91 child->pending.swayc_height =
92 parent_height / (num_children - 1);
153 } else { 93 } else {
154 child->height = parent_height; 94 child->pending.swayc_height = parent_height;
155 } 95 }
156 } 96 }
157 total_height += child->height; 97 total_height += child->pending.swayc_height;
158 } 98 }
159 double scale = parent_height / total_height; 99 double scale = parent_height / total_height;
160 100
161 // Resize 101 // Resize
162 wlr_log(L_DEBUG, "Arranging %p vertically", parent); 102 wlr_log(L_DEBUG, "Arranging %p vertically", parent);
163 double child_y = parent->y + parent_offset; 103 double child_y = parent->pending.swayc_y + parent_offset;
164 struct sway_container *child;
165 for (size_t i = 0; i < num_children; ++i) { 104 for (size_t i = 0; i < num_children; ++i) {
166 child = parent->children->items[i]; 105 struct sway_container *child = parent->children->items[i];
167 wlr_log(L_DEBUG, 106 wlr_log(L_DEBUG,
168 "Calculating arrangement for %p:%d (will scale %f by %f)", 107 "Calculating arrangement for %p:%d (will scale %f by %f)",
169 child, child->type, child->height, scale); 108 child, child->type, child->pending.swayc_height, scale);
170 child->x = parent->x; 109 child->pending.swayc_x = parent->pending.swayc_x;
171 child->y = child_y; 110 child->pending.swayc_y = child_y;
172 child->width = parent->width; 111 child->pending.swayc_width = parent->pending.swayc_width;
173 child->height = floor(child->height * scale); 112 child->pending.swayc_height =
174 child_y += child->height; 113 floor(child->pending.swayc_height * scale);
114 child_y += child->pending.swayc_height;
115
116 // Make last child use remaining height of parent
117 if (i == num_children - 1) {
118 child->pending.swayc_height = parent->pending.swayc_y +
119 parent_offset + parent_height - child->pending.swayc_y;
120 }
175 } 121 }
176 // Make last child use remaining height of parent
177 child->height = parent->y + parent_offset + parent_height - child->y;
178} 122}
179 123
180static void apply_tabbed_or_stacked_layout(struct sway_container *parent) { 124static void apply_tabbed_or_stacked_layout(struct sway_container *parent) {
@@ -182,46 +126,33 @@ static void apply_tabbed_or_stacked_layout(struct sway_container *parent) {
182 return; 126 return;
183 } 127 }
184 size_t parent_offset = 0; 128 size_t parent_offset = 0;
185 if (parent->parent->layout == L_TABBED) { 129 if (parent->parent->pending.layout == L_TABBED) {
186 parent_offset = container_titlebar_height(); 130 parent_offset = container_titlebar_height();
187 } else if (parent->parent->layout == L_STACKED) { 131 } else if (parent->parent->pending.layout == L_STACKED) {
188 parent_offset = 132 parent_offset =
189 container_titlebar_height() * parent->parent->children->length; 133 container_titlebar_height() * parent->parent->children->length;
190 } 134 }
191 size_t parent_height = parent->height - parent_offset; 135 size_t parent_height = parent->pending.swayc_height - parent_offset;
192 for (int i = 0; i < parent->children->length; ++i) { 136 for (int i = 0; i < parent->children->length; ++i) {
193 struct sway_container *child = parent->children->items[i]; 137 struct sway_container *child = parent->children->items[i];
194 child->x = parent->x; 138 child->pending.swayc_x = parent->pending.swayc_x;
195 child->y = parent->y + parent_offset; 139 child->pending.swayc_y = parent->pending.swayc_y + parent_offset;
196 child->width = parent->width; 140 child->pending.swayc_width = parent->pending.swayc_width;
197 child->height = parent_height; 141 child->pending.swayc_height = parent_height;
198 } 142 }
199} 143}
200 144
201void arrange_children_of(struct sway_container *parent) { 145static void _arrange_children_of(struct sway_container *parent,
146 struct sway_transaction *transaction) {
202 if (config->reloading) { 147 if (config->reloading) {
203 return; 148 return;
204 } 149 }
205 if (!sway_assert(parent->type == C_WORKSPACE || parent->type == C_CONTAINER,
206 "container is a %s", container_type_to_str(parent->type))) {
207 return;
208 }
209
210 struct sway_container *workspace = parent;
211 if (workspace->type != C_WORKSPACE) {
212 workspace = container_parent(workspace, C_WORKSPACE);
213 }
214 if (workspace->sway_workspace->fullscreen) {
215 // Just arrange the fullscreen view and jump out
216 view_autoconfigure(workspace->sway_workspace->fullscreen);
217 return;
218 }
219
220 wlr_log(L_DEBUG, "Arranging layout for %p %s %fx%f+%f,%f", parent, 150 wlr_log(L_DEBUG, "Arranging layout for %p %s %fx%f+%f,%f", parent,
221 parent->name, parent->width, parent->height, parent->x, parent->y); 151 parent->name, parent->pending.swayc_width, parent->pending.swayc_height,
152 parent->pending.swayc_x, parent->pending.swayc_y);
222 153
223 // Calculate x, y, width and height of children 154 // Calculate x, y, width and height of children
224 switch (parent->layout) { 155 switch (parent->pending.layout) {
225 case L_HORIZ: 156 case L_HORIZ:
226 apply_horiz_layout(parent); 157 apply_horiz_layout(parent);
227 break; 158 break;
@@ -232,33 +163,135 @@ void arrange_children_of(struct sway_container *parent) {
232 case L_STACKED: 163 case L_STACKED:
233 apply_tabbed_or_stacked_layout(parent); 164 apply_tabbed_or_stacked_layout(parent);
234 break; 165 break;
235 default: 166 case L_NONE:
236 wlr_log(L_DEBUG, "TODO: arrange layout type %d", parent->layout);
237 apply_horiz_layout(parent); 167 apply_horiz_layout(parent);
238 break; 168 break;
169 case L_FLOATING:
170 sway_assert(false, "Didn't expect to see floating here");
239 } 171 }
240 172
241 // Apply x, y, width and height to children and recurse if needed 173 // Recurse into child containers
242 for (int i = 0; i < parent->children->length; ++i) { 174 for (int i = 0; i < parent->children->length; ++i) {
243 struct sway_container *child = parent->children->items[i]; 175 struct sway_container *child = parent->children->items[i];
244 if (child->type == C_VIEW) { 176 if (child->type == C_VIEW) {
245 view_autoconfigure(child->sway_view); 177 view_autoconfigure(child->sway_view);
246 } else { 178 } else {
247 arrange_children_of(child); 179 _arrange_children_of(child, transaction);
248 } 180 }
181 transaction_add_container(transaction, child);
249 } 182 }
183}
250 184
251 // If container is a workspace, process floating containers too 185static void _arrange_workspace(struct sway_container *workspace,
252 if (parent->type == C_WORKSPACE) { 186 struct sway_transaction *transaction) {
253 struct sway_workspace *ws = workspace->sway_workspace; 187 if (config->reloading) {
254 for (int i = 0; i < ws->floating->children->length; ++i) { 188 return;
255 struct sway_container *child = ws->floating->children->items[i]; 189 }
256 if (child->type != C_VIEW) { 190 struct sway_container *output = workspace->parent;
257 arrange_children_of(child); 191 struct wlr_box *area = &output->sway_output->usable_area;
258 } 192 wlr_log(L_DEBUG, "Usable area for ws: %dx%d@%d,%d",
259 } 193 area->width, area->height, area->x, area->y);
194 workspace->pending.swayc_width = area->width;
195 workspace->pending.swayc_height = area->height;
196 workspace->pending.swayc_x = output->x + area->x;
197 workspace->pending.swayc_y = output->y + area->y;
198 transaction_add_container(transaction, workspace);
199 wlr_log(L_DEBUG, "Arranging workspace '%s' at %f, %f", workspace->name,
200 workspace->pending.swayc_x, workspace->pending.swayc_y);
201 _arrange_children_of(workspace, transaction);
202}
203
204static void _arrange_output(struct sway_container *output,
205 struct sway_transaction *transaction) {
206 if (config->reloading) {
207 return;
208 }
209 const struct wlr_box *output_box = wlr_output_layout_get_box(
210 root_container.sway_root->output_layout,
211 output->sway_output->wlr_output);
212 output->x = output_box->x;
213 output->y = output_box->y;
214 output->width = output_box->width;
215 output->height = output_box->height;
216 output->pending.swayc_x = output_box->x;
217 output->pending.swayc_y = output_box->y;
218 output->pending.swayc_width = output_box->width;
219 output->pending.swayc_height = output_box->height;
220 transaction_add_container(transaction, output);
221 wlr_log(L_DEBUG, "Arranging output '%s' at %f,%f",
222 output->name, output->pending.swayc_x, output->pending.swayc_y);
223 for (int i = 0; i < output->children->length; ++i) {
224 struct sway_container *workspace = output->children->items[i];
225 _arrange_workspace(workspace, transaction);
226 }
227}
228
229static void _arrange_root(struct sway_transaction *transaction) {
230 if (config->reloading) {
231 return;
260 } 232 }
233 struct wlr_output_layout *output_layout =
234 root_container.sway_root->output_layout;
235 const struct wlr_box *layout_box =
236 wlr_output_layout_get_box(output_layout, NULL);
237 root_container.x = layout_box->x;
238 root_container.y = layout_box->y;
239 root_container.width = layout_box->width;
240 root_container.height = layout_box->height;
241 root_container.pending.swayc_x = layout_box->x;
242 root_container.pending.swayc_y = layout_box->y;
243 root_container.pending.swayc_width = layout_box->width;
244 root_container.pending.swayc_height = layout_box->height;
245 transaction_add_container(transaction, &root_container);
246 for (int i = 0; i < root_container.children->length; ++i) {
247 struct sway_container *output = root_container.children->items[i];
248 _arrange_output(output, transaction);
249 }
250}
251
252void arrange_windows(struct sway_container *container,
253 struct sway_transaction *transaction) {
254 switch (container->type) {
255 case C_ROOT:
256 _arrange_root(transaction);
257 break;
258 case C_OUTPUT:
259 _arrange_output(container, transaction);
260 break;
261 case C_WORKSPACE:
262 _arrange_workspace(container, transaction);
263 break;
264 case C_CONTAINER:
265 _arrange_children_of(container, transaction);
266 transaction_add_container(transaction, container);
267 break;
268 case C_VIEW:
269 break;
270 case C_TYPES:
271 break;
272 }
273 transaction_add_damage(transaction, container_get_box(container));
274}
275
276void arrange_and_commit(struct sway_container *container) {
277 struct sway_transaction *transaction = transaction_create();
278 arrange_windows(container, transaction);
279 transaction_commit(transaction);
280}
281
282// These functions are only temporary
283void arrange_root() {
284 arrange_and_commit(&root_container);
285}
286
287void arrange_output(struct sway_container *container) {
288 arrange_and_commit(container);
289}
290
291void arrange_workspace(struct sway_container *container) {
292 arrange_and_commit(container);
293}
261 294
262 container_damage_whole(parent); 295void arrange_children_of(struct sway_container *container) {
263 update_debug_tree(); 296 arrange_and_commit(container);
264} 297}
diff --git a/sway/tree/container.c b/sway/tree/container.c
index cd2c083c..e6956f5c 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -116,6 +116,7 @@ struct sway_container *container_create(enum sway_container_type type) {
116 116
117 if (type != C_VIEW) { 117 if (type != C_VIEW) {
118 c->children = create_list(); 118 c->children = create_list();
119 //c->pending.children = create_list();
119 } 120 }
120 121
121 wl_signal_init(&c->events.destroy); 122 wl_signal_init(&c->events.destroy);
@@ -162,6 +163,7 @@ static void _container_destroy(struct sway_container *cont) {
162 wlr_texture_destroy(cont->title_urgent); 163 wlr_texture_destroy(cont->title_urgent);
163 164
164 list_free(cont->children); 165 list_free(cont->children);
166 //list_free(cont->pending.children);
165 cont->children = NULL; 167 cont->children = NULL;
166 free(cont); 168 free(cont);
167} 169}
@@ -971,3 +973,12 @@ bool container_is_floating(struct sway_container *container) {
971 } 973 }
972 return container->parent == workspace->sway_workspace->floating; 974 return container->parent == workspace->sway_workspace->floating;
973} 975}
976
977struct wlr_box *container_get_box(struct sway_container *container) {
978 struct wlr_box *box = calloc(1, sizeof(struct wlr_box));
979 box->x = container->x;
980 box->y = container->y;
981 box->width = container->width;
982 box->height = container->height;
983 return box;
984}
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index 6d4cd088..3bba049a 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -915,10 +915,10 @@ void container_recursive_resize(struct sway_container *container,
915 bool layout_match = true; 915 bool layout_match = true;
916 wlr_log(L_DEBUG, "Resizing %p with amount: %f", container, amount); 916 wlr_log(L_DEBUG, "Resizing %p with amount: %f", container, amount);
917 if (edge == RESIZE_EDGE_LEFT || edge == RESIZE_EDGE_RIGHT) { 917 if (edge == RESIZE_EDGE_LEFT || edge == RESIZE_EDGE_RIGHT) {
918 container->width += amount; 918 container->pending.swayc_width += amount;
919 layout_match = container->layout == L_HORIZ; 919 layout_match = container->layout == L_HORIZ;
920 } else if (edge == RESIZE_EDGE_TOP || edge == RESIZE_EDGE_BOTTOM) { 920 } else if (edge == RESIZE_EDGE_TOP || edge == RESIZE_EDGE_BOTTOM) {
921 container->height += amount; 921 container->pending.swayc_height += amount;
922 layout_match = container->layout == L_VERT; 922 layout_match = container->layout == L_VERT;
923 } 923 }
924 if (container->children) { 924 if (container->children) {
diff --git a/sway/tree/view.c b/sway/tree/view.c
index c9c82405..40fe2740 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -25,6 +25,7 @@ void view_init(struct sway_view *view, enum sway_view_type type,
25 view->impl = impl; 25 view->impl = impl;
26 view->executed_criteria = create_list(); 26 view->executed_criteria = create_list();
27 view->marks = create_list(); 27 view->marks = create_list();
28 view->instructions = create_list();
28 wl_signal_init(&view->events.unmap); 29 wl_signal_init(&view->events.unmap);
29} 30}
30 31
@@ -37,6 +38,11 @@ void view_destroy(struct sway_view *view) {
37 view_unmap(view); 38 view_unmap(view);
38 } 39 }
39 40
41 if (!sway_assert(view->instructions->length == 0,
42 "Tried to destroy view with pending instructions")) {
43 return;
44 }
45
40 list_free(view->executed_criteria); 46 list_free(view->executed_criteria);
41 47
42 for (int i = 0; i < view->marks->length; ++i) { 48 for (int i = 0; i < view->marks->length; ++i) {
@@ -44,6 +50,8 @@ void view_destroy(struct sway_view *view) {
44 } 50 }
45 list_free(view->marks); 51 list_free(view->marks);
46 52
53 list_free(view->instructions);
54
47 wlr_texture_destroy(view->marks_focused); 55 wlr_texture_destroy(view->marks_focused);
48 wlr_texture_destroy(view->marks_focused_inactive); 56 wlr_texture_destroy(view->marks_focused_inactive);
49 wlr_texture_destroy(view->marks_unfocused); 57 wlr_texture_destroy(view->marks_unfocused);
@@ -119,11 +127,12 @@ const char *view_get_shell(struct sway_view *view) {
119 return "unknown"; 127 return "unknown";
120} 128}
121 129
122void view_configure(struct sway_view *view, double lx, double ly, int width, 130uint32_t view_configure(struct sway_view *view, double lx, double ly, int width,
123 int height) { 131 int height) {
124 if (view->impl->configure) { 132 if (view->impl->configure) {
125 view->impl->configure(view, lx, ly, width, height); 133 return view->impl->configure(view, lx, ly, width, height);
126 } 134 }
135 return 0;
127} 136}
128 137
129static void view_autoconfigure_floating(struct sway_view *view) { 138static void view_autoconfigure_floating(struct sway_view *view) {
@@ -178,21 +187,23 @@ void view_autoconfigure(struct sway_view *view) {
178 } 187 }
179 } 188 }
180 189
181 view->border_top = view->border_bottom = true; 190 struct sway_container_state *state = &view->swayc->pending;
182 view->border_left = view->border_right = true; 191
192 state->border_top = state->border_bottom = true;
193 state->border_left = state->border_right = true;
183 if (config->hide_edge_borders == E_BOTH 194 if (config->hide_edge_borders == E_BOTH
184 || config->hide_edge_borders == E_VERTICAL 195 || config->hide_edge_borders == E_VERTICAL
185 || (config->hide_edge_borders == E_SMART && !other_views)) { 196 || (config->hide_edge_borders == E_SMART && !other_views)) {
186 view->border_left = view->swayc->x != ws->x; 197 state->border_left = state->swayc_x != ws->x;
187 int right_x = view->swayc->x + view->swayc->width; 198 int right_x = state->swayc_x + state->swayc_width;
188 view->border_right = right_x != ws->x + ws->width; 199 state->border_right = right_x != ws->x + ws->width;
189 } 200 }
190 if (config->hide_edge_borders == E_BOTH 201 if (config->hide_edge_borders == E_BOTH
191 || config->hide_edge_borders == E_HORIZONTAL 202 || config->hide_edge_borders == E_HORIZONTAL
192 || (config->hide_edge_borders == E_SMART && !other_views)) { 203 || (config->hide_edge_borders == E_SMART && !other_views)) {
193 view->border_top = view->swayc->y != ws->y; 204 state->border_top = state->swayc_y != ws->y;
194 int bottom_y = view->swayc->y + view->swayc->height; 205 int bottom_y = state->swayc_y + state->swayc_height;
195 view->border_bottom = bottom_y != ws->y + ws->height; 206 state->border_bottom = bottom_y != ws->y + ws->height;
196 } 207 }
197 208
198 double x, y, width, height; 209 double x, y, width, height;
@@ -202,53 +213,54 @@ void view_autoconfigure(struct sway_view *view) {
202 // In a tabbed or stacked container, the swayc's y is the top of the title 213 // In a tabbed or stacked container, the swayc's y is the top of the title
203 // area. We have to offset the surface y by the height of the title bar, and 214 // area. We have to offset the surface y by the height of the title bar, and
204 // disable any top border because we'll always have the title bar. 215 // disable any top border because we'll always have the title bar.
205 if (view->swayc->parent->layout == L_TABBED) { 216 if (view->swayc->parent->pending.layout == L_TABBED) {
206 y_offset = container_titlebar_height(); 217 y_offset = container_titlebar_height();
207 view->border_top = false; 218 state->border_top = false;
208 } else if (view->swayc->parent->layout == L_STACKED) { 219 } else if (view->swayc->parent->pending.layout == L_STACKED) {
209 y_offset = container_titlebar_height() 220 y_offset = container_titlebar_height()
210 * view->swayc->parent->children->length; 221 * view->swayc->parent->children->length;
211 view->border_top = false; 222 view->border_top = false;
212 } 223 }
213 224
214 switch (view->border) { 225 switch (state->border) {
215 case B_NONE: 226 case B_NONE:
216 x = view->swayc->x; 227 x = state->swayc_x;
217 y = view->swayc->y + y_offset; 228 y = state->swayc_y + y_offset;
218 width = view->swayc->width; 229 width = state->swayc_width;
219 height = view->swayc->height - y_offset; 230 height = state->swayc_height - y_offset;
220 break; 231 break;
221 case B_PIXEL: 232 case B_PIXEL:
222 x = view->swayc->x + view->border_thickness * view->border_left; 233 x = state->swayc_x + state->border_thickness * state->border_left;
223 y = view->swayc->y + view->border_thickness * view->border_top + y_offset; 234 y = state->swayc_y + state->border_thickness * state->border_top + y_offset;
224 width = view->swayc->width 235 width = state->swayc_width
225 - view->border_thickness * view->border_left 236 - state->border_thickness * state->border_left
226 - view->border_thickness * view->border_right; 237 - state->border_thickness * state->border_right;
227 height = view->swayc->height - y_offset 238 height = state->swayc_height - y_offset
228 - view->border_thickness * view->border_top 239 - state->border_thickness * state->border_top
229 - view->border_thickness * view->border_bottom; 240 - state->border_thickness * state->border_bottom;
230 break; 241 break;
231 case B_NORMAL: 242 case B_NORMAL:
232 // Height is: 1px border + 3px pad + title height + 3px pad + 1px border 243 // Height is: 1px border + 3px pad + title height + 3px pad + 1px border
233 x = view->swayc->x + view->border_thickness * view->border_left; 244 x = state->swayc_x + state->border_thickness * state->border_left;
234 width = view->swayc->width 245 width = state->swayc_width
235 - view->border_thickness * view->border_left 246 - state->border_thickness * state->border_left
236 - view->border_thickness * view->border_right; 247 - state->border_thickness * state->border_right;
237 if (y_offset) { 248 if (y_offset) {
238 y = view->swayc->y + y_offset; 249 y = state->swayc_y + y_offset;
239 height = view->swayc->height - y_offset 250 height = state->swayc_height - y_offset
240 - view->border_thickness * view->border_bottom; 251 - state->border_thickness * state->border_bottom;
241 } else { 252 } else {
242 y = view->swayc->y + container_titlebar_height(); 253 y = state->swayc_y + container_titlebar_height();
243 height = view->swayc->height - container_titlebar_height() 254 height = state->swayc_height - container_titlebar_height()
244 - view->border_thickness * view->border_bottom; 255 - state->border_thickness * state->border_bottom;
245 } 256 }
246 break; 257 break;
247 } 258 }
248 259
249 view->x = x; 260 state->view_x = x;
250 view->y = y; 261 state->view_y = y;
251 view_configure(view, x, y, width, height); 262 state->view_width = width;
263 state->view_height = height;
252} 264}
253 265
254void view_set_activated(struct sway_view *view, bool activated) { 266void view_set_activated(struct sway_view *view, bool activated) {
@@ -307,8 +319,8 @@ void view_set_fullscreen_raw(struct sway_view *view, bool fullscreen) {
307 view_configure(view, view->saved_x, view->saved_y, 319 view_configure(view, view->saved_x, view->saved_y,
308 view->saved_width, view->saved_height); 320 view->saved_width, view->saved_height);
309 } else { 321 } else {
310 view->swayc->width = view->swayc->saved_width; 322 view->swayc->width = view->swayc->saved_width;
311 view->swayc->height = view->swayc->saved_height; 323 view->swayc->height = view->swayc->saved_height;
312 view_autoconfigure(view); 324 view_autoconfigure(view);
313 } 325 }
314 } 326 }
@@ -496,6 +508,8 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
496 view->swayc = cont; 508 view->swayc = cont;
497 view->border = config->border; 509 view->border = config->border;
498 view->border_thickness = config->border_thickness; 510 view->border_thickness = config->border_thickness;
511 view->swayc->pending.border = config->border;
512 view->swayc->pending.border_thickness = config->border_thickness;
499 513
500 view_init_subsurfaces(view, wlr_surface); 514 view_init_subsurfaces(view, wlr_surface);
501 wl_signal_add(&wlr_surface->events.new_subsurface, 515 wl_signal_add(&wlr_surface->events.new_subsurface,
@@ -963,7 +977,7 @@ bool view_is_visible(struct sway_view *view) {
963 } 977 }
964 // Check the workspace is visible 978 // Check the workspace is visible
965 if (!is_sticky) { 979 if (!is_sticky) {
966 return workspace_is_visible(workspace); 980 return workspace_is_visible(workspace);
967 } 981 }
968 return true; 982 return true;
969} 983}
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index 9ba210fd..ad581a96 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -60,6 +60,12 @@ struct sway_container *workspace_create(struct sway_container *output,
60 workspace->prev_layout = L_NONE; 60 workspace->prev_layout = L_NONE;
61 workspace->layout = container_get_default_layout(output); 61 workspace->layout = container_get_default_layout(output);
62 62
63 workspace->pending.swayc_x = workspace->x;
64 workspace->pending.swayc_y = workspace->y;
65 workspace->pending.swayc_width = workspace->width;
66 workspace->pending.swayc_height = workspace->height;
67 workspace->pending.layout = workspace->layout;
68
63 struct sway_workspace *swayws = calloc(1, sizeof(struct sway_workspace)); 69 struct sway_workspace *swayws = calloc(1, sizeof(struct sway_workspace));
64 if (!swayws) { 70 if (!swayws) {
65 return NULL; 71 return NULL;