aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-06-23 17:47:28 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-06-23 17:47:28 +1000
commit32b865e610dd937af17ce36b8c986e41f55a4627 (patch)
treebb89819988dcebe0d621c645fac35c9bfe4198d4
parentMerge remote-tracking branch 'upstream/master' into atomic (diff)
downloadsway-32b865e610dd937af17ce36b8c986e41f55a4627.tar.gz
sway-32b865e610dd937af17ce36b8c986e41f55a4627.tar.zst
sway-32b865e610dd937af17ce36b8c986e41f55a4627.zip
Fix crash when deleting last child in a tabbed or stacked container
There was no `current` child because the container was destroyed. This makes it fall back to looking in the parent's current children list.
-rw-r--r--include/sway/input/seat.h11
-rw-r--r--sway/desktop/output.c28
-rw-r--r--sway/input/seat.c12
3 files changed, 39 insertions, 12 deletions
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h
index 1f7792ba..0e440701 100644
--- a/include/sway/input/seat.h
+++ b/include/sway/input/seat.h
@@ -119,6 +119,17 @@ struct sway_container *seat_get_active_child(struct sway_seat *seat,
119 struct sway_container *container); 119 struct sway_container *container);
120 120
121/** 121/**
122 * Return the immediate child of container which was most recently focused, with
123 * fallback to selecting the child in the parent's `current` (rendered) children
124 * list.
125 *
126 * This is useful for when a tabbed container and its children are destroyed but
127 * still being rendered, and we have to render an appropriate child.
128 */
129struct sway_container *seat_get_active_current_child(struct sway_seat *seat,
130 struct sway_container *container);
131
132/**
122 * Iterate over the focus-inactive children of the container calling the 133 * Iterate over the focus-inactive children of the container calling the
123 * function on each. 134 * function on each.
124 */ 135 */
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 9db95ef5..1ca48975 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -713,7 +713,7 @@ static void render_container_tabbed(struct sway_output *output,
713 } 713 }
714 struct sway_seat *seat = input_manager_current_seat(input_manager); 714 struct sway_seat *seat = input_manager_current_seat(input_manager);
715 struct sway_container *focus = seat_get_focus(seat); 715 struct sway_container *focus = seat_get_focus(seat);
716 struct sway_container *current = seat_get_active_child(seat, con); 716 struct sway_container *current = seat_get_active_current_child(seat, con);
717 struct border_colors *current_colors = NULL; 717 struct border_colors *current_colors = NULL;
718 struct sway_container_state *pstate = &con->current; 718 struct sway_container_state *pstate = &con->current;
719 719
@@ -756,11 +756,13 @@ static void render_container_tabbed(struct sway_output *output,
756 } 756 }
757 757
758 // Render surface and left/right/bottom borders 758 // Render surface and left/right/bottom borders
759 if (current->type == C_VIEW) { 759 if (current) {
760 render_view(output, damage, current, current_colors); 760 if (current->type == C_VIEW) {
761 } else { 761 render_view(output, damage, current, current_colors);
762 render_container(output, damage, current, 762 } else {
763 parent_focused || current == focus); 763 render_container(output, damage, current,
764 parent_focused || current == focus);
765 }
764 } 766 }
765} 767}
766 768
@@ -775,7 +777,7 @@ static void render_container_stacked(struct sway_output *output,
775 } 777 }
776 struct sway_seat *seat = input_manager_current_seat(input_manager); 778 struct sway_seat *seat = input_manager_current_seat(input_manager);
777 struct sway_container *focus = seat_get_focus(seat); 779 struct sway_container *focus = seat_get_focus(seat);
778 struct sway_container *current = seat_get_active_child(seat, con); 780 struct sway_container *current = seat_get_active_current_child(seat, con);
779 struct border_colors *current_colors = NULL; 781 struct border_colors *current_colors = NULL;
780 struct sway_container_state *pstate = &con->current; 782 struct sway_container_state *pstate = &con->current;
781 783
@@ -812,11 +814,13 @@ static void render_container_stacked(struct sway_output *output,
812 } 814 }
813 815
814 // Render surface and left/right/bottom borders 816 // Render surface and left/right/bottom borders
815 if (current->type == C_VIEW) { 817 if (current) {
816 render_view(output, damage, current, current_colors); 818 if (current->type == C_VIEW) {
817 } else { 819 render_view(output, damage, current, current_colors);
818 render_container(output, damage, current, 820 } else {
819 parent_focused || current == focus); 821 render_container(output, damage, current,
822 parent_focused || current == focus);
823 }
820 } 824 }
821} 825}
822 826
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 1ea36466..436d18e2 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -829,6 +829,18 @@ struct sway_container *seat_get_active_child(struct sway_seat *seat,
829 return NULL; 829 return NULL;
830} 830}
831 831
832struct sway_container *seat_get_active_current_child(struct sway_seat *seat,
833 struct sway_container *container) {
834 struct sway_container *child = seat_get_active_child(seat, container);
835 if (child) {
836 return child;
837 }
838 if (container->current.children->length == 1) {
839 return container->current.children->items[0];
840 }
841 return NULL;
842}
843
832struct sway_container *seat_get_focus(struct sway_seat *seat) { 844struct sway_container *seat_get_focus(struct sway_seat *seat) {
833 if (!seat->has_focus) { 845 if (!seat->has_focus) {
834 return NULL; 846 return NULL;