diff options
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r-- | sway/input/seat.c | 63 |
1 files changed, 44 insertions, 19 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c index a9c564e7..e10b6409 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -144,32 +144,43 @@ static void handle_seat_node_destroy(struct wl_listener *listener, void *data) { | |||
144 | struct sway_node *parent = node_get_parent(node); | 144 | struct sway_node *parent = node_get_parent(node); |
145 | struct sway_node *focus = seat_get_focus(seat); | 145 | struct sway_node *focus = seat_get_focus(seat); |
146 | 146 | ||
147 | bool set_focus = | 147 | if (node->type == N_WORKSPACE) { |
148 | focus != NULL && | 148 | seat_node_destroy(seat_node); |
149 | (focus == node || node_has_ancestor(focus, node)) && | 149 | return; |
150 | node->type == N_CONTAINER; | 150 | } |
151 | |||
152 | // Even though the container being destroyed might be nowhere near the | ||
153 | // focused container, we still need to set focus_inactive on a sibling of | ||
154 | // the container being destroyed. | ||
155 | bool needs_new_focus = focus && | ||
156 | (focus == node || node_has_ancestor(focus, node)); | ||
151 | 157 | ||
152 | seat_node_destroy(seat_node); | 158 | seat_node_destroy(seat_node); |
153 | 159 | ||
154 | if (set_focus) { | 160 | // Find new focus_inactive (ie. sibling, or workspace if no siblings left) |
155 | struct sway_node *next_focus = NULL; | 161 | struct sway_node *next_focus = NULL; |
156 | while (next_focus == NULL) { | 162 | while (next_focus == NULL) { |
157 | struct sway_container *con = | 163 | struct sway_container *con = |
158 | seat_get_focus_inactive_view(seat, parent); | 164 | seat_get_focus_inactive_view(seat, parent); |
159 | next_focus = con ? &con->node : NULL; | 165 | next_focus = con ? &con->node : NULL; |
160 | 166 | ||
161 | if (next_focus == NULL && parent->type == N_WORKSPACE) { | 167 | if (next_focus == NULL && parent->type == N_WORKSPACE) { |
162 | next_focus = parent; | 168 | next_focus = parent; |
163 | break; | 169 | break; |
164 | } | ||
165 | |||
166 | parent = node_get_parent(parent); | ||
167 | } | 170 | } |
168 | 171 | ||
169 | // the structure change might have caused it to move up to the top of | 172 | parent = node_get_parent(parent); |
173 | } | ||
174 | |||
175 | if (needs_new_focus) { | ||
176 | // The structure change might have caused it to move up to the top of | ||
170 | // the focus stack without sending focus notifications to the view | 177 | // the focus stack without sending focus notifications to the view |
171 | seat_send_focus(next_focus, seat); | 178 | seat_send_focus(next_focus, seat); |
172 | seat_set_focus(seat, next_focus); | 179 | seat_set_focus(seat, next_focus); |
180 | } else { | ||
181 | // Setting focus_inactive | ||
182 | seat_set_focus_warp(seat, next_focus, false, false); | ||
183 | seat_set_focus_warp(seat, focus, false, false); | ||
173 | } | 184 | } |
174 | } | 185 | } |
175 | 186 | ||
@@ -368,11 +379,20 @@ static void seat_update_capabilities(struct sway_seat *seat) { | |||
368 | caps |= WL_SEAT_CAPABILITY_TOUCH; | 379 | caps |= WL_SEAT_CAPABILITY_TOUCH; |
369 | break; | 380 | break; |
370 | case WLR_INPUT_DEVICE_TABLET_TOOL: | 381 | case WLR_INPUT_DEVICE_TABLET_TOOL: |
382 | caps |= WL_SEAT_CAPABILITY_POINTER; | ||
383 | break; | ||
371 | case WLR_INPUT_DEVICE_TABLET_PAD: | 384 | case WLR_INPUT_DEVICE_TABLET_PAD: |
372 | break; | 385 | break; |
373 | } | 386 | } |
374 | } | 387 | } |
375 | wlr_seat_set_capabilities(seat->wlr_seat, caps); | 388 | wlr_seat_set_capabilities(seat->wlr_seat, caps); |
389 | |||
390 | // Hide cursor if seat doesn't have pointer capability | ||
391 | if ((caps & WL_SEAT_CAPABILITY_POINTER) == 0) { | ||
392 | cursor_set_image(seat->cursor, NULL, NULL); | ||
393 | } else { | ||
394 | cursor_set_image(seat->cursor, "left_ptr", NULL); | ||
395 | } | ||
376 | } | 396 | } |
377 | 397 | ||
378 | static void seat_apply_input_config(struct sway_seat *seat, | 398 | static void seat_apply_input_config(struct sway_seat *seat, |
@@ -552,8 +572,7 @@ void seat_configure_xcursor(struct sway_seat *seat) { | |||
552 | output->name, (double)output->scale); | 572 | output->name, (double)output->scale); |
553 | } | 573 | } |
554 | 574 | ||
555 | wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager, | 575 | cursor_set_image(seat->cursor, "left_ptr", NULL); |
556 | "left_ptr", seat->cursor->cursor); | ||
557 | wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, | 576 | wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, |
558 | seat->cursor->cursor->y); | 577 | seat->cursor->cursor->y); |
559 | } | 578 | } |
@@ -752,6 +771,12 @@ void seat_set_focus_warp(struct sway_seat *seat, struct sway_node *node, | |||
752 | 771 | ||
753 | seat->has_focus = true; | 772 | seat->has_focus = true; |
754 | 773 | ||
774 | if (config->smart_gaps) { | ||
775 | // When smart gaps is on, gaps may change when the focus changes so | ||
776 | // the workspace needs to be arranged | ||
777 | arrange_workspace(new_workspace); | ||
778 | } | ||
779 | |||
755 | update_debug_tree(); | 780 | update_debug_tree(); |
756 | } | 781 | } |
757 | 782 | ||