diff options
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r-- | sway/input/seat.c | 508 |
1 files changed, 320 insertions, 188 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c index 1f5865ee..75fea484 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -4,22 +4,25 @@ | |||
4 | #include <string.h> | 4 | #include <string.h> |
5 | #include <strings.h> | 5 | #include <strings.h> |
6 | #include <time.h> | 6 | #include <time.h> |
7 | #include <wlr/config.h> | ||
7 | #include <wlr/types/wlr_cursor.h> | 8 | #include <wlr/types/wlr_cursor.h> |
8 | #include <wlr/types/wlr_data_device.h> | 9 | #include <wlr/types/wlr_data_device.h> |
9 | #include <wlr/types/wlr_idle.h> | 10 | #include <wlr/types/wlr_idle_notify_v1.h> |
10 | #include <wlr/types/wlr_keyboard_group.h> | 11 | #include <wlr/types/wlr_keyboard_group.h> |
11 | #include <wlr/types/wlr_output_layout.h> | 12 | #include <wlr/types/wlr_output_layout.h> |
12 | #include <wlr/types/wlr_primary_selection.h> | 13 | #include <wlr/types/wlr_primary_selection.h> |
13 | #include <wlr/types/wlr_tablet_v2.h> | 14 | #include <wlr/types/wlr_tablet_v2.h> |
15 | #include <wlr/types/wlr_touch.h> | ||
14 | #include <wlr/types/wlr_xcursor_manager.h> | 16 | #include <wlr/types/wlr_xcursor_manager.h> |
15 | #include "config.h" | 17 | #include "config.h" |
16 | #include "list.h" | 18 | #include "list.h" |
17 | #include "log.h" | 19 | #include "log.h" |
18 | #include "sway/config.h" | 20 | #include "sway/config.h" |
19 | #include "sway/desktop.h" | 21 | #include "sway/scene_descriptor.h" |
20 | #include "sway/input/cursor.h" | 22 | #include "sway/input/cursor.h" |
21 | #include "sway/input/input-manager.h" | 23 | #include "sway/input/input-manager.h" |
22 | #include "sway/input/keyboard.h" | 24 | #include "sway/input/keyboard.h" |
25 | #include "sway/input/libinput.h" | ||
23 | #include "sway/input/seat.h" | 26 | #include "sway/input/seat.h" |
24 | #include "sway/input/switch.h" | 27 | #include "sway/input/switch.h" |
25 | #include "sway/input/tablet.h" | 28 | #include "sway/input/tablet.h" |
@@ -41,6 +44,7 @@ static void seat_device_destroy(struct sway_seat_device *seat_device) { | |||
41 | sway_keyboard_destroy(seat_device->keyboard); | 44 | sway_keyboard_destroy(seat_device->keyboard); |
42 | sway_tablet_destroy(seat_device->tablet); | 45 | sway_tablet_destroy(seat_device->tablet); |
43 | sway_tablet_pad_destroy(seat_device->tablet_pad); | 46 | sway_tablet_pad_destroy(seat_device->tablet_pad); |
47 | sway_switch_destroy(seat_device->switch_device); | ||
44 | wlr_cursor_detach_input_device(seat_device->sway_seat->cursor->cursor, | 48 | wlr_cursor_detach_input_device(seat_device->sway_seat->cursor->cursor, |
45 | seat_device->input_device->wlr_device); | 49 | seat_device->input_device->wlr_device); |
46 | wl_list_remove(&seat_device->link); | 50 | wl_list_remove(&seat_device->link); |
@@ -50,6 +54,16 @@ static void seat_device_destroy(struct sway_seat_device *seat_device) { | |||
50 | static void seat_node_destroy(struct sway_seat_node *seat_node) { | 54 | static void seat_node_destroy(struct sway_seat_node *seat_node) { |
51 | wl_list_remove(&seat_node->destroy.link); | 55 | wl_list_remove(&seat_node->destroy.link); |
52 | wl_list_remove(&seat_node->link); | 56 | wl_list_remove(&seat_node->link); |
57 | |||
58 | /* | ||
59 | * This is the only time we remove items from the focus stack without | ||
60 | * immediately re-adding them. If we just removed the last thing, | ||
61 | * mark that nothing has focus anymore. | ||
62 | */ | ||
63 | if (wl_list_empty(&seat_node->seat->focus_stack)) { | ||
64 | seat_node->seat->has_focus = false; | ||
65 | } | ||
66 | |||
53 | free(seat_node); | 67 | free(seat_node); |
54 | } | 68 | } |
55 | 69 | ||
@@ -78,6 +92,7 @@ void seat_destroy(struct sway_seat *seat) { | |||
78 | for (int i = 0; i < seat->deferred_bindings->length; i++) { | 92 | for (int i = 0; i < seat->deferred_bindings->length; i++) { |
79 | free_sway_binding(seat->deferred_bindings->items[i]); | 93 | free_sway_binding(seat->deferred_bindings->items[i]); |
80 | } | 94 | } |
95 | wlr_scene_node_destroy(&seat->scene_tree->node); | ||
81 | list_free(seat->deferred_bindings); | 96 | list_free(seat->deferred_bindings); |
82 | free(seat->prev_workspace_name); | 97 | free(seat->prev_workspace_name); |
83 | free(seat); | 98 | free(seat); |
@@ -85,21 +100,10 @@ void seat_destroy(struct sway_seat *seat) { | |||
85 | 100 | ||
86 | void seat_idle_notify_activity(struct sway_seat *seat, | 101 | void seat_idle_notify_activity(struct sway_seat *seat, |
87 | enum sway_input_idle_source source) { | 102 | enum sway_input_idle_source source) { |
88 | uint32_t mask = seat->idle_inhibit_sources; | 103 | if ((source & seat->idle_inhibit_sources) == 0) { |
89 | struct wlr_idle_timeout *timeout; | 104 | 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 | } | 105 | } |
106 | wlr_idle_notifier_v1_notify_activity(server.idle_notifier_v1, seat->wlr_seat); | ||
103 | } | 107 | } |
104 | 108 | ||
105 | /** | 109 | /** |
@@ -129,7 +133,7 @@ static struct sway_keyboard *sway_keyboard_for_wlr_keyboard( | |||
129 | if (input_device->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { | 133 | if (input_device->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { |
130 | continue; | 134 | continue; |
131 | } | 135 | } |
132 | if (input_device->wlr_device->keyboard == wlr_keyboard) { | 136 | if (input_device->wlr_device == &wlr_keyboard->base) { |
133 | return seat_device->keyboard; | 137 | return seat_device->keyboard; |
134 | } | 138 | } |
135 | } | 139 | } |
@@ -137,7 +141,7 @@ static struct sway_keyboard *sway_keyboard_for_wlr_keyboard( | |||
137 | wl_list_for_each(group, &seat->keyboard_groups, link) { | 141 | wl_list_for_each(group, &seat->keyboard_groups, link) { |
138 | struct sway_input_device *input_device = | 142 | struct sway_input_device *input_device = |
139 | group->seat_device->input_device; | 143 | group->seat_device->input_device; |
140 | if (input_device->wlr_device->keyboard == wlr_keyboard) { | 144 | if (input_device->wlr_device == &wlr_keyboard->base) { |
141 | return group->seat_device->keyboard; | 145 | return group->seat_device->keyboard; |
142 | } | 146 | } |
143 | } | 147 | } |
@@ -161,11 +165,11 @@ static void seat_keyboard_notify_enter(struct sway_seat *seat, | |||
161 | state->pressed_keycodes, state->npressed, &keyboard->modifiers); | 165 | state->pressed_keycodes, state->npressed, &keyboard->modifiers); |
162 | } | 166 | } |
163 | 167 | ||
164 | static void seat_tablet_pads_notify_enter(struct sway_seat *seat, | 168 | static void seat_tablet_pads_set_focus(struct sway_seat *seat, |
165 | struct wlr_surface *surface) { | 169 | struct wlr_surface *surface) { |
166 | struct sway_seat_device *seat_device; | 170 | struct sway_seat_device *seat_device; |
167 | wl_list_for_each(seat_device, &seat->devices, link) { | 171 | wl_list_for_each(seat_device, &seat->devices, link) { |
168 | sway_tablet_pad_notify_enter(seat_device->tablet_pad, surface); | 172 | sway_tablet_pad_set_focus(seat_device->tablet_pad, surface); |
169 | } | 173 | } |
170 | } | 174 | } |
171 | 175 | ||
@@ -189,7 +193,7 @@ static void seat_send_focus(struct sway_node *node, struct sway_seat *seat) { | |||
189 | #endif | 193 | #endif |
190 | 194 | ||
191 | seat_keyboard_notify_enter(seat, view->surface); | 195 | seat_keyboard_notify_enter(seat, view->surface); |
192 | seat_tablet_pads_notify_enter(seat, view->surface); | 196 | seat_tablet_pads_set_focus(seat, view->surface); |
193 | sway_input_method_relay_set_focus(&seat->im_relay, view->surface); | 197 | sway_input_method_relay_set_focus(&seat->im_relay, view->surface); |
194 | 198 | ||
195 | struct wlr_pointer_constraint_v1 *constraint = | 199 | struct wlr_pointer_constraint_v1 *constraint = |
@@ -209,14 +213,13 @@ void seat_for_each_node(struct sway_seat *seat, | |||
209 | 213 | ||
210 | struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat, | 214 | struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat, |
211 | struct sway_node *ancestor) { | 215 | struct sway_node *ancestor) { |
212 | if (ancestor->type == N_CONTAINER && ancestor->sway_container->view) { | 216 | if (node_is_view(ancestor)) { |
213 | return ancestor->sway_container; | 217 | return ancestor->sway_container; |
214 | } | 218 | } |
215 | struct sway_seat_node *current; | 219 | struct sway_seat_node *current; |
216 | wl_list_for_each(current, &seat->focus_stack, link) { | 220 | wl_list_for_each(current, &seat->focus_stack, link) { |
217 | struct sway_node *node = current->node; | 221 | struct sway_node *node = current->node; |
218 | if (node->type == N_CONTAINER && node->sway_container->view && | 222 | if (node_is_view(node) && node_has_ancestor(node, ancestor)) { |
219 | node_has_ancestor(node, ancestor)) { | ||
220 | return node->sway_container; | 223 | return node->sway_container; |
221 | } | 224 | } |
222 | } | 225 | } |
@@ -235,7 +238,7 @@ static void handle_seat_node_destroy(struct wl_listener *listener, void *data) { | |||
235 | seat_node_destroy(seat_node); | 238 | seat_node_destroy(seat_node); |
236 | // If an unmanaged or layer surface is focused when an output gets | 239 | // 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 | 240 | // 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 | 241 | // seat, the seat needs to refocus its focus inactive to update the |
239 | // value of seat->workspace. | 242 | // value of seat->workspace. |
240 | if (seat->workspace == node->sway_workspace) { | 243 | if (seat->workspace == node->sway_workspace) { |
241 | struct sway_node *node = seat_get_focus_inactive(seat, &root->node); | 244 | struct sway_node *node = seat_get_focus_inactive(seat, &root->node); |
@@ -309,8 +312,8 @@ static void handle_seat_node_destroy(struct wl_listener *listener, void *data) { | |||
309 | // Setting focus_inactive | 312 | // Setting focus_inactive |
310 | focus = seat_get_focus_inactive(seat, &root->node); | 313 | focus = seat_get_focus_inactive(seat, &root->node); |
311 | seat_set_raw_focus(seat, next_focus); | 314 | seat_set_raw_focus(seat, next_focus); |
312 | if (focus->type == N_CONTAINER && focus->sway_container->workspace) { | 315 | if (focus->type == N_CONTAINER && focus->sway_container->pending.workspace) { |
313 | seat_set_raw_focus(seat, &focus->sway_container->workspace->node); | 316 | seat_set_raw_focus(seat, &focus->sway_container->pending.workspace->node); |
314 | } | 317 | } |
315 | seat_set_raw_focus(seat, focus); | 318 | seat_set_raw_focus(seat, focus); |
316 | } | 319 | } |
@@ -351,25 +354,15 @@ static void handle_new_node(struct wl_listener *listener, void *data) { | |||
351 | seat_node_from_node(seat, node); | 354 | seat_node_from_node(seat, node); |
352 | } | 355 | } |
353 | 356 | ||
354 | static void drag_icon_damage_whole(struct sway_drag_icon *icon) { | 357 | static void drag_icon_update_position(struct sway_seat *seat, struct wlr_scene_node *node) { |
355 | if (!icon->wlr_drag_icon->mapped) { | 358 | struct wlr_drag_icon *wlr_icon = scene_descriptor_try_get(node, SWAY_SCENE_DESC_DRAG_ICON); |
356 | return; | ||
357 | } | ||
358 | desktop_damage_surface(icon->wlr_drag_icon->surface, icon->x, icon->y, true); | ||
359 | } | ||
360 | |||
361 | void drag_icon_update_position(struct sway_drag_icon *icon) { | ||
362 | drag_icon_damage_whole(icon); | ||
363 | |||
364 | struct wlr_drag_icon *wlr_icon = icon->wlr_drag_icon; | ||
365 | struct sway_seat *seat = icon->seat; | ||
366 | struct wlr_cursor *cursor = seat->cursor->cursor; | 359 | struct wlr_cursor *cursor = seat->cursor->cursor; |
360 | |||
367 | switch (wlr_icon->drag->grab_type) { | 361 | switch (wlr_icon->drag->grab_type) { |
368 | case WLR_DRAG_GRAB_KEYBOARD: | 362 | case WLR_DRAG_GRAB_KEYBOARD: |
369 | return; | 363 | return; |
370 | case WLR_DRAG_GRAB_KEYBOARD_POINTER: | 364 | case WLR_DRAG_GRAB_KEYBOARD_POINTER: |
371 | icon->x = cursor->x; | 365 | wlr_scene_node_set_position(node, cursor->x, cursor->y); |
372 | icon->y = cursor->y; | ||
373 | break; | 366 | break; |
374 | case WLR_DRAG_GRAB_KEYBOARD_TOUCH:; | 367 | case WLR_DRAG_GRAB_KEYBOARD_TOUCH:; |
375 | struct wlr_touch_point *point = | 368 | struct wlr_touch_point *point = |
@@ -377,39 +370,15 @@ void drag_icon_update_position(struct sway_drag_icon *icon) { | |||
377 | if (point == NULL) { | 370 | if (point == NULL) { |
378 | return; | 371 | return; |
379 | } | 372 | } |
380 | icon->x = seat->touch_x; | 373 | wlr_scene_node_set_position(node, seat->touch_x, seat->touch_y); |
381 | icon->y = seat->touch_y; | ||
382 | } | 374 | } |
383 | |||
384 | drag_icon_damage_whole(icon); | ||
385 | } | ||
386 | |||
387 | static void drag_icon_handle_surface_commit(struct wl_listener *listener, | ||
388 | void *data) { | ||
389 | struct sway_drag_icon *icon = | ||
390 | wl_container_of(listener, icon, surface_commit); | ||
391 | drag_icon_update_position(icon); | ||
392 | } | ||
393 | |||
394 | static void drag_icon_handle_map(struct wl_listener *listener, void *data) { | ||
395 | struct sway_drag_icon *icon = wl_container_of(listener, icon, map); | ||
396 | drag_icon_damage_whole(icon); | ||
397 | } | ||
398 | |||
399 | static void drag_icon_handle_unmap(struct wl_listener *listener, void *data) { | ||
400 | struct sway_drag_icon *icon = wl_container_of(listener, icon, unmap); | ||
401 | drag_icon_damage_whole(icon); | ||
402 | } | 375 | } |
403 | 376 | ||
404 | static void drag_icon_handle_destroy(struct wl_listener *listener, void *data) { | 377 | void drag_icons_update_position(struct sway_seat *seat) { |
405 | struct sway_drag_icon *icon = wl_container_of(listener, icon, destroy); | 378 | struct wlr_scene_node *node; |
406 | icon->wlr_drag_icon->data = NULL; | 379 | wl_list_for_each(node, &seat->drag_icons->children, link) { |
407 | wl_list_remove(&icon->link); | 380 | drag_icon_update_position(seat, node); |
408 | wl_list_remove(&icon->surface_commit.link); | 381 | } |
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 | } | 382 | } |
414 | 383 | ||
415 | static void drag_handle_destroy(struct wl_listener *listener, void *data) { | 384 | static void drag_handle_destroy(struct wl_listener *listener, void *data) { |
@@ -481,27 +450,20 @@ static void handle_start_drag(struct wl_listener *listener, void *data) { | |||
481 | 450 | ||
482 | struct wlr_drag_icon *wlr_drag_icon = wlr_drag->icon; | 451 | struct wlr_drag_icon *wlr_drag_icon = wlr_drag->icon; |
483 | if (wlr_drag_icon != NULL) { | 452 | if (wlr_drag_icon != NULL) { |
484 | struct sway_drag_icon *icon = calloc(1, sizeof(struct sway_drag_icon)); | 453 | struct wlr_scene_tree *tree = wlr_scene_drag_icon_create(seat->drag_icons, wlr_drag_icon); |
485 | if (icon == NULL) { | 454 | if (!tree) { |
486 | sway_log(SWAY_ERROR, "Allocation failed"); | 455 | sway_log(SWAY_ERROR, "Failed to allocate a drag icon scene tree"); |
487 | return; | 456 | return; |
488 | } | 457 | } |
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 | 458 | ||
502 | wl_list_insert(&root->drag_icons, &icon->link); | 459 | if (!scene_descriptor_assign(&tree->node, SWAY_SCENE_DESC_DRAG_ICON, |
460 | wlr_drag_icon)) { | ||
461 | sway_log(SWAY_ERROR, "Failed to allocate a drag icon scene descriptor"); | ||
462 | wlr_scene_node_destroy(&tree->node); | ||
463 | return; | ||
464 | } | ||
503 | 465 | ||
504 | drag_icon_update_position(icon); | 466 | drag_icon_update_position(seat, &tree->node); |
505 | } | 467 | } |
506 | seatop_begin_default(seat); | 468 | seatop_begin_default(seat); |
507 | } | 469 | } |
@@ -548,8 +510,18 @@ struct sway_seat *seat_create(const char *seat_name) { | |||
548 | return NULL; | 510 | return NULL; |
549 | } | 511 | } |
550 | 512 | ||
513 | bool failed = false; | ||
514 | seat->scene_tree = alloc_scene_tree(root->layers.seat, &failed); | ||
515 | seat->drag_icons = alloc_scene_tree(seat->scene_tree, &failed); | ||
516 | if (failed) { | ||
517 | wlr_scene_node_destroy(&seat->scene_tree->node); | ||
518 | free(seat); | ||
519 | return NULL; | ||
520 | } | ||
521 | |||
551 | seat->wlr_seat = wlr_seat_create(server.wl_display, seat_name); | 522 | seat->wlr_seat = wlr_seat_create(server.wl_display, seat_name); |
552 | if (!sway_assert(seat->wlr_seat, "could not allocate seat")) { | 523 | if (!sway_assert(seat->wlr_seat, "could not allocate seat")) { |
524 | wlr_scene_node_destroy(&seat->scene_tree->node); | ||
553 | free(seat); | 525 | free(seat); |
554 | return NULL; | 526 | return NULL; |
555 | } | 527 | } |
@@ -557,6 +529,7 @@ struct sway_seat *seat_create(const char *seat_name) { | |||
557 | 529 | ||
558 | seat->cursor = sway_cursor_create(seat); | 530 | seat->cursor = sway_cursor_create(seat); |
559 | if (!seat->cursor) { | 531 | if (!seat->cursor) { |
532 | wlr_scene_node_destroy(&seat->scene_tree->node); | ||
560 | wlr_seat_destroy(seat->wlr_seat); | 533 | wlr_seat_destroy(seat->wlr_seat); |
561 | free(seat); | 534 | free(seat); |
562 | return NULL; | 535 | return NULL; |
@@ -653,7 +626,7 @@ static void seat_update_capabilities(struct sway_seat *seat) { | |||
653 | } else { | 626 | } else { |
654 | wlr_seat_set_capabilities(seat->wlr_seat, caps); | 627 | wlr_seat_set_capabilities(seat->wlr_seat, caps); |
655 | if ((previous_caps & WL_SEAT_CAPABILITY_POINTER) == 0) { | 628 | if ((previous_caps & WL_SEAT_CAPABILITY_POINTER) == 0) { |
656 | cursor_set_image(seat->cursor, "left_ptr", NULL); | 629 | cursor_set_image(seat->cursor, "default", NULL); |
657 | } | 630 | } |
658 | } | 631 | } |
659 | } | 632 | } |
@@ -666,12 +639,55 @@ static void seat_reset_input_config(struct sway_seat *seat, | |||
666 | sway_device->input_device->wlr_device, NULL); | 639 | sway_device->input_device->wlr_device, NULL); |
667 | } | 640 | } |
668 | 641 | ||
669 | static void seat_apply_input_config(struct sway_seat *seat, | 642 | static bool has_prefix(const char *str, const char *prefix) { |
643 | return strncmp(str, prefix, strlen(prefix)) == 0; | ||
644 | } | ||
645 | |||
646 | /** | ||
647 | * Get the name of the built-in output, if any. Returns NULL if there isn't | ||
648 | * exactly one built-in output. | ||
649 | */ | ||
650 | static const char *get_builtin_output_name(void) { | ||
651 | const char *match = NULL; | ||
652 | for (int i = 0; i < root->outputs->length; ++i) { | ||
653 | struct sway_output *output = root->outputs->items[i]; | ||
654 | const char *name = output->wlr_output->name; | ||
655 | if (has_prefix(name, "eDP-") || has_prefix(name, "LVDS-") || | ||
656 | has_prefix(name, "DSI-")) { | ||
657 | if (match != NULL) { | ||
658 | return NULL; | ||
659 | } | ||
660 | match = name; | ||
661 | } | ||
662 | } | ||
663 | return match; | ||
664 | } | ||
665 | |||
666 | static bool is_touch_or_tablet_tool(struct sway_seat_device *seat_device) { | ||
667 | switch (seat_device->input_device->wlr_device->type) { | ||
668 | case WLR_INPUT_DEVICE_TOUCH: | ||
669 | case WLR_INPUT_DEVICE_TABLET_TOOL: | ||
670 | return true; | ||
671 | default: | ||
672 | return false; | ||
673 | } | ||
674 | } | ||
675 | |||
676 | static void seat_apply_input_mapping(struct sway_seat *seat, | ||
670 | struct sway_seat_device *sway_device) { | 677 | struct sway_seat_device *sway_device) { |
671 | struct input_config *ic = | 678 | struct input_config *ic = |
672 | input_device_get_config(sway_device->input_device); | 679 | input_device_get_config(sway_device->input_device); |
673 | 680 | ||
674 | sway_log(SWAY_DEBUG, "Applying input config to %s", | 681 | switch (sway_device->input_device->wlr_device->type) { |
682 | case WLR_INPUT_DEVICE_POINTER: | ||
683 | case WLR_INPUT_DEVICE_TOUCH: | ||
684 | case WLR_INPUT_DEVICE_TABLET_TOOL: | ||
685 | break; | ||
686 | default: | ||
687 | return; // these devices don't support mappings | ||
688 | } | ||
689 | |||
690 | sway_log(SWAY_DEBUG, "Applying input mapping to %s", | ||
675 | sway_device->input_device->identifier); | 691 | sway_device->input_device->identifier); |
676 | 692 | ||
677 | const char *mapped_to_output = ic == NULL ? NULL : ic->mapped_to_output; | 693 | const char *mapped_to_output = ic == NULL ? NULL : ic->mapped_to_output; |
@@ -680,8 +696,38 @@ static void seat_apply_input_config(struct sway_seat *seat, | |||
680 | ic == NULL ? MAPPED_TO_DEFAULT : ic->mapped_to; | 696 | ic == NULL ? MAPPED_TO_DEFAULT : ic->mapped_to; |
681 | 697 | ||
682 | switch (mapped_to) { | 698 | switch (mapped_to) { |
683 | case MAPPED_TO_DEFAULT: | 699 | case MAPPED_TO_DEFAULT:; |
684 | mapped_to_output = sway_device->input_device->wlr_device->output_name; | 700 | /* |
701 | * If the wlroots backend provides an output name, use that. | ||
702 | * | ||
703 | * Otherwise, try to map built-in touch and pointer devices to the | ||
704 | * built-in output. | ||
705 | */ | ||
706 | struct wlr_input_device *dev = sway_device->input_device->wlr_device; | ||
707 | switch (dev->type) { | ||
708 | case WLR_INPUT_DEVICE_POINTER: | ||
709 | mapped_to_output = wlr_pointer_from_input_device(dev)->output_name; | ||
710 | break; | ||
711 | case WLR_INPUT_DEVICE_TOUCH: | ||
712 | mapped_to_output = wlr_touch_from_input_device(dev)->output_name; | ||
713 | break; | ||
714 | default: | ||
715 | mapped_to_output = NULL; | ||
716 | break; | ||
717 | } | ||
718 | #if WLR_HAS_LIBINPUT_BACKEND | ||
719 | if (mapped_to_output == NULL && is_touch_or_tablet_tool(sway_device) && | ||
720 | sway_libinput_device_is_builtin(sway_device->input_device)) { | ||
721 | mapped_to_output = get_builtin_output_name(); | ||
722 | if (mapped_to_output) { | ||
723 | sway_log(SWAY_DEBUG, "Auto-detected output '%s' for device '%s'", | ||
724 | mapped_to_output, sway_device->input_device->identifier); | ||
725 | } | ||
726 | } | ||
727 | #else | ||
728 | (void)is_touch_or_tablet_tool; | ||
729 | (void)get_builtin_output_name; | ||
730 | #endif | ||
685 | if (mapped_to_output == NULL) { | 731 | if (mapped_to_output == NULL) { |
686 | return; | 732 | return; |
687 | } | 733 | } |
@@ -725,12 +771,9 @@ static void seat_apply_input_config(struct sway_seat *seat, | |||
725 | 771 | ||
726 | static void seat_configure_pointer(struct sway_seat *seat, | 772 | static void seat_configure_pointer(struct sway_seat *seat, |
727 | struct sway_seat_device *sway_device) { | 773 | struct sway_seat_device *sway_device) { |
728 | if ((seat->wlr_seat->capabilities & WL_SEAT_CAPABILITY_POINTER) == 0) { | 774 | seat_configure_xcursor(seat); |
729 | seat_configure_xcursor(seat); | ||
730 | } | ||
731 | wlr_cursor_attach_input_device(seat->cursor->cursor, | 775 | wlr_cursor_attach_input_device(seat->cursor->cursor, |
732 | sway_device->input_device->wlr_device); | 776 | sway_device->input_device->wlr_device); |
733 | seat_apply_input_config(seat, sway_device); | ||
734 | wl_event_source_timer_update( | 777 | wl_event_source_timer_update( |
735 | seat->cursor->hide_source, cursor_get_timeout(seat->cursor)); | 778 | seat->cursor->hide_source, cursor_get_timeout(seat->cursor)); |
736 | } | 779 | } |
@@ -741,13 +784,22 @@ static void seat_configure_keyboard(struct sway_seat *seat, | |||
741 | sway_keyboard_create(seat, seat_device); | 784 | sway_keyboard_create(seat, seat_device); |
742 | } | 785 | } |
743 | sway_keyboard_configure(seat_device->keyboard); | 786 | sway_keyboard_configure(seat_device->keyboard); |
744 | wlr_seat_set_keyboard(seat->wlr_seat, | 787 | |
745 | seat_device->input_device->wlr_device); | 788 | // We only need to update the current keyboard, as the rest will be updated |
746 | struct sway_node *focus = seat_get_focus(seat); | 789 | // as they are activated. |
747 | if (focus && node_is_view(focus)) { | 790 | struct wlr_keyboard *wlr_keyboard = |
748 | // force notify reenter to pick up the new configuration | 791 | wlr_keyboard_from_input_device(seat_device->input_device->wlr_device); |
792 | struct wlr_keyboard *current_keyboard = seat->wlr_seat->keyboard_state.keyboard; | ||
793 | if (wlr_keyboard != current_keyboard) { | ||
794 | return; | ||
795 | } | ||
796 | |||
797 | // force notify reenter to pick up the new configuration. This reuses | ||
798 | // the current focused surface to avoid breaking input grabs. | ||
799 | struct wlr_surface *surface = seat->wlr_seat->keyboard_state.focused_surface; | ||
800 | if (surface) { | ||
749 | wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat); | 801 | wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat); |
750 | seat_keyboard_notify_enter(seat, focus->sway_container->view->surface); | 802 | seat_keyboard_notify_enter(seat, surface); |
751 | } | 803 | } |
752 | } | 804 | } |
753 | 805 | ||
@@ -756,7 +808,6 @@ static void seat_configure_switch(struct sway_seat *seat, | |||
756 | if (!seat_device->switch_device) { | 808 | if (!seat_device->switch_device) { |
757 | sway_switch_create(seat, seat_device); | 809 | sway_switch_create(seat, seat_device); |
758 | } | 810 | } |
759 | seat_apply_input_config(seat, seat_device); | ||
760 | sway_switch_configure(seat_device->switch_device); | 811 | sway_switch_configure(seat_device->switch_device); |
761 | } | 812 | } |
762 | 813 | ||
@@ -764,7 +815,6 @@ static void seat_configure_touch(struct sway_seat *seat, | |||
764 | struct sway_seat_device *sway_device) { | 815 | struct sway_seat_device *sway_device) { |
765 | wlr_cursor_attach_input_device(seat->cursor->cursor, | 816 | wlr_cursor_attach_input_device(seat->cursor->cursor, |
766 | sway_device->input_device->wlr_device); | 817 | sway_device->input_device->wlr_device); |
767 | seat_apply_input_config(seat, sway_device); | ||
768 | } | 818 | } |
769 | 819 | ||
770 | static void seat_configure_tablet_tool(struct sway_seat *seat, | 820 | static void seat_configure_tablet_tool(struct sway_seat *seat, |
@@ -775,7 +825,6 @@ static void seat_configure_tablet_tool(struct sway_seat *seat, | |||
775 | sway_configure_tablet(sway_device->tablet); | 825 | sway_configure_tablet(sway_device->tablet); |
776 | wlr_cursor_attach_input_device(seat->cursor->cursor, | 826 | wlr_cursor_attach_input_device(seat->cursor->cursor, |
777 | sway_device->input_device->wlr_device); | 827 | sway_device->input_device->wlr_device); |
778 | seat_apply_input_config(seat, sway_device); | ||
779 | } | 828 | } |
780 | 829 | ||
781 | static void seat_configure_tablet_pad(struct sway_seat *seat, | 830 | static void seat_configure_tablet_pad(struct sway_seat *seat, |
@@ -832,6 +881,18 @@ void seat_configure_device(struct sway_seat *seat, | |||
832 | seat_configure_tablet_pad(seat, seat_device); | 881 | seat_configure_tablet_pad(seat, seat_device); |
833 | break; | 882 | break; |
834 | } | 883 | } |
884 | |||
885 | seat_apply_input_mapping(seat, seat_device); | ||
886 | } | ||
887 | |||
888 | void seat_configure_device_mapping(struct sway_seat *seat, | ||
889 | struct sway_input_device *input_device) { | ||
890 | struct sway_seat_device *seat_device = seat_get_device(seat, input_device); | ||
891 | if (!seat_device) { | ||
892 | return; | ||
893 | } | ||
894 | |||
895 | seat_apply_input_mapping(seat, seat_device); | ||
835 | } | 896 | } |
836 | 897 | ||
837 | void seat_reset_device(struct sway_seat *seat, | 898 | void seat_reset_device(struct sway_seat *seat, |
@@ -948,7 +1009,7 @@ void seat_configure_xcursor(struct sway_seat *seat) { | |||
948 | 1009 | ||
949 | wlr_xcursor_manager_load(server.xwayland.xcursor_manager, 1); | 1010 | wlr_xcursor_manager_load(server.xwayland.xcursor_manager, 1); |
950 | struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor( | 1011 | struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor( |
951 | server.xwayland.xcursor_manager, "left_ptr", 1); | 1012 | server.xwayland.xcursor_manager, "default", 1); |
952 | if (xcursor != NULL) { | 1013 | if (xcursor != NULL) { |
953 | struct wlr_xcursor_image *image = xcursor->images[0]; | 1014 | struct wlr_xcursor_image *image = xcursor->images[0]; |
954 | wlr_xwayland_set_cursor( | 1015 | wlr_xwayland_set_cursor( |
@@ -974,32 +1035,35 @@ void seat_configure_xcursor(struct sway_seat *seat) { | |||
974 | sway_log(SWAY_ERROR, | 1035 | sway_log(SWAY_ERROR, |
975 | "Cannot create XCursor manager for theme '%s'", cursor_theme); | 1036 | "Cannot create XCursor manager for theme '%s'", cursor_theme); |
976 | } | 1037 | } |
977 | } | ||
978 | 1038 | ||
979 | for (int i = 0; i < root->outputs->length; ++i) { | 1039 | |
980 | struct sway_output *sway_output = root->outputs->items[i]; | 1040 | for (int i = 0; i < root->outputs->length; ++i) { |
981 | struct wlr_output *output = sway_output->wlr_output; | 1041 | struct sway_output *sway_output = root->outputs->items[i]; |
982 | bool result = | 1042 | struct wlr_output *output = sway_output->wlr_output; |
983 | wlr_xcursor_manager_load(seat->cursor->xcursor_manager, | 1043 | bool result = |
984 | output->scale); | 1044 | wlr_xcursor_manager_load(seat->cursor->xcursor_manager, |
985 | if (!result) { | 1045 | output->scale); |
986 | sway_log(SWAY_ERROR, | 1046 | if (!result) { |
987 | "Cannot load xcursor theme for output '%s' with scale %f", | 1047 | sway_log(SWAY_ERROR, |
988 | output->name, output->scale); | 1048 | "Cannot load xcursor theme for output '%s' with scale %f", |
1049 | output->name, output->scale); | ||
1050 | } | ||
989 | } | 1051 | } |
990 | } | ||
991 | 1052 | ||
992 | // Reset the cursor so that we apply it to outputs that just appeared | 1053 | // Reset the cursor so that we apply it to outputs that just appeared |
993 | cursor_set_image(seat->cursor, NULL, NULL); | 1054 | cursor_set_image(seat->cursor, NULL, NULL); |
994 | cursor_set_image(seat->cursor, "left_ptr", NULL); | 1055 | cursor_set_image(seat->cursor, "default", NULL); |
995 | wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, | 1056 | wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, |
996 | seat->cursor->cursor->y); | 1057 | seat->cursor->cursor->y); |
1058 | } | ||
997 | } | 1059 | } |
998 | 1060 | ||
999 | bool seat_is_input_allowed(struct sway_seat *seat, | 1061 | bool seat_is_input_allowed(struct sway_seat *seat, |
1000 | struct wlr_surface *surface) { | 1062 | struct wlr_surface *surface) { |
1001 | struct wl_client *client = wl_resource_get_client(surface->resource); | 1063 | if (server.session_lock.lock) { |
1002 | return !seat->exclusive_client || seat->exclusive_client == client; | 1064 | return sway_session_lock_has_surface(server.session_lock.lock, surface); |
1065 | } | ||
1066 | return true; | ||
1003 | } | 1067 | } |
1004 | 1068 | ||
1005 | static void send_unfocus(struct sway_container *con, void *data) { | 1069 | static void send_unfocus(struct sway_container *con, void *data) { |
@@ -1058,15 +1122,7 @@ void seat_set_raw_focus(struct sway_seat *seat, struct sway_node *node) { | |||
1058 | } | 1122 | } |
1059 | } | 1123 | } |
1060 | 1124 | ||
1061 | void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { | 1125 | static void seat_set_workspace_focus(struct sway_seat *seat, struct sway_node *node) { |
1062 | if (seat->focused_layer) { | ||
1063 | struct wlr_layer_surface_v1 *layer = seat->focused_layer; | ||
1064 | seat_set_focus_layer(seat, NULL); | ||
1065 | seat_set_focus(seat, node); | ||
1066 | seat_set_focus_layer(seat, layer); | ||
1067 | return; | ||
1068 | } | ||
1069 | |||
1070 | struct sway_node *last_focus = seat_get_focus(seat); | 1126 | struct sway_node *last_focus = seat_get_focus(seat); |
1071 | if (last_focus == node) { | 1127 | if (last_focus == node) { |
1072 | return; | 1128 | return; |
@@ -1086,30 +1142,19 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { | |||
1086 | } | 1142 | } |
1087 | 1143 | ||
1088 | struct sway_workspace *new_workspace = node->type == N_WORKSPACE ? | 1144 | struct sway_workspace *new_workspace = node->type == N_WORKSPACE ? |
1089 | node->sway_workspace : node->sway_container->workspace; | 1145 | node->sway_workspace : node->sway_container->pending.workspace; |
1090 | struct sway_container *container = node->type == N_CONTAINER ? | 1146 | struct sway_container *container = node->type == N_CONTAINER ? |
1091 | node->sway_container : NULL; | 1147 | node->sway_container : NULL; |
1092 | 1148 | ||
1093 | // Deny setting focus to a view which is hidden by a fullscreen container | 1149 | // Deny setting focus to a view which is hidden by a fullscreen container or global |
1094 | if (new_workspace && new_workspace->fullscreen && container && | 1150 | if (container && container_obstructing_fullscreen_container(container)) { |
1095 | !container_is_fullscreen_or_child(container)) { | 1151 | return; |
1096 | // Unless it's a transient container | ||
1097 | if (!container_is_transient_for(container, new_workspace->fullscreen)) { | ||
1098 | return; | ||
1099 | } | ||
1100 | } | 1152 | } |
1153 | |||
1101 | // Deny setting focus to a workspace node when using fullscreen global | 1154 | // Deny setting focus to a workspace node when using fullscreen global |
1102 | if (root->fullscreen_global && !container && new_workspace) { | 1155 | if (root->fullscreen_global && !container && new_workspace) { |
1103 | return; | 1156 | return; |
1104 | } | 1157 | } |
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 | 1158 | ||
1114 | struct sway_output *new_output = | 1159 | struct sway_output *new_output = |
1115 | new_workspace ? new_workspace->output : NULL; | 1160 | new_workspace ? new_workspace->output : NULL; |
@@ -1135,10 +1180,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 | 1180 | // Put the container parents on the focus stack, then the workspace, then |
1136 | // the focused container. | 1181 | // the focused container. |
1137 | if (container) { | 1182 | if (container) { |
1138 | struct sway_container *parent = container->parent; | 1183 | struct sway_container *parent = container->pending.parent; |
1139 | while (parent) { | 1184 | while (parent) { |
1140 | seat_set_raw_focus(seat, &parent->node); | 1185 | seat_set_raw_focus(seat, &parent->node); |
1141 | parent = parent->parent; | 1186 | parent = parent->pending.parent; |
1142 | } | 1187 | } |
1143 | } | 1188 | } |
1144 | if (new_workspace) { | 1189 | if (new_workspace) { |
@@ -1210,6 +1255,24 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { | |||
1210 | } | 1255 | } |
1211 | } | 1256 | } |
1212 | 1257 | ||
1258 | void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { | ||
1259 | // Prevents the layer from losing focus if it has keyboard exclusivity | ||
1260 | if (seat->has_exclusive_layer) { | ||
1261 | struct wlr_layer_surface_v1 *layer = seat->focused_layer; | ||
1262 | seat_set_focus_layer(seat, NULL); | ||
1263 | seat_set_workspace_focus(seat, node); | ||
1264 | seat_set_focus_layer(seat, layer); | ||
1265 | } else if (seat->focused_layer) { | ||
1266 | seat_set_focus_layer(seat, NULL); | ||
1267 | seat_set_workspace_focus(seat, node); | ||
1268 | } else { | ||
1269 | seat_set_workspace_focus(seat, node); | ||
1270 | } | ||
1271 | if (server.session_lock.lock) { | ||
1272 | seat_set_focus_surface(seat, server.session_lock.lock->focused, false); | ||
1273 | } | ||
1274 | } | ||
1275 | |||
1213 | void seat_set_focus_container(struct sway_seat *seat, | 1276 | void seat_set_focus_container(struct sway_seat *seat, |
1214 | struct sway_container *con) { | 1277 | struct sway_container *con) { |
1215 | seat_set_focus(seat, con ? &con->node : NULL); | 1278 | seat_set_focus(seat, con ? &con->node : NULL); |
@@ -1234,7 +1297,8 @@ void seat_set_focus_surface(struct sway_seat *seat, | |||
1234 | wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat); | 1297 | wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat); |
1235 | } | 1298 | } |
1236 | 1299 | ||
1237 | seat_tablet_pads_notify_enter(seat, surface); | 1300 | sway_input_method_relay_set_focus(&seat->im_relay, surface); |
1301 | seat_tablet_pads_set_focus(seat, surface); | ||
1238 | } | 1302 | } |
1239 | 1303 | ||
1240 | void seat_set_focus_layer(struct sway_seat *seat, | 1304 | void seat_set_focus_layer(struct sway_seat *seat, |
@@ -1248,28 +1312,23 @@ void seat_set_focus_layer(struct sway_seat *seat, | |||
1248 | seat_set_focus(seat, previous); | 1312 | seat_set_focus(seat, previous); |
1249 | } | 1313 | } |
1250 | return; | 1314 | return; |
1251 | } else if (!layer || seat->focused_layer == layer) { | 1315 | } else if (!layer) { |
1252 | return; | 1316 | return; |
1253 | } | 1317 | } |
1254 | assert(layer->mapped); | 1318 | assert(layer->surface->mapped); |
1255 | seat_set_focus_surface(seat, layer->surface, true); | 1319 | if (layer->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP && |
1256 | if (layer->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) { | 1320 | layer->current.keyboard_interactive |
1257 | seat->focused_layer = layer; | 1321 | == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) { |
1322 | seat->has_exclusive_layer = true; | ||
1258 | } | 1323 | } |
1259 | } | 1324 | if (seat->focused_layer == layer) { |
1260 | |||
1261 | void seat_set_exclusive_client(struct sway_seat *seat, | ||
1262 | struct wl_client *client) { | ||
1263 | if (!client) { | ||
1264 | seat->exclusive_client = client; | ||
1265 | // Triggers a refocus of the topmost surface layer if necessary | ||
1266 | // TODO: Make layer surface focus per-output based on cursor position | ||
1267 | for (int i = 0; i < root->outputs->length; ++i) { | ||
1268 | struct sway_output *output = root->outputs->items[i]; | ||
1269 | arrange_layers(output); | ||
1270 | } | ||
1271 | return; | 1325 | return; |
1272 | } | 1326 | } |
1327 | seat_set_focus_surface(seat, layer->surface, true); | ||
1328 | seat->focused_layer = layer; | ||
1329 | } | ||
1330 | |||
1331 | void seat_unfocus_unless_client(struct sway_seat *seat, struct wl_client *client) { | ||
1273 | if (seat->focused_layer) { | 1332 | if (seat->focused_layer) { |
1274 | if (wl_resource_get_client(seat->focused_layer->resource) != client) { | 1333 | if (wl_resource_get_client(seat->focused_layer->resource) != client) { |
1275 | seat_set_focus_layer(seat, NULL); | 1334 | seat_set_focus_layer(seat, NULL); |
@@ -1296,7 +1355,6 @@ void seat_set_exclusive_client(struct sway_seat *seat, | |||
1296 | now.tv_nsec / 1000, point->touch_id); | 1355 | now.tv_nsec / 1000, point->touch_id); |
1297 | } | 1356 | } |
1298 | } | 1357 | } |
1299 | seat->exclusive_client = client; | ||
1300 | } | 1358 | } |
1301 | 1359 | ||
1302 | struct sway_node *seat_get_focus_inactive(struct sway_seat *seat, | 1360 | struct sway_node *seat_get_focus_inactive(struct sway_seat *seat, |
@@ -1326,7 +1384,7 @@ struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat, | |||
1326 | struct sway_node *node = current->node; | 1384 | struct sway_node *node = current->node; |
1327 | if (node->type == N_CONTAINER && | 1385 | if (node->type == N_CONTAINER && |
1328 | !container_is_floating_or_child(node->sway_container) && | 1386 | !container_is_floating_or_child(node->sway_container) && |
1329 | node->sway_container->workspace == workspace) { | 1387 | node->sway_container->pending.workspace == workspace) { |
1330 | return node->sway_container; | 1388 | return node->sway_container; |
1331 | } | 1389 | } |
1332 | } | 1390 | } |
@@ -1343,7 +1401,7 @@ struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat, | |||
1343 | struct sway_node *node = current->node; | 1401 | struct sway_node *node = current->node; |
1344 | if (node->type == N_CONTAINER && | 1402 | if (node->type == N_CONTAINER && |
1345 | container_is_floating_or_child(node->sway_container) && | 1403 | container_is_floating_or_child(node->sway_container) && |
1346 | node->sway_container->workspace == workspace) { | 1404 | node->sway_container->pending.workspace == workspace) { |
1347 | return node->sway_container; | 1405 | return node->sway_container; |
1348 | } | 1406 | } |
1349 | } | 1407 | } |
@@ -1377,9 +1435,8 @@ struct sway_node *seat_get_focus(struct sway_seat *seat) { | |||
1377 | if (!seat->has_focus) { | 1435 | if (!seat->has_focus) { |
1378 | return NULL; | 1436 | return NULL; |
1379 | } | 1437 | } |
1380 | if (wl_list_empty(&seat->focus_stack)) { | 1438 | sway_assert(!wl_list_empty(&seat->focus_stack), |
1381 | return NULL; | 1439 | "focus_stack is empty, but has_focus is true"); |
1382 | } | ||
1383 | struct sway_seat_node *current = | 1440 | struct sway_seat_node *current = |
1384 | wl_container_of(seat->focus_stack.next, current, link); | 1441 | wl_container_of(seat->focus_stack.next, current, link); |
1385 | return current->node; | 1442 | return current->node; |
@@ -1391,7 +1448,7 @@ struct sway_workspace *seat_get_focused_workspace(struct sway_seat *seat) { | |||
1391 | return NULL; | 1448 | return NULL; |
1392 | } | 1449 | } |
1393 | if (focus->type == N_CONTAINER) { | 1450 | if (focus->type == N_CONTAINER) { |
1394 | return focus->sway_container->workspace; | 1451 | return focus->sway_container->pending.workspace; |
1395 | } | 1452 | } |
1396 | if (focus->type == N_WORKSPACE) { | 1453 | if (focus->type == N_WORKSPACE) { |
1397 | return focus->sway_workspace; | 1454 | return focus->sway_workspace; |
@@ -1404,8 +1461,8 @@ struct sway_workspace *seat_get_last_known_workspace(struct sway_seat *seat) { | |||
1404 | wl_list_for_each(current, &seat->focus_stack, link) { | 1461 | wl_list_for_each(current, &seat->focus_stack, link) { |
1405 | struct sway_node *node = current->node; | 1462 | struct sway_node *node = current->node; |
1406 | if (node->type == N_CONTAINER && | 1463 | if (node->type == N_CONTAINER && |
1407 | node->sway_container->workspace) { | 1464 | node->sway_container->pending.workspace) { |
1408 | return node->sway_container->workspace; | 1465 | return node->sway_container->pending.workspace; |
1409 | } else if (node->type == N_WORKSPACE) { | 1466 | } else if (node->type == N_WORKSPACE) { |
1410 | return node->sway_workspace; | 1467 | return node->sway_workspace; |
1411 | } | 1468 | } |
@@ -1514,12 +1571,38 @@ void seatop_pointer_motion(struct sway_seat *seat, uint32_t time_msec) { | |||
1514 | } | 1571 | } |
1515 | 1572 | ||
1516 | void seatop_pointer_axis(struct sway_seat *seat, | 1573 | void seatop_pointer_axis(struct sway_seat *seat, |
1517 | struct wlr_event_pointer_axis *event) { | 1574 | struct wlr_pointer_axis_event *event) { |
1518 | if (seat->seatop_impl->pointer_axis) { | 1575 | if (seat->seatop_impl->pointer_axis) { |
1519 | seat->seatop_impl->pointer_axis(seat, event); | 1576 | seat->seatop_impl->pointer_axis(seat, event); |
1520 | } | 1577 | } |
1521 | } | 1578 | } |
1522 | 1579 | ||
1580 | void seatop_touch_motion(struct sway_seat *seat, struct wlr_touch_motion_event *event, | ||
1581 | double lx, double ly) { | ||
1582 | if (seat->seatop_impl->touch_motion) { | ||
1583 | seat->seatop_impl->touch_motion(seat, event, lx, ly); | ||
1584 | } | ||
1585 | } | ||
1586 | |||
1587 | void seatop_touch_up(struct sway_seat *seat, struct wlr_touch_up_event *event) { | ||
1588 | if (seat->seatop_impl->touch_up) { | ||
1589 | seat->seatop_impl->touch_up(seat, event); | ||
1590 | } | ||
1591 | } | ||
1592 | |||
1593 | void seatop_touch_down(struct sway_seat *seat, struct wlr_touch_down_event *event, | ||
1594 | double lx, double ly) { | ||
1595 | if (seat->seatop_impl->touch_down) { | ||
1596 | seat->seatop_impl->touch_down(seat, event, lx, ly); | ||
1597 | } | ||
1598 | } | ||
1599 | |||
1600 | void seatop_touch_cancel(struct sway_seat *seat, struct wlr_touch_cancel_event *event) { | ||
1601 | if (seat->seatop_impl->touch_cancel) { | ||
1602 | seat->seatop_impl->touch_cancel(seat, event); | ||
1603 | } | ||
1604 | } | ||
1605 | |||
1523 | void seatop_tablet_tool_tip(struct sway_seat *seat, | 1606 | void seatop_tablet_tool_tip(struct sway_seat *seat, |
1524 | struct sway_tablet_tool *tool, uint32_t time_msec, | 1607 | struct sway_tablet_tool *tool, uint32_t time_msec, |
1525 | enum wlr_tablet_tool_tip_state state) { | 1608 | enum wlr_tablet_tool_tip_state state) { |
@@ -1537,6 +1620,62 @@ void seatop_tablet_tool_motion(struct sway_seat *seat, | |||
1537 | } | 1620 | } |
1538 | } | 1621 | } |
1539 | 1622 | ||
1623 | void seatop_hold_begin(struct sway_seat *seat, | ||
1624 | struct wlr_pointer_hold_begin_event *event) { | ||
1625 | if (seat->seatop_impl->hold_begin) { | ||
1626 | seat->seatop_impl->hold_begin(seat, event); | ||
1627 | } | ||
1628 | } | ||
1629 | |||
1630 | void seatop_hold_end(struct sway_seat *seat, | ||
1631 | struct wlr_pointer_hold_end_event *event) { | ||
1632 | if (seat->seatop_impl->hold_end) { | ||
1633 | seat->seatop_impl->hold_end(seat, event); | ||
1634 | } | ||
1635 | } | ||
1636 | |||
1637 | void seatop_pinch_begin(struct sway_seat *seat, | ||
1638 | struct wlr_pointer_pinch_begin_event *event) { | ||
1639 | if (seat->seatop_impl->pinch_begin) { | ||
1640 | seat->seatop_impl->pinch_begin(seat, event); | ||
1641 | } | ||
1642 | } | ||
1643 | |||
1644 | void seatop_pinch_update(struct sway_seat *seat, | ||
1645 | struct wlr_pointer_pinch_update_event *event) { | ||
1646 | if (seat->seatop_impl->pinch_update) { | ||
1647 | seat->seatop_impl->pinch_update(seat, event); | ||
1648 | } | ||
1649 | } | ||
1650 | |||
1651 | void seatop_pinch_end(struct sway_seat *seat, | ||
1652 | struct wlr_pointer_pinch_end_event *event) { | ||
1653 | if (seat->seatop_impl->pinch_end) { | ||
1654 | seat->seatop_impl->pinch_end(seat, event); | ||
1655 | } | ||
1656 | } | ||
1657 | |||
1658 | void seatop_swipe_begin(struct sway_seat *seat, | ||
1659 | struct wlr_pointer_swipe_begin_event *event) { | ||
1660 | if (seat->seatop_impl->swipe_begin) { | ||
1661 | seat->seatop_impl->swipe_begin(seat, event); | ||
1662 | } | ||
1663 | } | ||
1664 | |||
1665 | void seatop_swipe_update(struct sway_seat *seat, | ||
1666 | struct wlr_pointer_swipe_update_event *event) { | ||
1667 | if (seat->seatop_impl->swipe_update) { | ||
1668 | seat->seatop_impl->swipe_update(seat, event); | ||
1669 | } | ||
1670 | } | ||
1671 | |||
1672 | void seatop_swipe_end(struct sway_seat *seat, | ||
1673 | struct wlr_pointer_swipe_end_event *event) { | ||
1674 | if (seat->seatop_impl->swipe_end) { | ||
1675 | seat->seatop_impl->swipe_end(seat, event); | ||
1676 | } | ||
1677 | } | ||
1678 | |||
1540 | void seatop_rebase(struct sway_seat *seat, uint32_t time_msec) { | 1679 | void seatop_rebase(struct sway_seat *seat, uint32_t time_msec) { |
1541 | if (seat->seatop_impl->rebase) { | 1680 | if (seat->seatop_impl->rebase) { |
1542 | seat->seatop_impl->rebase(seat, time_msec); | 1681 | seat->seatop_impl->rebase(seat, time_msec); |
@@ -1552,13 +1691,6 @@ void seatop_end(struct sway_seat *seat) { | |||
1552 | seat->seatop_impl = NULL; | 1691 | seat->seatop_impl = NULL; |
1553 | } | 1692 | } |
1554 | 1693 | ||
1555 | void seatop_render(struct sway_seat *seat, struct sway_output *output, | ||
1556 | pixman_region32_t *damage) { | ||
1557 | if (seat->seatop_impl->render) { | ||
1558 | seat->seatop_impl->render(seat, output, damage); | ||
1559 | } | ||
1560 | } | ||
1561 | |||
1562 | bool seatop_allows_set_cursor(struct sway_seat *seat) { | 1694 | bool seatop_allows_set_cursor(struct sway_seat *seat) { |
1563 | return seat->seatop_impl->allow_set_cursor; | 1695 | return seat->seatop_impl->allow_set_cursor; |
1564 | } | 1696 | } |