diff options
-rw-r--r-- | include/sway/input/cursor.h | 4 | ||||
-rw-r--r-- | include/sway/input/seat.h | 23 | ||||
-rw-r--r-- | sway/input/cursor.c | 45 | ||||
-rw-r--r-- | sway/input/seat.c | 20 | ||||
-rw-r--r-- | sway/input/seatop_default.c | 37 | ||||
-rw-r--r-- | sway/input/seatop_down.c | 106 |
6 files changed, 187 insertions, 48 deletions
diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h index 828ac370..4a3774d9 100644 --- a/include/sway/input/cursor.h +++ b/include/sway/input/cursor.h | |||
@@ -108,6 +108,10 @@ void cursor_unhide(struct sway_cursor *cursor); | |||
108 | int cursor_get_timeout(struct sway_cursor *cursor); | 108 | int cursor_get_timeout(struct sway_cursor *cursor); |
109 | void cursor_notify_key_press(struct sway_cursor *cursor); | 109 | void cursor_notify_key_press(struct sway_cursor *cursor); |
110 | 110 | ||
111 | void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, | ||
112 | struct wlr_input_device *device, double dx, double dy, | ||
113 | double dx_unaccel, double dy_unaccel); | ||
114 | |||
111 | void dispatch_cursor_button(struct sway_cursor *cursor, | 115 | void dispatch_cursor_button(struct sway_cursor *cursor, |
112 | struct wlr_input_device *device, uint32_t time_msec, uint32_t button, | 116 | struct wlr_input_device *device, uint32_t time_msec, uint32_t button, |
113 | enum wlr_button_state state); | 117 | enum wlr_button_state state); |
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index 4abe91f7..227da78b 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h> | 4 | #include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h> |
5 | #include <wlr/types/wlr_layer_shell_v1.h> | 5 | #include <wlr/types/wlr_layer_shell_v1.h> |
6 | #include <wlr/types/wlr_seat.h> | 6 | #include <wlr/types/wlr_seat.h> |
7 | #include <wlr/types/wlr_touch.h> | ||
7 | #include <wlr/util/edges.h> | 8 | #include <wlr/util/edges.h> |
8 | #include "sway/config.h" | 9 | #include "sway/config.h" |
9 | #include "sway/input/input-manager.h" | 10 | #include "sway/input/input-manager.h" |
@@ -36,6 +37,12 @@ struct sway_seatop_impl { | |||
36 | void (*swipe_end)(struct sway_seat *seat, | 37 | void (*swipe_end)(struct sway_seat *seat, |
37 | struct wlr_pointer_swipe_end_event *event); | 38 | struct wlr_pointer_swipe_end_event *event); |
38 | void (*rebase)(struct sway_seat *seat, uint32_t time_msec); | 39 | void (*rebase)(struct sway_seat *seat, uint32_t time_msec); |
40 | void (*touch_motion)(struct sway_seat *seat, | ||
41 | struct wlr_touch_motion_event *event, double lx, double ly); | ||
42 | void (*touch_up)(struct sway_seat *seat, | ||
43 | struct wlr_touch_up_event *event); | ||
44 | void (*touch_down)(struct sway_seat *seat, | ||
45 | struct wlr_touch_down_event *event, double lx, double ly); | ||
39 | void (*tablet_tool_motion)(struct sway_seat *seat, | 46 | void (*tablet_tool_motion)(struct sway_seat *seat, |
40 | struct sway_tablet_tool *tool, uint32_t time_msec); | 47 | struct sway_tablet_tool *tool, uint32_t time_msec); |
41 | void (*tablet_tool_tip)(struct sway_seat *seat, struct sway_tablet_tool *tool, | 48 | void (*tablet_tool_tip)(struct sway_seat *seat, struct sway_tablet_tool *tool, |
@@ -256,10 +263,13 @@ enum wlr_edges find_resize_edge(struct sway_container *cont, | |||
256 | void seatop_begin_default(struct sway_seat *seat); | 263 | void seatop_begin_default(struct sway_seat *seat); |
257 | 264 | ||
258 | void seatop_begin_down(struct sway_seat *seat, struct sway_container *con, | 265 | void seatop_begin_down(struct sway_seat *seat, struct sway_container *con, |
259 | uint32_t time_msec, double sx, double sy); | 266 | double sx, double sy); |
260 | 267 | ||
261 | void seatop_begin_down_on_surface(struct sway_seat *seat, | 268 | void seatop_begin_down_on_surface(struct sway_seat *seat, |
262 | struct wlr_surface *surface, uint32_t time_msec, double sx, double sy); | 269 | struct wlr_surface *surface, double sx, double sy); |
270 | |||
271 | void seatop_begin_touch_down(struct sway_seat *seat, struct wlr_surface *surface, | ||
272 | struct wlr_touch_down_event *event, double sx, double sy, double lx, double ly); | ||
263 | 273 | ||
264 | void seatop_begin_move_floating(struct sway_seat *seat, | 274 | void seatop_begin_move_floating(struct sway_seat *seat, |
265 | struct sway_container *con); | 275 | struct sway_container *con); |
@@ -319,6 +329,15 @@ void seatop_swipe_update(struct sway_seat *seat, | |||
319 | void seatop_swipe_end(struct sway_seat *seat, | 329 | void seatop_swipe_end(struct sway_seat *seat, |
320 | struct wlr_pointer_swipe_end_event *event); | 330 | struct wlr_pointer_swipe_end_event *event); |
321 | 331 | ||
332 | void seatop_touch_motion(struct sway_seat *seat, | ||
333 | struct wlr_touch_motion_event *event, double lx, double ly); | ||
334 | |||
335 | void seatop_touch_up(struct sway_seat *seat, | ||
336 | struct wlr_touch_up_event *event); | ||
337 | |||
338 | void seatop_touch_down(struct sway_seat *seat, | ||
339 | struct wlr_touch_down_event *event, double lx, double ly); | ||
340 | |||
322 | void seatop_rebase(struct sway_seat *seat, uint32_t time_msec); | 341 | void seatop_rebase(struct sway_seat *seat, uint32_t time_msec); |
323 | 342 | ||
324 | /** | 343 | /** |
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index ad69e7c3..15687993 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -364,7 +364,7 @@ void cursor_unhide(struct sway_cursor *cursor) { | |||
364 | wl_event_source_timer_update(cursor->hide_source, cursor_get_timeout(cursor)); | 364 | wl_event_source_timer_update(cursor->hide_source, cursor_get_timeout(cursor)); |
365 | } | 365 | } |
366 | 366 | ||
367 | static void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, | 367 | void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, |
368 | struct wlr_input_device *device, double dx, double dy, | 368 | struct wlr_input_device *device, double dx, double dy, |
369 | double dx_unaccel, double dy_unaccel) { | 369 | double dx_unaccel, double dy_unaccel) { |
370 | wlr_relative_pointer_manager_v1_send_relative_motion( | 370 | wlr_relative_pointer_manager_v1_send_relative_motion( |
@@ -479,43 +479,16 @@ static void handle_touch_down(struct wl_listener *listener, void *data) { | |||
479 | cursor_hide(cursor); | 479 | cursor_hide(cursor); |
480 | 480 | ||
481 | struct sway_seat *seat = cursor->seat; | 481 | struct sway_seat *seat = cursor->seat; |
482 | struct wlr_seat *wlr_seat = seat->wlr_seat; | ||
483 | struct wlr_surface *surface = NULL; | ||
484 | 482 | ||
485 | double lx, ly; | 483 | double lx, ly; |
486 | wlr_cursor_absolute_to_layout_coords(cursor->cursor, &event->touch->base, | 484 | wlr_cursor_absolute_to_layout_coords(cursor->cursor, &event->touch->base, |
487 | event->x, event->y, &lx, &ly); | 485 | event->x, event->y, &lx, &ly); |
488 | double sx, sy; | ||
489 | struct sway_node *focused_node = node_at_coords(seat, lx, ly, &surface, &sx, &sy); | ||
490 | 486 | ||
491 | seat->touch_id = event->touch_id; | 487 | seat->touch_id = event->touch_id; |
492 | seat->touch_x = lx; | 488 | seat->touch_x = lx; |
493 | seat->touch_y = ly; | 489 | seat->touch_y = ly; |
494 | 490 | ||
495 | if (surface && wlr_surface_accepts_touch(wlr_seat, surface)) { | 491 | seatop_touch_down(seat, event, lx, ly); |
496 | if (seat_is_input_allowed(seat, surface)) { | ||
497 | wlr_seat_touch_notify_down(wlr_seat, surface, event->time_msec, | ||
498 | event->touch_id, sx, sy); | ||
499 | |||
500 | if (focused_node) { | ||
501 | seat_set_focus(seat, focused_node); | ||
502 | } | ||
503 | } | ||
504 | } else if (!cursor->simulating_pointer_from_touch && | ||
505 | (!surface || seat_is_input_allowed(seat, surface))) { | ||
506 | // Fallback to cursor simulation. | ||
507 | // The pointer_touch_id state is needed, so drags are not aborted when over | ||
508 | // a surface supporting touch and multi touch events don't interfere. | ||
509 | cursor->simulating_pointer_from_touch = true; | ||
510 | cursor->pointer_touch_id = seat->touch_id; | ||
511 | double dx, dy; | ||
512 | dx = lx - cursor->cursor->x; | ||
513 | dy = ly - cursor->cursor->y; | ||
514 | pointer_motion(cursor, event->time_msec, &event->touch->base, dx, dy, | ||
515 | dx, dy); | ||
516 | dispatch_cursor_button(cursor, &event->touch->base, event->time_msec, | ||
517 | BTN_LEFT, WLR_BUTTON_PRESSED); | ||
518 | } | ||
519 | } | 492 | } |
520 | 493 | ||
521 | static void handle_touch_up(struct wl_listener *listener, void *data) { | 494 | static void handle_touch_up(struct wl_listener *listener, void *data) { |
@@ -523,7 +496,7 @@ static void handle_touch_up(struct wl_listener *listener, void *data) { | |||
523 | struct wlr_touch_up_event *event = data; | 496 | struct wlr_touch_up_event *event = data; |
524 | cursor_handle_activity_from_device(cursor, &event->touch->base); | 497 | cursor_handle_activity_from_device(cursor, &event->touch->base); |
525 | 498 | ||
526 | struct wlr_seat *wlr_seat = cursor->seat->wlr_seat; | 499 | struct sway_seat *seat = cursor->seat; |
527 | 500 | ||
528 | if (cursor->simulating_pointer_from_touch) { | 501 | if (cursor->simulating_pointer_from_touch) { |
529 | if (cursor->pointer_touch_id == cursor->seat->touch_id) { | 502 | if (cursor->pointer_touch_id == cursor->seat->touch_id) { |
@@ -532,7 +505,7 @@ static void handle_touch_up(struct wl_listener *listener, void *data) { | |||
532 | event->time_msec, BTN_LEFT, WLR_BUTTON_RELEASED); | 505 | event->time_msec, BTN_LEFT, WLR_BUTTON_RELEASED); |
533 | } | 506 | } |
534 | } else { | 507 | } else { |
535 | wlr_seat_touch_notify_up(wlr_seat, event->time_msec, event->touch_id); | 508 | seatop_touch_up(seat, event); |
536 | } | 509 | } |
537 | } | 510 | } |
538 | 511 | ||
@@ -543,19 +516,14 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) { | |||
543 | cursor_handle_activity_from_device(cursor, &event->touch->base); | 516 | cursor_handle_activity_from_device(cursor, &event->touch->base); |
544 | 517 | ||
545 | struct sway_seat *seat = cursor->seat; | 518 | struct sway_seat *seat = cursor->seat; |
546 | struct wlr_seat *wlr_seat = seat->wlr_seat; | ||
547 | struct wlr_surface *surface = NULL; | ||
548 | 519 | ||
549 | double lx, ly; | 520 | double lx, ly; |
550 | wlr_cursor_absolute_to_layout_coords(cursor->cursor, &event->touch->base, | 521 | wlr_cursor_absolute_to_layout_coords(cursor->cursor, &event->touch->base, |
551 | event->x, event->y, &lx, &ly); | 522 | event->x, event->y, &lx, &ly); |
552 | double sx, sy; | ||
553 | node_at_coords(cursor->seat, lx, ly, &surface, &sx, &sy); | ||
554 | 523 | ||
555 | if (seat->touch_id == event->touch_id) { | 524 | if (seat->touch_id == event->touch_id) { |
556 | seat->touch_x = lx; | 525 | seat->touch_x = lx; |
557 | seat->touch_y = ly; | 526 | seat->touch_y = ly; |
558 | |||
559 | struct sway_drag_icon *drag_icon; | 527 | struct sway_drag_icon *drag_icon; |
560 | wl_list_for_each(drag_icon, &root->drag_icons, link) { | 528 | wl_list_for_each(drag_icon, &root->drag_icons, link) { |
561 | if (drag_icon->seat == seat) { | 529 | if (drag_icon->seat == seat) { |
@@ -572,9 +540,8 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) { | |||
572 | pointer_motion(cursor, event->time_msec, &event->touch->base, | 540 | pointer_motion(cursor, event->time_msec, &event->touch->base, |
573 | dx, dy, dx, dy); | 541 | dx, dy, dx, dy); |
574 | } | 542 | } |
575 | } else if (surface) { | 543 | } else { |
576 | wlr_seat_touch_notify_motion(wlr_seat, event->time_msec, | 544 | seatop_touch_motion(seat, event, lx, ly); |
577 | event->touch_id, sx, sy); | ||
578 | } | 545 | } |
579 | } | 546 | } |
580 | 547 | ||
diff --git a/sway/input/seat.c b/sway/input/seat.c index 090a4d3c..bff425dd 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -1618,6 +1618,26 @@ void seatop_pointer_axis(struct sway_seat *seat, | |||
1618 | } | 1618 | } |
1619 | } | 1619 | } |
1620 | 1620 | ||
1621 | void seatop_touch_motion(struct sway_seat *seat, struct wlr_touch_motion_event *event, | ||
1622 | double lx, double ly) { | ||
1623 | if (seat->seatop_impl->touch_motion) { | ||
1624 | seat->seatop_impl->touch_motion(seat, event, lx, ly); | ||
1625 | } | ||
1626 | } | ||
1627 | |||
1628 | void seatop_touch_up(struct sway_seat *seat, struct wlr_touch_up_event *event) { | ||
1629 | if (seat->seatop_impl->touch_up) { | ||
1630 | seat->seatop_impl->touch_up(seat, event); | ||
1631 | } | ||
1632 | } | ||
1633 | |||
1634 | void seatop_touch_down(struct sway_seat *seat, struct wlr_touch_down_event *event, | ||
1635 | double lx, double ly) { | ||
1636 | if (seat->seatop_impl->touch_down) { | ||
1637 | seat->seatop_impl->touch_down(seat, event, lx, ly); | ||
1638 | } | ||
1639 | } | ||
1640 | |||
1621 | void seatop_tablet_tool_tip(struct sway_seat *seat, | 1641 | void seatop_tablet_tool_tip(struct sway_seat *seat, |
1622 | struct sway_tablet_tool *tool, uint32_t time_msec, | 1642 | struct sway_tablet_tool *tool, uint32_t time_msec, |
1623 | enum wlr_tablet_tool_tip_state state) { | 1643 | enum wlr_tablet_tool_tip_state state) { |
diff --git a/sway/input/seatop_default.c b/sway/input/seatop_default.c index 0dcb87ab..5a55c186 100644 --- a/sway/input/seatop_default.c +++ b/sway/input/seatop_default.c | |||
@@ -261,7 +261,7 @@ static void handle_tablet_tool_tip(struct sway_seat *seat, | |||
261 | 261 | ||
262 | // Handle tapping on a container surface | 262 | // Handle tapping on a container surface |
263 | seat_set_focus_container(seat, cont); | 263 | seat_set_focus_container(seat, cont); |
264 | seatop_begin_down(seat, node->sway_container, time_msec, sx, sy); | 264 | seatop_begin_down(seat, node->sway_container, sx, sy); |
265 | } | 265 | } |
266 | #if HAVE_XWAYLAND | 266 | #if HAVE_XWAYLAND |
267 | // Handle tapping on an xwayland unmanaged view | 267 | // Handle tapping on an xwayland unmanaged view |
@@ -374,7 +374,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, | |||
374 | transaction_commit_dirty(); | 374 | transaction_commit_dirty(); |
375 | } | 375 | } |
376 | if (state == WLR_BUTTON_PRESSED) { | 376 | if (state == WLR_BUTTON_PRESSED) { |
377 | seatop_begin_down_on_surface(seat, surface, time_msec, sx, sy); | 377 | seatop_begin_down_on_surface(seat, surface, sx, sy); |
378 | } | 378 | } |
379 | seat_pointer_notify_button(seat, time_msec, button, state); | 379 | seat_pointer_notify_button(seat, time_msec, button, state); |
380 | return; | 380 | return; |
@@ -499,7 +499,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, | |||
499 | 499 | ||
500 | // Handle mousedown on a container surface | 500 | // Handle mousedown on a container surface |
501 | if (surface && cont && state == WLR_BUTTON_PRESSED) { | 501 | if (surface && cont && state == WLR_BUTTON_PRESSED) { |
502 | seatop_begin_down(seat, cont, time_msec, sx, sy); | 502 | seatop_begin_down(seat, cont, sx, sy); |
503 | seat_pointer_notify_button(seat, time_msec, button, WLR_BUTTON_PRESSED); | 503 | seat_pointer_notify_button(seat, time_msec, button, WLR_BUTTON_PRESSED); |
504 | return; | 504 | return; |
505 | } | 505 | } |
@@ -649,6 +649,36 @@ static void handle_tablet_tool_motion(struct sway_seat *seat, | |||
649 | e->previous_node = node; | 649 | e->previous_node = node; |
650 | } | 650 | } |
651 | 651 | ||
652 | static void handle_touch_down(struct sway_seat *seat, | ||
653 | struct wlr_touch_down_event *event, double lx, double ly) { | ||
654 | struct wlr_surface *surface = NULL; | ||
655 | struct wlr_seat *wlr_seat = seat->wlr_seat; | ||
656 | struct sway_cursor *cursor = seat->cursor; | ||
657 | double sx, sy; | ||
658 | node_at_coords(seat, seat->touch_x, seat->touch_y, &surface, &sx, &sy); | ||
659 | |||
660 | if (surface && wlr_surface_accepts_touch(wlr_seat, surface)) { | ||
661 | if (seat_is_input_allowed(seat, surface)) { | ||
662 | cursor->simulating_pointer_from_touch = false; | ||
663 | seatop_begin_touch_down(seat, surface, event, sx, sy, lx, ly); | ||
664 | } | ||
665 | } else if (!cursor->simulating_pointer_from_touch && | ||
666 | (!surface || seat_is_input_allowed(seat, surface))) { | ||
667 | // Fallback to cursor simulation. | ||
668 | // The pointer_touch_id state is needed, so drags are not aborted when over | ||
669 | // a surface supporting touch and multi touch events don't interfere. | ||
670 | cursor->simulating_pointer_from_touch = true; | ||
671 | cursor->pointer_touch_id = seat->touch_id; | ||
672 | double dx, dy; | ||
673 | dx = seat->touch_x - cursor->cursor->x; | ||
674 | dy = seat->touch_y - cursor->cursor->y; | ||
675 | pointer_motion(cursor, event->time_msec, &event->touch->base, dx, dy, | ||
676 | dx, dy); | ||
677 | dispatch_cursor_button(cursor, &event->touch->base, event->time_msec, | ||
678 | BTN_LEFT, WLR_BUTTON_PRESSED); | ||
679 | } | ||
680 | } | ||
681 | |||
652 | /*----------------------------------------\ | 682 | /*----------------------------------------\ |
653 | * Functions used by handle_pointer_axis / | 683 | * Functions used by handle_pointer_axis / |
654 | *--------------------------------------*/ | 684 | *--------------------------------------*/ |
@@ -1096,6 +1126,7 @@ static const struct sway_seatop_impl seatop_impl = { | |||
1096 | .swipe_begin = handle_swipe_begin, | 1126 | .swipe_begin = handle_swipe_begin, |
1097 | .swipe_update = handle_swipe_update, | 1127 | .swipe_update = handle_swipe_update, |
1098 | .swipe_end = handle_swipe_end, | 1128 | .swipe_end = handle_swipe_end, |
1129 | .touch_down = handle_touch_down, | ||
1099 | .rebase = handle_rebase, | 1130 | .rebase = handle_rebase, |
1100 | .allow_set_cursor = true, | 1131 | .allow_set_cursor = true, |
1101 | }; | 1132 | }; |
diff --git a/sway/input/seatop_down.c b/sway/input/seatop_down.c index 3f880ccf..6447134e 100644 --- a/sway/input/seatop_down.c +++ b/sway/input/seatop_down.c | |||
@@ -2,12 +2,20 @@ | |||
2 | #include <float.h> | 2 | #include <float.h> |
3 | #include <wlr/types/wlr_cursor.h> | 3 | #include <wlr/types/wlr_cursor.h> |
4 | #include <wlr/types/wlr_tablet_v2.h> | 4 | #include <wlr/types/wlr_tablet_v2.h> |
5 | #include <wlr/types/wlr_touch.h> | ||
5 | #include "sway/input/cursor.h" | 6 | #include "sway/input/cursor.h" |
6 | #include "sway/input/seat.h" | 7 | #include "sway/input/seat.h" |
7 | #include "sway/tree/view.h" | 8 | #include "sway/tree/view.h" |
8 | #include "sway/desktop/transaction.h" | 9 | #include "sway/desktop/transaction.h" |
9 | #include "log.h" | 10 | #include "log.h" |
10 | 11 | ||
12 | struct seatop_touch_point_event { | ||
13 | double ref_lx, ref_ly; // touch's x/y at start of op | ||
14 | double ref_con_lx, ref_con_ly; // container's x/y at start of op | ||
15 | int32_t touch_id; | ||
16 | struct wl_list link; | ||
17 | }; | ||
18 | |||
11 | struct seatop_down_event { | 19 | struct seatop_down_event { |
12 | struct sway_container *con; | 20 | struct sway_container *con; |
13 | struct sway_seat *seat; | 21 | struct sway_seat *seat; |
@@ -15,8 +23,87 @@ struct seatop_down_event { | |||
15 | struct wlr_surface *surface; | 23 | struct wlr_surface *surface; |
16 | double ref_lx, ref_ly; // cursor's x/y at start of op | 24 | double ref_lx, ref_ly; // cursor's x/y at start of op |
17 | double ref_con_lx, ref_con_ly; // container's x/y at start of op | 25 | double ref_con_lx, ref_con_ly; // container's x/y at start of op |
26 | struct wl_list point_events; // seatop_touch_point_event::link | ||
18 | }; | 27 | }; |
19 | 28 | ||
29 | static void handle_touch_motion(struct sway_seat *seat, | ||
30 | struct wlr_touch_motion_event *event, double lx, double ly) { | ||
31 | struct seatop_down_event *e = seat->seatop_data; | ||
32 | |||
33 | struct seatop_touch_point_event *point_event; | ||
34 | bool found = false; | ||
35 | wl_list_for_each(point_event, &e->point_events, link) { | ||
36 | if (point_event->touch_id == event->touch_id) { | ||
37 | found = true; | ||
38 | break; | ||
39 | } | ||
40 | } | ||
41 | if (!found) { | ||
42 | return; // Probably not a point_event from this seatop_down | ||
43 | } | ||
44 | |||
45 | double moved_x = lx - point_event->ref_lx; | ||
46 | double moved_y = ly - point_event->ref_ly; | ||
47 | double sx = point_event->ref_con_lx + moved_x; | ||
48 | double sy = point_event->ref_con_ly + moved_y; | ||
49 | |||
50 | wlr_seat_touch_notify_motion(seat->wlr_seat, event->time_msec, | ||
51 | event->touch_id, sx, sy); | ||
52 | } | ||
53 | |||
54 | static void handle_touch_up(struct sway_seat *seat, | ||
55 | struct wlr_touch_up_event *event) { | ||
56 | struct seatop_down_event *e = seat->seatop_data; | ||
57 | struct seatop_touch_point_event *point_event, *tmp; | ||
58 | |||
59 | wl_list_for_each_safe(point_event, tmp, &e->point_events, link) { | ||
60 | if (point_event->touch_id == event->touch_id) { | ||
61 | wl_list_remove(&point_event->link); | ||
62 | free(point_event); | ||
63 | break; | ||
64 | } | ||
65 | } | ||
66 | |||
67 | if (wl_list_empty(&e->point_events)) { | ||
68 | seatop_begin_default(seat); | ||
69 | } | ||
70 | |||
71 | wlr_seat_touch_notify_up(seat->wlr_seat, event->time_msec, event->touch_id); | ||
72 | } | ||
73 | |||
74 | static void handle_touch_down(struct sway_seat *seat, | ||
75 | struct wlr_touch_down_event *event, double lx, double ly) { | ||
76 | struct seatop_down_event *e = seat->seatop_data; | ||
77 | double sx, sy; | ||
78 | struct wlr_surface *surface = NULL; | ||
79 | struct sway_node *focused_node = node_at_coords(seat, seat->touch_x, | ||
80 | seat->touch_y, &surface, &sx, &sy); | ||
81 | |||
82 | if (!surface || surface != e->surface) { // Must start from the initial surface | ||
83 | return; | ||
84 | } | ||
85 | |||
86 | struct seatop_touch_point_event *point_event = | ||
87 | calloc(1, sizeof(struct seatop_touch_point_event)); | ||
88 | if (!sway_assert(point_event, "Unable to allocate point_event")) { | ||
89 | return; | ||
90 | } | ||
91 | point_event->touch_id = event->touch_id; | ||
92 | point_event->ref_lx = lx; | ||
93 | point_event->ref_ly = ly; | ||
94 | point_event->ref_con_lx = sx; | ||
95 | point_event->ref_con_ly = sy; | ||
96 | |||
97 | wl_list_insert(&e->point_events, &point_event->link); | ||
98 | |||
99 | wlr_seat_touch_notify_down(seat->wlr_seat, surface, event->time_msec, | ||
100 | event->touch_id, sx, sy); | ||
101 | |||
102 | if (focused_node) { | ||
103 | seat_set_focus(seat, focused_node); | ||
104 | } | ||
105 | } | ||
106 | |||
20 | static void handle_pointer_axis(struct sway_seat *seat, | 107 | static void handle_pointer_axis(struct sway_seat *seat, |
21 | struct wlr_pointer_axis_event *event) { | 108 | struct wlr_pointer_axis_event *event) { |
22 | struct sway_input_device *input_device = | 109 | struct sway_input_device *input_device = |
@@ -99,14 +186,17 @@ static const struct sway_seatop_impl seatop_impl = { | |||
99 | .pointer_axis = handle_pointer_axis, | 186 | .pointer_axis = handle_pointer_axis, |
100 | .tablet_tool_tip = handle_tablet_tool_tip, | 187 | .tablet_tool_tip = handle_tablet_tool_tip, |
101 | .tablet_tool_motion = handle_tablet_tool_motion, | 188 | .tablet_tool_motion = handle_tablet_tool_motion, |
189 | .touch_motion = handle_touch_motion, | ||
190 | .touch_up = handle_touch_up, | ||
191 | .touch_down = handle_touch_down, | ||
102 | .unref = handle_unref, | 192 | .unref = handle_unref, |
103 | .end = handle_end, | 193 | .end = handle_end, |
104 | .allow_set_cursor = true, | 194 | .allow_set_cursor = true, |
105 | }; | 195 | }; |
106 | 196 | ||
107 | void seatop_begin_down(struct sway_seat *seat, struct sway_container *con, | 197 | void seatop_begin_down(struct sway_seat *seat, struct sway_container *con, |
108 | uint32_t time_msec, double sx, double sy) { | 198 | double sx, double sy) { |
109 | seatop_begin_down_on_surface(seat, con->view->surface, time_msec, sx, sy); | 199 | seatop_begin_down_on_surface(seat, con->view->surface, sx, sy); |
110 | struct seatop_down_event *e = seat->seatop_data; | 200 | struct seatop_down_event *e = seat->seatop_data; |
111 | e->con = con; | 201 | e->con = con; |
112 | 202 | ||
@@ -114,13 +204,20 @@ void seatop_begin_down(struct sway_seat *seat, struct sway_container *con, | |||
114 | transaction_commit_dirty(); | 204 | transaction_commit_dirty(); |
115 | } | 205 | } |
116 | 206 | ||
207 | void seatop_begin_touch_down(struct sway_seat *seat, | ||
208 | struct wlr_surface *surface, struct wlr_touch_down_event *event, | ||
209 | double sx, double sy, double lx, double ly) { | ||
210 | seatop_begin_down_on_surface(seat, surface, sx, sy); | ||
211 | handle_touch_down(seat, event, lx, ly); | ||
212 | } | ||
213 | |||
117 | void seatop_begin_down_on_surface(struct sway_seat *seat, | 214 | void seatop_begin_down_on_surface(struct sway_seat *seat, |
118 | struct wlr_surface *surface, uint32_t time_msec, double sx, double sy) { | 215 | struct wlr_surface *surface, double sx, double sy) { |
119 | seatop_end(seat); | 216 | seatop_end(seat); |
120 | 217 | ||
121 | struct seatop_down_event *e = | 218 | struct seatop_down_event *e = |
122 | calloc(1, sizeof(struct seatop_down_event)); | 219 | calloc(1, sizeof(struct seatop_down_event)); |
123 | if (!e) { | 220 | if (!sway_assert(e, "Unable to allocate e")) { |
124 | return; | 221 | return; |
125 | } | 222 | } |
126 | e->con = NULL; | 223 | e->con = NULL; |
@@ -132,6 +229,7 @@ void seatop_begin_down_on_surface(struct sway_seat *seat, | |||
132 | e->ref_ly = seat->cursor->cursor->y; | 229 | e->ref_ly = seat->cursor->cursor->y; |
133 | e->ref_con_lx = sx; | 230 | e->ref_con_lx = sx; |
134 | e->ref_con_ly = sy; | 231 | e->ref_con_ly = sy; |
232 | wl_list_init(&e->point_events); | ||
135 | 233 | ||
136 | seat->seatop_impl = &seatop_impl; | 234 | seat->seatop_impl = &seatop_impl; |
137 | seat->seatop_data = e; | 235 | seat->seatop_data = e; |