aboutsummaryrefslogtreecommitdiff
path: root/sway/input/seat.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r--sway/input/seat.c63
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) {
struct sway_node *parent = node_get_parent(node);
struct sway_node *focus = seat_get_focus(seat);
- bool set_focus =
- focus != NULL &&
- (focus == node || node_has_ancestor(focus, node)) &&
- node->type == N_CONTAINER;
+ if (node->type == N_WORKSPACE) {
+ seat_node_destroy(seat_node);
+ return;
+ }
+
+ // Even though the container being destroyed might be nowhere near the
+ // focused container, we still need to set focus_inactive on a sibling of
+ // the container being destroyed.
+ bool needs_new_focus = focus &&
+ (focus == node || node_has_ancestor(focus, node));
seat_node_destroy(seat_node);
- if (set_focus) {
- struct sway_node *next_focus = NULL;
- while (next_focus == NULL) {
- struct sway_container *con =
- seat_get_focus_inactive_view(seat, parent);
- next_focus = con ? &con->node : NULL;
+ // Find new focus_inactive (ie. sibling, or workspace if no siblings left)
+ struct sway_node *next_focus = NULL;
+ while (next_focus == NULL) {
+ struct sway_container *con =
+ seat_get_focus_inactive_view(seat, parent);
+ next_focus = con ? &con->node : NULL;
- if (next_focus == NULL && parent->type == N_WORKSPACE) {
- next_focus = parent;
- break;
- }
-
- parent = node_get_parent(parent);
+ if (next_focus == NULL && parent->type == N_WORKSPACE) {
+ next_focus = parent;
+ break;
}
- // the structure change might have caused it to move up to the top of
+ parent = node_get_parent(parent);
+ }
+
+ if (needs_new_focus) {
+ // The structure change might have caused it to move up to the top of
// the focus stack without sending focus notifications to the view
seat_send_focus(next_focus, seat);
seat_set_focus(seat, next_focus);
+ } else {
+ // Setting focus_inactive
+ seat_set_focus_warp(seat, next_focus, false, false);
+ seat_set_focus_warp(seat, focus, false, false);
}
}
@@ -368,11 +379,20 @@ static void seat_update_capabilities(struct sway_seat *seat) {
caps |= WL_SEAT_CAPABILITY_TOUCH;
break;
case WLR_INPUT_DEVICE_TABLET_TOOL:
+ caps |= WL_SEAT_CAPABILITY_POINTER;
+ break;
case WLR_INPUT_DEVICE_TABLET_PAD:
break;
}
}
wlr_seat_set_capabilities(seat->wlr_seat, caps);
+
+ // Hide cursor if seat doesn't have pointer capability
+ if ((caps & WL_SEAT_CAPABILITY_POINTER) == 0) {
+ cursor_set_image(seat->cursor, NULL, NULL);
+ } else {
+ cursor_set_image(seat->cursor, "left_ptr", NULL);
+ }
}
static void seat_apply_input_config(struct sway_seat *seat,
@@ -552,8 +572,7 @@ void seat_configure_xcursor(struct sway_seat *seat) {
output->name, (double)output->scale);
}
- wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager,
- "left_ptr", seat->cursor->cursor);
+ cursor_set_image(seat->cursor, "left_ptr", NULL);
wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x,
seat->cursor->cursor->y);
}
@@ -752,6 +771,12 @@ void seat_set_focus_warp(struct sway_seat *seat, struct sway_node *node,
seat->has_focus = true;
+ if (config->smart_gaps) {
+ // When smart gaps is on, gaps may change when the focus changes so
+ // the workspace needs to be arranged
+ arrange_workspace(new_workspace);
+ }
+
update_debug_tree();
}