aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/input/seat.h3
-rw-r--r--sway/commands/focus.c14
-rw-r--r--sway/input/seat.c23
-rw-r--r--sway/tree/container.c5
4 files changed, 32 insertions, 13 deletions
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h
index ab25788f..07febe2c 100644
--- a/include/sway/input/seat.h
+++ b/include/sway/input/seat.h
@@ -124,6 +124,9 @@ struct sway_container *seat_get_focus(struct sway_seat *seat);
124struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, 124struct sway_container *seat_get_focus_inactive(struct sway_seat *seat,
125 struct sway_container *container); 125 struct sway_container *container);
126 126
127struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat,
128 struct sway_container *container);
129
127/** 130/**
128 * Descend into the focus stack to find the focus-inactive view. Useful for 131 * Descend into the focus stack to find the focus-inactive view. Useful for
129 * container placement when they change position in the tree. 132 * container placement when they change position in the tree.
diff --git a/sway/commands/focus.c b/sway/commands/focus.c
index 9cd8bfae..ce3d032f 100644
--- a/sway/commands/focus.c
+++ b/sway/commands/focus.c
@@ -35,14 +35,16 @@ static struct cmd_results *focus_mode(struct sway_container *con,
35 struct sway_seat *seat, bool floating) { 35 struct sway_seat *seat, bool floating) {
36 struct sway_container *ws = con->type == C_WORKSPACE ? 36 struct sway_container *ws = con->type == C_WORKSPACE ?
37 con : container_parent(con, C_WORKSPACE); 37 con : container_parent(con, C_WORKSPACE);
38 struct sway_container *new_focus = ws; 38 struct sway_container *new_focus = NULL;
39 if (floating) { 39 if (floating) {
40 new_focus = ws->sway_workspace->floating; 40 new_focus = seat_get_focus_inactive(seat, ws->sway_workspace->floating);
41 if (new_focus->children->length == 0) { 41 } else {
42 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 42 new_focus = seat_get_focus_inactive_tiling(seat, ws);
43 } 43 }
44 if (!new_focus) {
45 new_focus = ws;
44 } 46 }
45 seat_set_focus(seat, seat_get_active_child(seat, new_focus)); 47 seat_set_focus(seat, new_focus);
46 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 48 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
47} 49}
48 50
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 877a93c6..18d5591d 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -124,12 +124,14 @@ static void seat_send_focus(struct sway_container *con,
124} 124}
125 125
126static struct sway_container *seat_get_focus_by_type(struct sway_seat *seat, 126static struct sway_container *seat_get_focus_by_type(struct sway_seat *seat,
127 struct sway_container *container, enum sway_container_type type) { 127 struct sway_container *container, enum sway_container_type type,
128 bool only_tiling) {
128 if (container->type == C_VIEW) { 129 if (container->type == C_VIEW) {
129 return container; 130 return container;
130 } 131 }
131 132
132 struct sway_container *floating = container->type == C_WORKSPACE ? 133 struct sway_container *floating =
134 container->type == C_WORKSPACE && !only_tiling ?
133 container->sway_workspace->floating : NULL; 135 container->sway_workspace->floating : NULL;
134 if (container->children->length == 0 && 136 if (container->children->length == 0 &&
135 (!floating || floating->children->length == 0)) { 137 (!floating || floating->children->length == 0)) {
@@ -143,6 +145,10 @@ static struct sway_container *seat_get_focus_by_type(struct sway_seat *seat,
143 } 145 }
144 146
145 if (container_has_child(container, current->container)) { 147 if (container_has_child(container, current->container)) {
148 if (only_tiling &&
149 container_is_floating_or_child(current->container)) {
150 continue;
151 }
146 return current->container; 152 return current->container;
147 } 153 }
148 if (floating && container_has_child(floating, current->container)) { 154 if (floating && container_has_child(floating, current->container)) {
@@ -169,7 +175,7 @@ void seat_focus_inactive_children_for_each(struct sway_seat *seat,
169 175
170struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat, 176struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat,
171 struct sway_container *container) { 177 struct sway_container *container) {
172 return seat_get_focus_by_type(seat, container, C_VIEW); 178 return seat_get_focus_by_type(seat, container, C_VIEW, false);
173} 179}
174 180
175static void handle_seat_container_destroy(struct wl_listener *listener, 181static void handle_seat_container_destroy(struct wl_listener *listener,
@@ -191,7 +197,7 @@ static void handle_seat_container_destroy(struct wl_listener *listener,
191 if (set_focus) { 197 if (set_focus) {
192 struct sway_container *next_focus = NULL; 198 struct sway_container *next_focus = NULL;
193 while (next_focus == NULL) { 199 while (next_focus == NULL) {
194 next_focus = seat_get_focus_by_type(seat, parent, C_VIEW); 200 next_focus = seat_get_focus_by_type(seat, parent, C_VIEW, false);
195 201
196 if (next_focus == NULL && parent->type == C_WORKSPACE) { 202 if (next_focus == NULL && parent->type == C_WORKSPACE) {
197 next_focus = parent; 203 next_focus = parent;
@@ -648,7 +654,7 @@ void seat_set_focus_warp(struct sway_seat *seat,
648 struct sway_container *new_output_last_ws = NULL; 654 struct sway_container *new_output_last_ws = NULL;
649 if (last_output && new_output && last_output != new_output) { 655 if (last_output && new_output && last_output != new_output) {
650 new_output_last_ws = 656 new_output_last_ws =
651 seat_get_focus_by_type(seat, new_output, C_WORKSPACE); 657 seat_get_focus_by_type(seat, new_output, C_WORKSPACE, false);
652 } 658 }
653 659
654 if (container && container->parent) { 660 if (container && container->parent) {
@@ -853,7 +859,12 @@ void seat_set_exclusive_client(struct sway_seat *seat,
853 859
854struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, 860struct sway_container *seat_get_focus_inactive(struct sway_seat *seat,
855 struct sway_container *container) { 861 struct sway_container *container) {
856 return seat_get_focus_by_type(seat, container, C_TYPES); 862 return seat_get_focus_by_type(seat, container, C_TYPES, false);
863}
864
865struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat,
866 struct sway_container *container) {
867 return seat_get_focus_by_type(seat, container, C_TYPES, true);
857} 868}
858 869
859struct sway_container *seat_get_active_child(struct sway_seat *seat, 870struct sway_container *seat_get_active_child(struct sway_seat *seat,
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 566432b1..b8ff87e1 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -1015,6 +1015,7 @@ void container_set_floating(struct sway_container *container, bool enable) {
1015 return; 1015 return;
1016 } 1016 }
1017 1017
1018 struct sway_seat *seat = input_manager_current_seat(input_manager);
1018 struct sway_container *workspace = container_parent(container, C_WORKSPACE); 1019 struct sway_container *workspace = container_parent(container, C_WORKSPACE);
1019 1020
1020 if (enable) { 1021 if (enable) {
@@ -1029,8 +1030,10 @@ void container_set_floating(struct sway_container *container, bool enable) {
1029 if (container->scratchpad) { 1030 if (container->scratchpad) {
1030 scratchpad_remove_container(container); 1031 scratchpad_remove_container(container);
1031 } 1032 }
1033 struct sway_container *sibling =
1034 seat_get_focus_inactive_tiling(seat, workspace);
1032 container_remove_child(container); 1035 container_remove_child(container);
1033 container_add_child(workspace, container); 1036 container_add_child(sibling, container);
1034 container->width = container->parent->width; 1037 container->width = container->parent->width;
1035 container->height = container->parent->height; 1038 container->height = container->parent->height;
1036 if (container->type == C_VIEW) { 1039 if (container->type == C_VIEW) {