diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-06-23 17:47:28 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-06-23 17:47:28 +1000 |
commit | 32b865e610dd937af17ce36b8c986e41f55a4627 (patch) | |
tree | bb89819988dcebe0d621c645fac35c9bfe4198d4 | |
parent | Merge remote-tracking branch 'upstream/master' into atomic (diff) | |
download | sway-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.h | 11 | ||||
-rw-r--r-- | sway/desktop/output.c | 28 | ||||
-rw-r--r-- | sway/input/seat.c | 12 |
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 | */ | ||
129 | struct 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 | ||
832 | struct 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 | |||
832 | struct sway_container *seat_get_focus(struct sway_seat *seat) { | 844 | struct 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; |