aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/transaction.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/desktop/transaction.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/desktop/transaction.c')
-rw-r--r--sway/desktop/transaction.c374
1 files changed, 235 insertions, 139 deletions
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c
index 145c5f92..b4eec933 100644
--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -12,6 +12,7 @@
12#include "sway/desktop/transaction.h" 12#include "sway/desktop/transaction.h"
13#include "sway/output.h" 13#include "sway/output.h"
14#include "sway/tree/container.h" 14#include "sway/tree/container.h"
15#include "sway/tree/node.h"
15#include "sway/tree/view.h" 16#include "sway/tree/view.h"
16#include "sway/tree/workspace.h" 17#include "sway/tree/workspace.h"
17#include "list.h" 18#include "list.h"
@@ -27,8 +28,12 @@ struct sway_transaction {
27 28
28struct sway_transaction_instruction { 29struct sway_transaction_instruction {
29 struct sway_transaction *transaction; 30 struct sway_transaction *transaction;
30 struct sway_container *container; 31 struct sway_node *node;
31 struct sway_container_state state; 32 union {
33 struct sway_output_state *output_state;
34 struct sway_workspace_state *workspace_state;
35 struct sway_container_state *container_state;
36 };
32 uint32_t serial; 37 uint32_t serial;
33}; 38};
34 39
@@ -47,26 +52,24 @@ static void transaction_destroy(struct sway_transaction *transaction) {
47 for (int i = 0; i < transaction->instructions->length; ++i) { 52 for (int i = 0; i < transaction->instructions->length; ++i) {
48 struct sway_transaction_instruction *instruction = 53 struct sway_transaction_instruction *instruction =
49 transaction->instructions->items[i]; 54 transaction->instructions->items[i];
50 struct sway_container *con = instruction->container; 55 struct sway_node *node = instruction->node;
51 con->ntxnrefs--; 56 node->ntxnrefs--;
52 if (con->instruction == instruction) { 57 if (node->instruction == instruction) {
53 con->instruction = NULL; 58 node->instruction = NULL;
54 } 59 }
55 if (con->destroying && con->ntxnrefs == 0) { 60 if (node->destroying && node->ntxnrefs == 0) {
56 switch (con->type) { 61 switch (node->type) {
57 case C_ROOT: 62 case N_ROOT:
63 sway_assert(false, "Never reached");
58 break; 64 break;
59 case C_OUTPUT: 65 case N_OUTPUT:
60 output_destroy(con); 66 output_destroy(node->sway_output);
61 break; 67 break;
62 case C_WORKSPACE: 68 case N_WORKSPACE:
63 workspace_destroy(con); 69 workspace_destroy(node->sway_workspace);
64 break; 70 break;
65 case C_CONTAINER: 71 case N_CONTAINER:
66 case C_VIEW: 72 container_destroy(node->sway_container);
67 container_destroy(con);
68 break;
69 case C_TYPES:
70 break; 73 break;
71 } 74 }
72 } 75 }
@@ -80,22 +83,79 @@ static void transaction_destroy(struct sway_transaction *transaction) {
80 free(transaction); 83 free(transaction);
81} 84}
82 85
83static void copy_pending_state(struct sway_container *container, 86static void copy_output_state(struct sway_output *output,
84 struct sway_container_state *state) { 87 struct sway_transaction_instruction *instruction) {
88 struct sway_output_state *state =
89 calloc(1, sizeof(struct sway_output_state));
90 if (!state) {
91 wlr_log(WLR_ERROR, "Could not allocate output state");
92 return;
93 }
94 instruction->output_state = state;
95
96 state->workspaces = create_list();
97 list_cat(state->workspaces, output->workspaces);
98
99 state->active_workspace = output_get_active_workspace(output);
100}
101
102static void copy_workspace_state(struct sway_workspace *ws,
103 struct sway_transaction_instruction *instruction) {
104 struct sway_workspace_state *state =
105 calloc(1, sizeof(struct sway_workspace_state));
106 if (!state) {
107 wlr_log(WLR_ERROR, "Could not allocate workspace state");
108 return;
109 }
110 instruction->workspace_state = state;
111
112 state->fullscreen = ws->fullscreen;
113 state->x = ws->x;
114 state->y = ws->y;
115 state->width = ws->width;
116 state->height = ws->height;
117 state->layout = ws->layout;
118
119 state->output = ws->output;
120 state->floating = create_list();
121 state->tiling = create_list();
122 list_cat(state->floating, ws->floating);
123 list_cat(state->tiling, ws->tiling);
124
125 struct sway_seat *seat = input_manager_current_seat(input_manager);
126 state->focused = seat_get_focus(seat) == &ws->node;
127
128 // Set focused_inactive_child to the direct tiling child
129 struct sway_container *focus = seat_get_focus_inactive_tiling(seat, ws);
130 if (focus) {
131 while (focus->parent) {
132 focus = focus->parent;
133 }
134 }
135 state->focused_inactive_child = focus;
136}
137
138static void copy_container_state(struct sway_container *container,
139 struct sway_transaction_instruction *instruction) {
140 struct sway_container_state *state =
141 calloc(1, sizeof(struct sway_container_state));
142 if (!state) {
143 wlr_log(WLR_ERROR, "Could not allocate container state");
144 return;
145 }
146 instruction->container_state = state;
147
85 state->layout = container->layout; 148 state->layout = container->layout;
86 state->swayc_x = container->x; 149 state->con_x = container->x;
87 state->swayc_y = container->y; 150 state->con_y = container->y;
88 state->swayc_width = container->width; 151 state->con_width = container->width;
89 state->swayc_height = container->height; 152 state->con_height = container->height;
90 state->is_fullscreen = container->is_fullscreen; 153 state->is_fullscreen = container->is_fullscreen;
91 state->has_gaps = container->has_gaps;
92 state->current_gaps = container->current_gaps;
93 state->gaps_inner = container->gaps_inner;
94 state->gaps_outer = container->gaps_outer;
95 state->parent = container->parent; 154 state->parent = container->parent;
155 state->workspace = container->workspace;
96 156
97 if (container->type == C_VIEW) { 157 if (container->view) {
98 struct sway_view *view = container->sway_view; 158 struct sway_view *view = container->view;
99 state->view_x = view->x; 159 state->view_x = view->x;
100 state->view_y = view->y; 160 state->view_y = view->y;
101 state->view_width = view->width; 161 state->view_width = view->width;
@@ -107,50 +167,111 @@ static void copy_pending_state(struct sway_container *container,
107 state->border_right = view->border_right; 167 state->border_right = view->border_right;
108 state->border_bottom = view->border_bottom; 168 state->border_bottom = view->border_bottom;
109 state->using_csd = view->using_csd; 169 state->using_csd = view->using_csd;
110 } else if (container->type == C_WORKSPACE) {
111 state->ws_fullscreen = container->sway_workspace->fullscreen;
112 state->ws_floating = create_list();
113 state->children = create_list();
114 list_cat(state->ws_floating, container->sway_workspace->floating);
115 list_cat(state->children, container->children);
116 } else { 170 } else {
117 state->children = create_list(); 171 state->children = create_list();
118 list_cat(state->children, container->children); 172 list_cat(state->children, container->children);
119 } 173 }
120 174
121 struct sway_seat *seat = input_manager_current_seat(input_manager); 175 struct sway_seat *seat = input_manager_current_seat(input_manager);
122 state->focused = seat_get_focus(seat) == container; 176 state->focused = seat_get_focus(seat) == &container->node;
123 177
124 if (container->type == C_WORKSPACE) { 178 if (!container->view) {
125 // Set focused_inactive_child to the direct tiling child 179 struct sway_node *focus = seat_get_active_child(seat, &container->node);
126 struct sway_container *focus = 180 state->focused_inactive_child = focus ? focus->sway_container : NULL;
127 seat_get_focus_inactive_tiling(seat, container);
128 if (focus && focus->type > C_WORKSPACE) {
129 while (focus->parent->type != C_WORKSPACE) {
130 focus = focus->parent;
131 }
132 }
133 state->focused_inactive_child = focus;
134 } else if (container->type != C_VIEW) {
135 state->focused_inactive_child =
136 seat_get_active_child(seat, container);
137 } 181 }
138} 182}
139 183
140static void transaction_add_container(struct sway_transaction *transaction, 184static void transaction_add_node(struct sway_transaction *transaction,
141 struct sway_container *container) { 185 struct sway_node *node) {
142 struct sway_transaction_instruction *instruction = 186 struct sway_transaction_instruction *instruction =
143 calloc(1, sizeof(struct sway_transaction_instruction)); 187 calloc(1, sizeof(struct sway_transaction_instruction));
144 if (!sway_assert(instruction, "Unable to allocate instruction")) { 188 if (!sway_assert(instruction, "Unable to allocate instruction")) {
145 return; 189 return;
146 } 190 }
147 instruction->transaction = transaction; 191 instruction->transaction = transaction;
148 instruction->container = container; 192 instruction->node = node;
149 193
150 copy_pending_state(container, &instruction->state); 194 switch (node->type) {
195 case N_ROOT:
196 break;
197 case N_OUTPUT:
198 copy_output_state(node->sway_output, instruction);
199 break;
200 case N_WORKSPACE:
201 copy_workspace_state(node->sway_workspace, instruction);
202 break;
203 case N_CONTAINER:
204 copy_container_state(node->sway_container, instruction);
205 break;
206 }
151 207
152 list_add(transaction->instructions, instruction); 208 list_add(transaction->instructions, instruction);
153 container->ntxnrefs++; 209 node->ntxnrefs++;
210}
211
212static void apply_output_state(struct sway_output *output,
213 struct sway_output_state *state) {
214 output_damage_whole(output);
215 list_free(output->current.workspaces);
216 memcpy(&output->current, state, sizeof(struct sway_output_state));
217 output_damage_whole(output);
218}
219
220static void apply_workspace_state(struct sway_workspace *ws,
221 struct sway_workspace_state *state) {
222 output_damage_whole(ws->current.output);
223 list_free(ws->current.floating);
224 list_free(ws->current.tiling);
225 memcpy(&ws->current, state, sizeof(struct sway_workspace_state));
226 output_damage_whole(ws->current.output);
227}
228
229static void apply_container_state(struct sway_container *container,
230 struct sway_container_state *state) {
231 struct sway_view *view = container->view;
232 // Damage the old location
233 desktop_damage_whole_container(container);
234 if (view && view->saved_buffer) {
235 struct wlr_box box = {
236 .x = container->current.view_x - view->saved_geometry.x,
237 .y = container->current.view_y - view->saved_geometry.y,
238 .width = view->saved_buffer_width,
239 .height = view->saved_buffer_height,
240 };
241 desktop_damage_box(&box);
242 }
243
244 // There are separate children lists for each instruction state, the
245 // container's current state and the container's pending state
246 // (ie. con->children). The list itself needs to be freed here.
247 // Any child containers which are being deleted will be cleaned up in
248 // transaction_destroy().
249 list_free(container->current.children);
250
251 memcpy(&container->current, state, sizeof(struct sway_container_state));
252
253 if (view && view->saved_buffer) {
254 if (!container->node.destroying || container->node.ntxnrefs == 1) {
255 view_remove_saved_buffer(view);
256 }
257 }
258
259 // Damage the new location
260 desktop_damage_whole_container(container);
261 if (view && view->surface) {
262 struct wlr_surface *surface = view->surface;
263 struct wlr_box box = {
264 .x = container->current.view_x - view->geometry.x,
265 .y = container->current.view_y - view->geometry.y,
266 .width = surface->current.width,
267 .height = surface->current.height,
268 };
269 desktop_damage_box(&box);
270 }
271
272 if (!container->node.destroying) {
273 container_discover_outputs(container);
274 }
154} 275}
155 276
156/** 277/**
@@ -168,67 +289,36 @@ static void transaction_apply(struct sway_transaction *transaction) {
168 "(%.1f frames if 60Hz)", transaction, ms, ms / (1000.0f / 60)); 289 "(%.1f frames if 60Hz)", transaction, ms, ms / (1000.0f / 60));
169 } 290 }
170 291
171 // Apply the instruction state to the container's current state 292 // Apply the instruction state to the node's current state
172 for (int i = 0; i < transaction->instructions->length; ++i) { 293 for (int i = 0; i < transaction->instructions->length; ++i) {
173 struct sway_transaction_instruction *instruction = 294 struct sway_transaction_instruction *instruction =
174 transaction->instructions->items[i]; 295 transaction->instructions->items[i];
175 struct sway_container *container = instruction->container; 296 struct sway_node *node = instruction->node;
176
177 // Damage the old location
178 desktop_damage_whole_container(container);
179 if (container->type == C_VIEW && container->sway_view->saved_buffer) {
180 struct sway_view *view = container->sway_view;
181 struct wlr_box box = {
182 .x = container->current.view_x - view->saved_geometry.x,
183 .y = container->current.view_y - view->saved_geometry.y,
184 .width = view->saved_buffer_width,
185 .height = view->saved_buffer_height,
186 };
187 desktop_damage_box(&box);
188 }
189
190 // There are separate children lists for each instruction state, the
191 // container's current state and the container's pending state
192 // (ie. con->children). The list itself needs to be freed here.
193 // Any child containers which are being deleted will be cleaned up in
194 // transaction_destroy().
195 list_free(container->current.children);
196 list_free(container->current.ws_floating);
197
198 memcpy(&container->current, &instruction->state,
199 sizeof(struct sway_container_state));
200
201 if (container->type == C_VIEW && container->sway_view->saved_buffer) {
202 if (!container->destroying || container->ntxnrefs == 1) {
203 view_remove_saved_buffer(container->sway_view);
204 }
205 }
206 297
207 // Damage the new location 298 switch (node->type) {
208 desktop_damage_whole_container(container); 299 case N_ROOT:
209 if (container->type == C_VIEW && container->sway_view->surface) { 300 break;
210 struct sway_view *view = container->sway_view; 301 case N_OUTPUT:
211 struct wlr_surface *surface = view->surface; 302 apply_output_state(node->sway_output, instruction->output_state);
212 struct wlr_box box = { 303 break;
213 .x = container->current.view_x - view->geometry.x, 304 case N_WORKSPACE:
214 .y = container->current.view_y - view->geometry.y, 305 apply_workspace_state(node->sway_workspace,
215 .width = surface->current.width, 306 instruction->workspace_state);
216 .height = surface->current.height, 307 break;
217 }; 308 case N_CONTAINER:
218 desktop_damage_box(&box); 309 apply_container_state(node->sway_container,
310 instruction->container_state);
311 break;
219 } 312 }
220 313
221 container->instruction = NULL; 314 node->instruction = NULL;
222 if (container->type == C_CONTAINER || container->type == C_VIEW) {
223 container_discover_outputs(container);
224 }
225 } 315 }
226} 316}
227 317
228static void transaction_commit(struct sway_transaction *transaction); 318static void transaction_commit(struct sway_transaction *transaction);
229 319
230// Return true if both transactions operate on the same containers 320// Return true if both transactions operate on the same nodes
231static bool transaction_same_containers(struct sway_transaction *a, 321static bool transaction_same_nodes(struct sway_transaction *a,
232 struct sway_transaction *b) { 322 struct sway_transaction *b) {
233 if (a->instructions->length != b->instructions->length) { 323 if (a->instructions->length != b->instructions->length) {
234 return false; 324 return false;
@@ -236,7 +326,7 @@ static bool transaction_same_containers(struct sway_transaction *a,
236 for (int i = 0; i < a->instructions->length; ++i) { 326 for (int i = 0; i < a->instructions->length; ++i) {
237 struct sway_transaction_instruction *a_inst = a->instructions->items[i]; 327 struct sway_transaction_instruction *a_inst = a->instructions->items[i];
238 struct sway_transaction_instruction *b_inst = b->instructions->items[i]; 328 struct sway_transaction_instruction *b_inst = b->instructions->items[i];
239 if (a_inst->container != b_inst->container) { 329 if (a_inst->node != b_inst->node) {
240 return false; 330 return false;
241 } 331 }
242 } 332 }
@@ -267,7 +357,7 @@ static void transaction_progress_queue() {
267 while (server.transactions->length >= 2) { 357 while (server.transactions->length >= 2) {
268 struct sway_transaction *a = server.transactions->items[0]; 358 struct sway_transaction *a = server.transactions->items[0];
269 struct sway_transaction *b = server.transactions->items[1]; 359 struct sway_transaction *b = server.transactions->items[1];
270 if (transaction_same_containers(a, b)) { 360 if (transaction_same_nodes(a, b)) {
271 list_del(server.transactions, 0); 361 list_del(server.transactions, 0);
272 transaction_destroy(a); 362 transaction_destroy(a);
273 } else { 363 } else {
@@ -289,16 +379,18 @@ static int handle_timeout(void *data) {
289 return 0; 379 return 0;
290} 380}
291 381
292static bool should_configure(struct sway_container *con, 382static bool should_configure(struct sway_node *node,
293 struct sway_transaction_instruction *instruction) { 383 struct sway_transaction_instruction *instruction) {
294 if (con->type != C_VIEW) { 384 if (!node_is_view(node)) {
295 return false; 385 return false;
296 } 386 }
297 if (con->destroying) { 387 if (node->destroying) {
298 return false; 388 return false;
299 } 389 }
300 if (con->current.view_width == instruction->state.view_width && 390 struct sway_container_state *cstate = &node->sway_container->current;
301 con->current.view_height == instruction->state.view_height) { 391 struct sway_container_state *istate = instruction->container_state;
392 if (cstate->view_width == istate->view_width &&
393 cstate->view_height == istate->view_height) {
302 return false; 394 return false;
303 } 395 }
304 return true; 396 return true;
@@ -311,13 +403,13 @@ static void transaction_commit(struct sway_transaction *transaction) {
311 for (int i = 0; i < transaction->instructions->length; ++i) { 403 for (int i = 0; i < transaction->instructions->length; ++i) {
312 struct sway_transaction_instruction *instruction = 404 struct sway_transaction_instruction *instruction =
313 transaction->instructions->items[i]; 405 transaction->instructions->items[i];
314 struct sway_container *con = instruction->container; 406 struct sway_node *node = instruction->node;
315 if (should_configure(con, instruction)) { 407 if (should_configure(node, instruction)) {
316 instruction->serial = view_configure(con->sway_view, 408 instruction->serial = view_configure(node->sway_container->view,
317 instruction->state.view_x, 409 instruction->container_state->view_x,
318 instruction->state.view_y, 410 instruction->container_state->view_y,
319 instruction->state.view_width, 411 instruction->container_state->view_width,
320 instruction->state.view_height); 412 instruction->container_state->view_height);
321 ++transaction->num_waiting; 413 ++transaction->num_waiting;
322 414
323 // From here on we are rendering a saved buffer of the view, which 415 // From here on we are rendering a saved buffer of the view, which
@@ -325,14 +417,16 @@ static void transaction_commit(struct sway_transaction *transaction) {
325 // as soon as possible. Additionally, this is required if a view is 417 // as soon as possible. Additionally, this is required if a view is
326 // mapping and its default geometry doesn't intersect an output. 418 // mapping and its default geometry doesn't intersect an output.
327 struct timespec when; 419 struct timespec when;
328 wlr_surface_send_frame_done(con->sway_view->surface, &when); 420 wlr_surface_send_frame_done(
421 node->sway_container->view->surface, &when);
329 } 422 }
330 if (con->type == C_VIEW && !con->sway_view->saved_buffer) { 423 if (node_is_view(node) && !node->sway_container->view->saved_buffer) {
331 view_save_buffer(con->sway_view); 424 view_save_buffer(node->sway_container->view);
332 memcpy(&con->sway_view->saved_geometry, &con->sway_view->geometry, 425 memcpy(&node->sway_container->view->saved_geometry,
426 &node->sway_container->view->geometry,
333 sizeof(struct wlr_box)); 427 sizeof(struct wlr_box));
334 } 428 }
335 con->instruction = instruction; 429 node->instruction = instruction;
336 } 430 }
337 transaction->num_configures = transaction->num_waiting; 431 transaction->num_configures = transaction->num_waiting;
338 if (debug.txn_timings) { 432 if (debug.txn_timings) {
@@ -381,7 +475,7 @@ static void set_instruction_ready(
381 transaction, 475 transaction,
382 transaction->num_configures - transaction->num_waiting + 1, 476 transaction->num_configures - transaction->num_waiting + 1,
383 transaction->num_configures, ms, 477 transaction->num_configures, ms,
384 instruction->container->name); 478 instruction->node->sway_container->title);
385 } 479 }
386 480
387 // If the transaction has timed out then its num_waiting will be 0 already. 481 // If the transaction has timed out then its num_waiting will be 0 already.
@@ -390,41 +484,43 @@ static void set_instruction_ready(
390 wl_event_source_timer_update(transaction->timer, 0); 484 wl_event_source_timer_update(transaction->timer, 0);
391 } 485 }
392 486
393 instruction->container->instruction = NULL; 487 instruction->node->instruction = NULL;
394 transaction_progress_queue(); 488 transaction_progress_queue();
395} 489}
396 490
397void transaction_notify_view_ready_by_serial(struct sway_view *view, 491void transaction_notify_view_ready_by_serial(struct sway_view *view,
398 uint32_t serial) { 492 uint32_t serial) {
399 struct sway_transaction_instruction *instruction = view->swayc->instruction; 493 struct sway_transaction_instruction *instruction =
400 if (view->swayc->instruction->serial == serial) { 494 view->container->node.instruction;
495 if (instruction->serial == serial) {
401 set_instruction_ready(instruction); 496 set_instruction_ready(instruction);
402 } 497 }
403} 498}
404 499
405void transaction_notify_view_ready_by_size(struct sway_view *view, 500void transaction_notify_view_ready_by_size(struct sway_view *view,
406 int width, int height) { 501 int width, int height) {
407 struct sway_transaction_instruction *instruction = view->swayc->instruction; 502 struct sway_transaction_instruction *instruction =
408 if (instruction->state.view_width == width && 503 view->container->node.instruction;
409 instruction->state.view_height == height) { 504 if (instruction->container_state->view_width == width &&
505 instruction->container_state->view_height == height) {
410 set_instruction_ready(instruction); 506 set_instruction_ready(instruction);
411 } 507 }
412} 508}
413 509
414void transaction_commit_dirty(void) { 510void transaction_commit_dirty(void) {
415 if (!server.dirty_containers->length) { 511 if (!server.dirty_nodes->length) {
416 return; 512 return;
417 } 513 }
418 struct sway_transaction *transaction = transaction_create(); 514 struct sway_transaction *transaction = transaction_create();
419 if (!transaction) { 515 if (!transaction) {
420 return; 516 return;
421 } 517 }
422 for (int i = 0; i < server.dirty_containers->length; ++i) { 518 for (int i = 0; i < server.dirty_nodes->length; ++i) {
423 struct sway_container *container = server.dirty_containers->items[i]; 519 struct sway_node *node = server.dirty_nodes->items[i];
424 transaction_add_container(transaction, container); 520 transaction_add_node(transaction, node);
425 container->dirty = false; 521 node->dirty = false;
426 } 522 }
427 server.dirty_containers->length = 0; 523 server.dirty_nodes->length = 0;
428 524
429 list_add(server.transactions, transaction); 525 list_add(server.transactions, transaction);
430 526