diff options
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r-- | sway/input/seat.c | 445 |
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) { | |||
51 | static void seat_node_destroy(struct sway_seat_node *seat_node) { | 53 | static 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 | ||
57 | void seat_destroy(struct sway_seat *seat) { | 69 | void seat_destroy(struct sway_seat *seat) { |
70 | wlr_seat_destroy(seat->wlr_seat); | ||
71 | } | ||
72 | |||
73 | static void handle_seat_destroy(struct wl_listener *listener, void *data) { | ||
74 | struct sway_seat *seat = wl_container_of(listener, seat, destroy); | ||
75 | |||
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 | ||
87 | void seat_idle_notify_activity(struct sway_seat *seat, | 106 | void 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 | ||
165 | static void seat_tablet_pads_notify_enter(struct sway_seat *seat, | 173 | static 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 | ||
211 | struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat, | 219 | struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat, |
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 | ||
355 | static void drag_icon_damage_whole(struct sway_drag_icon *icon) { | 362 | static void drag_icon_update_position(struct sway_seat *seat, struct wlr_scene_node *node) { |
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 | |||
362 | void 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 | ||
388 | static void drag_icon_handle_surface_commit(struct wl_listener *listener, | 382 | void 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 | |||
395 | static 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 | |||
400 | static 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 | |||
405 | static 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 | ||
416 | static void drag_handle_destroy(struct wl_listener *listener, void *data) { | 389 | static 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) { | |||
694 | static bool is_touch_or_tablet_tool(struct sway_seat_device *seat_device) { | 674 | static 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 | ||
704 | static void seat_apply_input_config(struct sway_seat *seat, | 684 | static 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 | ||
775 | static void seat_configure_pointer(struct sway_seat *seat, | 780 | static 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 | ||
819 | static void seat_configure_tablet_tool(struct sway_seat *seat, | 828 | static 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 | ||
830 | static void seat_configure_tablet_pad(struct sway_seat *seat, | 838 | static 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 | |||
896 | void seat_configure_device_mapping(struct sway_seat *seat, | ||
897 | struct sway_input_device *input_device) { | ||
898 | struct sway_seat_device *seat_device = seat_get_device(seat, input_device); | ||
899 | if (!seat_device) { | ||
900 | return; | ||
901 | } | ||
902 | |||
903 | seat_apply_input_mapping(seat, seat_device); | ||
884 | } | 904 | } |
885 | 905 | ||
886 | void seat_reset_device(struct sway_seat *seat, | 906 | void 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 | ||
1048 | bool seat_is_input_allowed(struct sway_seat *seat, | 1069 | bool 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 | ||
1054 | static void send_unfocus(struct sway_container *con, void *data) { | 1077 | static 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 | ||
1110 | void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { | 1133 | static void seat_set_workspace_focus(struct sway_seat *seat, struct sway_node *node) { |
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 | ||
1266 | void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { | ||
1267 | // Prevents the layer from losing focus if it has keyboard exclusivity | ||
1268 | if (seat->has_exclusive_layer) { | ||
1269 | struct wlr_layer_surface_v1 *layer = seat->focused_layer; | ||
1270 | seat_set_focus_layer(seat, NULL); | ||
1271 | seat_set_workspace_focus(seat, node); | ||
1272 | seat_set_focus_layer(seat, layer); | ||
1273 | } else if (seat->focused_layer) { | ||
1274 | seat_set_focus_layer(seat, NULL); | ||
1275 | seat_set_workspace_focus(seat, node); | ||
1276 | } else { | ||
1277 | seat_set_workspace_focus(seat, node); | ||
1278 | } | ||
1279 | if (server.session_lock.lock) { | ||
1280 | seat_set_focus_surface(seat, server.session_lock.lock->focused, false); | ||
1281 | } | ||
1282 | } | ||
1283 | |||
1251 | void seat_set_focus_container(struct sway_seat *seat, | 1284 | void 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 | ||
1279 | void seat_set_focus_layer(struct sway_seat *seat, | 1312 | void 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 | |||
1300 | void 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 | |||
1339 | void 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 | ||
1341 | struct sway_node *seat_get_focus_inactive(struct sway_seat *seat, | 1368 | struct 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 | ||
1505 | void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, | 1531 | void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, |
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 | ||
1541 | void seatop_button(struct sway_seat *seat, uint32_t time_msec, | 1567 | void 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 | ||
1555 | void seatop_pointer_axis(struct sway_seat *seat, | 1581 | void 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 | ||
1588 | void seatop_touch_motion(struct sway_seat *seat, struct wlr_touch_motion_event *event, | ||
1589 | double lx, double ly) { | ||
1590 | if (seat->seatop_impl->touch_motion) { | ||
1591 | seat->seatop_impl->touch_motion(seat, event, lx, ly); | ||
1592 | } | ||
1593 | } | ||
1594 | |||
1595 | void seatop_touch_up(struct sway_seat *seat, struct wlr_touch_up_event *event) { | ||
1596 | if (seat->seatop_impl->touch_up) { | ||
1597 | seat->seatop_impl->touch_up(seat, event); | ||
1598 | } | ||
1599 | } | ||
1600 | |||
1601 | void seatop_touch_down(struct sway_seat *seat, struct wlr_touch_down_event *event, | ||
1602 | double lx, double ly) { | ||
1603 | if (seat->seatop_impl->touch_down) { | ||
1604 | seat->seatop_impl->touch_down(seat, event, lx, ly); | ||
1605 | } | ||
1606 | } | ||
1607 | |||
1608 | void seatop_touch_cancel(struct sway_seat *seat, struct wlr_touch_cancel_event *event) { | ||
1609 | if (seat->seatop_impl->touch_cancel) { | ||
1610 | seat->seatop_impl->touch_cancel(seat, event); | ||
1611 | } | ||
1612 | } | ||
1613 | |||
1562 | void seatop_tablet_tool_tip(struct sway_seat *seat, | 1614 | void 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 | ||
1631 | void seatop_hold_begin(struct sway_seat *seat, | ||
1632 | struct wlr_pointer_hold_begin_event *event) { | ||
1633 | if (seat->seatop_impl->hold_begin) { | ||
1634 | seat->seatop_impl->hold_begin(seat, event); | ||
1635 | } | ||
1636 | } | ||
1637 | |||
1638 | void seatop_hold_end(struct sway_seat *seat, | ||
1639 | struct wlr_pointer_hold_end_event *event) { | ||
1640 | if (seat->seatop_impl->hold_end) { | ||
1641 | seat->seatop_impl->hold_end(seat, event); | ||
1642 | } | ||
1643 | } | ||
1644 | |||
1645 | void seatop_pinch_begin(struct sway_seat *seat, | ||
1646 | struct wlr_pointer_pinch_begin_event *event) { | ||
1647 | if (seat->seatop_impl->pinch_begin) { | ||
1648 | seat->seatop_impl->pinch_begin(seat, event); | ||
1649 | } | ||
1650 | } | ||
1651 | |||
1652 | void seatop_pinch_update(struct sway_seat *seat, | ||
1653 | struct wlr_pointer_pinch_update_event *event) { | ||
1654 | if (seat->seatop_impl->pinch_update) { | ||
1655 | seat->seatop_impl->pinch_update(seat, event); | ||
1656 | } | ||
1657 | } | ||
1658 | |||
1659 | void seatop_pinch_end(struct sway_seat *seat, | ||
1660 | struct wlr_pointer_pinch_end_event *event) { | ||
1661 | if (seat->seatop_impl->pinch_end) { | ||
1662 | seat->seatop_impl->pinch_end(seat, event); | ||
1663 | } | ||
1664 | } | ||
1665 | |||
1666 | void seatop_swipe_begin(struct sway_seat *seat, | ||
1667 | struct wlr_pointer_swipe_begin_event *event) { | ||
1668 | if (seat->seatop_impl->swipe_begin) { | ||
1669 | seat->seatop_impl->swipe_begin(seat, event); | ||
1670 | } | ||
1671 | } | ||
1672 | |||
1673 | void seatop_swipe_update(struct sway_seat *seat, | ||
1674 | struct wlr_pointer_swipe_update_event *event) { | ||
1675 | if (seat->seatop_impl->swipe_update) { | ||
1676 | seat->seatop_impl->swipe_update(seat, event); | ||
1677 | } | ||
1678 | } | ||
1679 | |||
1680 | void seatop_swipe_end(struct sway_seat *seat, | ||
1681 | struct wlr_pointer_swipe_end_event *event) { | ||
1682 | if (seat->seatop_impl->swipe_end) { | ||
1683 | seat->seatop_impl->swipe_end(seat, event); | ||
1684 | } | ||
1685 | } | ||
1686 | |||
1579 | void seatop_rebase(struct sway_seat *seat, uint32_t time_msec) { | 1687 | void 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 | ||
1594 | void 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 | |||
1601 | bool seatop_allows_set_cursor(struct sway_seat *seat) { | 1702 | bool 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 | } |