diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-06-23 16:24:11 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-06-23 16:24:11 +1000 |
commit | 38398e2d77d57dc06b67ec88a54091c897915602 (patch) | |
tree | c80935807865fd96ab7d037070287d4dfaba1863 /sway/tree/view.c | |
parent | Preserve buffers during transactions (diff) | |
download | sway-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.c | 76 |
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 | ||
32 | void view_destroy(struct sway_view *view) { | 31 | void 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 | */ | ||
71 | void 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 | |||
69 | const char *view_get_title(struct sway_view *view) { | 82 | const 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 | ||
357 | void view_for_each_surface(struct sway_view *view, | 370 | void 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 | ||
526 | void view_unmap(struct sway_view *view) { | 542 | struct 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 | ||
556 | void view_update_position(struct sway_view *view, double lx, double ly) { | 556 | void 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 | ||
926 | bool view_is_visible(struct sway_view *view) { | 926 | bool 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 = |