diff options
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r-- | sway/input/seat.c | 126 |
1 files changed, 75 insertions, 51 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c index 57cc65f6..fa41904a 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -124,42 +124,6 @@ static void seat_send_focus(struct sway_container *con, | |||
124 | } | 124 | } |
125 | } | 125 | } |
126 | 126 | ||
127 | static struct sway_container *seat_get_focus_by_type(struct sway_seat *seat, | ||
128 | struct sway_container *container, enum sway_container_type type, | ||
129 | bool only_tiling) { | ||
130 | if (container->type == C_VIEW) { | ||
131 | return container; | ||
132 | } | ||
133 | |||
134 | struct sway_container *floating = | ||
135 | container->type == C_WORKSPACE && !only_tiling ? | ||
136 | container->sway_workspace->floating : NULL; | ||
137 | if (container->children->length == 0 && | ||
138 | (!floating || floating->children->length == 0)) { | ||
139 | return container; | ||
140 | } | ||
141 | |||
142 | struct sway_seat_container *current = NULL; | ||
143 | wl_list_for_each(current, &seat->focus_stack, link) { | ||
144 | if (current->container->type != type && type != C_TYPES) { | ||
145 | continue; | ||
146 | } | ||
147 | |||
148 | if (container_has_ancestor(current->container, container)) { | ||
149 | if (only_tiling && | ||
150 | container_is_floating_or_child(current->container)) { | ||
151 | continue; | ||
152 | } | ||
153 | return current->container; | ||
154 | } | ||
155 | if (floating && container_has_ancestor(current->container, floating)) { | ||
156 | return current->container; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | return NULL; | ||
161 | } | ||
162 | |||
163 | void seat_focus_inactive_children_for_each(struct sway_seat *seat, | 127 | void seat_focus_inactive_children_for_each(struct sway_seat *seat, |
164 | struct sway_container *container, | 128 | struct sway_container *container, |
165 | void (*f)(struct sway_container *container, void *data), void *data) { | 129 | void (*f)(struct sway_container *container, void *data), void *data) { |
@@ -175,8 +139,18 @@ void seat_focus_inactive_children_for_each(struct sway_seat *seat, | |||
175 | } | 139 | } |
176 | 140 | ||
177 | struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat, | 141 | struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat, |
178 | struct sway_container *container) { | 142 | struct sway_container *ancestor) { |
179 | return seat_get_focus_by_type(seat, container, C_VIEW, false); | 143 | if (ancestor->type == C_VIEW) { |
144 | return ancestor; | ||
145 | } | ||
146 | struct sway_seat_container *current; | ||
147 | wl_list_for_each(current, &seat->focus_stack, link) { | ||
148 | struct sway_container *con = current->container; | ||
149 | if (con->type == C_VIEW && container_has_ancestor(con, ancestor)) { | ||
150 | return con; | ||
151 | } | ||
152 | } | ||
153 | return NULL; | ||
180 | } | 154 | } |
181 | 155 | ||
182 | static void handle_seat_container_destroy(struct wl_listener *listener, | 156 | static void handle_seat_container_destroy(struct wl_listener *listener, |
@@ -198,7 +172,7 @@ static void handle_seat_container_destroy(struct wl_listener *listener, | |||
198 | if (set_focus) { | 172 | if (set_focus) { |
199 | struct sway_container *next_focus = NULL; | 173 | struct sway_container *next_focus = NULL; |
200 | while (next_focus == NULL) { | 174 | while (next_focus == NULL) { |
201 | next_focus = seat_get_focus_by_type(seat, parent, C_VIEW, false); | 175 | next_focus = seat_get_focus_inactive_view(seat, parent); |
202 | 176 | ||
203 | if (next_focus == NULL && parent->type == C_WORKSPACE) { | 177 | if (next_focus == NULL && parent->type == C_WORKSPACE) { |
204 | next_focus = parent; | 178 | next_focus = parent; |
@@ -653,8 +627,7 @@ void seat_set_focus_warp(struct sway_seat *seat, | |||
653 | // find new output's old workspace, which might have to be removed if empty | 627 | // find new output's old workspace, which might have to be removed if empty |
654 | struct sway_container *new_output_last_ws = NULL; | 628 | struct sway_container *new_output_last_ws = NULL; |
655 | if (last_output && new_output && last_output != new_output) { | 629 | if (last_output && new_output && last_output != new_output) { |
656 | new_output_last_ws = | 630 | new_output_last_ws = seat_get_active_child(seat, new_output); |
657 | seat_get_focus_by_type(seat, new_output, C_WORKSPACE, false); | ||
658 | } | 631 | } |
659 | 632 | ||
660 | if (container && container->parent) { | 633 | if (container && container->parent) { |
@@ -877,22 +850,71 @@ void seat_set_exclusive_client(struct sway_seat *seat, | |||
877 | } | 850 | } |
878 | 851 | ||
879 | struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, | 852 | struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, |
880 | struct sway_container *container) { | 853 | struct sway_container *con) { |
881 | return seat_get_focus_by_type(seat, container, C_TYPES, false); | 854 | if (con->type == C_WORKSPACE && !con->children->length && |
855 | !con->sway_workspace->floating->children->length) { | ||
856 | return con; | ||
857 | } | ||
858 | if (con->type == C_VIEW) { | ||
859 | return con; | ||
860 | } | ||
861 | struct sway_seat_container *current; | ||
862 | wl_list_for_each(current, &seat->focus_stack, link) { | ||
863 | if (container_has_ancestor(current->container, con)) { | ||
864 | return current->container; | ||
865 | } | ||
866 | } | ||
867 | return NULL; | ||
882 | } | 868 | } |
883 | 869 | ||
884 | struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat, | 870 | struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat, |
885 | struct sway_container *container) { | 871 | struct sway_container *ancestor) { |
886 | return seat_get_focus_by_type(seat, container, C_TYPES, true); | 872 | if (ancestor->type == C_WORKSPACE && !ancestor->children->length) { |
873 | return ancestor; | ||
874 | } | ||
875 | struct sway_seat_container *current; | ||
876 | wl_list_for_each(current, &seat->focus_stack, link) { | ||
877 | struct sway_container *con = current->container; | ||
878 | if (con->layout != L_FLOATING && !container_is_floating_or_child(con) && | ||
879 | container_has_ancestor(current->container, ancestor)) { | ||
880 | return con; | ||
881 | } | ||
882 | } | ||
883 | return NULL; | ||
884 | } | ||
885 | |||
886 | struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat, | ||
887 | struct sway_container *ancestor) { | ||
888 | if (ancestor->type == C_WORKSPACE && | ||
889 | !ancestor->sway_workspace->floating->children->length) { | ||
890 | return NULL; | ||
891 | } | ||
892 | struct sway_seat_container *current; | ||
893 | wl_list_for_each(current, &seat->focus_stack, link) { | ||
894 | struct sway_container *con = current->container; | ||
895 | if (con->layout != L_FLOATING && container_is_floating_or_child(con) && | ||
896 | container_has_ancestor(current->container, ancestor)) { | ||
897 | return con; | ||
898 | } | ||
899 | } | ||
900 | return NULL; | ||
901 | } | ||
902 | |||
903 | static bool impl_focus_active_child(struct sway_container *con, void *data) { | ||
904 | struct sway_container *parent = data; | ||
905 | return con->parent == parent && con->layout != L_FLOATING; | ||
887 | } | 906 | } |
888 | 907 | ||
889 | struct sway_container *seat_get_active_child(struct sway_seat *seat, | 908 | struct sway_container *seat_get_active_child(struct sway_seat *seat, |
890 | struct sway_container *container) { | 909 | struct sway_container *parent) { |
891 | struct sway_seat_container *current = NULL; | 910 | if (parent->type == C_VIEW) { |
911 | return parent; | ||
912 | } | ||
913 | struct sway_seat_container *current; | ||
892 | wl_list_for_each(current, &seat->focus_stack, link) { | 914 | wl_list_for_each(current, &seat->focus_stack, link) { |
893 | if (current->container->parent == container && | 915 | struct sway_container *con = current->container; |
894 | current->container->layout != L_FLOATING) { | 916 | if (con->parent == parent && con->layout != L_FLOATING) { |
895 | return current->container; | 917 | return con; |
896 | } | 918 | } |
897 | } | 919 | } |
898 | return NULL; | 920 | return NULL; |
@@ -902,7 +924,9 @@ struct sway_container *seat_get_focus(struct sway_seat *seat) { | |||
902 | if (!seat->has_focus) { | 924 | if (!seat->has_focus) { |
903 | return NULL; | 925 | return NULL; |
904 | } | 926 | } |
905 | return seat_get_focus_inactive(seat, &root_container); | 927 | struct sway_seat_container *current = |
928 | wl_container_of(seat->focus_stack.next, current, link); | ||
929 | return current->container; | ||
906 | } | 930 | } |
907 | 931 | ||
908 | void seat_apply_config(struct sway_seat *seat, | 932 | void seat_apply_config(struct sway_seat *seat, |