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.c530
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) {
50static void seat_node_destroy(struct sway_seat_node *seat_node) { 53static 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
56void 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
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
86void seat_idle_notify_activity(struct sway_seat *seat, 106void 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
164static void seat_tablet_pads_notify_enter(struct sway_seat *seat, 173static 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
210struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat, 219struct 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
354static 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) {
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
361void 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
387static void drag_icon_handle_surface_commit(struct wl_listener *listener, 382void 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
394static 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
399static 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
404static 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
415static void drag_handle_destroy(struct wl_listener *listener, void *data) { 389static 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
669static void seat_apply_input_config(struct sway_seat *seat, 650static 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 */
658static 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
674static 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
684static 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
726static void seat_configure_pointer(struct sway_seat *seat, 780static 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
770static void seat_configure_tablet_tool(struct sway_seat *seat, 828static 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
781static void seat_configure_tablet_pad(struct sway_seat *seat, 838static 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
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);
835} 904}
836 905
837void seat_reset_device(struct sway_seat *seat, 906void 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
999bool seat_is_input_allowed(struct sway_seat *seat, 1069bool 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
1005static void send_unfocus(struct sway_container *con, void *data) { 1077static 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
1061void 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) {
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
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
1213void seat_set_focus_container(struct sway_seat *seat, 1284void 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
1240void seat_set_focus_layer(struct sway_seat *seat, 1312void 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
1261void 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
1339void 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
1302struct sway_node *seat_get_focus_inactive(struct sway_seat *seat, 1368struct 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
1466void 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,
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
1502void seatop_button(struct sway_seat *seat, uint32_t time_msec, 1567void 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
1516void seatop_pointer_axis(struct sway_seat *seat, 1581void 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
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
1523void seatop_tablet_tool_tip(struct sway_seat *seat, 1614void 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
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
1540void seatop_rebase(struct sway_seat *seat, uint32_t time_msec) { 1687void 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
1555void 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
1562bool seatop_allows_set_cursor(struct sway_seat *seat) { 1702bool 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}