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.c347
1 files changed, 177 insertions, 170 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c
index b21e1b86..0c5672bc 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -1,12 +1,12 @@
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>
@@ -17,7 +17,7 @@
17#include "list.h" 17#include "list.h"
18#include "log.h" 18#include "log.h"
19#include "sway/config.h" 19#include "sway/config.h"
20#include "sway/desktop.h" 20#include "sway/scene_descriptor.h"
21#include "sway/input/cursor.h" 21#include "sway/input/cursor.h"
22#include "sway/input/input-manager.h" 22#include "sway/input/input-manager.h"
23#include "sway/input/keyboard.h" 23#include "sway/input/keyboard.h"
@@ -67,6 +67,12 @@ static void seat_node_destroy(struct sway_seat_node *seat_node) {
67} 67}
68 68
69void 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
70 if (seat == config->handler_context.seat) { 76 if (seat == config->handler_context.seat) {
71 config->handler_context.seat = input_manager_get_default_seat(); 77 config->handler_context.seat = input_manager_get_default_seat();
72 } 78 }
@@ -87,10 +93,11 @@ void seat_destroy(struct sway_seat *seat) {
87 wl_list_remove(&seat->request_set_selection.link); 93 wl_list_remove(&seat->request_set_selection.link);
88 wl_list_remove(&seat->request_set_primary_selection.link); 94 wl_list_remove(&seat->request_set_primary_selection.link);
89 wl_list_remove(&seat->link); 95 wl_list_remove(&seat->link);
90 wlr_seat_destroy(seat->wlr_seat); 96 wl_list_remove(&seat->destroy.link);
91 for (int i = 0; i < seat->deferred_bindings->length; i++) { 97 for (int i = 0; i < seat->deferred_bindings->length; i++) {
92 free_sway_binding(seat->deferred_bindings->items[i]); 98 free_sway_binding(seat->deferred_bindings->items[i]);
93 } 99 }
100 wlr_scene_node_destroy(&seat->scene_tree->node);
94 list_free(seat->deferred_bindings); 101 list_free(seat->deferred_bindings);
95 free(seat->prev_workspace_name); 102 free(seat->prev_workspace_name);
96 free(seat); 103 free(seat);
@@ -98,21 +105,10 @@ void seat_destroy(struct sway_seat *seat) {
98 105
99void seat_idle_notify_activity(struct sway_seat *seat, 106void seat_idle_notify_activity(struct sway_seat *seat,
100 enum sway_input_idle_source source) { 107 enum sway_input_idle_source source) {
101 uint32_t mask = seat->idle_inhibit_sources; 108 if ((source & seat->idle_inhibit_sources) == 0) {
102 struct wlr_idle_timeout *timeout; 109 return;
103 int ntimers = 0, nidle = 0;
104 wl_list_for_each(timeout, &server.idle->idle_timers, link) {
105 ++ntimers;
106 if (timeout->idle_state) {
107 ++nidle;
108 }
109 }
110 if (nidle == ntimers) {
111 mask = seat->idle_wake_sources;
112 }
113 if ((source & mask) > 0) {
114 wlr_idle_notify_activity(server.idle, seat->wlr_seat);
115 } 110 }
111 wlr_idle_notifier_v1_notify_activity(server.idle_notifier_v1, seat->wlr_seat);
116} 112}
117 113
118/** 114/**
@@ -174,11 +170,11 @@ static void seat_keyboard_notify_enter(struct sway_seat *seat,
174 state->pressed_keycodes, state->npressed, &keyboard->modifiers); 170 state->pressed_keycodes, state->npressed, &keyboard->modifiers);
175} 171}
176 172
177static void seat_tablet_pads_notify_enter(struct sway_seat *seat, 173static void seat_tablet_pads_set_focus(struct sway_seat *seat,
178 struct wlr_surface *surface) { 174 struct wlr_surface *surface) {
179 struct sway_seat_device *seat_device; 175 struct sway_seat_device *seat_device;
180 wl_list_for_each(seat_device, &seat->devices, link) { 176 wl_list_for_each(seat_device, &seat->devices, link) {
181 sway_tablet_pad_notify_enter(seat_device->tablet_pad, surface); 177 sway_tablet_pad_set_focus(seat_device->tablet_pad, surface);
182 } 178 }
183} 179}
184 180
@@ -202,7 +198,7 @@ static void seat_send_focus(struct sway_node *node, struct sway_seat *seat) {
202#endif 198#endif
203 199
204 seat_keyboard_notify_enter(seat, view->surface); 200 seat_keyboard_notify_enter(seat, view->surface);
205 seat_tablet_pads_notify_enter(seat, view->surface); 201 seat_tablet_pads_set_focus(seat, view->surface);
206 sway_input_method_relay_set_focus(&seat->im_relay, view->surface); 202 sway_input_method_relay_set_focus(&seat->im_relay, view->surface);
207 203
208 struct wlr_pointer_constraint_v1 *constraint = 204 struct wlr_pointer_constraint_v1 *constraint =
@@ -212,15 +208,6 @@ static void seat_send_focus(struct sway_node *node, struct sway_seat *seat) {
212 } 208 }
213} 209}
214 210
215void sway_force_focus(struct wlr_surface *surface) {
216 struct sway_seat *seat;
217 wl_list_for_each(seat, &server.input->seats, link) {
218 seat_keyboard_notify_enter(seat, surface);
219 seat_tablet_pads_notify_enter(seat, surface);
220 sway_input_method_relay_set_focus(&seat->im_relay, surface);
221 }
222}
223
224void seat_for_each_node(struct sway_seat *seat, 211void seat_for_each_node(struct sway_seat *seat,
225 void (*f)(struct sway_node *node, void *data), void *data) { 212 void (*f)(struct sway_node *node, void *data), void *data) {
226 struct sway_seat_node *current = NULL; 213 struct sway_seat_node *current = NULL;
@@ -372,25 +359,15 @@ static void handle_new_node(struct wl_listener *listener, void *data) {
372 seat_node_from_node(seat, node); 359 seat_node_from_node(seat, node);
373} 360}
374 361
375static 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) {
376 if (!icon->wlr_drag_icon->mapped) { 363 struct wlr_drag_icon *wlr_icon = scene_descriptor_try_get(node, SWAY_SCENE_DESC_DRAG_ICON);
377 return;
378 }
379 desktop_damage_surface(icon->wlr_drag_icon->surface, icon->x, icon->y, true);
380}
381
382void drag_icon_update_position(struct sway_drag_icon *icon) {
383 drag_icon_damage_whole(icon);
384
385 struct wlr_drag_icon *wlr_icon = icon->wlr_drag_icon;
386 struct sway_seat *seat = icon->seat;
387 struct wlr_cursor *cursor = seat->cursor->cursor; 364 struct wlr_cursor *cursor = seat->cursor->cursor;
365
388 switch (wlr_icon->drag->grab_type) { 366 switch (wlr_icon->drag->grab_type) {
389 case WLR_DRAG_GRAB_KEYBOARD: 367 case WLR_DRAG_GRAB_KEYBOARD:
390 return; 368 return;
391 case WLR_DRAG_GRAB_KEYBOARD_POINTER: 369 case WLR_DRAG_GRAB_KEYBOARD_POINTER:
392 icon->x = cursor->x + wlr_icon->surface->sx; 370 wlr_scene_node_set_position(node, cursor->x, cursor->y);
393 icon->y = cursor->y + wlr_icon->surface->sy;
394 break; 371 break;
395 case WLR_DRAG_GRAB_KEYBOARD_TOUCH:; 372 case WLR_DRAG_GRAB_KEYBOARD_TOUCH:;
396 struct wlr_touch_point *point = 373 struct wlr_touch_point *point =
@@ -398,39 +375,15 @@ void drag_icon_update_position(struct sway_drag_icon *icon) {
398 if (point == NULL) { 375 if (point == NULL) {
399 return; 376 return;
400 } 377 }
401 icon->x = seat->touch_x + wlr_icon->surface->sx; 378 wlr_scene_node_set_position(node, seat->touch_x, seat->touch_y);
402 icon->y = seat->touch_y + wlr_icon->surface->sy;
403 } 379 }
404
405 drag_icon_damage_whole(icon);
406}
407
408static void drag_icon_handle_surface_commit(struct wl_listener *listener,
409 void *data) {
410 struct sway_drag_icon *icon =
411 wl_container_of(listener, icon, surface_commit);
412 drag_icon_update_position(icon);
413}
414
415static void drag_icon_handle_map(struct wl_listener *listener, void *data) {
416 struct sway_drag_icon *icon = wl_container_of(listener, icon, map);
417 drag_icon_damage_whole(icon);
418} 380}
419 381
420static void drag_icon_handle_unmap(struct wl_listener *listener, void *data) { 382void drag_icons_update_position(struct sway_seat *seat) {
421 struct sway_drag_icon *icon = wl_container_of(listener, icon, unmap); 383 struct wlr_scene_node *node;
422 drag_icon_damage_whole(icon); 384 wl_list_for_each(node, &seat->drag_icons->children, link) {
423} 385 drag_icon_update_position(seat, node);
424 386 }
425static void drag_icon_handle_destroy(struct wl_listener *listener, void *data) {
426 struct sway_drag_icon *icon = wl_container_of(listener, icon, destroy);
427 icon->wlr_drag_icon->data = NULL;
428 wl_list_remove(&icon->link);
429 wl_list_remove(&icon->surface_commit.link);
430 wl_list_remove(&icon->unmap.link);
431 wl_list_remove(&icon->map.link);
432 wl_list_remove(&icon->destroy.link);
433 free(icon);
434} 387}
435 388
436static void drag_handle_destroy(struct wl_listener *listener, void *data) { 389static void drag_handle_destroy(struct wl_listener *listener, void *data) {
@@ -502,27 +455,20 @@ static void handle_start_drag(struct wl_listener *listener, void *data) {
502 455
503 struct wlr_drag_icon *wlr_drag_icon = wlr_drag->icon; 456 struct wlr_drag_icon *wlr_drag_icon = wlr_drag->icon;
504 if (wlr_drag_icon != NULL) { 457 if (wlr_drag_icon != NULL) {
505 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);
506 if (icon == NULL) { 459 if (!tree) {
507 sway_log(SWAY_ERROR, "Allocation failed"); 460 sway_log(SWAY_ERROR, "Failed to allocate a drag icon scene tree");
508 return; 461 return;
509 } 462 }
510 icon->seat = seat;
511 icon->wlr_drag_icon = wlr_drag_icon;
512 wlr_drag_icon->data = icon;
513 463
514 icon->surface_commit.notify = drag_icon_handle_surface_commit; 464 if (!scene_descriptor_assign(&tree->node, SWAY_SCENE_DESC_DRAG_ICON,
515 wl_signal_add(&wlr_drag_icon->surface->events.commit, &icon->surface_commit); 465 wlr_drag_icon)) {
516 icon->unmap.notify = drag_icon_handle_unmap; 466 sway_log(SWAY_ERROR, "Failed to allocate a drag icon scene descriptor");
517 wl_signal_add(&wlr_drag_icon->events.unmap, &icon->unmap); 467 wlr_scene_node_destroy(&tree->node);
518 icon->map.notify = drag_icon_handle_map; 468 return;
519 wl_signal_add(&wlr_drag_icon->events.map, &icon->map); 469 }
520 icon->destroy.notify = drag_icon_handle_destroy;
521 wl_signal_add(&wlr_drag_icon->events.destroy, &icon->destroy);
522
523 wl_list_insert(&root->drag_icons, &icon->link);
524 470
525 drag_icon_update_position(icon); 471 drag_icon_update_position(seat, &tree->node);
526 } 472 }
527 seatop_begin_default(seat); 473 seatop_begin_default(seat);
528} 474}
@@ -569,8 +515,18 @@ struct sway_seat *seat_create(const char *seat_name) {
569 return NULL; 515 return NULL;
570 } 516 }
571 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
572 seat->wlr_seat = wlr_seat_create(server.wl_display, seat_name); 527 seat->wlr_seat = wlr_seat_create(server.wl_display, seat_name);
573 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);
574 free(seat); 530 free(seat);
575 return NULL; 531 return NULL;
576 } 532 }
@@ -578,11 +534,15 @@ struct sway_seat *seat_create(const char *seat_name) {
578 534
579 seat->cursor = sway_cursor_create(seat); 535 seat->cursor = sway_cursor_create(seat);
580 if (!seat->cursor) { 536 if (!seat->cursor) {
537 wlr_scene_node_destroy(&seat->scene_tree->node);
581 wlr_seat_destroy(seat->wlr_seat); 538 wlr_seat_destroy(seat->wlr_seat);
582 free(seat); 539 free(seat);
583 return NULL; 540 return NULL;
584 } 541 }
585 542
543 seat->destroy.notify = handle_seat_destroy;
544 wl_signal_add(&seat->wlr_seat->events.destroy, &seat->destroy);
545
586 seat->idle_inhibit_sources = seat->idle_wake_sources = 546 seat->idle_inhibit_sources = seat->idle_wake_sources =
587 IDLE_SOURCE_KEYBOARD | 547 IDLE_SOURCE_KEYBOARD |
588 IDLE_SOURCE_POINTER | 548 IDLE_SOURCE_POINTER |
@@ -656,7 +616,7 @@ static void seat_update_capabilities(struct sway_seat *seat) {
656 case WLR_INPUT_DEVICE_TOUCH: 616 case WLR_INPUT_DEVICE_TOUCH:
657 caps |= WL_SEAT_CAPABILITY_TOUCH; 617 caps |= WL_SEAT_CAPABILITY_TOUCH;
658 break; 618 break;
659 case WLR_INPUT_DEVICE_TABLET_TOOL: 619 case WLR_INPUT_DEVICE_TABLET:
660 caps |= WL_SEAT_CAPABILITY_POINTER; 620 caps |= WL_SEAT_CAPABILITY_POINTER;
661 break; 621 break;
662 case WLR_INPUT_DEVICE_SWITCH: 622 case WLR_INPUT_DEVICE_SWITCH:
@@ -674,7 +634,7 @@ static void seat_update_capabilities(struct sway_seat *seat) {
674 } else { 634 } else {
675 wlr_seat_set_capabilities(seat->wlr_seat, caps); 635 wlr_seat_set_capabilities(seat->wlr_seat, caps);
676 if ((previous_caps & WL_SEAT_CAPABILITY_POINTER) == 0) { 636 if ((previous_caps & WL_SEAT_CAPABILITY_POINTER) == 0) {
677 cursor_set_image(seat->cursor, "left_ptr", NULL); 637 cursor_set_image(seat->cursor, "default", NULL);
678 } 638 }
679 } 639 }
680} 640}
@@ -714,19 +674,28 @@ static const char *get_builtin_output_name(void) {
714static 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) {
715 switch (seat_device->input_device->wlr_device->type) { 675 switch (seat_device->input_device->wlr_device->type) {
716 case WLR_INPUT_DEVICE_TOUCH: 676 case WLR_INPUT_DEVICE_TOUCH:
717 case WLR_INPUT_DEVICE_TABLET_TOOL: 677 case WLR_INPUT_DEVICE_TABLET:
718 return true; 678 return true;
719 default: 679 default:
720 return false; 680 return false;
721 } 681 }
722} 682}
723 683
724static void seat_apply_input_config(struct sway_seat *seat, 684static void seat_apply_input_mapping(struct sway_seat *seat,
725 struct sway_seat_device *sway_device) { 685 struct sway_seat_device *sway_device) {
726 struct input_config *ic = 686 struct input_config *ic =
727 input_device_get_config(sway_device->input_device); 687 input_device_get_config(sway_device->input_device);
728 688
729 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",
730 sway_device->input_device->identifier); 699 sway_device->input_device->identifier);
731 700
732 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;
@@ -754,6 +723,7 @@ static void seat_apply_input_config(struct sway_seat *seat,
754 mapped_to_output = NULL; 723 mapped_to_output = NULL;
755 break; 724 break;
756 } 725 }
726#if WLR_HAS_LIBINPUT_BACKEND
757 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) &&
758 sway_libinput_device_is_builtin(sway_device->input_device)) { 728 sway_libinput_device_is_builtin(sway_device->input_device)) {
759 mapped_to_output = get_builtin_output_name(); 729 mapped_to_output = get_builtin_output_name();
@@ -762,6 +732,10 @@ static void seat_apply_input_config(struct sway_seat *seat,
762 mapped_to_output, sway_device->input_device->identifier); 732 mapped_to_output, sway_device->input_device->identifier);
763 } 733 }
764 } 734 }
735#else
736 (void)is_touch_or_tablet_tool;
737 (void)get_builtin_output_name;
738#endif
765 if (mapped_to_output == NULL) { 739 if (mapped_to_output == NULL) {
766 return; 740 return;
767 } 741 }
@@ -805,12 +779,9 @@ static void seat_apply_input_config(struct sway_seat *seat,
805 779
806static void seat_configure_pointer(struct sway_seat *seat, 780static void seat_configure_pointer(struct sway_seat *seat,
807 struct sway_seat_device *sway_device) { 781 struct sway_seat_device *sway_device) {
808 if ((seat->wlr_seat->capabilities & WL_SEAT_CAPABILITY_POINTER) == 0) { 782 seat_configure_xcursor(seat);
809 seat_configure_xcursor(seat);
810 }
811 wlr_cursor_attach_input_device(seat->cursor->cursor, 783 wlr_cursor_attach_input_device(seat->cursor->cursor,
812 sway_device->input_device->wlr_device); 784 sway_device->input_device->wlr_device);
813 seat_apply_input_config(seat, sway_device);
814 wl_event_source_timer_update( 785 wl_event_source_timer_update(
815 seat->cursor->hide_source, cursor_get_timeout(seat->cursor)); 786 seat->cursor->hide_source, cursor_get_timeout(seat->cursor));
816} 787}
@@ -821,8 +792,15 @@ static void seat_configure_keyboard(struct sway_seat *seat,
821 sway_keyboard_create(seat, seat_device); 792 sway_keyboard_create(seat, seat_device);
822 } 793 }
823 sway_keyboard_configure(seat_device->keyboard); 794 sway_keyboard_configure(seat_device->keyboard);
824 wlr_seat_set_keyboard(seat->wlr_seat, 795
825 wlr_keyboard_from_input_device(seat_device->input_device->wlr_device)); 796 // We only need to update the current keyboard, as the rest will be updated
797 // as they are activated.
798 struct wlr_keyboard *wlr_keyboard =
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 }
826 804
827 // force notify reenter to pick up the new configuration. This reuses 805 // force notify reenter to pick up the new configuration. This reuses
828 // the current focused surface to avoid breaking input grabs. 806 // the current focused surface to avoid breaking input grabs.
@@ -838,7 +816,6 @@ static void seat_configure_switch(struct sway_seat *seat,
838 if (!seat_device->switch_device) { 816 if (!seat_device->switch_device) {
839 sway_switch_create(seat, seat_device); 817 sway_switch_create(seat, seat_device);
840 } 818 }
841 seat_apply_input_config(seat, seat_device);
842 sway_switch_configure(seat_device->switch_device); 819 sway_switch_configure(seat_device->switch_device);
843} 820}
844 821
@@ -846,7 +823,6 @@ static void seat_configure_touch(struct sway_seat *seat,
846 struct sway_seat_device *sway_device) { 823 struct sway_seat_device *sway_device) {
847 wlr_cursor_attach_input_device(seat->cursor->cursor, 824 wlr_cursor_attach_input_device(seat->cursor->cursor,
848 sway_device->input_device->wlr_device); 825 sway_device->input_device->wlr_device);
849 seat_apply_input_config(seat, sway_device);
850} 826}
851 827
852static void seat_configure_tablet_tool(struct sway_seat *seat, 828static void seat_configure_tablet_tool(struct sway_seat *seat,
@@ -857,7 +833,6 @@ static void seat_configure_tablet_tool(struct sway_seat *seat,
857 sway_configure_tablet(sway_device->tablet); 833 sway_configure_tablet(sway_device->tablet);
858 wlr_cursor_attach_input_device(seat->cursor->cursor, 834 wlr_cursor_attach_input_device(seat->cursor->cursor,
859 sway_device->input_device->wlr_device); 835 sway_device->input_device->wlr_device);
860 seat_apply_input_config(seat, sway_device);
861} 836}
862 837
863static void seat_configure_tablet_pad(struct sway_seat *seat, 838static void seat_configure_tablet_pad(struct sway_seat *seat,
@@ -907,13 +882,25 @@ void seat_configure_device(struct sway_seat *seat,
907 case WLR_INPUT_DEVICE_TOUCH: 882 case WLR_INPUT_DEVICE_TOUCH:
908 seat_configure_touch(seat, seat_device); 883 seat_configure_touch(seat, seat_device);
909 break; 884 break;
910 case WLR_INPUT_DEVICE_TABLET_TOOL: 885 case WLR_INPUT_DEVICE_TABLET:
911 seat_configure_tablet_tool(seat, seat_device); 886 seat_configure_tablet_tool(seat, seat_device);
912 break; 887 break;
913 case WLR_INPUT_DEVICE_TABLET_PAD: 888 case WLR_INPUT_DEVICE_TABLET_PAD:
914 seat_configure_tablet_pad(seat, seat_device); 889 seat_configure_tablet_pad(seat, seat_device);
915 break; 890 break;
916 } 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);
917} 904}
918 905
919void seat_reset_device(struct sway_seat *seat, 906void seat_reset_device(struct sway_seat *seat,
@@ -934,7 +921,7 @@ void seat_reset_device(struct sway_seat *seat,
934 case WLR_INPUT_DEVICE_TOUCH: 921 case WLR_INPUT_DEVICE_TOUCH:
935 seat_reset_input_config(seat, seat_device); 922 seat_reset_input_config(seat, seat_device);
936 break; 923 break;
937 case WLR_INPUT_DEVICE_TABLET_TOOL: 924 case WLR_INPUT_DEVICE_TABLET:
938 seat_reset_input_config(seat, seat_device); 925 seat_reset_input_config(seat, seat_device);
939 break; 926 break;
940 case WLR_INPUT_DEVICE_TABLET_PAD: 927 case WLR_INPUT_DEVICE_TABLET_PAD:
@@ -1030,7 +1017,7 @@ void seat_configure_xcursor(struct sway_seat *seat) {
1030 1017
1031 wlr_xcursor_manager_load(server.xwayland.xcursor_manager, 1); 1018 wlr_xcursor_manager_load(server.xwayland.xcursor_manager, 1);
1032 struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor( 1019 struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor(
1033 server.xwayland.xcursor_manager, "left_ptr", 1); 1020 server.xwayland.xcursor_manager, "default", 1);
1034 if (xcursor != NULL) { 1021 if (xcursor != NULL) {
1035 struct wlr_xcursor_image *image = xcursor->images[0]; 1022 struct wlr_xcursor_image *image = xcursor->images[0];
1036 wlr_xwayland_set_cursor( 1023 wlr_xwayland_set_cursor(
@@ -1056,33 +1043,35 @@ void seat_configure_xcursor(struct sway_seat *seat) {
1056 sway_log(SWAY_ERROR, 1043 sway_log(SWAY_ERROR,
1057 "Cannot create XCursor manager for theme '%s'", cursor_theme); 1044 "Cannot create XCursor manager for theme '%s'", cursor_theme);
1058 } 1045 }
1059 }
1060 1046
1061 for (int i = 0; i < root->outputs->length; ++i) { 1047
1062 struct sway_output *sway_output = root->outputs->items[i]; 1048 for (int i = 0; i < root->outputs->length; ++i) {
1063 struct wlr_output *output = sway_output->wlr_output; 1049 struct sway_output *sway_output = root->outputs->items[i];
1064 bool result = 1050 struct wlr_output *output = sway_output->wlr_output;
1065 wlr_xcursor_manager_load(seat->cursor->xcursor_manager, 1051 bool result =
1066 output->scale); 1052 wlr_xcursor_manager_load(seat->cursor->xcursor_manager,
1067 if (!result) { 1053 output->scale);
1068 sway_log(SWAY_ERROR, 1054 if (!result) {
1069 "Cannot load xcursor theme for output '%s' with scale %f", 1055 sway_log(SWAY_ERROR,
1070 output->name, output->scale); 1056 "Cannot load xcursor theme for output '%s' with scale %f",
1057 output->name, output->scale);
1058 }
1071 } 1059 }
1072 }
1073 1060
1074 // 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
1075 cursor_set_image(seat->cursor, NULL, NULL); 1062 cursor_set_image(seat->cursor, NULL, NULL);
1076 cursor_set_image(seat->cursor, "left_ptr", NULL); 1063 cursor_set_image(seat->cursor, "default", NULL);
1077 wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, 1064 wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x,
1078 seat->cursor->cursor->y); 1065 seat->cursor->cursor->y);
1066 }
1079} 1067}
1080 1068
1081bool seat_is_input_allowed(struct sway_seat *seat, 1069bool seat_is_input_allowed(struct sway_seat *seat,
1082 struct wlr_surface *surface) { 1070 struct wlr_surface *surface) {
1083 struct wl_client *client = wl_resource_get_client(surface->resource); 1071 if (server.session_lock.lock) {
1084 return seat->exclusive_client == client || 1072 return sway_session_lock_has_surface(server.session_lock.lock, surface);
1085 (seat->exclusive_client == NULL && !server.session_lock.locked); 1073 }
1074 return true;
1086} 1075}
1087 1076
1088static void send_unfocus(struct sway_container *con, void *data) { 1077static void send_unfocus(struct sway_container *con, void *data) {
@@ -1141,15 +1130,7 @@ void seat_set_raw_focus(struct sway_seat *seat, struct sway_node *node) {
1141 } 1130 }
1142} 1131}
1143 1132
1144void 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) {
1145 if (seat->focused_layer) {
1146 struct wlr_layer_surface_v1 *layer = seat->focused_layer;
1147 seat_set_focus_layer(seat, NULL);
1148 seat_set_focus(seat, node);
1149 seat_set_focus_layer(seat, layer);
1150 return;
1151 }
1152
1153 struct sway_node *last_focus = seat_get_focus(seat); 1134 struct sway_node *last_focus = seat_get_focus(seat);
1154 if (last_focus == node) { 1135 if (last_focus == node) {
1155 return; 1136 return;
@@ -1183,11 +1164,6 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) {
1183 return; 1164 return;
1184 } 1165 }
1185 1166
1186 // Deny setting focus when an input grab or lockscreen is active
1187 if (container && container->view && !seat_is_input_allowed(seat, container->view->surface)) {
1188 return;
1189 }
1190
1191 struct sway_output *new_output = 1167 struct sway_output *new_output =
1192 new_workspace ? new_workspace->output : NULL; 1168 new_workspace ? new_workspace->output : NULL;
1193 1169
@@ -1287,6 +1263,24 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) {
1287 } 1263 }
1288} 1264}
1289 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
1290void seat_set_focus_container(struct sway_seat *seat, 1284void seat_set_focus_container(struct sway_seat *seat,
1291 struct sway_container *con) { 1285 struct sway_container *con) {
1292 seat_set_focus(seat, con ? &con->node : NULL); 1286 seat_set_focus(seat, con ? &con->node : NULL);
@@ -1312,7 +1306,7 @@ void seat_set_focus_surface(struct sway_seat *seat,
1312 } 1306 }
1313 1307
1314 sway_input_method_relay_set_focus(&seat->im_relay, surface); 1308 sway_input_method_relay_set_focus(&seat->im_relay, surface);
1315 seat_tablet_pads_notify_enter(seat, surface); 1309 seat_tablet_pads_set_focus(seat, surface);
1316} 1310}
1317 1311
1318void seat_set_focus_layer(struct sway_seat *seat, 1312void seat_set_focus_layer(struct sway_seat *seat,
@@ -1326,28 +1320,23 @@ void seat_set_focus_layer(struct sway_seat *seat,
1326 seat_set_focus(seat, previous); 1320 seat_set_focus(seat, previous);
1327 } 1321 }
1328 return; 1322 return;
1329 } else if (!layer || seat->focused_layer == layer) { 1323 } else if (!layer) {
1330 return; 1324 return;
1331 } 1325 }
1332 assert(layer->mapped); 1326 assert(layer->surface->mapped);
1333 seat_set_focus_surface(seat, layer->surface, true); 1327 if (layer->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP &&
1334 if (layer->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) { 1328 layer->current.keyboard_interactive
1335 seat->focused_layer = layer; 1329 == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) {
1330 seat->has_exclusive_layer = true;
1336 } 1331 }
1337} 1332 if (seat->focused_layer == layer) {
1338
1339void seat_set_exclusive_client(struct sway_seat *seat,
1340 struct wl_client *client) {
1341 if (!client) {
1342 seat->exclusive_client = client;
1343 // Triggers a refocus of the topmost surface layer if necessary
1344 // TODO: Make layer surface focus per-output based on cursor position
1345 for (int i = 0; i < root->outputs->length; ++i) {
1346 struct sway_output *output = root->outputs->items[i];
1347 arrange_layers(output);
1348 }
1349 return; 1333 return;
1350 } 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) {
1351 if (seat->focused_layer) { 1340 if (seat->focused_layer) {
1352 if (wl_resource_get_client(seat->focused_layer->resource) != client) { 1341 if (wl_resource_get_client(seat->focused_layer->resource) != client) {
1353 seat_set_focus_layer(seat, NULL); 1342 seat_set_focus_layer(seat, NULL);
@@ -1374,7 +1363,6 @@ void seat_set_exclusive_client(struct sway_seat *seat,
1374 now.tv_nsec / 1000, point->touch_id); 1363 now.tv_nsec / 1000, point->touch_id);
1375 } 1364 }
1376 } 1365 }
1377 seat->exclusive_client = client;
1378} 1366}
1379 1367
1380struct sway_node *seat_get_focus_inactive(struct sway_seat *seat, 1368struct sway_node *seat_get_focus_inactive(struct sway_seat *seat,
@@ -1541,7 +1529,7 @@ struct seat_config *seat_get_config_by_name(const char *name) {
1541} 1529}
1542 1530
1543void 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,
1544 uint32_t button, enum wlr_button_state state) { 1532 uint32_t button, enum wl_pointer_button_state state) {
1545 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,
1546 time_msec, button, state); 1534 time_msec, button, state);
1547} 1535}
@@ -1578,7 +1566,7 @@ void seatop_unref(struct sway_seat *seat, struct sway_container *con) {
1578 1566
1579void seatop_button(struct sway_seat *seat, uint32_t time_msec, 1567void seatop_button(struct sway_seat *seat, uint32_t time_msec,
1580 struct wlr_input_device *device, uint32_t button, 1568 struct wlr_input_device *device, uint32_t button,
1581 enum wlr_button_state state) { 1569 enum wl_pointer_button_state state) {
1582 if (seat->seatop_impl->button) { 1570 if (seat->seatop_impl->button) {
1583 seat->seatop_impl->button(seat, time_msec, device, button, state); 1571 seat->seatop_impl->button(seat, time_msec, device, button, state);
1584 } 1572 }
@@ -1597,6 +1585,32 @@ void seatop_pointer_axis(struct sway_seat *seat,
1597 } 1585 }
1598} 1586}
1599 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
1600void seatop_tablet_tool_tip(struct sway_seat *seat, 1614void seatop_tablet_tool_tip(struct sway_seat *seat,
1601 struct sway_tablet_tool *tool, uint32_t time_msec, 1615 struct sway_tablet_tool *tool, uint32_t time_msec,
1602 enum wlr_tablet_tool_tip_state state) { 1616 enum wlr_tablet_tool_tip_state state) {
@@ -1685,13 +1699,6 @@ void seatop_end(struct sway_seat *seat) {
1685 seat->seatop_impl = NULL; 1699 seat->seatop_impl = NULL;
1686} 1700}
1687 1701
1688void seatop_render(struct sway_seat *seat, struct sway_output *output,
1689 pixman_region32_t *damage) {
1690 if (seat->seatop_impl->render) {
1691 seat->seatop_impl->render(seat, output, damage);
1692 }
1693}
1694
1695bool seatop_allows_set_cursor(struct sway_seat *seat) { 1702bool seatop_allows_set_cursor(struct sway_seat *seat) {
1696 return seat->seatop_impl->allow_set_cursor; 1703 return seat->seatop_impl->allow_set_cursor;
1697} 1704}