summaryrefslogtreecommitdiffstats
path: root/sway/tree/view.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-06-23 16:24:11 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-06-23 16:24:11 +1000
commit38398e2d77d57dc06b67ec88a54091c897915602 (patch)
treec80935807865fd96ab7d037070287d4dfaba1863 /sway/tree/view.c
parentPreserve buffers during transactions (diff)
downloadsway-38398e2d77d57dc06b67ec88a54091c897915602.tar.gz
sway-38398e2d77d57dc06b67ec88a54091c897915602.tar.zst
sway-38398e2d77d57dc06b67ec88a54091c897915602.zip
Implement atomic layout updates for tree operations
This implements atomic layout updates for when views map, reparent or unmap.
Diffstat (limited to 'sway/tree/view.c')
-rw-r--r--sway/tree/view.c76
1 files changed, 38 insertions, 38 deletions
diff --git a/sway/tree/view.c b/sway/tree/view.c
index 658a94e8..cb36f123 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -25,47 +25,60 @@ 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();
29 wl_signal_init(&view->events.unmap); 28 wl_signal_init(&view->events.unmap);
30} 29}
31 30
32void view_destroy(struct sway_view *view) { 31void view_free(struct sway_view *view) {
33 if (view == NULL) { 32 if (!sway_assert(view->surface == NULL, "Tried to free mapped view")) {
34 return; 33 return;
35 } 34 }
36 35 if (!sway_assert(view->destroying,
37 if (view->surface != NULL) { 36 "Tried to free view which wasn't marked as destroying")) {
38 view_unmap(view); 37 return;
39 } 38 }
40 39 if (!sway_assert(view->swayc == NULL,
41 if (!sway_assert(view->instructions->length == 0, 40 "Tried to free view which still has a swayc "
42 "Tried to destroy view with pending instructions")) { 41 "(might have a pending transaction?)")) {
43 return; 42 return;
44 } 43 }
45
46 list_free(view->executed_criteria); 44 list_free(view->executed_criteria);
47 45
48 for (int i = 0; i < view->marks->length; ++i) { 46 list_foreach(view->marks, free);
49 free(view->marks->items[i]);
50 }
51 list_free(view->marks); 47 list_free(view->marks);
52 48
53 list_free(view->instructions);
54
55 wlr_texture_destroy(view->marks_focused); 49 wlr_texture_destroy(view->marks_focused);
56 wlr_texture_destroy(view->marks_focused_inactive); 50 wlr_texture_destroy(view->marks_focused_inactive);
57 wlr_texture_destroy(view->marks_unfocused); 51 wlr_texture_destroy(view->marks_unfocused);
58 wlr_texture_destroy(view->marks_urgent); 52 wlr_texture_destroy(view->marks_urgent);
59 53
60 container_destroy(view->swayc); 54 if (view->impl->free) {
61 55 view->impl->free(view);
62 if (view->impl->destroy) {
63 view->impl->destroy(view);
64 } else { 56 } else {
65 free(view); 57 free(view);
66 } 58 }
67} 59}
68 60
61/**
62 * The view may or may not be involved in a transaction. For example, a view may
63 * unmap then attempt to destroy itself before we've applied the new layout. If
64 * an unmapping view is still involved in a transaction then it'll still have a
65 * swayc.
66 *
67 * If there's no transaction we can simply free the view. Otherwise the
68 * destroying flag will make the view get freed when the transaction is
69 * finished.
70 */
71void view_destroy(struct sway_view *view) {
72 if (!sway_assert(view->surface == NULL, "Tried to destroy a mapped view")) {
73 return;
74 }
75 view->destroying = true;
76
77 if (!view->swayc) {
78 view_free(view);
79 }
80}
81
69const char *view_get_title(struct sway_view *view) { 82const char *view_get_title(struct sway_view *view) {
70 if (view->impl->get_string_prop) { 83 if (view->impl->get_string_prop) {
71 return view->impl->get_string_prop(view, VIEW_PROP_TITLE); 84 return view->impl->get_string_prop(view, VIEW_PROP_TITLE);
@@ -356,6 +369,9 @@ static void view_get_layout_box(struct sway_view *view, struct wlr_box *box) {
356 369
357void view_for_each_surface(struct sway_view *view, 370void view_for_each_surface(struct sway_view *view,
358 wlr_surface_iterator_func_t iterator, void *user_data) { 371 wlr_surface_iterator_func_t iterator, void *user_data) {
372 if (!view->surface) {
373 return;
374 }
359 if (view->impl->for_each_surface) { 375 if (view->impl->for_each_surface) {
360 view->impl->for_each_surface(view, iterator, user_data); 376 view->impl->for_each_surface(view, iterator, user_data);
361 } else { 377 } else {
@@ -523,11 +539,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
523 view_handle_container_reparent(&view->container_reparent, NULL); 539 view_handle_container_reparent(&view->container_reparent, NULL);
524} 540}
525 541
526void view_unmap(struct sway_view *view) { 542struct sway_container *view_unmap(struct sway_view *view) {
527 if (!sway_assert(view->surface != NULL, "cannot unmap unmapped view")) {
528 return;
529 }
530
531 wl_signal_emit(&view->events.unmap, view); 543 wl_signal_emit(&view->events.unmap, view);
532 544
533 if (view->is_fullscreen) { 545 if (view->is_fullscreen) {
@@ -535,22 +547,10 @@ void view_unmap(struct sway_view *view) {
535 ws->sway_workspace->fullscreen = NULL; 547 ws->sway_workspace->fullscreen = NULL;
536 } 548 }
537 549
538 container_damage_whole(view->swayc);
539
540 wl_list_remove(&view->surface_new_subsurface.link); 550 wl_list_remove(&view->surface_new_subsurface.link);
541 wl_list_remove(&view->container_reparent.link); 551 wl_list_remove(&view->container_reparent.link);
542 552
543 struct sway_container *parent = container_destroy(view->swayc); 553 return container_destroy(view->swayc);
544
545 view->swayc = NULL;
546 view->surface = NULL;
547
548 if (view->title_format) {
549 free(view->title_format);
550 view->title_format = NULL;
551 }
552
553 arrange_and_commit(parent);
554} 554}
555 555
556void view_update_position(struct sway_view *view, double lx, double ly) { 556void view_update_position(struct sway_view *view, double lx, double ly) {
@@ -924,7 +924,7 @@ void view_update_marks_textures(struct sway_view *view) {
924} 924}
925 925
926bool view_is_visible(struct sway_view *view) { 926bool view_is_visible(struct sway_view *view) {
927 if (!view->swayc) { 927 if (!view->swayc || view->swayc->destroying) {
928 return false; 928 return false;
929 } 929 }
930 struct sway_container *workspace = 930 struct sway_container *workspace =