aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/seat.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r--sway/input/seat.c445
1 files changed, 273 insertions, 172 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 2d714acd..0c5672bc 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -1,22 +1,23 @@
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"
@@ -42,6 +43,7 @@ static void seat_device_destroy(struct sway_seat_device *seat_device) {
42 sway_keyboard_destroy(seat_device->keyboard); 43 sway_keyboard_destroy(seat_device->keyboard);
43 sway_tablet_destroy(seat_device->tablet); 44 sway_tablet_destroy(seat_device->tablet);
44 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);
45 wlr_cursor_detach_input_device(seat_device->sway_seat->cursor->cursor, 47 wlr_cursor_detach_input_device(seat_device->sway_seat->cursor->cursor,
46 seat_device->input_device->wlr_device); 48 seat_device->input_device->wlr_device);
47 wl_list_remove(&seat_device->link); 49 wl_list_remove(&seat_device->link);
@@ -51,10 +53,26 @@ static void seat_device_destroy(struct sway_seat_device *seat_device) {
51static void seat_node_destroy(struct sway_seat_node *seat_node) { 53static void seat_node_destroy(struct sway_seat_node *seat_node) {
52 wl_list_remove(&seat_node->destroy.link); 54 wl_list_remove(&seat_node->destroy.link);
53 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
54 free(seat_node); 66 free(seat_node);
55} 67}
56 68
57void seat_destroy(struct sway_seat *seat) { 69void seat_destroy(struct sway_seat *seat) {
70 wlr_seat_destroy(seat->wlr_seat);
71}
72
73static void handle_seat_destroy(struct wl_listener *listener, void *data) {
74 struct sway_seat *seat = wl_container_of(listener, seat, destroy);
75
58 if (seat == config->handler_context.seat) { 76 if (seat == config->handler_context.seat) {
59 config->handler_context.seat = input_manager_get_default_seat(); 77 config->handler_context.seat = input_manager_get_default_seat();
60 } 78 }
@@ -75,10 +93,11 @@ void seat_destroy(struct sway_seat *seat) {
75 wl_list_remove(&seat->request_set_selection.link); 93 wl_list_remove(&seat->request_set_selection.link);
76 wl_list_remove(&seat->request_set_primary_selection.link); 94 wl_list_remove(&seat->request_set_primary_selection.link);
77 wl_list_remove(&seat->link); 95 wl_list_remove(&seat->link);
78 wlr_seat_destroy(seat->wlr_seat); 96 wl_list_remove(&seat->destroy.link);
79 for (int i = 0; i < seat->deferred_bindings->length; i++) { 97 for (int i = 0; i < seat->deferred_bindings->length; i++) {
80 free_sway_binding(seat->deferred_bindings->items[i]); 98 free_sway_binding(seat->deferred_bindings->items[i]);
81 } 99 }
100 wlr_scene_node_destroy(&seat->scene_tree->node);
82 list_free(seat->deferred_bindings); 101 list_free(seat->deferred_bindings);
83 free(seat->prev_workspace_name); 102 free(seat->prev_workspace_name);
84 free(seat); 103 free(seat);
@@ -86,21 +105,10 @@ void seat_destroy(struct sway_seat *seat) {
86 105
87void seat_idle_notify_activity(struct sway_seat *seat, 106void seat_idle_notify_activity(struct sway_seat *seat,
88 enum sway_input_idle_source source) { 107 enum sway_input_idle_source source) {
89 uint32_t mask = seat->idle_inhibit_sources; 108 if ((source & seat->idle_inhibit_sources) == 0) {
90 struct wlr_idle_timeout *timeout; 109 return;
91 int ntimers = 0, nidle = 0;
92 wl_list_for_each(timeout, &server.idle->idle_timers, link) {
93 ++ntimers;
94 if (timeout->idle_state) {
95 ++nidle;
96 }
97 }
98 if (nidle == ntimers) {
99 mask = seat->idle_wake_sources;
100 }
101 if ((source & mask) > 0) {
102 wlr_idle_notify_activity(server.idle, seat->wlr_seat);
103 } 110 }
111 wlr_idle_notifier_v1_notify_activity(server.idle_notifier_v1, seat->wlr_seat);
104} 112}
105 113
106/** 114/**
@@ -130,7 +138,7 @@ static struct sway_keyboard *sway_keyboard_for_wlr_keyboard(
130 if (input_device->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { 138 if (input_device->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) {
131 continue; 139 continue;
132 } 140 }
133 if (input_device->wlr_device->keyboard == wlr_keyboard) { 141 if (input_device->wlr_device == &wlr_keyboard->base) {
134 return seat_device->keyboard; 142 return seat_device->keyboard;
135 } 143 }
136 } 144 }
@@ -138,7 +146,7 @@ static struct sway_keyboard *sway_keyboard_for_wlr_keyboard(
138 wl_list_for_each(group, &seat->keyboard_groups, link) { 146 wl_list_for_each(group, &seat->keyboard_groups, link) {
139 struct sway_input_device *input_device = 147 struct sway_input_device *input_device =
140 group->seat_device->input_device; 148 group->seat_device->input_device;
141 if (input_device->wlr_device->keyboard == wlr_keyboard) { 149 if (input_device->wlr_device == &wlr_keyboard->base) {
142 return group->seat_device->keyboard; 150 return group->seat_device->keyboard;
143 } 151 }
144 } 152 }
@@ -162,11 +170,11 @@ static void seat_keyboard_notify_enter(struct sway_seat *seat,
162 state->pressed_keycodes, state->npressed, &keyboard->modifiers); 170 state->pressed_keycodes, state->npressed, &keyboard->modifiers);
163} 171}
164 172
165static void seat_tablet_pads_notify_enter(struct sway_seat *seat, 173static void seat_tablet_pads_set_focus(struct sway_seat *seat,
166 struct wlr_surface *surface) { 174 struct wlr_surface *surface) {
167 struct sway_seat_device *seat_device; 175 struct sway_seat_device *seat_device;
168 wl_list_for_each(seat_device, &seat->devices, link) { 176 wl_list_for_each(seat_device, &seat->devices, link) {
169 sway_tablet_pad_notify_enter(seat_device->tablet_pad, surface); 177 sway_tablet_pad_set_focus(seat_device->tablet_pad, surface);
170 } 178 }
171} 179}
172 180
@@ -190,7 +198,7 @@ static void seat_send_focus(struct sway_node *node, struct sway_seat *seat) {
190#endif 198#endif
191 199
192 seat_keyboard_notify_enter(seat, view->surface); 200 seat_keyboard_notify_enter(seat, view->surface);
193 seat_tablet_pads_notify_enter(seat, view->surface); 201 seat_tablet_pads_set_focus(seat, view->surface);
194 sway_input_method_relay_set_focus(&seat->im_relay, view->surface); 202 sway_input_method_relay_set_focus(&seat->im_relay, view->surface);
195 203
196 struct wlr_pointer_constraint_v1 *constraint = 204 struct wlr_pointer_constraint_v1 *constraint =
@@ -210,14 +218,13 @@ void seat_for_each_node(struct sway_seat *seat,
210 218
211struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat, 219struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat,
212 struct sway_node *ancestor) { 220 struct sway_node *ancestor) {
213 if (ancestor->type == N_CONTAINER && ancestor->sway_container->view) { 221 if (node_is_view(ancestor)) {
214 return ancestor->sway_container; 222 return ancestor->sway_container;
215 } 223 }
216 struct sway_seat_node *current; 224 struct sway_seat_node *current;
217 wl_list_for_each(current, &seat->focus_stack, link) { 225 wl_list_for_each(current, &seat->focus_stack, link) {
218 struct sway_node *node = current->node; 226 struct sway_node *node = current->node;
219 if (node->type == N_CONTAINER && node->sway_container->view && 227 if (node_is_view(node) && node_has_ancestor(node, ancestor)) {
220 node_has_ancestor(node, ancestor)) {
221 return node->sway_container; 228 return node->sway_container;
222 } 229 }
223 } 230 }
@@ -236,7 +243,7 @@ static void handle_seat_node_destroy(struct wl_listener *listener, void *data) {
236 seat_node_destroy(seat_node); 243 seat_node_destroy(seat_node);
237 // 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
238 // 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
239 // 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
240 // value of seat->workspace. 247 // value of seat->workspace.
241 if (seat->workspace == node->sway_workspace) { 248 if (seat->workspace == node->sway_workspace) {
242 struct sway_node *node = seat_get_focus_inactive(seat, &root->node); 249 struct sway_node *node = seat_get_focus_inactive(seat, &root->node);
@@ -352,25 +359,15 @@ static void handle_new_node(struct wl_listener *listener, void *data) {
352 seat_node_from_node(seat, node); 359 seat_node_from_node(seat, node);
353} 360}
354 361
355static void drag_icon_damage_whole(struct sway_drag_icon *icon) { 362static void drag_icon_update_position(struct sway_seat *seat, struct wlr_scene_node *node) {
356 if (!icon->wlr_drag_icon->mapped) { 363 struct wlr_drag_icon *wlr_icon = scene_descriptor_try_get(node, SWAY_SCENE_DESC_DRAG_ICON);
357 return;
358 }
359 desktop_damage_surface(icon->wlr_drag_icon->surface, icon->x, icon->y, true);
360}
361
362void drag_icon_update_position(struct sway_drag_icon *icon) {
363 drag_icon_damage_whole(icon);
364
365 struct wlr_drag_icon *wlr_icon = icon->wlr_drag_icon;
366 struct sway_seat *seat = icon->seat;
367 struct wlr_cursor *cursor = seat->cursor->cursor; 364 struct wlr_cursor *cursor = seat->cursor->cursor;
365
368 switch (wlr_icon->drag->grab_type) { 366 switch (wlr_icon->drag->grab_type) {
369 case WLR_DRAG_GRAB_KEYBOARD: 367 case WLR_DRAG_GRAB_KEYBOARD:
370 return; 368 return;
371 case WLR_DRAG_GRAB_KEYBOARD_POINTER: 369 case WLR_DRAG_GRAB_KEYBOARD_POINTER:
372 icon->x = cursor->x; 370 wlr_scene_node_set_position(node, cursor->x, cursor->y);
373 icon->y = cursor->y;
374 break; 371 break;
375 case WLR_DRAG_GRAB_KEYBOARD_TOUCH:; 372 case WLR_DRAG_GRAB_KEYBOARD_TOUCH:;
376 struct wlr_touch_point *point = 373 struct wlr_touch_point *point =
@@ -378,39 +375,15 @@ void drag_icon_update_position(struct sway_drag_icon *icon) {
378 if (point == NULL) { 375 if (point == NULL) {
379 return; 376 return;
380 } 377 }
381 icon->x = seat->touch_x; 378 wlr_scene_node_set_position(node, seat->touch_x, seat->touch_y);
382 icon->y = seat->touch_y;
383 } 379 }
384
385 drag_icon_damage_whole(icon);
386} 380}
387 381
388static void drag_icon_handle_surface_commit(struct wl_listener *listener, 382void drag_icons_update_position(struct sway_seat *seat) {
389 void *data) { 383 struct wlr_scene_node *node;
390 struct sway_drag_icon *icon = 384 wl_list_for_each(node, &seat->drag_icons->children, link) {
391 wl_container_of(listener, icon, surface_commit); 385 drag_icon_update_position(seat, node);
392 drag_icon_update_position(icon); 386 }
393}
394
395static void drag_icon_handle_map(struct wl_listener *listener, void *data) {
396 struct sway_drag_icon *icon = wl_container_of(listener, icon, map);
397 drag_icon_damage_whole(icon);
398}
399
400static void drag_icon_handle_unmap(struct wl_listener *listener, void *data) {
401 struct sway_drag_icon *icon = wl_container_of(listener, icon, unmap);
402 drag_icon_damage_whole(icon);
403}
404
405static void drag_icon_handle_destroy(struct wl_listener *listener, void *data) {
406 struct sway_drag_icon *icon = wl_container_of(listener, icon, destroy);
407 icon->wlr_drag_icon->data = NULL;
408 wl_list_remove(&icon->link);
409 wl_list_remove(&icon->surface_commit.link);
410 wl_list_remove(&icon->unmap.link);
411 wl_list_remove(&icon->map.link);
412 wl_list_remove(&icon->destroy.link);
413 free(icon);
414} 387}
415 388
416static void drag_handle_destroy(struct wl_listener *listener, void *data) { 389static void drag_handle_destroy(struct wl_listener *listener, void *data) {
@@ -482,27 +455,20 @@ static void handle_start_drag(struct wl_listener *listener, void *data) {
482 455
483 struct wlr_drag_icon *wlr_drag_icon = wlr_drag->icon; 456 struct wlr_drag_icon *wlr_drag_icon = wlr_drag->icon;
484 if (wlr_drag_icon != NULL) { 457 if (wlr_drag_icon != NULL) {
485 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);
486 if (icon == NULL) { 459 if (!tree) {
487 sway_log(SWAY_ERROR, "Allocation failed"); 460 sway_log(SWAY_ERROR, "Failed to allocate a drag icon scene tree");
488 return; 461 return;
489 } 462 }
490 icon->seat = seat;
491 icon->wlr_drag_icon = wlr_drag_icon;
492 wlr_drag_icon->data = icon;
493 463
494 icon->surface_commit.notify = drag_icon_handle_surface_commit; 464 if (!scene_descriptor_assign(&tree->node, SWAY_SCENE_DESC_DRAG_ICON,
495 wl_signal_add(&wlr_drag_icon->surface->events.commit, &icon->surface_commit); 465 wlr_drag_icon)) {
496 icon->unmap.notify = drag_icon_handle_unmap; 466 sway_log(SWAY_ERROR, "Failed to allocate a drag icon scene descriptor");
497 wl_signal_add(&wlr_drag_icon->events.unmap, &icon->unmap); 467 wlr_scene_node_destroy(&tree->node);
498 icon->map.notify = drag_icon_handle_map; 468 return;
499 wl_signal_add(&wlr_drag_icon->events.map, &icon->map); 469 }
500 icon->destroy.notify = drag_icon_handle_destroy;
501 wl_signal_add(&wlr_drag_icon->events.destroy, &icon->destroy);
502
503 wl_list_insert(&root->drag_icons, &icon->link);
504 470
505 drag_icon_update_position(icon); 471 drag_icon_update_position(seat, &tree->node);
506 } 472 }
507 seatop_begin_default(seat); 473 seatop_begin_default(seat);
508} 474}
@@ -549,8 +515,18 @@ struct sway_seat *seat_create(const char *seat_name) {
549 return NULL; 515 return NULL;
550 } 516 }
551 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
552 seat->wlr_seat = wlr_seat_create(server.wl_display, seat_name); 527 seat->wlr_seat = wlr_seat_create(server.wl_display, seat_name);
553 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);
554 free(seat); 530 free(seat);
555 return NULL; 531 return NULL;
556 } 532 }
@@ -558,11 +534,15 @@ struct sway_seat *seat_create(const char *seat_name) {
558 534
559 seat->cursor = sway_cursor_create(seat); 535 seat->cursor = sway_cursor_create(seat);
560 if (!seat->cursor) { 536 if (!seat->cursor) {
537 wlr_scene_node_destroy(&seat->scene_tree->node);
561 wlr_seat_destroy(seat->wlr_seat); 538 wlr_seat_destroy(seat->wlr_seat);
562 free(seat); 539 free(seat);
563 return NULL; 540 return NULL;
564 } 541 }
565 542
543 seat->destroy.notify = handle_seat_destroy;
544 wl_signal_add(&seat->wlr_seat->events.destroy, &seat->destroy);
545
566 seat->idle_inhibit_sources = seat->idle_wake_sources = 546 seat->idle_inhibit_sources = seat->idle_wake_sources =
567 IDLE_SOURCE_KEYBOARD | 547 IDLE_SOURCE_KEYBOARD |
568 IDLE_SOURCE_POINTER | 548 IDLE_SOURCE_POINTER |
@@ -636,7 +616,7 @@ static void seat_update_capabilities(struct sway_seat *seat) {
636 case WLR_INPUT_DEVICE_TOUCH: 616 case WLR_INPUT_DEVICE_TOUCH:
637 caps |= WL_SEAT_CAPABILITY_TOUCH; 617 caps |= WL_SEAT_CAPABILITY_TOUCH;
638 break; 618 break;
639 case WLR_INPUT_DEVICE_TABLET_TOOL: 619 case WLR_INPUT_DEVICE_TABLET:
640 caps |= WL_SEAT_CAPABILITY_POINTER; 620 caps |= WL_SEAT_CAPABILITY_POINTER;
641 break; 621 break;
642 case WLR_INPUT_DEVICE_SWITCH: 622 case WLR_INPUT_DEVICE_SWITCH:
@@ -654,7 +634,7 @@ static void seat_update_capabilities(struct sway_seat *seat) {
654 } else { 634 } else {
655 wlr_seat_set_capabilities(seat->wlr_seat, caps); 635 wlr_seat_set_capabilities(seat->wlr_seat, caps);
656 if ((previous_caps & WL_SEAT_CAPABILITY_POINTER) == 0) { 636 if ((previous_caps & WL_SEAT_CAPABILITY_POINTER) == 0) {
657 cursor_set_image(seat->cursor, "left_ptr", NULL); 637 cursor_set_image(seat->cursor, "default", NULL);
658 } 638 }
659 } 639 }
660} 640}
@@ -694,19 +674,28 @@ static const char *get_builtin_output_name(void) {
694static bool is_touch_or_tablet_tool(struct sway_seat_device *seat_device) { 674static bool is_touch_or_tablet_tool(struct sway_seat_device *seat_device) {
695 switch (seat_device->input_device->wlr_device->type) { 675 switch (seat_device->input_device->wlr_device->type) {
696 case WLR_INPUT_DEVICE_TOUCH: 676 case WLR_INPUT_DEVICE_TOUCH:
697 case WLR_INPUT_DEVICE_TABLET_TOOL: 677 case WLR_INPUT_DEVICE_TABLET:
698 return true; 678 return true;
699 default: 679 default:
700 return false; 680 return false;
701 } 681 }
702} 682}
703 683
704static void seat_apply_input_config(struct sway_seat *seat, 684static void seat_apply_input_mapping(struct sway_seat *seat,
705 struct sway_seat_device *sway_device) { 685 struct sway_seat_device *sway_device) {
706 struct input_config *ic = 686 struct input_config *ic =
707 input_device_get_config(sway_device->input_device); 687 input_device_get_config(sway_device->input_device);
708 688
709 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",
710 sway_device->input_device->identifier); 699 sway_device->input_device->identifier);
711 700
712 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;
@@ -715,14 +704,26 @@ static void seat_apply_input_config(struct sway_seat *seat,
715 ic == NULL ? MAPPED_TO_DEFAULT : ic->mapped_to; 704 ic == NULL ? MAPPED_TO_DEFAULT : ic->mapped_to;
716 705
717 switch (mapped_to) { 706 switch (mapped_to) {
718 case MAPPED_TO_DEFAULT: 707 case MAPPED_TO_DEFAULT:;
719 /* 708 /*
720 * If the wlroots backend provides an output name, use that. 709 * If the wlroots backend provides an output name, use that.
721 * 710 *
722 * Otherwise, try to map built-in touch and tablet tool devices to the 711 * Otherwise, try to map built-in touch and pointer devices to the
723 * built-in output. 712 * built-in output.
724 */ 713 */
725 mapped_to_output = sway_device->input_device->wlr_device->output_name; 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
726 if (mapped_to_output == NULL && is_touch_or_tablet_tool(sway_device) && 727 if (mapped_to_output == NULL && is_touch_or_tablet_tool(sway_device) &&
727 sway_libinput_device_is_builtin(sway_device->input_device)) { 728 sway_libinput_device_is_builtin(sway_device->input_device)) {
728 mapped_to_output = get_builtin_output_name(); 729 mapped_to_output = get_builtin_output_name();
@@ -731,6 +732,10 @@ static void seat_apply_input_config(struct sway_seat *seat,
731 mapped_to_output, sway_device->input_device->identifier); 732 mapped_to_output, sway_device->input_device->identifier);
732 } 733 }
733 } 734 }
735#else
736 (void)is_touch_or_tablet_tool;
737 (void)get_builtin_output_name;
738#endif
734 if (mapped_to_output == NULL) { 739 if (mapped_to_output == NULL) {
735 return; 740 return;
736 } 741 }
@@ -774,12 +779,9 @@ static void seat_apply_input_config(struct sway_seat *seat,
774 779
775static void seat_configure_pointer(struct sway_seat *seat, 780static void seat_configure_pointer(struct sway_seat *seat,
776 struct sway_seat_device *sway_device) { 781 struct sway_seat_device *sway_device) {
777 if ((seat->wlr_seat->capabilities & WL_SEAT_CAPABILITY_POINTER) == 0) { 782 seat_configure_xcursor(seat);
778 seat_configure_xcursor(seat);
779 }
780 wlr_cursor_attach_input_device(seat->cursor->cursor, 783 wlr_cursor_attach_input_device(seat->cursor->cursor,
781 sway_device->input_device->wlr_device); 784 sway_device->input_device->wlr_device);
782 seat_apply_input_config(seat, sway_device);
783 wl_event_source_timer_update( 785 wl_event_source_timer_update(
784 seat->cursor->hide_source, cursor_get_timeout(seat->cursor)); 786 seat->cursor->hide_source, cursor_get_timeout(seat->cursor));
785} 787}
@@ -790,13 +792,22 @@ static void seat_configure_keyboard(struct sway_seat *seat,
790 sway_keyboard_create(seat, seat_device); 792 sway_keyboard_create(seat, seat_device);
791 } 793 }
792 sway_keyboard_configure(seat_device->keyboard); 794 sway_keyboard_configure(seat_device->keyboard);
793 wlr_seat_set_keyboard(seat->wlr_seat, 795
794 seat_device->input_device->wlr_device); 796 // We only need to update the current keyboard, as the rest will be updated
795 struct sway_node *focus = seat_get_focus(seat); 797 // as they are activated.
796 if (focus && node_is_view(focus)) { 798 struct wlr_keyboard *wlr_keyboard =
797 // 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) {
798 wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat); 809 wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat);
799 seat_keyboard_notify_enter(seat, focus->sway_container->view->surface); 810 seat_keyboard_notify_enter(seat, surface);
800 } 811 }
801} 812}
802 813
@@ -805,7 +816,6 @@ static void seat_configure_switch(struct sway_seat *seat,
805 if (!seat_device->switch_device) { 816 if (!seat_device->switch_device) {
806 sway_switch_create(seat, seat_device); 817 sway_switch_create(seat, seat_device);
807 } 818 }
808 seat_apply_input_config(seat, seat_device);
809 sway_switch_configure(seat_device->switch_device); 819 sway_switch_configure(seat_device->switch_device);
810} 820}
811 821
@@ -813,7 +823,6 @@ static void seat_configure_touch(struct sway_seat *seat,
813 struct sway_seat_device *sway_device) { 823 struct sway_seat_device *sway_device) {
814 wlr_cursor_attach_input_device(seat->cursor->cursor, 824 wlr_cursor_attach_input_device(seat->cursor->cursor,
815 sway_device->input_device->wlr_device); 825 sway_device->input_device->wlr_device);
816 seat_apply_input_config(seat, sway_device);
817} 826}
818 827
819static void seat_configure_tablet_tool(struct sway_seat *seat, 828static void seat_configure_tablet_tool(struct sway_seat *seat,
@@ -824,7 +833,6 @@ static void seat_configure_tablet_tool(struct sway_seat *seat,
824 sway_configure_tablet(sway_device->tablet); 833 sway_configure_tablet(sway_device->tablet);
825 wlr_cursor_attach_input_device(seat->cursor->cursor, 834 wlr_cursor_attach_input_device(seat->cursor->cursor,
826 sway_device->input_device->wlr_device); 835 sway_device->input_device->wlr_device);
827 seat_apply_input_config(seat, sway_device);
828} 836}
829 837
830static void seat_configure_tablet_pad(struct sway_seat *seat, 838static void seat_configure_tablet_pad(struct sway_seat *seat,
@@ -874,13 +882,25 @@ void seat_configure_device(struct sway_seat *seat,
874 case WLR_INPUT_DEVICE_TOUCH: 882 case WLR_INPUT_DEVICE_TOUCH:
875 seat_configure_touch(seat, seat_device); 883 seat_configure_touch(seat, seat_device);
876 break; 884 break;
877 case WLR_INPUT_DEVICE_TABLET_TOOL: 885 case WLR_INPUT_DEVICE_TABLET:
878 seat_configure_tablet_tool(seat, seat_device); 886 seat_configure_tablet_tool(seat, seat_device);
879 break; 887 break;
880 case WLR_INPUT_DEVICE_TABLET_PAD: 888 case WLR_INPUT_DEVICE_TABLET_PAD:
881 seat_configure_tablet_pad(seat, seat_device); 889 seat_configure_tablet_pad(seat, seat_device);
882 break; 890 break;
883 } 891 }
892
893 seat_apply_input_mapping(seat, seat_device);
894}
895
896void 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);
884} 904}
885 905
886void seat_reset_device(struct sway_seat *seat, 906void seat_reset_device(struct sway_seat *seat,
@@ -901,7 +921,7 @@ void seat_reset_device(struct sway_seat *seat,
901 case WLR_INPUT_DEVICE_TOUCH: 921 case WLR_INPUT_DEVICE_TOUCH:
902 seat_reset_input_config(seat, seat_device); 922 seat_reset_input_config(seat, seat_device);
903 break; 923 break;
904 case WLR_INPUT_DEVICE_TABLET_TOOL: 924 case WLR_INPUT_DEVICE_TABLET:
905 seat_reset_input_config(seat, seat_device); 925 seat_reset_input_config(seat, seat_device);
906 break; 926 break;
907 case WLR_INPUT_DEVICE_TABLET_PAD: 927 case WLR_INPUT_DEVICE_TABLET_PAD:
@@ -997,7 +1017,7 @@ void seat_configure_xcursor(struct sway_seat *seat) {
997 1017
998 wlr_xcursor_manager_load(server.xwayland.xcursor_manager, 1); 1018 wlr_xcursor_manager_load(server.xwayland.xcursor_manager, 1);
999 struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor( 1019 struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor(
1000 server.xwayland.xcursor_manager, "left_ptr", 1); 1020 server.xwayland.xcursor_manager, "default", 1);
1001 if (xcursor != NULL) { 1021 if (xcursor != NULL) {
1002 struct wlr_xcursor_image *image = xcursor->images[0]; 1022 struct wlr_xcursor_image *image = xcursor->images[0];
1003 wlr_xwayland_set_cursor( 1023 wlr_xwayland_set_cursor(
@@ -1023,32 +1043,35 @@ void seat_configure_xcursor(struct sway_seat *seat) {
1023 sway_log(SWAY_ERROR, 1043 sway_log(SWAY_ERROR,
1024 "Cannot create XCursor manager for theme '%s'", cursor_theme); 1044 "Cannot create XCursor manager for theme '%s'", cursor_theme);
1025 } 1045 }
1026 }
1027 1046
1028 for (int i = 0; i < root->outputs->length; ++i) { 1047
1029 struct sway_output *sway_output = root->outputs->items[i]; 1048 for (int i = 0; i < root->outputs->length; ++i) {
1030 struct wlr_output *output = sway_output->wlr_output; 1049 struct sway_output *sway_output = root->outputs->items[i];
1031 bool result = 1050 struct wlr_output *output = sway_output->wlr_output;
1032 wlr_xcursor_manager_load(seat->cursor->xcursor_manager, 1051 bool result =
1033 output->scale); 1052 wlr_xcursor_manager_load(seat->cursor->xcursor_manager,
1034 if (!result) { 1053 output->scale);
1035 sway_log(SWAY_ERROR, 1054 if (!result) {
1036 "Cannot load xcursor theme for output '%s' with scale %f", 1055 sway_log(SWAY_ERROR,
1037 output->name, output->scale); 1056 "Cannot load xcursor theme for output '%s' with scale %f",
1057 output->name, output->scale);
1058 }
1038 } 1059 }
1039 }
1040 1060
1041 // 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
1042 cursor_set_image(seat->cursor, NULL, NULL); 1062 cursor_set_image(seat->cursor, NULL, NULL);
1043 cursor_set_image(seat->cursor, "left_ptr", NULL); 1063 cursor_set_image(seat->cursor, "default", NULL);
1044 wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, 1064 wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x,
1045 seat->cursor->cursor->y); 1065 seat->cursor->cursor->y);
1066 }
1046} 1067}
1047 1068
1048bool seat_is_input_allowed(struct sway_seat *seat, 1069bool seat_is_input_allowed(struct sway_seat *seat,
1049 struct wlr_surface *surface) { 1070 struct wlr_surface *surface) {
1050 struct wl_client *client = wl_resource_get_client(surface->resource); 1071 if (server.session_lock.lock) {
1051 return !seat->exclusive_client || seat->exclusive_client == client; 1072 return sway_session_lock_has_surface(server.session_lock.lock, surface);
1073 }
1074 return true;
1052} 1075}
1053 1076
1054static void send_unfocus(struct sway_container *con, void *data) { 1077static void send_unfocus(struct sway_container *con, void *data) {
@@ -1107,15 +1130,7 @@ void seat_set_raw_focus(struct sway_seat *seat, struct sway_node *node) {
1107 } 1130 }
1108} 1131}
1109 1132
1110void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { 1133static void seat_set_workspace_focus(struct sway_seat *seat, struct sway_node *node) {
1111 if (seat->focused_layer) {
1112 struct wlr_layer_surface_v1 *layer = seat->focused_layer;
1113 seat_set_focus_layer(seat, NULL);
1114 seat_set_focus(seat, node);
1115 seat_set_focus_layer(seat, layer);
1116 return;
1117 }
1118
1119 struct sway_node *last_focus = seat_get_focus(seat); 1134 struct sway_node *last_focus = seat_get_focus(seat);
1120 if (last_focus == node) { 1135 if (last_focus == node) {
1121 return; 1136 return;
@@ -1248,6 +1263,24 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) {
1248 } 1263 }
1249} 1264}
1250 1265
1266void 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
1251void seat_set_focus_container(struct sway_seat *seat, 1284void seat_set_focus_container(struct sway_seat *seat,
1252 struct sway_container *con) { 1285 struct sway_container *con) {
1253 seat_set_focus(seat, con ? &con->node : NULL); 1286 seat_set_focus(seat, con ? &con->node : NULL);
@@ -1273,7 +1306,7 @@ void seat_set_focus_surface(struct sway_seat *seat,
1273 } 1306 }
1274 1307
1275 sway_input_method_relay_set_focus(&seat->im_relay, surface); 1308 sway_input_method_relay_set_focus(&seat->im_relay, surface);
1276 seat_tablet_pads_notify_enter(seat, surface); 1309 seat_tablet_pads_set_focus(seat, surface);
1277} 1310}
1278 1311
1279void seat_set_focus_layer(struct sway_seat *seat, 1312void seat_set_focus_layer(struct sway_seat *seat,
@@ -1287,28 +1320,23 @@ void seat_set_focus_layer(struct sway_seat *seat,
1287 seat_set_focus(seat, previous); 1320 seat_set_focus(seat, previous);
1288 } 1321 }
1289 return; 1322 return;
1290 } else if (!layer || seat->focused_layer == layer) { 1323 } else if (!layer) {
1291 return; 1324 return;
1292 } 1325 }
1293 assert(layer->mapped); 1326 assert(layer->surface->mapped);
1294 seat_set_focus_surface(seat, layer->surface, true); 1327 if (layer->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP &&
1295 if (layer->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) { 1328 layer->current.keyboard_interactive
1296 seat->focused_layer = layer; 1329 == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) {
1330 seat->has_exclusive_layer = true;
1297 } 1331 }
1298} 1332 if (seat->focused_layer == layer) {
1299
1300void seat_set_exclusive_client(struct sway_seat *seat,
1301 struct wl_client *client) {
1302 if (!client) {
1303 seat->exclusive_client = client;
1304 // Triggers a refocus of the topmost surface layer if necessary
1305 // TODO: Make layer surface focus per-output based on cursor position
1306 for (int i = 0; i < root->outputs->length; ++i) {
1307 struct sway_output *output = root->outputs->items[i];
1308 arrange_layers(output);
1309 }
1310 return; 1333 return;
1311 } 1334 }
1335 seat_set_focus_surface(seat, layer->surface, true);
1336 seat->focused_layer = layer;
1337}
1338
1339void seat_unfocus_unless_client(struct sway_seat *seat, struct wl_client *client) {
1312 if (seat->focused_layer) { 1340 if (seat->focused_layer) {
1313 if (wl_resource_get_client(seat->focused_layer->resource) != client) { 1341 if (wl_resource_get_client(seat->focused_layer->resource) != client) {
1314 seat_set_focus_layer(seat, NULL); 1342 seat_set_focus_layer(seat, NULL);
@@ -1335,7 +1363,6 @@ void seat_set_exclusive_client(struct sway_seat *seat,
1335 now.tv_nsec / 1000, point->touch_id); 1363 now.tv_nsec / 1000, point->touch_id);
1336 } 1364 }
1337 } 1365 }
1338 seat->exclusive_client = client;
1339} 1366}
1340 1367
1341struct sway_node *seat_get_focus_inactive(struct sway_seat *seat, 1368struct sway_node *seat_get_focus_inactive(struct sway_seat *seat,
@@ -1416,9 +1443,8 @@ struct sway_node *seat_get_focus(struct sway_seat *seat) {
1416 if (!seat->has_focus) { 1443 if (!seat->has_focus) {
1417 return NULL; 1444 return NULL;
1418 } 1445 }
1419 if (wl_list_empty(&seat->focus_stack)) { 1446 sway_assert(!wl_list_empty(&seat->focus_stack),
1420 return NULL; 1447 "focus_stack is empty, but has_focus is true");
1421 }
1422 struct sway_seat_node *current = 1448 struct sway_seat_node *current =
1423 wl_container_of(seat->focus_stack.next, current, link); 1449 wl_container_of(seat->focus_stack.next, current, link);
1424 return current->node; 1450 return current->node;
@@ -1503,7 +1529,7 @@ struct seat_config *seat_get_config_by_name(const char *name) {
1503} 1529}
1504 1530
1505void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, 1531void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec,
1506 uint32_t button, enum wlr_button_state state) { 1532 uint32_t button, enum wl_pointer_button_state state) {
1507 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,
1508 time_msec, button, state); 1534 time_msec, button, state);
1509} 1535}
@@ -1540,7 +1566,7 @@ void seatop_unref(struct sway_seat *seat, struct sway_container *con) {
1540 1566
1541void seatop_button(struct sway_seat *seat, uint32_t time_msec, 1567void seatop_button(struct sway_seat *seat, uint32_t time_msec,
1542 struct wlr_input_device *device, uint32_t button, 1568 struct wlr_input_device *device, uint32_t button,
1543 enum wlr_button_state state) { 1569 enum wl_pointer_button_state state) {
1544 if (seat->seatop_impl->button) { 1570 if (seat->seatop_impl->button) {
1545 seat->seatop_impl->button(seat, time_msec, device, button, state); 1571 seat->seatop_impl->button(seat, time_msec, device, button, state);
1546 } 1572 }
@@ -1553,12 +1579,38 @@ void seatop_pointer_motion(struct sway_seat *seat, uint32_t time_msec) {
1553} 1579}
1554 1580
1555void seatop_pointer_axis(struct sway_seat *seat, 1581void seatop_pointer_axis(struct sway_seat *seat,
1556 struct wlr_event_pointer_axis *event) { 1582 struct wlr_pointer_axis_event *event) {
1557 if (seat->seatop_impl->pointer_axis) { 1583 if (seat->seatop_impl->pointer_axis) {
1558 seat->seatop_impl->pointer_axis(seat, event); 1584 seat->seatop_impl->pointer_axis(seat, event);
1559 } 1585 }
1560} 1586}
1561 1587
1588void 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
1595void 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
1601void 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
1608void 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
1562void seatop_tablet_tool_tip(struct sway_seat *seat, 1614void seatop_tablet_tool_tip(struct sway_seat *seat,
1563 struct sway_tablet_tool *tool, uint32_t time_msec, 1615 struct sway_tablet_tool *tool, uint32_t time_msec,
1564 enum wlr_tablet_tool_tip_state state) { 1616 enum wlr_tablet_tool_tip_state state) {
@@ -1576,6 +1628,62 @@ void seatop_tablet_tool_motion(struct sway_seat *seat,
1576 } 1628 }
1577} 1629}
1578 1630
1631void 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
1638void 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
1645void 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
1652void 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
1659void 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
1666void 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
1673void 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
1680void 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
1579void seatop_rebase(struct sway_seat *seat, uint32_t time_msec) { 1687void seatop_rebase(struct sway_seat *seat, uint32_t time_msec) {
1580 if (seat->seatop_impl->rebase) { 1688 if (seat->seatop_impl->rebase) {
1581 seat->seatop_impl->rebase(seat, time_msec); 1689 seat->seatop_impl->rebase(seat, time_msec);
@@ -1591,13 +1699,6 @@ void seatop_end(struct sway_seat *seat) {
1591 seat->seatop_impl = NULL; 1699 seat->seatop_impl = NULL;
1592} 1700}
1593 1701
1594void seatop_render(struct sway_seat *seat, struct sway_output *output,
1595 pixman_region32_t *damage) {
1596 if (seat->seatop_impl->render) {
1597 seat->seatop_impl->render(seat, output, damage);
1598 }
1599}
1600
1601bool seatop_allows_set_cursor(struct sway_seat *seat) { 1702bool seatop_allows_set_cursor(struct sway_seat *seat) {
1602 return seat->seatop_impl->allow_set_cursor; 1703 return seat->seatop_impl->allow_set_cursor;
1603} 1704}