aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/desktop/transaction.c')
-rw-r--r--sway/desktop/transaction.c500
1 files changed, 441 insertions, 59 deletions
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c
index f5a3a053..042141ab 100644
--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -1,11 +1,10 @@
1#define _POSIX_C_SOURCE 200809L
2#include <stdbool.h> 1#include <stdbool.h>
3#include <stdlib.h> 2#include <stdlib.h>
4#include <string.h> 3#include <string.h>
5#include <time.h> 4#include <time.h>
6#include <wlr/types/wlr_buffer.h> 5#include <wlr/types/wlr_buffer.h>
7#include "sway/config.h" 6#include "sway/config.h"
8#include "sway/desktop.h" 7#include "sway/scene_descriptor.h"
9#include "sway/desktop/idle_inhibit_v1.h" 8#include "sway/desktop/idle_inhibit_v1.h"
10#include "sway/desktop/transaction.h" 9#include "sway/desktop/transaction.h"
11#include "sway/input/cursor.h" 10#include "sway/input/cursor.h"
@@ -214,39 +213,20 @@ static void transaction_add_node(struct sway_transaction *transaction,
214 213
215static void apply_output_state(struct sway_output *output, 214static void apply_output_state(struct sway_output *output,
216 struct sway_output_state *state) { 215 struct sway_output_state *state) {
217 output_damage_whole(output);
218 list_free(output->current.workspaces); 216 list_free(output->current.workspaces);
219 memcpy(&output->current, state, sizeof(struct sway_output_state)); 217 memcpy(&output->current, state, sizeof(struct sway_output_state));
220 output_damage_whole(output);
221} 218}
222 219
223static void apply_workspace_state(struct sway_workspace *ws, 220static void apply_workspace_state(struct sway_workspace *ws,
224 struct sway_workspace_state *state) { 221 struct sway_workspace_state *state) {
225 output_damage_whole(ws->current.output);
226 list_free(ws->current.floating); 222 list_free(ws->current.floating);
227 list_free(ws->current.tiling); 223 list_free(ws->current.tiling);
228 memcpy(&ws->current, state, sizeof(struct sway_workspace_state)); 224 memcpy(&ws->current, state, sizeof(struct sway_workspace_state));
229 output_damage_whole(ws->current.output);
230} 225}
231 226
232static void apply_container_state(struct sway_container *container, 227static void apply_container_state(struct sway_container *container,
233 struct sway_container_state *state) { 228 struct sway_container_state *state) {
234 struct sway_view *view = container->view; 229 struct sway_view *view = container->view;
235 // Damage the old location
236 desktop_damage_whole_container(container);
237 if (view && !wl_list_empty(&view->saved_buffers)) {
238 struct sway_saved_buffer *saved_buf;
239 wl_list_for_each(saved_buf, &view->saved_buffers, link) {
240 struct wlr_box box = {
241 .x = saved_buf->x - view->saved_geometry.x,
242 .y = saved_buf->y - view->saved_geometry.y,
243 .width = saved_buf->width,
244 .height = saved_buf->height,
245 };
246 desktop_damage_box(&box);
247 }
248 }
249
250 // There are separate children lists for each instruction state, the 230 // There are separate children lists for each instruction state, the
251 // container's current state and the container's pending state 231 // container's current state and the container's pending state
252 // (ie. con->children). The list itself needs to be freed here. 232 // (ie. con->children). The list itself needs to be freed here.
@@ -256,35 +236,443 @@ static void apply_container_state(struct sway_container *container,
256 236
257 memcpy(&container->current, state, sizeof(struct sway_container_state)); 237 memcpy(&container->current, state, sizeof(struct sway_container_state));
258 238
259 if (view && !wl_list_empty(&view->saved_buffers)) { 239 if (view) {
260 if (!container->node.destroying || container->node.ntxnrefs == 1) { 240 if (view->saved_surface_tree) {
261 view_remove_saved_buffer(view); 241 if (!container->node.destroying || container->node.ntxnrefs == 1) {
242 view_remove_saved_buffer(view);
243 }
244 }
245
246 // If the view hasn't responded to the configure, center it within
247 // the container. This is important for fullscreen views which
248 // refuse to resize to the size of the output.
249 if (view->surface) {
250 view_center_and_clip_surface(view);
251 }
252 }
253}
254
255static void arrange_title_bar(struct sway_container *con,
256 int x, int y, int width, int height) {
257 container_update(con);
258
259 bool has_title_bar = height > 0;
260 wlr_scene_node_set_enabled(&con->title_bar.tree->node, has_title_bar);
261 if (!has_title_bar) {
262 return;
263 }
264
265 wlr_scene_node_set_position(&con->title_bar.tree->node, x, y);
266
267 con->title_width = width;
268 container_arrange_title_bar(con);
269}
270
271static void disable_container(struct sway_container *con) {
272 if (con->view) {
273 wlr_scene_node_reparent(&con->view->scene_tree->node, con->content_tree);
274 } else {
275 for (int i = 0; i < con->current.children->length; i++) {
276 struct sway_container *child = con->current.children->items[i];
277
278 wlr_scene_node_reparent(&child->scene_tree->node, con->content_tree);
279
280 disable_container(child);
281 }
282 }
283}
284
285static void arrange_container(struct sway_container *con,
286 int width, int height, bool title_bar, int gaps);
287
288static void arrange_children(enum sway_container_layout layout, list_t *children,
289 struct sway_container *active, struct wlr_scene_tree *content,
290 int width, int height, int gaps) {
291 int title_bar_height = container_titlebar_height();
292
293 if (layout == L_TABBED) {
294 struct sway_container *first = children->length == 1 ?
295 ((struct sway_container *)children->items[0]) : NULL;
296 if (config->hide_lone_tab && first && first->view &&
297 first->current.border != B_NORMAL) {
298 title_bar_height = 0;
299 }
300
301 double w = (double) width / children->length;
302 int title_offset = 0;
303 for (int i = 0; i < children->length; i++) {
304 struct sway_container *child = children->items[i];
305 bool activated = child == active;
306 int next_title_offset = round(w * i + w);
307
308 arrange_title_bar(child, title_offset, -title_bar_height,
309 next_title_offset - title_offset, title_bar_height);
310 wlr_scene_node_set_enabled(&child->border.tree->node, activated);
311 wlr_scene_node_set_position(&child->scene_tree->node, 0, title_bar_height);
312 wlr_scene_node_reparent(&child->scene_tree->node, content);
313
314 if (activated) {
315 arrange_container(child, width, height - title_bar_height,
316 false, 0);
317 } else {
318 disable_container(child);
319 }
320
321 title_offset = next_title_offset;
322 }
323 } else if (layout == L_STACKED) {
324 struct sway_container *first = children->length == 1 ?
325 ((struct sway_container *)children->items[0]) : NULL;
326 if (config->hide_lone_tab && first && first->view &&
327 first->current.border != B_NORMAL) {
328 title_bar_height = 0;
329 }
330
331 int title_height = title_bar_height * children->length;
332
333 int y = 0;
334 for (int i = 0; i < children->length; i++) {
335 struct sway_container *child = children->items[i];
336 bool activated = child == active;
337
338 arrange_title_bar(child, 0, y - title_height, width, title_bar_height);
339 wlr_scene_node_set_enabled(&child->border.tree->node, activated);
340 wlr_scene_node_set_position(&child->scene_tree->node, 0, title_height);
341 wlr_scene_node_reparent(&child->scene_tree->node, content);
342
343 if (activated) {
344 arrange_container(child, width, height - title_height,
345 false, 0);
346 } else {
347 disable_container(child);
348 }
349
350 y += title_bar_height;
351 }
352 } else if (layout == L_VERT) {
353 int off = 0;
354 for (int i = 0; i < children->length; i++) {
355 struct sway_container *child = children->items[i];
356 int cheight = child->current.height;
357
358 wlr_scene_node_set_enabled(&child->border.tree->node, true);
359 wlr_scene_node_set_position(&child->scene_tree->node, 0, off);
360 wlr_scene_node_reparent(&child->scene_tree->node, content);
361 arrange_container(child, width, cheight, true, gaps);
362 off += cheight + gaps;
363 }
364 } else if (layout == L_HORIZ) {
365 int off = 0;
366 for (int i = 0; i < children->length; i++) {
367 struct sway_container *child = children->items[i];
368 int cwidth = child->current.width;
369
370 wlr_scene_node_set_enabled(&child->border.tree->node, true);
371 wlr_scene_node_set_position(&child->scene_tree->node, off, 0);
372 wlr_scene_node_reparent(&child->scene_tree->node, content);
373 arrange_container(child, cwidth, height, true, gaps);
374 off += cwidth + gaps;
375 }
376 } else {
377 sway_assert(false, "unreachable");
378 }
379}
380
381static void arrange_container(struct sway_container *con,
382 int width, int height, bool title_bar, int gaps) {
383 // this container might have previously been in the scratchpad,
384 // make sure it's enabled for viewing
385 wlr_scene_node_set_enabled(&con->scene_tree->node, true);
386
387 if (con->output_handler) {
388 wlr_scene_buffer_set_dest_size(con->output_handler, width, height);
389 }
390
391 if (con->view) {
392 int border_top = container_titlebar_height();
393 int border_width = con->current.border_thickness;
394
395 if (title_bar && con->current.border != B_NORMAL) {
396 wlr_scene_node_set_enabled(&con->title_bar.tree->node, false);
397 wlr_scene_node_set_enabled(&con->border.top->node, true);
398 } else {
399 wlr_scene_node_set_enabled(&con->border.top->node, false);
400 }
401
402 if (con->current.border == B_NORMAL) {
403 if (title_bar) {
404 arrange_title_bar(con, 0, 0, width, border_top);
405 } else {
406 border_top = 0;
407 // should be handled by the parent container
408 }
409 } else if (con->current.border == B_PIXEL) {
410 container_update(con);
411 border_top = title_bar && con->current.border_top ? border_width : 0;
412 } else if (con->current.border == B_NONE) {
413 container_update(con);
414 border_top = 0;
415 border_width = 0;
416 } else if (con->current.border == B_CSD) {
417 border_top = 0;
418 border_width = 0;
419 } else {
420 sway_assert(false, "unreachable");
421 }
422
423 int border_bottom = con->current.border_bottom ? border_width : 0;
424 int border_left = con->current.border_left ? border_width : 0;
425 int border_right = con->current.border_right ? border_width : 0;
426
427 wlr_scene_rect_set_size(con->border.top, width, border_top);
428 wlr_scene_rect_set_size(con->border.bottom, width, border_bottom);
429 wlr_scene_rect_set_size(con->border.left,
430 border_left, height - border_top - border_bottom);
431 wlr_scene_rect_set_size(con->border.right,
432 border_right, height - border_top - border_bottom);
433
434 wlr_scene_node_set_position(&con->border.top->node, 0, 0);
435 wlr_scene_node_set_position(&con->border.bottom->node,
436 0, height - border_bottom);
437 wlr_scene_node_set_position(&con->border.left->node,
438 0, border_top);
439 wlr_scene_node_set_position(&con->border.right->node,
440 width - border_right, border_top);
441
442 // make sure to reparent, it's possible that the client just came out of
443 // fullscreen mode where the parent of the surface is not the container
444 wlr_scene_node_reparent(&con->view->scene_tree->node, con->content_tree);
445 wlr_scene_node_set_position(&con->view->scene_tree->node,
446 border_left, border_top);
447 } else {
448 // make sure to disable the title bar if the parent is not managing it
449 if (title_bar) {
450 wlr_scene_node_set_enabled(&con->title_bar.tree->node, false);
451 }
452
453 arrange_children(con->current.layout, con->current.children,
454 con->current.focused_inactive_child, con->content_tree,
455 width, height, gaps);
456 }
457}
458
459static int container_get_gaps(struct sway_container *con) {
460 struct sway_workspace *ws = con->current.workspace;
461 struct sway_container *temp = con;
462 while (temp) {
463 enum sway_container_layout layout;
464 if (temp->current.parent) {
465 layout = temp->current.parent->current.layout;
466 } else {
467 layout = ws->current.layout;
468 }
469 if (layout == L_TABBED || layout == L_STACKED) {
470 return 0;
471 }
472 temp = temp->pending.parent;
473 }
474 return ws->gaps_inner;
475}
476
477static void arrange_fullscreen(struct wlr_scene_tree *tree,
478 struct sway_container *fs, struct sway_workspace *ws,
479 int width, int height) {
480 struct wlr_scene_node *fs_node;
481 if (fs->view) {
482 fs_node = &fs->view->scene_tree->node;
483
484 // if we only care about the view, disable any decorations
485 wlr_scene_node_set_enabled(&fs->scene_tree->node, false);
486 } else {
487 fs_node = &fs->scene_tree->node;
488 arrange_container(fs, width, height, true, container_get_gaps(fs));
489 }
490
491 wlr_scene_node_reparent(fs_node, tree);
492 wlr_scene_node_lower_to_bottom(fs_node);
493 wlr_scene_node_set_position(fs_node, 0, 0);
494}
495
496static void arrange_workspace_floating(struct sway_workspace *ws) {
497 for (int i = 0; i < ws->current.floating->length; i++) {
498 struct sway_container *floater = ws->current.floating->items[i];
499 struct wlr_scene_tree *layer = root->layers.floating;
500
501 if (floater->current.fullscreen_mode != FULLSCREEN_NONE) {
502 continue;
503 }
504
505 if (root->fullscreen_global) {
506 if (container_is_transient_for(floater, root->fullscreen_global)) {
507 layer = root->layers.fullscreen_global;
508 }
509 } else {
510 for (int i = 0; i < root->outputs->length; i++) {
511 struct sway_output *output = root->outputs->items[i];
512 struct sway_workspace *active = output->current.active_workspace;
513
514 if (active && active->fullscreen &&
515 container_is_transient_for(floater, active->fullscreen)) {
516 layer = root->layers.fullscreen;
517 }
518 }
519 }
520
521 wlr_scene_node_reparent(&floater->scene_tree->node, layer);
522 wlr_scene_node_set_position(&floater->scene_tree->node,
523 floater->current.x, floater->current.y);
524 wlr_scene_node_set_enabled(&floater->scene_tree->node, true);
525
526 arrange_container(floater, floater->current.width, floater->current.height,
527 true, ws->gaps_inner);
528 }
529}
530
531static void arrange_workspace_tiling(struct sway_workspace *ws,
532 int width, int height) {
533 arrange_children(ws->current.layout, ws->current.tiling,
534 ws->current.focused_inactive_child, ws->layers.tiling,
535 width, height, ws->gaps_inner);
536}
537
538static void disable_workspace(struct sway_workspace *ws) {
539 // if any containers were just moved to a disabled workspace it will
540 // have the parent of the old workspace. Move the workspace so that it won't
541 // be shown.
542 for (int i = 0; i < ws->current.tiling->length; i++) {
543 struct sway_container *child = ws->current.tiling->items[i];
544
545 wlr_scene_node_reparent(&child->scene_tree->node, ws->layers.tiling);
546 disable_container(child);
547 }
548
549 for (int i = 0; i < ws->current.floating->length; i++) {
550 struct sway_container *floater = ws->current.floating->items[i];
551 wlr_scene_node_reparent(&floater->scene_tree->node, root->layers.floating);
552 disable_container(floater);
553 wlr_scene_node_set_enabled(&floater->scene_tree->node, false);
554 }
555}
556
557static void arrange_output(struct sway_output *output, int width, int height) {
558 for (int i = 0; i < output->current.workspaces->length; i++) {
559 struct sway_workspace *child = output->current.workspaces->items[i];
560
561 bool activated = output->current.active_workspace == child;
562
563 wlr_scene_node_reparent(&child->layers.tiling->node, output->layers.tiling);
564 wlr_scene_node_reparent(&child->layers.fullscreen->node, output->layers.fullscreen);
565
566 for (int i = 0; i < child->current.floating->length; i++) {
567 struct sway_container *floater = child->current.floating->items[i];
568 wlr_scene_node_reparent(&floater->scene_tree->node, root->layers.floating);
569 wlr_scene_node_set_enabled(&floater->scene_tree->node, activated);
570 }
571
572 if (activated) {
573 struct sway_container *fs = child->current.fullscreen;
574 wlr_scene_node_set_enabled(&child->layers.tiling->node, !fs);
575 wlr_scene_node_set_enabled(&child->layers.fullscreen->node, fs);
576
577 arrange_workspace_floating(child);
578
579 wlr_scene_node_set_enabled(&output->layers.shell_background->node, !fs);
580 wlr_scene_node_set_enabled(&output->layers.shell_bottom->node, !fs);
581 wlr_scene_node_set_enabled(&output->layers.fullscreen->node, fs);
582
583 if (fs) {
584 wlr_scene_rect_set_size(output->fullscreen_background, width, height);
585
586 arrange_fullscreen(child->layers.fullscreen, fs, child,
587 width, height);
588 } else {
589 struct wlr_box *area = &output->usable_area;
590 struct side_gaps *gaps = &child->current_gaps;
591
592 wlr_scene_node_set_position(&child->layers.tiling->node,
593 gaps->left + area->x, gaps->top + area->y);
594
595 arrange_workspace_tiling(child,
596 area->width - gaps->left - gaps->right,
597 area->height - gaps->top - gaps->bottom);
598 }
599 } else {
600 wlr_scene_node_set_enabled(&child->layers.tiling->node, false);
601 wlr_scene_node_set_enabled(&child->layers.fullscreen->node, false);
602
603 disable_workspace(child);
262 } 604 }
263 } 605 }
606}
264 607
265 // If the view hasn't responded to the configure, center it within 608void arrange_popups(struct wlr_scene_tree *popups) {
266 // the container. This is important for fullscreen views which 609 struct wlr_scene_node *node;
267 // refuse to resize to the size of the output. 610 wl_list_for_each(node, &popups->children, link) {
268 if (view && view->surface) { 611 struct sway_popup_desc *popup = scene_descriptor_try_get(node,
269 view_center_surface(view); 612 SWAY_SCENE_DESC_POPUP);
613
614 int lx, ly;
615 wlr_scene_node_coords(popup->relative, &lx, &ly);
616 wlr_scene_node_set_position(node, lx, ly);
270 } 617 }
618}
619
620static void arrange_root(struct sway_root *root) {
621 struct sway_container *fs = root->fullscreen_global;
622
623 wlr_scene_node_set_enabled(&root->layers.shell_background->node, !fs);
624 wlr_scene_node_set_enabled(&root->layers.shell_bottom->node, !fs);
625 wlr_scene_node_set_enabled(&root->layers.tiling->node, !fs);
626 wlr_scene_node_set_enabled(&root->layers.floating->node, !fs);
627 wlr_scene_node_set_enabled(&root->layers.shell_top->node, !fs);
628 wlr_scene_node_set_enabled(&root->layers.fullscreen->node, !fs);
271 629
272 // Damage the new location 630 // hide all contents in the scratchpad
273 desktop_damage_whole_container(container); 631 for (int i = 0; i < root->scratchpad->length; i++) {
274 if (view && view->surface) { 632 struct sway_container *con = root->scratchpad->items[i];
275 struct wlr_surface *surface = view->surface; 633
276 struct wlr_box box = { 634 wlr_scene_node_set_enabled(&con->scene_tree->node, false);
277 .x = container->current.content_x - view->geometry.x,
278 .y = container->current.content_y - view->geometry.y,
279 .width = surface->current.width,
280 .height = surface->current.height,
281 };
282 desktop_damage_box(&box);
283 } 635 }
284 636
285 if (!container->node.destroying) { 637 if (fs) {
286 container_discover_outputs(container); 638 for (int i = 0; i < root->outputs->length; i++) {
639 struct sway_output *output = root->outputs->items[i];
640 struct sway_workspace *ws = output->current.active_workspace;
641
642 if (ws) {
643 arrange_workspace_floating(ws);
644 }
645 }
646
647 arrange_fullscreen(root->layers.fullscreen_global, fs, NULL,
648 root->width, root->height);
649 } else {
650 for (int i = 0; i < root->outputs->length; i++) {
651 struct sway_output *output = root->outputs->items[i];
652
653 wlr_scene_output_set_position(output->scene_output, output->lx, output->ly);
654
655 wlr_scene_node_reparent(&output->layers.shell_background->node, root->layers.shell_background);
656 wlr_scene_node_reparent(&output->layers.shell_bottom->node, root->layers.shell_bottom);
657 wlr_scene_node_reparent(&output->layers.tiling->node, root->layers.tiling);
658 wlr_scene_node_reparent(&output->layers.shell_top->node, root->layers.shell_top);
659 wlr_scene_node_reparent(&output->layers.shell_overlay->node, root->layers.shell_overlay);
660 wlr_scene_node_reparent(&output->layers.fullscreen->node, root->layers.fullscreen);
661 wlr_scene_node_reparent(&output->layers.session_lock->node, root->layers.session_lock);
662
663 wlr_scene_node_set_position(&output->layers.shell_background->node, output->lx, output->ly);
664 wlr_scene_node_set_position(&output->layers.shell_bottom->node, output->lx, output->ly);
665 wlr_scene_node_set_position(&output->layers.tiling->node, output->lx, output->ly);
666 wlr_scene_node_set_position(&output->layers.fullscreen->node, output->lx, output->ly);
667 wlr_scene_node_set_position(&output->layers.shell_top->node, output->lx, output->ly);
668 wlr_scene_node_set_position(&output->layers.shell_overlay->node, output->lx, output->ly);
669 wlr_scene_node_set_position(&output->layers.session_lock->node, output->lx, output->ly);
670
671 arrange_output(output, output->width, output->height);
672 }
287 } 673 }
674
675 arrange_popups(root->layers.popup);
288} 676}
289 677
290/** 678/**
@@ -326,8 +714,6 @@ static void transaction_apply(struct sway_transaction *transaction) {
326 714
327 node->instruction = NULL; 715 node->instruction = NULL;
328 } 716 }
329
330 cursor_rebase_all();
331} 717}
332 718
333static void transaction_commit_pending(void); 719static void transaction_commit_pending(void);
@@ -340,11 +726,13 @@ static void transaction_progress(void) {
340 return; 726 return;
341 } 727 }
342 transaction_apply(server.queued_transaction); 728 transaction_apply(server.queued_transaction);
729 arrange_root(root);
730 cursor_rebase_all();
343 transaction_destroy(server.queued_transaction); 731 transaction_destroy(server.queued_transaction);
344 server.queued_transaction = NULL; 732 server.queued_transaction = NULL;
345 733
346 if (!server.pending_transaction) { 734 if (!server.pending_transaction) {
347 sway_idle_inhibit_v1_check_active(server.idle_inhibit_manager_v1); 735 sway_idle_inhibit_v1_check_active();
348 return; 736 return;
349 } 737 }
350 738
@@ -415,21 +803,11 @@ static void transaction_commit(struct sway_transaction *transaction) {
415 ++transaction->num_waiting; 803 ++transaction->num_waiting;
416 } 804 }
417 805
418 // From here on we are rendering a saved buffer of the view, which 806 view_send_frame_done(node->sway_container->view);
419 // means we can send a frame done event to make the client redraw it
420 // as soon as possible. Additionally, this is required if a view is
421 // mapping and its default geometry doesn't intersect an output.
422 struct timespec now;
423 clock_gettime(CLOCK_MONOTONIC, &now);
424 wlr_surface_send_frame_done(
425 node->sway_container->view->surface, &now);
426 } 807 }
427 if (!hidden && node_is_view(node) && 808 if (!hidden && node_is_view(node) &&
428 wl_list_empty(&node->sway_container->view->saved_buffers)) { 809 !node->sway_container->view->saved_surface_tree) {
429 view_save_buffer(node->sway_container->view); 810 view_save_buffer(node->sway_container->view);
430 memcpy(&node->sway_container->view->saved_geometry,
431 &node->sway_container->view->geometry,
432 sizeof(struct wlr_box));
433 } 811 }
434 node->instruction = instruction; 812 node->instruction = instruction;
435 } 813 }
@@ -499,16 +877,18 @@ static void set_instruction_ready(
499 transaction_progress(); 877 transaction_progress();
500} 878}
501 879
502void transaction_notify_view_ready_by_serial(struct sway_view *view, 880bool transaction_notify_view_ready_by_serial(struct sway_view *view,
503 uint32_t serial) { 881 uint32_t serial) {
504 struct sway_transaction_instruction *instruction = 882 struct sway_transaction_instruction *instruction =
505 view->container->node.instruction; 883 view->container->node.instruction;
506 if (instruction != NULL && instruction->serial == serial) { 884 if (instruction != NULL && instruction->serial == serial) {
507 set_instruction_ready(instruction); 885 set_instruction_ready(instruction);
886 return true;
508 } 887 }
888 return false;
509} 889}
510 890
511void transaction_notify_view_ready_by_geometry(struct sway_view *view, 891bool transaction_notify_view_ready_by_geometry(struct sway_view *view,
512 double x, double y, int width, int height) { 892 double x, double y, int width, int height) {
513 struct sway_transaction_instruction *instruction = 893 struct sway_transaction_instruction *instruction =
514 view->container->node.instruction; 894 view->container->node.instruction;
@@ -518,7 +898,9 @@ void transaction_notify_view_ready_by_geometry(struct sway_view *view,
518 instruction->container_state.content_width == width && 898 instruction->container_state.content_width == width &&
519 instruction->container_state.content_height == height) { 899 instruction->container_state.content_height == height) {
520 set_instruction_ready(instruction); 900 set_instruction_ready(instruction);
901 return true;
521 } 902 }
903 return false;
522} 904}
523 905
524static void _transaction_commit_dirty(bool server_request) { 906static void _transaction_commit_dirty(bool server_request) {