aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/seat.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-17 17:32:53 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-17 17:32:53 +1000
commit3a888163a03e8fb6fbe91bfe8e2fe4f3d2f03cec (patch)
tree56dff4af22bf816ab5ec024f694d41ef3275d48e /sway/input/seat.c
parentMerge pull request #2465 from DonnieWest/master (diff)
downloadsway-3a888163a03e8fb6fbe91bfe8e2fe4f3d2f03cec.tar.gz
sway-3a888163a03e8fb6fbe91bfe8e2fe4f3d2f03cec.tar.zst
sway-3a888163a03e8fb6fbe91bfe8e2fe4f3d2f03cec.zip
Refactor seat_get_focus functions
Fixes #2467. This commit introduces seat_get_focus_inactive_floating to supplement seat_get_focus_inactive_tiling, and uses it during `focus mode_toggle` which fixes a focus bug. This also refactors the seat_get_focus_inactive functions so that they do their selection logic themselves rather than offloading it to seat_get_focus_by_type which was getting bloated. seat_get_focus_by_type is now removed. Lastly, this commit changes seat_get_focus to just return the first container in the focus stack rather than looping and calling seat_get_focus_by_type.
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r--sway/input/seat.c126
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
127static 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
163void seat_focus_inactive_children_for_each(struct sway_seat *seat, 127void 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
177struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat, 141struct 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
182static void handle_seat_container_destroy(struct wl_listener *listener, 156static 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
879struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, 852struct 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
884struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat, 870struct 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
886struct 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
903static 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
889struct sway_container *seat_get_active_child(struct sway_seat *seat, 908struct 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
908void seat_apply_config(struct sway_seat *seat, 932void seat_apply_config(struct sway_seat *seat,