aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Stacy Harper <contact@stacyharper.net>2021-08-21 16:04:08 +0200
committerLibravatar Simon Zeni <simon@bl4ckb0ne.ca>2023-02-20 10:35:10 -0500
commit4666d1785bfb6635e6e8604de383c91714bceebc (patch)
treee940606bd8e735c26b4239342afe88116bf9f457
parentlayer-shell: enter output before surface is mapped (diff)
downloadsway-4666d1785bfb6635e6e8604de383c91714bceebc.tar.gz
sway-4666d1785bfb6635e6e8604de383c91714bceebc.tar.zst
sway-4666d1785bfb6635e6e8604de383c91714bceebc.zip
Implement seatop_touch
Atm we got issue with the touch position sent to the clients. While holding contact, leaving the initial container will continue to send motion event to the client but with the new local position from the new container. This seatop goal is to send the position of the touch event, relatively to the initial container layout position.
-rw-r--r--include/sway/input/cursor.h4
-rw-r--r--include/sway/input/seat.h23
-rw-r--r--sway/input/cursor.c45
-rw-r--r--sway/input/seat.c20
-rw-r--r--sway/input/seatop_default.c37
-rw-r--r--sway/input/seatop_down.c106
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);
108int cursor_get_timeout(struct sway_cursor *cursor); 108int cursor_get_timeout(struct sway_cursor *cursor);
109void cursor_notify_key_press(struct sway_cursor *cursor); 109void cursor_notify_key_press(struct sway_cursor *cursor);
110 110
111void 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
111void dispatch_cursor_button(struct sway_cursor *cursor, 115void 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,
256void seatop_begin_default(struct sway_seat *seat); 263void seatop_begin_default(struct sway_seat *seat);
257 264
258void seatop_begin_down(struct sway_seat *seat, struct sway_container *con, 265void 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
261void seatop_begin_down_on_surface(struct sway_seat *seat, 268void 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
271void 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
264void seatop_begin_move_floating(struct sway_seat *seat, 274void 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,
319void seatop_swipe_end(struct sway_seat *seat, 329void 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
332void seatop_touch_motion(struct sway_seat *seat,
333 struct wlr_touch_motion_event *event, double lx, double ly);
334
335void seatop_touch_up(struct sway_seat *seat,
336 struct wlr_touch_up_event *event);
337
338void seatop_touch_down(struct sway_seat *seat,
339 struct wlr_touch_down_event *event, double lx, double ly);
340
322void seatop_rebase(struct sway_seat *seat, uint32_t time_msec); 341void 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
367static void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, 367void 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
521static void handle_touch_up(struct wl_listener *listener, void *data) { 494static 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
1621void 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
1628void 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
1634void 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
1621void seatop_tablet_tool_tip(struct sway_seat *seat, 1641void 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
652static 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
12struct 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
11struct seatop_down_event { 19struct 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
29static 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
54static 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
74static 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
20static void handle_pointer_axis(struct sway_seat *seat, 107static 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
107void seatop_begin_down(struct sway_seat *seat, struct sway_container *con, 197void 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
207void 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
117void seatop_begin_down_on_surface(struct sway_seat *seat, 214void 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;