summaryrefslogtreecommitdiffstats
path: root/sway/input/seat.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r--sway/input/seat.c159
1 files changed, 101 insertions, 58 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 57cc65f6..4077a8dd 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;
@@ -339,9 +313,6 @@ static void handle_new_drag_icon(struct wl_listener *listener, void *data) {
339 313
340static void collect_focus_iter(struct sway_container *con, void *data) { 314static void collect_focus_iter(struct sway_container *con, void *data) {
341 struct sway_seat *seat = data; 315 struct sway_seat *seat = data;
342 if (con->type > C_WORKSPACE) {
343 return;
344 }
345 struct sway_seat_container *seat_con = 316 struct sway_seat_container *seat_con =
346 seat_container_from_container(seat, con); 317 seat_container_from_container(seat, con);
347 if (!seat_con) { 318 if (!seat_con) {
@@ -375,7 +346,8 @@ struct sway_seat *seat_create(struct sway_input_manager *input,
375 // init the focus stack 346 // init the focus stack
376 wl_list_init(&seat->focus_stack); 347 wl_list_init(&seat->focus_stack);
377 348
378 container_for_each_descendant(&root_container, collect_focus_iter, seat); 349 root_for_each_workspace(collect_focus_iter, seat);
350 root_for_each_container(collect_focus_iter, seat);
379 351
380 wl_signal_add(&root_container.sway_root->events.new_container, 352 wl_signal_add(&root_container.sway_root->events.new_container,
381 &seat->new_container); 353 &seat->new_container);
@@ -653,8 +625,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 625 // find new output's old workspace, which might have to be removed if empty
654 struct sway_container *new_output_last_ws = NULL; 626 struct sway_container *new_output_last_ws = NULL;
655 if (last_output && new_output && last_output != new_output) { 627 if (last_output && new_output && last_output != new_output) {
656 new_output_last_ws = 628 new_output_last_ws = seat_get_active_child(seat, new_output);
657 seat_get_focus_by_type(seat, new_output, C_WORKSPACE, false);
658 } 629 }
659 630
660 if (container && container->parent) { 631 if (container && container->parent) {
@@ -717,7 +688,8 @@ void seat_set_focus_warp(struct sway_seat *seat,
717 // If we've focused a floating container, bring it to the front. 688 // If we've focused a floating container, bring it to the front.
718 // We do this by putting it at the end of the floating list. 689 // We do this by putting it at the end of the floating list.
719 if (container && container_is_floating(container)) { 690 if (container && container_is_floating(container)) {
720 list_move_to_end(container->parent->children, container); 691 list_move_to_end(
692 container->parent->sway_workspace->floating, container);
721 } 693 }
722 694
723 // clean up unfocused empty workspace on new output 695 // clean up unfocused empty workspace on new output
@@ -877,22 +849,66 @@ void seat_set_exclusive_client(struct sway_seat *seat,
877} 849}
878 850
879struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, 851struct sway_container *seat_get_focus_inactive(struct sway_seat *seat,
880 struct sway_container *container) { 852 struct sway_container *con) {
881 return seat_get_focus_by_type(seat, container, C_TYPES, false); 853 if (con->type == C_WORKSPACE && !con->children->length &&
854 !con->sway_workspace->floating->length) {
855 return con;
856 }
857 if (con->type == C_VIEW) {
858 return con;
859 }
860 struct sway_seat_container *current;
861 wl_list_for_each(current, &seat->focus_stack, link) {
862 if (container_has_ancestor(current->container, con)) {
863 return current->container;
864 }
865 }
866 return NULL;
882} 867}
883 868
884struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat, 869struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat,
885 struct sway_container *container) { 870 struct sway_container *ancestor) {
886 return seat_get_focus_by_type(seat, container, C_TYPES, true); 871 if (ancestor->type == C_WORKSPACE && !ancestor->children->length) {
872 return ancestor;
873 }
874 struct sway_seat_container *current;
875 wl_list_for_each(current, &seat->focus_stack, link) {
876 struct sway_container *con = current->container;
877 if (!container_is_floating_or_child(con) &&
878 container_has_ancestor(current->container, ancestor)) {
879 return con;
880 }
881 }
882 return NULL;
883}
884
885struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat,
886 struct sway_container *ancestor) {
887 if (ancestor->type == C_WORKSPACE &&
888 !ancestor->sway_workspace->floating->length) {
889 return NULL;
890 }
891 struct sway_seat_container *current;
892 wl_list_for_each(current, &seat->focus_stack, link) {
893 struct sway_container *con = current->container;
894 if (container_is_floating_or_child(con) &&
895 container_has_ancestor(current->container, ancestor)) {
896 return con;
897 }
898 }
899 return NULL;
887} 900}
888 901
889struct sway_container *seat_get_active_child(struct sway_seat *seat, 902struct sway_container *seat_get_active_child(struct sway_seat *seat,
890 struct sway_container *container) { 903 struct sway_container *parent) {
891 struct sway_seat_container *current = NULL; 904 if (parent->type == C_VIEW) {
905 return parent;
906 }
907 struct sway_seat_container *current;
892 wl_list_for_each(current, &seat->focus_stack, link) { 908 wl_list_for_each(current, &seat->focus_stack, link) {
893 if (current->container->parent == container && 909 struct sway_container *con = current->container;
894 current->container->layout != L_FLOATING) { 910 if (con->parent == parent) {
895 return current->container; 911 return con;
896 } 912 }
897 } 913 }
898 return NULL; 914 return NULL;
@@ -902,7 +918,9 @@ struct sway_container *seat_get_focus(struct sway_seat *seat) {
902 if (!seat->has_focus) { 918 if (!seat->has_focus) {
903 return NULL; 919 return NULL;
904 } 920 }
905 return seat_get_focus_inactive(seat, &root_container); 921 struct sway_seat_container *current =
922 wl_container_of(seat->focus_stack.next, current, link);
923 return current->container;
906} 924}
907 925
908void seat_apply_config(struct sway_seat *seat, 926void seat_apply_config(struct sway_seat *seat,
@@ -930,6 +948,18 @@ struct seat_config *seat_get_config(struct sway_seat *seat) {
930 return NULL; 948 return NULL;
931} 949}
932 950
951void seat_begin_down(struct sway_seat *seat, struct sway_container *con,
952 uint32_t button, double sx, double sy) {
953 seat->operation = OP_DOWN;
954 seat->op_container = con;
955 seat->op_button = button;
956 seat->op_ref_lx = seat->cursor->cursor->x;
957 seat->op_ref_ly = seat->cursor->cursor->y;
958 seat->op_ref_con_lx = sx;
959 seat->op_ref_con_ly = sy;
960 seat->op_moved = false;
961}
962
933void seat_begin_move(struct sway_seat *seat, struct sway_container *con, 963void seat_begin_move(struct sway_seat *seat, struct sway_container *con,
934 uint32_t button) { 964 uint32_t button) {
935 if (!seat->cursor) { 965 if (!seat->cursor) {
@@ -954,7 +984,7 @@ void seat_begin_resize_floating(struct sway_seat *seat,
954 seat->op_resize_preserve_ratio = keyboard && 984 seat->op_resize_preserve_ratio = keyboard &&
955 (wlr_keyboard_get_modifiers(keyboard) & WLR_MODIFIER_SHIFT); 985 (wlr_keyboard_get_modifiers(keyboard) & WLR_MODIFIER_SHIFT);
956 seat->op_resize_edge = edge == WLR_EDGE_NONE ? 986 seat->op_resize_edge = edge == WLR_EDGE_NONE ?
957 RESIZE_EDGE_BOTTOM | RESIZE_EDGE_RIGHT : edge; 987 WLR_EDGE_BOTTOM | WLR_EDGE_RIGHT : edge;
958 seat->op_button = button; 988 seat->op_button = button;
959 seat->op_ref_lx = seat->cursor->cursor->x; 989 seat->op_ref_lx = seat->cursor->cursor->x;
960 seat->op_ref_ly = seat->cursor->cursor->y; 990 seat->op_ref_ly = seat->cursor->cursor->y;
@@ -983,6 +1013,7 @@ void seat_begin_resize_tiling(struct sway_seat *seat,
983} 1013}
984 1014
985void seat_end_mouse_operation(struct sway_seat *seat) { 1015void seat_end_mouse_operation(struct sway_seat *seat) {
1016 enum sway_seat_operation operation = seat->operation;
986 if (seat->operation == OP_MOVE) { 1017 if (seat->operation == OP_MOVE) {
987 // We "move" the container to its own location so it discovers its 1018 // We "move" the container to its own location so it discovers its
988 // output again. 1019 // output again.
@@ -991,7 +1022,19 @@ void seat_end_mouse_operation(struct sway_seat *seat) {
991 } 1022 }
992 seat->operation = OP_NONE; 1023 seat->operation = OP_NONE;
993 seat->op_container = NULL; 1024 seat->op_container = NULL;
994 cursor_set_image(seat->cursor, "left_ptr", NULL); 1025 if (operation == OP_DOWN) {
1026 // Set the cursor's previous coords to the x/y at the start of the
1027 // operation, so the container change will be detected if using
1028 // focus_follows_mouse and the cursor moved off the original container
1029 // during the operation.
1030 seat->cursor->previous.x = seat->op_ref_lx;
1031 seat->cursor->previous.y = seat->op_ref_ly;
1032 if (seat->op_moved) {
1033 cursor_send_pointer_motion(seat->cursor, 0, true);
1034 }
1035 } else {
1036 cursor_set_image(seat->cursor, "left_ptr", NULL);
1037 }
995} 1038}
996 1039
997void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, 1040void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec,