diff options
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r-- | sway/input/seat.c | 530 |
1 files changed, 335 insertions, 195 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c index 1f5865ee..0c5672bc 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -1,25 +1,27 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <assert.h> | 1 | #include <assert.h> |
3 | #include <linux/input-event-codes.h> | 2 | #include <linux/input-event-codes.h> |
4 | #include <string.h> | 3 | #include <string.h> |
5 | #include <strings.h> | 4 | #include <strings.h> |
6 | #include <time.h> | 5 | #include <time.h> |
6 | #include <wlr/config.h> | ||
7 | #include <wlr/types/wlr_cursor.h> | 7 | #include <wlr/types/wlr_cursor.h> |
8 | #include <wlr/types/wlr_data_device.h> | 8 | #include <wlr/types/wlr_data_device.h> |
9 | #include <wlr/types/wlr_idle.h> | 9 | #include <wlr/types/wlr_idle_notify_v1.h> |
10 | #include <wlr/types/wlr_keyboard_group.h> | 10 | #include <wlr/types/wlr_keyboard_group.h> |
11 | #include <wlr/types/wlr_output_layout.h> | 11 | #include <wlr/types/wlr_output_layout.h> |
12 | #include <wlr/types/wlr_primary_selection.h> | 12 | #include <wlr/types/wlr_primary_selection.h> |
13 | #include <wlr/types/wlr_tablet_v2.h> | 13 | #include <wlr/types/wlr_tablet_v2.h> |
14 | #include <wlr/types/wlr_touch.h> | ||
14 | #include <wlr/types/wlr_xcursor_manager.h> | 15 | #include <wlr/types/wlr_xcursor_manager.h> |
15 | #include "config.h" | 16 | #include "config.h" |
16 | #include "list.h" | 17 | #include "list.h" |
17 | #include "log.h" | 18 | #include "log.h" |
18 | #include "sway/config.h" | 19 | #include "sway/config.h" |
19 | #include "sway/desktop.h" | 20 | #include "sway/scene_descriptor.h" |
20 | #include "sway/input/cursor.h" | 21 | #include "sway/input/cursor.h" |
21 | #include "sway/input/input-manager.h" | 22 | #include "sway/input/input-manager.h" |
22 | #include "sway/input/keyboard.h" | 23 | #include "sway/input/keyboard.h" |
24 | #include "sway/input/libinput.h" | ||
23 | #include "sway/input/seat.h" | 25 | #include "sway/input/seat.h" |
24 | #include "sway/input/switch.h" | 26 | #include "sway/input/switch.h" |
25 | #include "sway/input/tablet.h" | 27 | #include "sway/input/tablet.h" |
@@ -41,6 +43,7 @@ static void seat_device_destroy(struct sway_seat_device *seat_device) { | |||
41 | sway_keyboard_destroy(seat_device->keyboard); | 43 | sway_keyboard_destroy(seat_device->keyboard); |
42 | sway_tablet_destroy(seat_device->tablet); | 44 | sway_tablet_destroy(seat_device->tablet); |
43 | sway_tablet_pad_destroy(seat_device->tablet_pad); | 45 | sway_tablet_pad_destroy(seat_device->tablet_pad); |
46 | sway_switch_destroy(seat_device->switch_device); | ||
44 | wlr_cursor_detach_input_device(seat_device->sway_seat->cursor->cursor, | 47 | wlr_cursor_detach_input_device(seat_device->sway_seat->cursor->cursor, |
45 | seat_device->input_device->wlr_device); | 48 | seat_device->input_device->wlr_device); |
46 | wl_list_remove(&seat_device->link); | 49 | wl_list_remove(&seat_device->link); |
@@ -50,10 +53,26 @@ static void seat_device_destroy(struct sway_seat_device *seat_device) { | |||
50 | static void seat_node_destroy(struct sway_seat_node *seat_node) { | 53 | static void seat_node_destroy(struct sway_seat_node *seat_node) { |
51 | wl_list_remove(&seat_node->destroy.link); | 54 | wl_list_remove(&seat_node->destroy.link); |
52 | wl_list_remove(&seat_node->link); | 55 | wl_list_remove(&seat_node->link); |
56 | |||
57 | /* | ||
58 | * This is the only time we remove items from the focus stack without | ||
59 | * immediately re-adding them. If we just removed the last thing, | ||
60 | * mark that nothing has focus anymore. | ||
61 | */ | ||
62 | if (wl_list_empty(&seat_node->seat->focus_stack)) { | ||
63 | seat_node->seat->has_focus = false; | ||
64 | } | ||
65 | |||
53 | free(seat_node); | 66 | free(seat_node); |
54 | } | 67 | } |
55 | 68 | ||
56 | void seat_destroy(struct sway_seat *seat) { | 69 | void seat_destroy(struct sway_seat *seat) { |
70 | wlr_seat_destroy(seat->wlr_seat); | ||
71 | } | ||
72 | |||
73 | static void handle_seat_destroy(struct wl_listener *listener, void *data) { | ||
74 | struct sway_seat *seat = wl_container_of(listener, seat, destroy); | ||
75 | |||
57 | if (seat == config->handler_context.seat) { | 76 | if (seat == config->handler_context.seat) { |
58 | config->handler_context.seat = input_manager_get_default_seat(); | 77 | config->handler_context.seat = input_manager_get_default_seat(); |
59 | } | 78 | } |
@@ -74,10 +93,11 @@ void seat_destroy(struct sway_seat *seat) { | |||
74 | wl_list_remove(&seat->request_set_selection.link); | 93 | wl_list_remove(&seat->request_set_selection.link); |
75 | wl_list_remove(&seat->request_set_primary_selection.link); | 94 | wl_list_remove(&seat->request_set_primary_selection.link); |
76 | wl_list_remove(&seat->link); | 95 | wl_list_remove(&seat->link); |
77 | wlr_seat_destroy(seat->wlr_seat); | 96 | wl_list_remove(&seat->destroy.link); |
78 | for (int i = 0; i < seat->deferred_bindings->length; i++) { | 97 | for (int i = 0; i < seat->deferred_bindings->length; i++) { |
79 | free_sway_binding(seat->deferred_bindings->items[i]); | 98 | free_sway_binding(seat->deferred_bindings->items[i]); |
80 | } | 99 | } |
100 | wlr_scene_node_destroy(&seat->scene_tree->node); | ||
81 | list_free(seat->deferred_bindings); | 101 | list_free(seat->deferred_bindings); |
82 | free(seat->prev_workspace_name); | 102 | free(seat->prev_workspace_name); |
83 | free(seat); | 103 | free(seat); |
@@ -85,21 +105,10 @@ void seat_destroy(struct sway_seat *seat) { | |||
85 | 105 | ||
86 | void seat_idle_notify_activity(struct sway_seat *seat, | 106 | void seat_idle_notify_activity(struct sway_seat *seat, |
87 | enum sway_input_idle_source source) { | 107 | enum sway_input_idle_source source) { |
88 | uint32_t mask = seat->idle_inhibit_sources; | 108 | if ((source & seat->idle_inhibit_sources) == 0) { |
89 | struct wlr_idle_timeout *timeout; | 109 | return; |
90 | int ntimers = 0, nidle = 0; | ||
91 | wl_list_for_each(timeout, &server.idle->idle_timers, link) { | ||
92 | ++ntimers; | ||
93 | if (timeout->idle_state) { | ||
94 | ++nidle; | ||
95 | } | ||
96 | } | ||
97 | if (nidle == ntimers) { | ||
98 | mask = seat->idle_wake_sources; | ||
99 | } | ||
100 | if ((source & mask) > 0) { | ||
101 | wlr_idle_notify_activity(server.idle, seat->wlr_seat); | ||
102 | } | 110 | } |
111 | wlr_idle_notifier_v1_notify_activity(server.idle_notifier_v1, seat->wlr_seat); | ||
103 | } | 112 | } |
104 | 113 | ||
105 | /** | 114 | /** |
@@ -129,7 +138,7 @@ static struct sway_keyboard *sway_keyboard_for_wlr_keyboard( | |||
129 | if (input_device->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { | 138 | if (input_device->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { |
130 | continue; | 139 | continue; |
131 | } | 140 | } |
132 | if (input_device->wlr_device->keyboard == wlr_keyboard) { | 141 | if (input_device->wlr_device == &wlr_keyboard->base) { |
133 | return seat_device->keyboard; | 142 | return seat_device->keyboard; |
134 | } | 143 | } |
135 | } | 144 | } |
@@ -137,7 +146,7 @@ static struct sway_keyboard *sway_keyboard_for_wlr_keyboard( | |||
137 | wl_list_for_each(group, &seat->keyboard_groups, link) { | 146 | wl_list_for_each(group, &seat->keyboard_groups, link) { |
138 | struct sway_input_device *input_device = | 147 | struct sway_input_device *input_device = |
139 | group->seat_device->input_device; | 148 | group->seat_device->input_device; |
140 | if (input_device->wlr_device->keyboard == wlr_keyboard) { | 149 | if (input_device->wlr_device == &wlr_keyboard->base) { |
141 | return group->seat_device->keyboard; | 150 | return group->seat_device->keyboard; |
142 | } | 151 | } |
143 | } | 152 | } |
@@ -161,11 +170,11 @@ static void seat_keyboard_notify_enter(struct sway_seat *seat, | |||
161 | state->pressed_keycodes, state->npressed, &keyboard->modifiers); | 170 | state->pressed_keycodes, state->npressed, &keyboard->modifiers); |
162 | } | 171 | } |
163 | 172 | ||
164 | static void seat_tablet_pads_notify_enter(struct sway_seat *seat, | 173 | static void seat_tablet_pads_set_focus(struct sway_seat *seat, |
165 | struct wlr_surface *surface) { | 174 | struct wlr_surface *surface) { |
166 | struct sway_seat_device *seat_device; | 175 | struct sway_seat_device *seat_device; |
167 | wl_list_for_each(seat_device, &seat->devices, link) { | 176 | wl_list_for_each(seat_device, &seat->devices, link) { |
168 | sway_tablet_pad_notify_enter(seat_device->tablet_pad, surface); | 177 | sway_tablet_pad_set_focus(seat_device->tablet_pad, surface); |
169 | } | 178 | } |
170 | } | 179 | } |
171 | 180 | ||
@@ -189,7 +198,7 @@ static void seat_send_focus(struct sway_node *node, struct sway_seat *seat) { | |||
189 | #endif | 198 | #endif |
190 | 199 | ||
191 | seat_keyboard_notify_enter(seat, view->surface); | 200 | seat_keyboard_notify_enter(seat, view->surface); |
192 | seat_tablet_pads_notify_enter(seat, view->surface); | 201 | seat_tablet_pads_set_focus(seat, view->surface); |
193 | sway_input_method_relay_set_focus(&seat->im_relay, view->surface); | 202 | sway_input_method_relay_set_focus(&seat->im_relay, view->surface); |
194 | 203 | ||
195 | struct wlr_pointer_constraint_v1 *constraint = | 204 | struct wlr_pointer_constraint_v1 *constraint = |
@@ -209,14 +218,13 @@ void seat_for_each_node(struct sway_seat *seat, | |||
209 | 218 | ||
210 | struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat, | 219 | struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat, |
211 | struct sway_node *ancestor) { | 220 | struct sway_node *ancestor) { |
212 | if (ancestor->type == N_CONTAINER && ancestor->sway_container->view) { | 221 | if (node_is_view(ancestor)) { |
213 | return ancestor->sway_container; | 222 | return ancestor->sway_container; |
214 | } | 223 | } |
215 | struct sway_seat_node *current; | 224 | struct sway_seat_node *current; |
216 | wl_list_for_each(current, &seat->focus_stack, link) { | 225 | wl_list_for_each(current, &seat->focus_stack, link) { |
217 | struct sway_node *node = current->node; | 226 | struct sway_node *node = current->node; |
218 | if (node->type == N_CONTAINER && node->sway_container->view && | 227 | if (node_is_view(node) && node_has_ancestor(node, ancestor)) { |
219 | node_has_ancestor(node, ancestor)) { | ||
220 | return node->sway_container; | 228 | return node->sway_container; |
221 | } | 229 | } |
222 | } | 230 | } |
@@ -235,7 +243,7 @@ static void handle_seat_node_destroy(struct wl_listener *listener, void *data) { | |||
235 | seat_node_destroy(seat_node); | 243 | seat_node_destroy(seat_node); |
236 | // If an unmanaged or layer surface is focused when an output gets | 244 | // If an unmanaged or layer surface is focused when an output gets |
237 | // disabled and an empty workspace on the output was focused by the | 245 | // disabled and an empty workspace on the output was focused by the |
238 | // seat, the seat needs to refocus it's focus inactive to update the | 246 | // seat, the seat needs to refocus its focus inactive to update the |
239 | // value of seat->workspace. | 247 | // value of seat->workspace. |
240 | if (seat->workspace == node->sway_workspace) { | 248 | if (seat->workspace == node->sway_workspace) { |
241 | struct sway_node *node = seat_get_focus_inactive(seat, &root->node); | 249 | struct sway_node *node = seat_get_focus_inactive(seat, &root->node); |
@@ -309,8 +317,8 @@ static void handle_seat_node_destroy(struct wl_listener *listener, void *data) { | |||
309 | // Setting focus_inactive | 317 | // Setting focus_inactive |
310 | focus = seat_get_focus_inactive(seat, &root->node); | 318 | focus = seat_get_focus_inactive(seat, &root->node); |
311 | seat_set_raw_focus(seat, next_focus); | 319 | seat_set_raw_focus(seat, next_focus); |
312 | if (focus->type == N_CONTAINER && focus->sway_container->workspace) { | 320 | if (focus->type == N_CONTAINER && focus->sway_container->pending.workspace) { |
313 | seat_set_raw_focus(seat, &focus->sway_container->workspace->node); | 321 | seat_set_raw_focus(seat, &focus->sway_container->pending.workspace->node); |
314 | } | 322 | } |
315 | seat_set_raw_focus(seat, focus); | 323 | seat_set_raw_focus(seat, focus); |
316 | } | 324 | } |
@@ -351,25 +359,15 @@ static void handle_new_node(struct wl_listener *listener, void *data) { | |||
351 | seat_node_from_node(seat, node); | 359 | seat_node_from_node(seat, node); |
352 | } | 360 | } |
353 | 361 | ||
354 | static void drag_icon_damage_whole(struct sway_drag_icon *icon) { | 362 | static void drag_icon_update_position(struct sway_seat *seat, struct wlr_scene_node *node) { |
355 | if (!icon->wlr_drag_icon->mapped) { | 363 | struct wlr_drag_icon *wlr_icon = scene_descriptor_try_get(node, SWAY_SCENE_DESC_DRAG_ICON); |
356 | return; | ||
357 | } | ||
358 | desktop_damage_surface(icon->wlr_drag_icon->surface, icon->x, icon->y, true); | ||
359 | } | ||
360 | |||
361 | void drag_icon_update_position(struct sway_drag_icon *icon) { | ||
362 | drag_icon_damage_whole(icon); | ||
363 | |||
364 | struct wlr_drag_icon *wlr_icon = icon->wlr_drag_icon; | ||
365 | struct sway_seat *seat = icon->seat; | ||
366 | struct wlr_cursor *cursor = seat->cursor->cursor; | 364 | struct wlr_cursor *cursor = seat->cursor->cursor; |
365 | |||
367 | switch (wlr_icon->drag->grab_type) { | 366 | switch (wlr_icon->drag->grab_type) { |
368 | case WLR_DRAG_GRAB_KEYBOARD: | 367 | case WLR_DRAG_GRAB_KEYBOARD: |
369 | return; | 368 | return; |
370 | case WLR_DRAG_GRAB_KEYBOARD_POINTER: | 369 | case WLR_DRAG_GRAB_KEYBOARD_POINTER: |
371 | icon->x = cursor->x; | 370 | wlr_scene_node_set_position(node, cursor->x, cursor->y); |
372 | icon->y = cursor->y; | ||
373 | break; | 371 | break; |
374 | case WLR_DRAG_GRAB_KEYBOARD_TOUCH:; | 372 | case WLR_DRAG_GRAB_KEYBOARD_TOUCH:; |
375 | struct wlr_touch_point *point = | 373 | struct wlr_touch_point *point = |
@@ -377,39 +375,15 @@ void drag_icon_update_position(struct sway_drag_icon *icon) { | |||
377 | if (point == NULL) { | 375 | if (point == NULL) { |
378 | return; | 376 | return; |
379 | } | 377 | } |
380 | icon->x = seat->touch_x; | 378 | wlr_scene_node_set_position(node, seat->touch_x, seat->touch_y); |
381 | icon->y = seat->touch_y; | ||
382 | } | 379 | } |
383 | |||
384 | drag_icon_damage_whole(icon); | ||
385 | } | 380 | } |
386 | 381 | ||
387 | static void drag_icon_handle_surface_commit(struct wl_listener *listener, | 382 | void drag_icons_update_position(struct sway_seat *seat) { |
388 | void *data) { | 383 | struct wlr_scene_node *node; |
389 | struct sway_drag_icon *icon = | 384 | wl_list_for_each(node, &seat->drag_icons->children, link) { |
390 | wl_container_of(listener, icon, surface_commit); | 385 | drag_icon_update_position(seat, node); |
391 | drag_icon_update_position(icon); | 386 | } |
392 | } | ||
393 | |||
394 | static void drag_icon_handle_map(struct wl_listener *listener, void *data) { | ||
395 | struct sway_drag_icon *icon = wl_container_of(listener, icon, map); | ||
396 | drag_icon_damage_whole(icon); | ||
397 | } | ||
398 | |||
399 | static void drag_icon_handle_unmap(struct wl_listener *listener, void *data) { | ||
400 | struct sway_drag_icon *icon = wl_container_of(listener, icon, unmap); | ||
401 | drag_icon_damage_whole(icon); | ||
402 | } | ||
403 | |||
404 | static void drag_icon_handle_destroy(struct wl_listener *listener, void *data) { | ||
405 | struct sway_drag_icon *icon = wl_container_of(listener, icon, destroy); | ||
406 | icon->wlr_drag_icon->data = NULL; | ||
407 | wl_list_remove(&icon->link); | ||
408 | wl_list_remove(&icon->surface_commit.link); | ||
409 | wl_list_remove(&icon->unmap.link); | ||
410 | wl_list_remove(&icon->map.link); | ||
411 | wl_list_remove(&icon->destroy.link); | ||
412 | free(icon); | ||
413 | } | 387 | } |
414 | 388 | ||
415 | static void drag_handle_destroy(struct wl_listener *listener, void *data) { | 389 | static void drag_handle_destroy(struct wl_listener *listener, void *data) { |
@@ -481,27 +455,20 @@ static void handle_start_drag(struct wl_listener *listener, void *data) { | |||
481 | 455 | ||
482 | struct wlr_drag_icon *wlr_drag_icon = wlr_drag->icon; | 456 | struct wlr_drag_icon *wlr_drag_icon = wlr_drag->icon; |
483 | if (wlr_drag_icon != NULL) { | 457 | if (wlr_drag_icon != NULL) { |
484 | struct sway_drag_icon *icon = calloc(1, sizeof(struct sway_drag_icon)); | 458 | struct wlr_scene_tree *tree = wlr_scene_drag_icon_create(seat->drag_icons, wlr_drag_icon); |
485 | if (icon == NULL) { | 459 | if (!tree) { |
486 | sway_log(SWAY_ERROR, "Allocation failed"); | 460 | sway_log(SWAY_ERROR, "Failed to allocate a drag icon scene tree"); |
487 | return; | 461 | return; |
488 | } | 462 | } |
489 | icon->seat = seat; | ||
490 | icon->wlr_drag_icon = wlr_drag_icon; | ||
491 | wlr_drag_icon->data = icon; | ||
492 | |||
493 | icon->surface_commit.notify = drag_icon_handle_surface_commit; | ||
494 | wl_signal_add(&wlr_drag_icon->surface->events.commit, &icon->surface_commit); | ||
495 | icon->unmap.notify = drag_icon_handle_unmap; | ||
496 | wl_signal_add(&wlr_drag_icon->events.unmap, &icon->unmap); | ||
497 | icon->map.notify = drag_icon_handle_map; | ||
498 | wl_signal_add(&wlr_drag_icon->events.map, &icon->map); | ||
499 | icon->destroy.notify = drag_icon_handle_destroy; | ||
500 | wl_signal_add(&wlr_drag_icon->events.destroy, &icon->destroy); | ||
501 | 463 | ||
502 | wl_list_insert(&root->drag_icons, &icon->link); | 464 | if (!scene_descriptor_assign(&tree->node, SWAY_SCENE_DESC_DRAG_ICON, |
465 | wlr_drag_icon)) { | ||
466 | sway_log(SWAY_ERROR, "Failed to allocate a drag icon scene descriptor"); | ||
467 | wlr_scene_node_destroy(&tree->node); | ||
468 | return; | ||
469 | } | ||
503 | 470 | ||
504 | drag_icon_update_position(icon); | 471 | drag_icon_update_position(seat, &tree->node); |
505 | } | 472 | } |
506 | seatop_begin_default(seat); | 473 | seatop_begin_default(seat); |
507 | } | 474 | } |
@@ -548,8 +515,18 @@ struct sway_seat *seat_create(const char *seat_name) { | |||
548 | return NULL; | 515 | return NULL; |
549 | } | 516 | } |
550 | 517 | ||
518 | bool failed = false; | ||
519 | seat->scene_tree = alloc_scene_tree(root->layers.seat, &failed); | ||
520 | seat->drag_icons = alloc_scene_tree(seat->scene_tree, &failed); | ||
521 | if (failed) { | ||
522 | wlr_scene_node_destroy(&seat->scene_tree->node); | ||
523 | free(seat); | ||
524 | return NULL; | ||
525 | } | ||
526 | |||
551 | seat->wlr_seat = wlr_seat_create(server.wl_display, seat_name); | 527 | seat->wlr_seat = wlr_seat_create(server.wl_display, seat_name); |
552 | if (!sway_assert(seat->wlr_seat, "could not allocate seat")) { | 528 | if (!sway_assert(seat->wlr_seat, "could not allocate seat")) { |
529 | wlr_scene_node_destroy(&seat->scene_tree->node); | ||
553 | free(seat); | 530 | free(seat); |
554 | return NULL; | 531 | return NULL; |
555 | } | 532 | } |
@@ -557,11 +534,15 @@ struct sway_seat *seat_create(const char *seat_name) { | |||
557 | 534 | ||
558 | seat->cursor = sway_cursor_create(seat); | 535 | seat->cursor = sway_cursor_create(seat); |
559 | if (!seat->cursor) { | 536 | if (!seat->cursor) { |
537 | wlr_scene_node_destroy(&seat->scene_tree->node); | ||
560 | wlr_seat_destroy(seat->wlr_seat); | 538 | wlr_seat_destroy(seat->wlr_seat); |
561 | free(seat); | 539 | free(seat); |
562 | return NULL; | 540 | return NULL; |
563 | } | 541 | } |
564 | 542 | ||
543 | seat->destroy.notify = handle_seat_destroy; | ||
544 | wl_signal_add(&seat->wlr_seat->events.destroy, &seat->destroy); | ||
545 | |||
565 | seat->idle_inhibit_sources = seat->idle_wake_sources = | 546 | seat->idle_inhibit_sources = seat->idle_wake_sources = |
566 | IDLE_SOURCE_KEYBOARD | | 547 | IDLE_SOURCE_KEYBOARD | |
567 | IDLE_SOURCE_POINTER | | 548 | IDLE_SOURCE_POINTER | |
@@ -635,7 +616,7 @@ static void seat_update_capabilities(struct sway_seat *seat) { | |||
635 | case WLR_INPUT_DEVICE_TOUCH: | 616 | case WLR_INPUT_DEVICE_TOUCH: |
636 | caps |= WL_SEAT_CAPABILITY_TOUCH; | 617 | caps |= WL_SEAT_CAPABILITY_TOUCH; |
637 | break; | 618 | break; |
638 | case WLR_INPUT_DEVICE_TABLET_TOOL: | 619 | case WLR_INPUT_DEVICE_TABLET: |
639 | caps |= WL_SEAT_CAPABILITY_POINTER; | 620 | caps |= WL_SEAT_CAPABILITY_POINTER; |
640 | break; | 621 | break; |
641 | case WLR_INPUT_DEVICE_SWITCH: | 622 | case WLR_INPUT_DEVICE_SWITCH: |
@@ -653,7 +634,7 @@ static void seat_update_capabilities(struct sway_seat *seat) { | |||
653 | } else { | 634 | } else { |
654 | wlr_seat_set_capabilities(seat->wlr_seat, caps); | 635 | wlr_seat_set_capabilities(seat->wlr_seat, caps); |
655 | if ((previous_caps & WL_SEAT_CAPABILITY_POINTER) == 0) { | 636 | if ((previous_caps & WL_SEAT_CAPABILITY_POINTER) == 0) { |
656 | cursor_set_image(seat->cursor, "left_ptr", NULL); | 637 | cursor_set_image(seat->cursor, "default", NULL); |
657 | } | 638 | } |
658 | } | 639 | } |
659 | } | 640 | } |
@@ -666,12 +647,55 @@ static void seat_reset_input_config(struct sway_seat *seat, | |||
666 | sway_device->input_device->wlr_device, NULL); | 647 | sway_device->input_device->wlr_device, NULL); |
667 | } | 648 | } |
668 | 649 | ||
669 | static void seat_apply_input_config(struct sway_seat *seat, | 650 | static bool has_prefix(const char *str, const char *prefix) { |
651 | return strncmp(str, prefix, strlen(prefix)) == 0; | ||
652 | } | ||
653 | |||
654 | /** | ||
655 | * Get the name of the built-in output, if any. Returns NULL if there isn't | ||
656 | * exactly one built-in output. | ||
657 | */ | ||
658 | static const char *get_builtin_output_name(void) { | ||
659 | const char *match = NULL; | ||
660 | for (int i = 0; i < root->outputs->length; ++i) { | ||
661 | struct sway_output *output = root->outputs->items[i]; | ||
662 | const char *name = output->wlr_output->name; | ||
663 | if (has_prefix(name, "eDP-") || has_prefix(name, "LVDS-") || | ||
664 | has_prefix(name, "DSI-")) { | ||
665 | if (match != NULL) { | ||
666 | return NULL; | ||
667 | } | ||
668 | match = name; | ||
669 | } | ||
670 | } | ||
671 | return match; | ||
672 | } | ||
673 | |||
674 | static bool is_touch_or_tablet_tool(struct sway_seat_device *seat_device) { | ||
675 | switch (seat_device->input_device->wlr_device->type) { | ||
676 | case WLR_INPUT_DEVICE_TOUCH: | ||
677 | case WLR_INPUT_DEVICE_TABLET: | ||
678 | return true; | ||
679 | default: | ||
680 | return false; | ||
681 | } | ||
682 | } | ||
683 | |||
684 | static void seat_apply_input_mapping(struct sway_seat *seat, | ||
670 | struct sway_seat_device *sway_device) { | 685 | struct sway_seat_device *sway_device) { |
671 | struct input_config *ic = | 686 | struct input_config *ic = |
672 | input_device_get_config(sway_device->input_device); | 687 | input_device_get_config(sway_device->input_device); |
673 | 688 | ||
674 | sway_log(SWAY_DEBUG, "Applying input config to %s", | 689 | switch (sway_device->input_device->wlr_device->type) { |
690 | case WLR_INPUT_DEVICE_POINTER: | ||
691 | case WLR_INPUT_DEVICE_TOUCH: | ||
692 | case WLR_INPUT_DEVICE_TABLET: | ||
693 | break; | ||
694 | default: | ||
695 | return; // these devices don't support mappings | ||
696 | } | ||
697 | |||
698 | sway_log(SWAY_DEBUG, "Applying input mapping to %s", | ||
675 | sway_device->input_device->identifier); | 699 | sway_device->input_device->identifier); |
676 | 700 | ||
677 | const char *mapped_to_output = ic == NULL ? NULL : ic->mapped_to_output; | 701 | const char *mapped_to_output = ic == NULL ? NULL : ic->mapped_to_output; |
@@ -680,8 +704,38 @@ static void seat_apply_input_config(struct sway_seat *seat, | |||
680 | ic == NULL ? MAPPED_TO_DEFAULT : ic->mapped_to; | 704 | ic == NULL ? MAPPED_TO_DEFAULT : ic->mapped_to; |
681 | 705 | ||
682 | switch (mapped_to) { | 706 | switch (mapped_to) { |
683 | case MAPPED_TO_DEFAULT: | 707 | case MAPPED_TO_DEFAULT:; |
684 | mapped_to_output = sway_device->input_device->wlr_device->output_name; | 708 | /* |
709 | * If the wlroots backend provides an output name, use that. | ||
710 | * | ||
711 | * Otherwise, try to map built-in touch and pointer devices to the | ||
712 | * built-in output. | ||
713 | */ | ||
714 | struct wlr_input_device *dev = sway_device->input_device->wlr_device; | ||
715 | switch (dev->type) { | ||
716 | case WLR_INPUT_DEVICE_POINTER: | ||
717 | mapped_to_output = wlr_pointer_from_input_device(dev)->output_name; | ||
718 | break; | ||
719 | case WLR_INPUT_DEVICE_TOUCH: | ||
720 | mapped_to_output = wlr_touch_from_input_device(dev)->output_name; | ||
721 | break; | ||
722 | default: | ||
723 | mapped_to_output = NULL; | ||
724 | break; | ||
725 | } | ||
726 | #if WLR_HAS_LIBINPUT_BACKEND | ||
727 | if (mapped_to_output == NULL && is_touch_or_tablet_tool(sway_device) && | ||
728 | sway_libinput_device_is_builtin(sway_device->input_device)) { | ||
729 | mapped_to_output = get_builtin_output_name(); | ||
730 | if (mapped_to_output) { | ||
731 | sway_log(SWAY_DEBUG, "Auto-detected output '%s' for device '%s'", | ||
732 | mapped_to_output, sway_device->input_device->identifier); | ||
733 | } | ||
734 | } | ||
735 | #else | ||
736 | (void)is_touch_or_tablet_tool; | ||
737 | (void)get_builtin_output_name; | ||
738 | #endif | ||
685 | if (mapped_to_output == NULL) { | 739 | if (mapped_to_output == NULL) { |
686 | return; | 740 | return; |
687 | } | 741 | } |
@@ -725,12 +779,9 @@ static void seat_apply_input_config(struct sway_seat *seat, | |||
725 | 779 | ||
726 | static void seat_configure_pointer(struct sway_seat *seat, | 780 | static void seat_configure_pointer(struct sway_seat *seat, |
727 | struct sway_seat_device *sway_device) { | 781 | struct sway_seat_device *sway_device) { |
728 | if ((seat->wlr_seat->capabilities & WL_SEAT_CAPABILITY_POINTER) == 0) { | 782 | seat_configure_xcursor(seat); |
729 | seat_configure_xcursor(seat); | ||
730 | } | ||
731 | wlr_cursor_attach_input_device(seat->cursor->cursor, | 783 | wlr_cursor_attach_input_device(seat->cursor->cursor, |
732 | sway_device->input_device->wlr_device); | 784 | sway_device->input_device->wlr_device); |
733 | seat_apply_input_config(seat, sway_device); | ||
734 | wl_event_source_timer_update( | 785 | wl_event_source_timer_update( |
735 | seat->cursor->hide_source, cursor_get_timeout(seat->cursor)); | 786 | seat->cursor->hide_source, cursor_get_timeout(seat->cursor)); |
736 | } | 787 | } |
@@ -741,13 +792,22 @@ static void seat_configure_keyboard(struct sway_seat *seat, | |||
741 | sway_keyboard_create(seat, seat_device); | 792 | sway_keyboard_create(seat, seat_device); |
742 | } | 793 | } |
743 | sway_keyboard_configure(seat_device->keyboard); | 794 | sway_keyboard_configure(seat_device->keyboard); |
744 | wlr_seat_set_keyboard(seat->wlr_seat, | 795 | |
745 | seat_device->input_device->wlr_device); | 796 | // We only need to update the current keyboard, as the rest will be updated |
746 | struct sway_node *focus = seat_get_focus(seat); | 797 | // as they are activated. |
747 | if (focus && node_is_view(focus)) { | 798 | struct wlr_keyboard *wlr_keyboard = |
748 | // force notify reenter to pick up the new configuration | 799 | wlr_keyboard_from_input_device(seat_device->input_device->wlr_device); |
800 | struct wlr_keyboard *current_keyboard = seat->wlr_seat->keyboard_state.keyboard; | ||
801 | if (wlr_keyboard != current_keyboard) { | ||
802 | return; | ||
803 | } | ||
804 | |||
805 | // force notify reenter to pick up the new configuration. This reuses | ||
806 | // the current focused surface to avoid breaking input grabs. | ||
807 | struct wlr_surface *surface = seat->wlr_seat->keyboard_state.focused_surface; | ||
808 | if (surface) { | ||
749 | wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat); | 809 | wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat); |
750 | seat_keyboard_notify_enter(seat, focus->sway_container->view->surface); | 810 | seat_keyboard_notify_enter(seat, surface); |
751 | } | 811 | } |
752 | } | 812 | } |
753 | 813 | ||
@@ -756,7 +816,6 @@ static void seat_configure_switch(struct sway_seat *seat, | |||
756 | if (!seat_device->switch_device) { | 816 | if (!seat_device->switch_device) { |
757 | sway_switch_create(seat, seat_device); | 817 | sway_switch_create(seat, seat_device); |
758 | } | 818 | } |
759 | seat_apply_input_config(seat, seat_device); | ||
760 | sway_switch_configure(seat_device->switch_device); | 819 | sway_switch_configure(seat_device->switch_device); |
761 | } | 820 | } |
762 | 821 | ||
@@ -764,7 +823,6 @@ static void seat_configure_touch(struct sway_seat *seat, | |||
764 | struct sway_seat_device *sway_device) { | 823 | struct sway_seat_device *sway_device) { |
765 | wlr_cursor_attach_input_device(seat->cursor->cursor, | 824 | wlr_cursor_attach_input_device(seat->cursor->cursor, |
766 | sway_device->input_device->wlr_device); | 825 | sway_device->input_device->wlr_device); |
767 | seat_apply_input_config(seat, sway_device); | ||
768 | } | 826 | } |
769 | 827 | ||
770 | static void seat_configure_tablet_tool(struct sway_seat *seat, | 828 | static void seat_configure_tablet_tool(struct sway_seat *seat, |
@@ -775,7 +833,6 @@ static void seat_configure_tablet_tool(struct sway_seat *seat, | |||
775 | sway_configure_tablet(sway_device->tablet); | 833 | sway_configure_tablet(sway_device->tablet); |
776 | wlr_cursor_attach_input_device(seat->cursor->cursor, | 834 | wlr_cursor_attach_input_device(seat->cursor->cursor, |
777 | sway_device->input_device->wlr_device); | 835 | sway_device->input_device->wlr_device); |
778 | seat_apply_input_config(seat, sway_device); | ||
779 | } | 836 | } |
780 | 837 | ||
781 | static void seat_configure_tablet_pad(struct sway_seat *seat, | 838 | static void seat_configure_tablet_pad(struct sway_seat *seat, |
@@ -825,13 +882,25 @@ void seat_configure_device(struct sway_seat *seat, | |||
825 | case WLR_INPUT_DEVICE_TOUCH: | 882 | case WLR_INPUT_DEVICE_TOUCH: |
826 | seat_configure_touch(seat, seat_device); | 883 | seat_configure_touch(seat, seat_device); |
827 | break; | 884 | break; |
828 | case WLR_INPUT_DEVICE_TABLET_TOOL: | 885 | case WLR_INPUT_DEVICE_TABLET: |
829 | seat_configure_tablet_tool(seat, seat_device); | 886 | seat_configure_tablet_tool(seat, seat_device); |
830 | break; | 887 | break; |
831 | case WLR_INPUT_DEVICE_TABLET_PAD: | 888 | case WLR_INPUT_DEVICE_TABLET_PAD: |
832 | seat_configure_tablet_pad(seat, seat_device); | 889 | seat_configure_tablet_pad(seat, seat_device); |
833 | break; | 890 | break; |
834 | } | 891 | } |
892 | |||
893 | seat_apply_input_mapping(seat, seat_device); | ||
894 | } | ||
895 | |||
896 | void seat_configure_device_mapping(struct sway_seat *seat, | ||
897 | struct sway_input_device *input_device) { | ||
898 | struct sway_seat_device *seat_device = seat_get_device(seat, input_device); | ||
899 | if (!seat_device) { | ||
900 | return; | ||
901 | } | ||
902 | |||
903 | seat_apply_input_mapping(seat, seat_device); | ||
835 | } | 904 | } |
836 | 905 | ||
837 | void seat_reset_device(struct sway_seat *seat, | 906 | void seat_reset_device(struct sway_seat *seat, |
@@ -852,7 +921,7 @@ void seat_reset_device(struct sway_seat *seat, | |||
852 | case WLR_INPUT_DEVICE_TOUCH: | 921 | case WLR_INPUT_DEVICE_TOUCH: |
853 | seat_reset_input_config(seat, seat_device); | 922 | seat_reset_input_config(seat, seat_device); |
854 | break; | 923 | break; |
855 | case WLR_INPUT_DEVICE_TABLET_TOOL: | 924 | case WLR_INPUT_DEVICE_TABLET: |
856 | seat_reset_input_config(seat, seat_device); | 925 | seat_reset_input_config(seat, seat_device); |
857 | break; | 926 | break; |
858 | case WLR_INPUT_DEVICE_TABLET_PAD: | 927 | case WLR_INPUT_DEVICE_TABLET_PAD: |
@@ -948,7 +1017,7 @@ void seat_configure_xcursor(struct sway_seat *seat) { | |||
948 | 1017 | ||
949 | wlr_xcursor_manager_load(server.xwayland.xcursor_manager, 1); | 1018 | wlr_xcursor_manager_load(server.xwayland.xcursor_manager, 1); |
950 | struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor( | 1019 | struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor( |
951 | server.xwayland.xcursor_manager, "left_ptr", 1); | 1020 | server.xwayland.xcursor_manager, "default", 1); |
952 | if (xcursor != NULL) { | 1021 | if (xcursor != NULL) { |
953 | struct wlr_xcursor_image *image = xcursor->images[0]; | 1022 | struct wlr_xcursor_image *image = xcursor->images[0]; |
954 | wlr_xwayland_set_cursor( | 1023 | wlr_xwayland_set_cursor( |
@@ -974,32 +1043,35 @@ void seat_configure_xcursor(struct sway_seat *seat) { | |||
974 | sway_log(SWAY_ERROR, | 1043 | sway_log(SWAY_ERROR, |
975 | "Cannot create XCursor manager for theme '%s'", cursor_theme); | 1044 | "Cannot create XCursor manager for theme '%s'", cursor_theme); |
976 | } | 1045 | } |
977 | } | ||
978 | 1046 | ||
979 | for (int i = 0; i < root->outputs->length; ++i) { | 1047 | |
980 | struct sway_output *sway_output = root->outputs->items[i]; | 1048 | for (int i = 0; i < root->outputs->length; ++i) { |
981 | struct wlr_output *output = sway_output->wlr_output; | 1049 | struct sway_output *sway_output = root->outputs->items[i]; |
982 | bool result = | 1050 | struct wlr_output *output = sway_output->wlr_output; |
983 | wlr_xcursor_manager_load(seat->cursor->xcursor_manager, | 1051 | bool result = |
984 | output->scale); | 1052 | wlr_xcursor_manager_load(seat->cursor->xcursor_manager, |
985 | if (!result) { | 1053 | output->scale); |
986 | sway_log(SWAY_ERROR, | 1054 | if (!result) { |
987 | "Cannot load xcursor theme for output '%s' with scale %f", | 1055 | sway_log(SWAY_ERROR, |
988 | output->name, output->scale); | 1056 | "Cannot load xcursor theme for output '%s' with scale %f", |
1057 | output->name, output->scale); | ||
1058 | } | ||
989 | } | 1059 | } |
990 | } | ||
991 | 1060 | ||
992 | // Reset the cursor so that we apply it to outputs that just appeared | 1061 | // Reset the cursor so that we apply it to outputs that just appeared |
993 | cursor_set_image(seat->cursor, NULL, NULL); | 1062 | cursor_set_image(seat->cursor, NULL, NULL); |
994 | cursor_set_image(seat->cursor, "left_ptr", NULL); | 1063 | cursor_set_image(seat->cursor, "default", NULL); |
995 | wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, | 1064 | wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, |
996 | seat->cursor->cursor->y); | 1065 | seat->cursor->cursor->y); |
1066 | } | ||
997 | } | 1067 | } |
998 | 1068 | ||
999 | bool seat_is_input_allowed(struct sway_seat *seat, | 1069 | bool seat_is_input_allowed(struct sway_seat *seat, |
1000 | struct wlr_surface *surface) { | 1070 | struct wlr_surface *surface) { |
1001 | struct wl_client *client = wl_resource_get_client(surface->resource); | 1071 | if (server.session_lock.lock) { |
1002 | return !seat->exclusive_client || seat->exclusive_client == client; | 1072 | return sway_session_lock_has_surface(server.session_lock.lock, surface); |
1073 | } | ||
1074 | return true; | ||
1003 | } | 1075 | } |
1004 | 1076 | ||
1005 | static void send_unfocus(struct sway_container *con, void *data) { | 1077 | static void send_unfocus(struct sway_container *con, void *data) { |
@@ -1058,15 +1130,7 @@ void seat_set_raw_focus(struct sway_seat *seat, struct sway_node *node) { | |||
1058 | } | 1130 | } |
1059 | } | 1131 | } |
1060 | 1132 | ||
1061 | void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { | 1133 | static void seat_set_workspace_focus(struct sway_seat *seat, struct sway_node *node) { |
1062 | if (seat->focused_layer) { | ||
1063 | struct wlr_layer_surface_v1 *layer = seat->focused_layer; | ||
1064 | seat_set_focus_layer(seat, NULL); | ||
1065 | seat_set_focus(seat, node); | ||
1066 | seat_set_focus_layer(seat, layer); | ||
1067 | return; | ||
1068 | } | ||
1069 | |||
1070 | struct sway_node *last_focus = seat_get_focus(seat); | 1134 | struct sway_node *last_focus = seat_get_focus(seat); |
1071 | if (last_focus == node) { | 1135 | if (last_focus == node) { |
1072 | return; | 1136 | return; |
@@ -1086,30 +1150,19 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { | |||
1086 | } | 1150 | } |
1087 | 1151 | ||
1088 | struct sway_workspace *new_workspace = node->type == N_WORKSPACE ? | 1152 | struct sway_workspace *new_workspace = node->type == N_WORKSPACE ? |
1089 | node->sway_workspace : node->sway_container->workspace; | 1153 | node->sway_workspace : node->sway_container->pending.workspace; |
1090 | struct sway_container *container = node->type == N_CONTAINER ? | 1154 | struct sway_container *container = node->type == N_CONTAINER ? |
1091 | node->sway_container : NULL; | 1155 | node->sway_container : NULL; |
1092 | 1156 | ||
1093 | // Deny setting focus to a view which is hidden by a fullscreen container | 1157 | // Deny setting focus to a view which is hidden by a fullscreen container or global |
1094 | if (new_workspace && new_workspace->fullscreen && container && | 1158 | if (container && container_obstructing_fullscreen_container(container)) { |
1095 | !container_is_fullscreen_or_child(container)) { | 1159 | return; |
1096 | // Unless it's a transient container | ||
1097 | if (!container_is_transient_for(container, new_workspace->fullscreen)) { | ||
1098 | return; | ||
1099 | } | ||
1100 | } | 1160 | } |
1161 | |||
1101 | // Deny setting focus to a workspace node when using fullscreen global | 1162 | // Deny setting focus to a workspace node when using fullscreen global |
1102 | if (root->fullscreen_global && !container && new_workspace) { | 1163 | if (root->fullscreen_global && !container && new_workspace) { |
1103 | return; | 1164 | return; |
1104 | } | 1165 | } |
1105 | // Deny setting focus to a view which is hidden by a fullscreen global | ||
1106 | if (root->fullscreen_global && container != root->fullscreen_global && | ||
1107 | !container_has_ancestor(container, root->fullscreen_global)) { | ||
1108 | // Unless it's a transient container | ||
1109 | if (!container_is_transient_for(container, root->fullscreen_global)) { | ||
1110 | return; | ||
1111 | } | ||
1112 | } | ||
1113 | 1166 | ||
1114 | struct sway_output *new_output = | 1167 | struct sway_output *new_output = |
1115 | new_workspace ? new_workspace->output : NULL; | 1168 | new_workspace ? new_workspace->output : NULL; |
@@ -1135,10 +1188,10 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { | |||
1135 | // Put the container parents on the focus stack, then the workspace, then | 1188 | // Put the container parents on the focus stack, then the workspace, then |
1136 | // the focused container. | 1189 | // the focused container. |
1137 | if (container) { | 1190 | if (container) { |
1138 | struct sway_container *parent = container->parent; | 1191 | struct sway_container *parent = container->pending.parent; |
1139 | while (parent) { | 1192 | while (parent) { |
1140 | seat_set_raw_focus(seat, &parent->node); | 1193 | seat_set_raw_focus(seat, &parent->node); |
1141 | parent = parent->parent; | 1194 | parent = parent->pending.parent; |
1142 | } | 1195 | } |
1143 | } | 1196 | } |
1144 | if (new_workspace) { | 1197 | if (new_workspace) { |
@@ -1210,6 +1263,24 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { | |||
1210 | } | 1263 | } |
1211 | } | 1264 | } |
1212 | 1265 | ||
1266 | void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { | ||
1267 | // Prevents the layer from losing focus if it has keyboard exclusivity | ||
1268 | if (seat->has_exclusive_layer) { | ||
1269 | struct wlr_layer_surface_v1 *layer = seat->focused_layer; | ||
1270 | seat_set_focus_layer(seat, NULL); | ||
1271 | seat_set_workspace_focus(seat, node); | ||
1272 | seat_set_focus_layer(seat, layer); | ||
1273 | } else if (seat->focused_layer) { | ||
1274 | seat_set_focus_layer(seat, NULL); | ||
1275 | seat_set_workspace_focus(seat, node); | ||
1276 | } else { | ||
1277 | seat_set_workspace_focus(seat, node); | ||
1278 | } | ||
1279 | if (server.session_lock.lock) { | ||
1280 | seat_set_focus_surface(seat, server.session_lock.lock->focused, false); | ||
1281 | } | ||
1282 | } | ||
1283 | |||
1213 | void seat_set_focus_container(struct sway_seat *seat, | 1284 | void seat_set_focus_container(struct sway_seat *seat, |
1214 | struct sway_container *con) { | 1285 | struct sway_container *con) { |
1215 | seat_set_focus(seat, con ? &con->node : NULL); | 1286 | seat_set_focus(seat, con ? &con->node : NULL); |
@@ -1234,7 +1305,8 @@ void seat_set_focus_surface(struct sway_seat *seat, | |||
1234 | wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat); | 1305 | wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat); |
1235 | } | 1306 | } |
1236 | 1307 | ||
1237 | seat_tablet_pads_notify_enter(seat, surface); | 1308 | sway_input_method_relay_set_focus(&seat->im_relay, surface); |
1309 | seat_tablet_pads_set_focus(seat, surface); | ||
1238 | } | 1310 | } |
1239 | 1311 | ||
1240 | void seat_set_focus_layer(struct sway_seat *seat, | 1312 | void seat_set_focus_layer(struct sway_seat *seat, |
@@ -1248,28 +1320,23 @@ void seat_set_focus_layer(struct sway_seat *seat, | |||
1248 | seat_set_focus(seat, previous); | 1320 | seat_set_focus(seat, previous); |
1249 | } | 1321 | } |
1250 | return; | 1322 | return; |
1251 | } else if (!layer || seat->focused_layer == layer) { | 1323 | } else if (!layer) { |
1252 | return; | 1324 | return; |
1253 | } | 1325 | } |
1254 | assert(layer->mapped); | 1326 | assert(layer->surface->mapped); |
1255 | seat_set_focus_surface(seat, layer->surface, true); | 1327 | if (layer->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP && |
1256 | if (layer->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) { | 1328 | layer->current.keyboard_interactive |
1257 | seat->focused_layer = layer; | 1329 | == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) { |
1330 | seat->has_exclusive_layer = true; | ||
1258 | } | 1331 | } |
1259 | } | 1332 | if (seat->focused_layer == layer) { |
1260 | |||
1261 | void seat_set_exclusive_client(struct sway_seat *seat, | ||
1262 | struct wl_client *client) { | ||
1263 | if (!client) { | ||
1264 | seat->exclusive_client = client; | ||
1265 | // Triggers a refocus of the topmost surface layer if necessary | ||
1266 | // TODO: Make layer surface focus per-output based on cursor position | ||
1267 | for (int i = 0; i < root->outputs->length; ++i) { | ||
1268 | struct sway_output *output = root->outputs->items[i]; | ||
1269 | arrange_layers(output); | ||
1270 | } | ||
1271 | return; | 1333 | return; |
1272 | } | 1334 | } |
1335 | seat_set_focus_surface(seat, layer->surface, true); | ||
1336 | seat->focused_layer = layer; | ||
1337 | } | ||
1338 | |||
1339 | void seat_unfocus_unless_client(struct sway_seat *seat, struct wl_client *client) { | ||
1273 | if (seat->focused_layer) { | 1340 | if (seat->focused_layer) { |
1274 | if (wl_resource_get_client(seat->focused_layer->resource) != client) { | 1341 | if (wl_resource_get_client(seat->focused_layer->resource) != client) { |
1275 | seat_set_focus_layer(seat, NULL); | 1342 | seat_set_focus_layer(seat, NULL); |
@@ -1296,7 +1363,6 @@ void seat_set_exclusive_client(struct sway_seat *seat, | |||
1296 | now.tv_nsec / 1000, point->touch_id); | 1363 | now.tv_nsec / 1000, point->touch_id); |
1297 | } | 1364 | } |
1298 | } | 1365 | } |
1299 | seat->exclusive_client = client; | ||
1300 | } | 1366 | } |
1301 | 1367 | ||
1302 | struct sway_node *seat_get_focus_inactive(struct sway_seat *seat, | 1368 | struct sway_node *seat_get_focus_inactive(struct sway_seat *seat, |
@@ -1326,7 +1392,7 @@ struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat, | |||
1326 | struct sway_node *node = current->node; | 1392 | struct sway_node *node = current->node; |
1327 | if (node->type == N_CONTAINER && | 1393 | if (node->type == N_CONTAINER && |
1328 | !container_is_floating_or_child(node->sway_container) && | 1394 | !container_is_floating_or_child(node->sway_container) && |
1329 | node->sway_container->workspace == workspace) { | 1395 | node->sway_container->pending.workspace == workspace) { |
1330 | return node->sway_container; | 1396 | return node->sway_container; |
1331 | } | 1397 | } |
1332 | } | 1398 | } |
@@ -1343,7 +1409,7 @@ struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat, | |||
1343 | struct sway_node *node = current->node; | 1409 | struct sway_node *node = current->node; |
1344 | if (node->type == N_CONTAINER && | 1410 | if (node->type == N_CONTAINER && |
1345 | container_is_floating_or_child(node->sway_container) && | 1411 | container_is_floating_or_child(node->sway_container) && |
1346 | node->sway_container->workspace == workspace) { | 1412 | node->sway_container->pending.workspace == workspace) { |
1347 | return node->sway_container; | 1413 | return node->sway_container; |
1348 | } | 1414 | } |
1349 | } | 1415 | } |
@@ -1377,9 +1443,8 @@ struct sway_node *seat_get_focus(struct sway_seat *seat) { | |||
1377 | if (!seat->has_focus) { | 1443 | if (!seat->has_focus) { |
1378 | return NULL; | 1444 | return NULL; |
1379 | } | 1445 | } |
1380 | if (wl_list_empty(&seat->focus_stack)) { | 1446 | sway_assert(!wl_list_empty(&seat->focus_stack), |
1381 | return NULL; | 1447 | "focus_stack is empty, but has_focus is true"); |
1382 | } | ||
1383 | struct sway_seat_node *current = | 1448 | struct sway_seat_node *current = |
1384 | wl_container_of(seat->focus_stack.next, current, link); | 1449 | wl_container_of(seat->focus_stack.next, current, link); |
1385 | return current->node; | 1450 | return current->node; |
@@ -1391,7 +1456,7 @@ struct sway_workspace *seat_get_focused_workspace(struct sway_seat *seat) { | |||
1391 | return NULL; | 1456 | return NULL; |
1392 | } | 1457 | } |
1393 | if (focus->type == N_CONTAINER) { | 1458 | if (focus->type == N_CONTAINER) { |
1394 | return focus->sway_container->workspace; | 1459 | return focus->sway_container->pending.workspace; |
1395 | } | 1460 | } |
1396 | if (focus->type == N_WORKSPACE) { | 1461 | if (focus->type == N_WORKSPACE) { |
1397 | return focus->sway_workspace; | 1462 | return focus->sway_workspace; |
@@ -1404,8 +1469,8 @@ struct sway_workspace *seat_get_last_known_workspace(struct sway_seat *seat) { | |||
1404 | wl_list_for_each(current, &seat->focus_stack, link) { | 1469 | wl_list_for_each(current, &seat->focus_stack, link) { |
1405 | struct sway_node *node = current->node; | 1470 | struct sway_node *node = current->node; |
1406 | if (node->type == N_CONTAINER && | 1471 | if (node->type == N_CONTAINER && |
1407 | node->sway_container->workspace) { | 1472 | node->sway_container->pending.workspace) { |
1408 | return node->sway_container->workspace; | 1473 | return node->sway_container->pending.workspace; |
1409 | } else if (node->type == N_WORKSPACE) { | 1474 | } else if (node->type == N_WORKSPACE) { |
1410 | return node->sway_workspace; | 1475 | return node->sway_workspace; |
1411 | } | 1476 | } |
@@ -1464,7 +1529,7 @@ struct seat_config *seat_get_config_by_name(const char *name) { | |||
1464 | } | 1529 | } |
1465 | 1530 | ||
1466 | void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, | 1531 | void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, |
1467 | uint32_t button, enum wlr_button_state state) { | 1532 | uint32_t button, enum wl_pointer_button_state state) { |
1468 | seat->last_button_serial = wlr_seat_pointer_notify_button(seat->wlr_seat, | 1533 | seat->last_button_serial = wlr_seat_pointer_notify_button(seat->wlr_seat, |
1469 | time_msec, button, state); | 1534 | time_msec, button, state); |
1470 | } | 1535 | } |
@@ -1501,7 +1566,7 @@ void seatop_unref(struct sway_seat *seat, struct sway_container *con) { | |||
1501 | 1566 | ||
1502 | void seatop_button(struct sway_seat *seat, uint32_t time_msec, | 1567 | void seatop_button(struct sway_seat *seat, uint32_t time_msec, |
1503 | struct wlr_input_device *device, uint32_t button, | 1568 | struct wlr_input_device *device, uint32_t button, |
1504 | enum wlr_button_state state) { | 1569 | enum wl_pointer_button_state state) { |
1505 | if (seat->seatop_impl->button) { | 1570 | if (seat->seatop_impl->button) { |
1506 | seat->seatop_impl->button(seat, time_msec, device, button, state); | 1571 | seat->seatop_impl->button(seat, time_msec, device, button, state); |
1507 | } | 1572 | } |
@@ -1514,12 +1579,38 @@ void seatop_pointer_motion(struct sway_seat *seat, uint32_t time_msec) { | |||
1514 | } | 1579 | } |
1515 | 1580 | ||
1516 | void seatop_pointer_axis(struct sway_seat *seat, | 1581 | void seatop_pointer_axis(struct sway_seat *seat, |
1517 | struct wlr_event_pointer_axis *event) { | 1582 | struct wlr_pointer_axis_event *event) { |
1518 | if (seat->seatop_impl->pointer_axis) { | 1583 | if (seat->seatop_impl->pointer_axis) { |
1519 | seat->seatop_impl->pointer_axis(seat, event); | 1584 | seat->seatop_impl->pointer_axis(seat, event); |
1520 | } | 1585 | } |
1521 | } | 1586 | } |
1522 | 1587 | ||
1588 | void seatop_touch_motion(struct sway_seat *seat, struct wlr_touch_motion_event *event, | ||
1589 | double lx, double ly) { | ||
1590 | if (seat->seatop_impl->touch_motion) { | ||
1591 | seat->seatop_impl->touch_motion(seat, event, lx, ly); | ||
1592 | } | ||
1593 | } | ||
1594 | |||
1595 | void seatop_touch_up(struct sway_seat *seat, struct wlr_touch_up_event *event) { | ||
1596 | if (seat->seatop_impl->touch_up) { | ||
1597 | seat->seatop_impl->touch_up(seat, event); | ||
1598 | } | ||
1599 | } | ||
1600 | |||
1601 | void seatop_touch_down(struct sway_seat *seat, struct wlr_touch_down_event *event, | ||
1602 | double lx, double ly) { | ||
1603 | if (seat->seatop_impl->touch_down) { | ||
1604 | seat->seatop_impl->touch_down(seat, event, lx, ly); | ||
1605 | } | ||
1606 | } | ||
1607 | |||
1608 | void seatop_touch_cancel(struct sway_seat *seat, struct wlr_touch_cancel_event *event) { | ||
1609 | if (seat->seatop_impl->touch_cancel) { | ||
1610 | seat->seatop_impl->touch_cancel(seat, event); | ||
1611 | } | ||
1612 | } | ||
1613 | |||
1523 | void seatop_tablet_tool_tip(struct sway_seat *seat, | 1614 | void seatop_tablet_tool_tip(struct sway_seat *seat, |
1524 | struct sway_tablet_tool *tool, uint32_t time_msec, | 1615 | struct sway_tablet_tool *tool, uint32_t time_msec, |
1525 | enum wlr_tablet_tool_tip_state state) { | 1616 | enum wlr_tablet_tool_tip_state state) { |
@@ -1537,6 +1628,62 @@ void seatop_tablet_tool_motion(struct sway_seat *seat, | |||
1537 | } | 1628 | } |
1538 | } | 1629 | } |
1539 | 1630 | ||
1631 | void seatop_hold_begin(struct sway_seat *seat, | ||
1632 | struct wlr_pointer_hold_begin_event *event) { | ||
1633 | if (seat->seatop_impl->hold_begin) { | ||
1634 | seat->seatop_impl->hold_begin(seat, event); | ||
1635 | } | ||
1636 | } | ||
1637 | |||
1638 | void seatop_hold_end(struct sway_seat *seat, | ||
1639 | struct wlr_pointer_hold_end_event *event) { | ||
1640 | if (seat->seatop_impl->hold_end) { | ||
1641 | seat->seatop_impl->hold_end(seat, event); | ||
1642 | } | ||
1643 | } | ||
1644 | |||
1645 | void seatop_pinch_begin(struct sway_seat *seat, | ||
1646 | struct wlr_pointer_pinch_begin_event *event) { | ||
1647 | if (seat->seatop_impl->pinch_begin) { | ||
1648 | seat->seatop_impl->pinch_begin(seat, event); | ||
1649 | } | ||
1650 | } | ||
1651 | |||
1652 | void seatop_pinch_update(struct sway_seat *seat, | ||
1653 | struct wlr_pointer_pinch_update_event *event) { | ||
1654 | if (seat->seatop_impl->pinch_update) { | ||
1655 | seat->seatop_impl->pinch_update(seat, event); | ||
1656 | } | ||
1657 | } | ||
1658 | |||
1659 | void seatop_pinch_end(struct sway_seat *seat, | ||
1660 | struct wlr_pointer_pinch_end_event *event) { | ||
1661 | if (seat->seatop_impl->pinch_end) { | ||
1662 | seat->seatop_impl->pinch_end(seat, event); | ||
1663 | } | ||
1664 | } | ||
1665 | |||
1666 | void seatop_swipe_begin(struct sway_seat *seat, | ||
1667 | struct wlr_pointer_swipe_begin_event *event) { | ||
1668 | if (seat->seatop_impl->swipe_begin) { | ||
1669 | seat->seatop_impl->swipe_begin(seat, event); | ||
1670 | } | ||
1671 | } | ||
1672 | |||
1673 | void seatop_swipe_update(struct sway_seat *seat, | ||
1674 | struct wlr_pointer_swipe_update_event *event) { | ||
1675 | if (seat->seatop_impl->swipe_update) { | ||
1676 | seat->seatop_impl->swipe_update(seat, event); | ||
1677 | } | ||
1678 | } | ||
1679 | |||
1680 | void seatop_swipe_end(struct sway_seat *seat, | ||
1681 | struct wlr_pointer_swipe_end_event *event) { | ||
1682 | if (seat->seatop_impl->swipe_end) { | ||
1683 | seat->seatop_impl->swipe_end(seat, event); | ||
1684 | } | ||
1685 | } | ||
1686 | |||
1540 | void seatop_rebase(struct sway_seat *seat, uint32_t time_msec) { | 1687 | void seatop_rebase(struct sway_seat *seat, uint32_t time_msec) { |
1541 | if (seat->seatop_impl->rebase) { | 1688 | if (seat->seatop_impl->rebase) { |
1542 | seat->seatop_impl->rebase(seat, time_msec); | 1689 | seat->seatop_impl->rebase(seat, time_msec); |
@@ -1552,13 +1699,6 @@ void seatop_end(struct sway_seat *seat) { | |||
1552 | seat->seatop_impl = NULL; | 1699 | seat->seatop_impl = NULL; |
1553 | } | 1700 | } |
1554 | 1701 | ||
1555 | void seatop_render(struct sway_seat *seat, struct sway_output *output, | ||
1556 | pixman_region32_t *damage) { | ||
1557 | if (seat->seatop_impl->render) { | ||
1558 | seat->seatop_impl->render(seat, output, damage); | ||
1559 | } | ||
1560 | } | ||
1561 | |||
1562 | bool seatop_allows_set_cursor(struct sway_seat *seat) { | 1702 | bool seatop_allows_set_cursor(struct sway_seat *seat) { |
1563 | return seat->seatop_impl->allow_set_cursor; | 1703 | return seat->seatop_impl->allow_set_cursor; |
1564 | } | 1704 | } |