aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/cursor.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input/cursor.c')
-rw-r--r--sway/input/cursor.c286
1 files changed, 163 insertions, 123 deletions
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index fa604426..2ee63124 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -4,8 +4,8 @@
4#include <libevdev/libevdev.h> 4#include <libevdev/libevdev.h>
5#include <linux/input-event-codes.h> 5#include <linux/input-event-codes.h>
6#include <errno.h> 6#include <errno.h>
7#include <time.h>
7#include <strings.h> 8#include <strings.h>
8#include <wlr/types/wlr_box.h>
9#include <wlr/types/wlr_cursor.h> 9#include <wlr/types/wlr_cursor.h>
10#include <wlr/types/wlr_idle.h> 10#include <wlr/types/wlr_idle.h>
11#include <wlr/types/wlr_pointer.h> 11#include <wlr/types/wlr_pointer.h>
@@ -20,7 +20,6 @@
20#include "util.h" 20#include "util.h"
21#include "sway/commands.h" 21#include "sway/commands.h"
22#include "sway/desktop.h" 22#include "sway/desktop.h"
23#include "sway/desktop/transaction.h"
24#include "sway/input/cursor.h" 23#include "sway/input/cursor.h"
25#include "sway/input/keyboard.h" 24#include "sway/input/keyboard.h"
26#include "sway/input/tablet.h" 25#include "sway/input/tablet.h"
@@ -32,6 +31,12 @@
32#include "sway/tree/workspace.h" 31#include "sway/tree/workspace.h"
33#include "wlr-layer-shell-unstable-v1-protocol.h" 32#include "wlr-layer-shell-unstable-v1-protocol.h"
34 33
34static uint32_t get_current_time_msec(void) {
35 struct timespec now;
36 clock_gettime(CLOCK_MONOTONIC, &now);
37 return now.tv_sec * 1000 + now.tv_nsec / 1000000;
38}
39
35static struct wlr_surface *layer_surface_at(struct sway_output *output, 40static struct wlr_surface *layer_surface_at(struct sway_output *output,
36 struct wl_list *layer, double ox, double oy, double *sx, double *sy) { 41 struct wl_list *layer, double ox, double oy, double *sx, double *sy) {
37 struct sway_layer_surface *sway_layer; 42 struct sway_layer_surface *sway_layer;
@@ -78,7 +83,28 @@ static struct wlr_surface *layer_surface_popup_at(struct sway_output *output,
78struct sway_node *node_at_coords( 83struct sway_node *node_at_coords(
79 struct sway_seat *seat, double lx, double ly, 84 struct sway_seat *seat, double lx, double ly,
80 struct wlr_surface **surface, double *sx, double *sy) { 85 struct wlr_surface **surface, double *sx, double *sy) {
81 // check for unmanaged views first 86 // find the output the cursor is on
87 struct wlr_output *wlr_output = wlr_output_layout_output_at(
88 root->output_layout, lx, ly);
89 if (wlr_output == NULL) {
90 return NULL;
91 }
92 struct sway_output *output = wlr_output->data;
93 if (!output || !output->enabled) {
94 // output is being destroyed or is being enabled
95 return NULL;
96 }
97 double ox = lx, oy = ly;
98 wlr_output_layout_output_coords(root->output_layout, wlr_output, &ox, &oy);
99
100 // layer surfaces on the overlay layer are rendered on top
101 if ((*surface = layer_surface_at(output,
102 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
103 ox, oy, sx, sy))) {
104 return NULL;
105 }
106
107 // check for unmanaged views
82#if HAVE_XWAYLAND 108#if HAVE_XWAYLAND
83 struct wl_list *unmanaged = &root->xwayland_unmanaged; 109 struct wl_list *unmanaged = &root->xwayland_unmanaged;
84 struct sway_xwayland_unmanaged *unmanaged_surface; 110 struct sway_xwayland_unmanaged *unmanaged_surface;
@@ -96,19 +122,6 @@ struct sway_node *node_at_coords(
96 } 122 }
97 } 123 }
98#endif 124#endif
99 // find the output the cursor is on
100 struct wlr_output *wlr_output = wlr_output_layout_output_at(
101 root->output_layout, lx, ly);
102 if (wlr_output == NULL) {
103 return NULL;
104 }
105 struct sway_output *output = wlr_output->data;
106 if (!output || !output->enabled) {
107 // output is being destroyed or is being enabled
108 return NULL;
109 }
110 double ox = lx, oy = ly;
111 wlr_output_layout_output_coords(root->output_layout, wlr_output, &ox, &oy);
112 125
113 if (root->fullscreen_global) { 126 if (root->fullscreen_global) {
114 // Try fullscreen container 127 // Try fullscreen container
@@ -126,11 +139,6 @@ struct sway_node *node_at_coords(
126 return NULL; 139 return NULL;
127 } 140 }
128 141
129 if ((*surface = layer_surface_at(output,
130 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
131 ox, oy, sx, sy))) {
132 return NULL;
133 }
134 if (ws->fullscreen) { 142 if (ws->fullscreen) {
135 // Try transient containers 143 // Try transient containers
136 for (int i = 0; i < ws->floating->length; ++i) { 144 for (int i = 0; i < ws->floating->length; ++i) {
@@ -378,30 +386,29 @@ static void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
378static void handle_pointer_motion_relative( 386static void handle_pointer_motion_relative(
379 struct wl_listener *listener, void *data) { 387 struct wl_listener *listener, void *data) {
380 struct sway_cursor *cursor = wl_container_of(listener, cursor, motion); 388 struct sway_cursor *cursor = wl_container_of(listener, cursor, motion);
381 struct wlr_event_pointer_motion *e = data; 389 struct wlr_pointer_motion_event *e = data;
382 cursor_handle_activity_from_device(cursor, e->device); 390 cursor_handle_activity_from_device(cursor, &e->pointer->base);
383 391
384 pointer_motion(cursor, e->time_msec, e->device, e->delta_x, e->delta_y, 392 pointer_motion(cursor, e->time_msec, &e->pointer->base, e->delta_x,
385 e->unaccel_dx, e->unaccel_dy); 393 e->delta_y, e->unaccel_dx, e->unaccel_dy);
386 transaction_commit_dirty();
387} 394}
388 395
389static void handle_pointer_motion_absolute( 396static void handle_pointer_motion_absolute(
390 struct wl_listener *listener, void *data) { 397 struct wl_listener *listener, void *data) {
391 struct sway_cursor *cursor = 398 struct sway_cursor *cursor =
392 wl_container_of(listener, cursor, motion_absolute); 399 wl_container_of(listener, cursor, motion_absolute);
393 struct wlr_event_pointer_motion_absolute *event = data; 400 struct wlr_pointer_motion_absolute_event *event = data;
394 cursor_handle_activity_from_device(cursor, event->device); 401 cursor_handle_activity_from_device(cursor, &event->pointer->base);
395 402
396 double lx, ly; 403 double lx, ly;
397 wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device, 404 wlr_cursor_absolute_to_layout_coords(cursor->cursor, &event->pointer->base,
398 event->x, event->y, &lx, &ly); 405 event->x, event->y, &lx, &ly);
399 406
400 double dx = lx - cursor->cursor->x; 407 double dx = lx - cursor->cursor->x;
401 double dy = ly - cursor->cursor->y; 408 double dy = ly - cursor->cursor->y;
402 409
403 pointer_motion(cursor, event->time_msec, event->device, dx, dy, dx, dy); 410 pointer_motion(cursor, event->time_msec, &event->pointer->base, dx, dy,
404 transaction_commit_dirty(); 411 dx, dy);
405} 412}
406 413
407void dispatch_cursor_button(struct sway_cursor *cursor, 414void dispatch_cursor_button(struct sway_cursor *cursor,
@@ -416,7 +423,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
416 423
417static void handle_pointer_button(struct wl_listener *listener, void *data) { 424static void handle_pointer_button(struct wl_listener *listener, void *data) {
418 struct sway_cursor *cursor = wl_container_of(listener, cursor, button); 425 struct sway_cursor *cursor = wl_container_of(listener, cursor, button);
419 struct wlr_event_pointer_button *event = data; 426 struct wlr_pointer_button_event *event = data;
420 427
421 if (event->state == WLR_BUTTON_PRESSED) { 428 if (event->state == WLR_BUTTON_PRESSED) {
422 cursor->pressed_button_count++; 429 cursor->pressed_button_count++;
@@ -428,23 +435,21 @@ static void handle_pointer_button(struct wl_listener *listener, void *data) {
428 } 435 }
429 } 436 }
430 437
431 cursor_handle_activity_from_device(cursor, event->device); 438 cursor_handle_activity_from_device(cursor, &event->pointer->base);
432 dispatch_cursor_button(cursor, event->device, 439 dispatch_cursor_button(cursor, &event->pointer->base,
433 event->time_msec, event->button, event->state); 440 event->time_msec, event->button, event->state);
434 transaction_commit_dirty();
435} 441}
436 442
437void dispatch_cursor_axis(struct sway_cursor *cursor, 443void dispatch_cursor_axis(struct sway_cursor *cursor,
438 struct wlr_event_pointer_axis *event) { 444 struct wlr_pointer_axis_event *event) {
439 seatop_pointer_axis(cursor->seat, event); 445 seatop_pointer_axis(cursor->seat, event);
440} 446}
441 447
442static void handle_pointer_axis(struct wl_listener *listener, void *data) { 448static void handle_pointer_axis(struct wl_listener *listener, void *data) {
443 struct sway_cursor *cursor = wl_container_of(listener, cursor, axis); 449 struct sway_cursor *cursor = wl_container_of(listener, cursor, axis);
444 struct wlr_event_pointer_axis *event = data; 450 struct wlr_pointer_axis_event *event = data;
445 cursor_handle_activity_from_device(cursor, event->device); 451 cursor_handle_activity_from_device(cursor, &event->pointer->base);
446 dispatch_cursor_axis(cursor, event); 452 dispatch_cursor_axis(cursor, event);
447 transaction_commit_dirty();
448} 453}
449 454
450static void handle_pointer_frame(struct wl_listener *listener, void *data) { 455static void handle_pointer_frame(struct wl_listener *listener, void *data) {
@@ -454,8 +459,8 @@ static void handle_pointer_frame(struct wl_listener *listener, void *data) {
454 459
455static void handle_touch_down(struct wl_listener *listener, void *data) { 460static void handle_touch_down(struct wl_listener *listener, void *data) {
456 struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_down); 461 struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_down);
457 struct wlr_event_touch_down *event = data; 462 struct wlr_touch_down_event *event = data;
458 cursor_handle_activity_from_device(cursor, event->device); 463 cursor_handle_activity_from_device(cursor, &event->touch->base);
459 cursor_hide(cursor); 464 cursor_hide(cursor);
460 465
461 struct sway_seat *seat = cursor->seat; 466 struct sway_seat *seat = cursor->seat;
@@ -463,7 +468,7 @@ static void handle_touch_down(struct wl_listener *listener, void *data) {
463 struct wlr_surface *surface = NULL; 468 struct wlr_surface *surface = NULL;
464 469
465 double lx, ly; 470 double lx, ly;
466 wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device, 471 wlr_cursor_absolute_to_layout_coords(cursor->cursor, &event->touch->base,
467 event->x, event->y, &lx, &ly); 472 event->x, event->y, &lx, &ly);
468 double sx, sy; 473 double sx, sy;
469 struct sway_node *focused_node = node_at_coords(seat, lx, ly, &surface, &sx, &sy); 474 struct sway_node *focused_node = node_at_coords(seat, lx, ly, &surface, &sx, &sy);
@@ -491,28 +496,25 @@ static void handle_touch_down(struct wl_listener *listener, void *data) {
491 double dx, dy; 496 double dx, dy;
492 dx = lx - cursor->cursor->x; 497 dx = lx - cursor->cursor->x;
493 dy = ly - cursor->cursor->y; 498 dy = ly - cursor->cursor->y;
494 pointer_motion(cursor, event->time_msec, event->device, dx, dy, dx, dy); 499 pointer_motion(cursor, event->time_msec, &event->touch->base, dx, dy,
495 dispatch_cursor_button(cursor, event->device, event->time_msec, 500 dx, dy);
501 dispatch_cursor_button(cursor, &event->touch->base, event->time_msec,
496 BTN_LEFT, WLR_BUTTON_PRESSED); 502 BTN_LEFT, WLR_BUTTON_PRESSED);
497 wlr_seat_pointer_notify_frame(wlr_seat);
498 transaction_commit_dirty();
499 } 503 }
500} 504}
501 505
502static void handle_touch_up(struct wl_listener *listener, void *data) { 506static void handle_touch_up(struct wl_listener *listener, void *data) {
503 struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_up); 507 struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_up);
504 struct wlr_event_touch_up *event = data; 508 struct wlr_touch_up_event *event = data;
505 cursor_handle_activity_from_device(cursor, event->device); 509 cursor_handle_activity_from_device(cursor, &event->touch->base);
506 510
507 struct wlr_seat *wlr_seat = cursor->seat->wlr_seat; 511 struct wlr_seat *wlr_seat = cursor->seat->wlr_seat;
508 512
509 if (cursor->simulating_pointer_from_touch) { 513 if (cursor->simulating_pointer_from_touch) {
510 if (cursor->pointer_touch_id == cursor->seat->touch_id) { 514 if (cursor->pointer_touch_id == cursor->seat->touch_id) {
511 cursor->simulating_pointer_from_touch = false; 515 cursor->pointer_touch_up = true;
512 dispatch_cursor_button(cursor, event->device, event->time_msec, 516 dispatch_cursor_button(cursor, &event->touch->base,
513 BTN_LEFT, WLR_BUTTON_RELEASED); 517 event->time_msec, BTN_LEFT, WLR_BUTTON_RELEASED);
514 wlr_seat_pointer_notify_frame(wlr_seat);
515 transaction_commit_dirty();
516 } 518 }
517 } else { 519 } else {
518 wlr_seat_touch_notify_up(wlr_seat, event->time_msec, event->touch_id); 520 wlr_seat_touch_notify_up(wlr_seat, event->time_msec, event->touch_id);
@@ -522,15 +524,15 @@ static void handle_touch_up(struct wl_listener *listener, void *data) {
522static void handle_touch_motion(struct wl_listener *listener, void *data) { 524static void handle_touch_motion(struct wl_listener *listener, void *data) {
523 struct sway_cursor *cursor = 525 struct sway_cursor *cursor =
524 wl_container_of(listener, cursor, touch_motion); 526 wl_container_of(listener, cursor, touch_motion);
525 struct wlr_event_touch_motion *event = data; 527 struct wlr_touch_motion_event *event = data;
526 cursor_handle_activity_from_device(cursor, event->device); 528 cursor_handle_activity_from_device(cursor, &event->touch->base);
527 529
528 struct sway_seat *seat = cursor->seat; 530 struct sway_seat *seat = cursor->seat;
529 struct wlr_seat *wlr_seat = seat->wlr_seat; 531 struct wlr_seat *wlr_seat = seat->wlr_seat;
530 struct wlr_surface *surface = NULL; 532 struct wlr_surface *surface = NULL;
531 533
532 double lx, ly; 534 double lx, ly;
533 wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device, 535 wlr_cursor_absolute_to_layout_coords(cursor->cursor, &event->touch->base,
534 event->x, event->y, &lx, &ly); 536 event->x, event->y, &lx, &ly);
535 double sx, sy; 537 double sx, sy;
536 node_at_coords(cursor->seat, lx, ly, &surface, &sx, &sy); 538 node_at_coords(cursor->seat, lx, ly, &surface, &sx, &sy);
@@ -552,8 +554,8 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) {
552 double dx, dy; 554 double dx, dy;
553 dx = lx - cursor->cursor->x; 555 dx = lx - cursor->cursor->x;
554 dy = ly - cursor->cursor->y; 556 dy = ly - cursor->cursor->y;
555 pointer_motion(cursor, event->time_msec, event->device, dx, dy, dx, dy); 557 pointer_motion(cursor, event->time_msec, &event->touch->base,
556 transaction_commit_dirty(); 558 dx, dy, dx, dy);
557 } 559 }
558 } else if (surface) { 560 } else if (surface) {
559 wlr_seat_touch_notify_motion(wlr_seat, event->time_msec, 561 wlr_seat_touch_notify_motion(wlr_seat, event->time_msec,
@@ -561,6 +563,24 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) {
561 } 563 }
562} 564}
563 565
566static void handle_touch_frame(struct wl_listener *listener, void *data) {
567 struct sway_cursor *cursor =
568 wl_container_of(listener, cursor, touch_frame);
569
570 struct wlr_seat *wlr_seat = cursor->seat->wlr_seat;
571
572 if (cursor->simulating_pointer_from_touch) {
573 wlr_seat_pointer_notify_frame(wlr_seat);
574
575 if (cursor->pointer_touch_up) {
576 cursor->pointer_touch_up = false;
577 cursor->simulating_pointer_from_touch = false;
578 }
579 } else {
580 wlr_seat_touch_notify_frame(wlr_seat);
581 }
582}
583
564static double apply_mapping_from_coord(double low, double high, double value) { 584static double apply_mapping_from_coord(double low, double high, double value) {
565 if (isnan(value)) { 585 if (isnan(value)) {
566 return value; 586 return value;
@@ -574,14 +594,15 @@ static void apply_mapping_from_region(struct wlr_input_device *device,
574 double x1 = region->x1, x2 = region->x2; 594 double x1 = region->x1, x2 = region->x2;
575 double y1 = region->y1, y2 = region->y2; 595 double y1 = region->y1, y2 = region->y2;
576 596
577 if (region->mm) { 597 if (region->mm && device->type == WLR_INPUT_DEVICE_TABLET_TOOL) {
578 if (device->width_mm == 0 || device->height_mm == 0) { 598 struct wlr_tablet *tablet = wlr_tablet_from_input_device(device);
599 if (tablet->width_mm == 0 || tablet->height_mm == 0) {
579 return; 600 return;
580 } 601 }
581 x1 /= device->width_mm; 602 x1 /= tablet->width_mm;
582 x2 /= device->width_mm; 603 x2 /= tablet->width_mm;
583 y1 /= device->height_mm; 604 y1 /= tablet->height_mm;
584 y2 /= device->height_mm; 605 y2 /= tablet->height_mm;
585 } 606 }
586 607
587 *x = apply_mapping_from_coord(x1, x2, *x); 608 *x = apply_mapping_from_coord(x1, x2, *x);
@@ -639,14 +660,12 @@ static void handle_tablet_tool_position(struct sway_cursor *cursor,
639 wlr_tablet_v2_tablet_tool_notify_proximity_out(tool->tablet_v2_tool); 660 wlr_tablet_v2_tablet_tool_notify_proximity_out(tool->tablet_v2_tool);
640 pointer_motion(cursor, time_msec, input_device->wlr_device, dx, dy, dx, dy); 661 pointer_motion(cursor, time_msec, input_device->wlr_device, dx, dy, dx, dy);
641 } 662 }
642
643 transaction_commit_dirty();
644} 663}
645 664
646static void handle_tool_axis(struct wl_listener *listener, void *data) { 665static void handle_tool_axis(struct wl_listener *listener, void *data) {
647 struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_axis); 666 struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_axis);
648 struct wlr_event_tablet_tool_axis *event = data; 667 struct wlr_tablet_tool_axis_event *event = data;
649 cursor_handle_activity_from_device(cursor, event->device); 668 cursor_handle_activity_from_device(cursor, &event->tablet->base);
650 669
651 struct sway_tablet_tool *sway_tool = event->tool->data; 670 struct sway_tablet_tool *sway_tool = event->tool->data;
652 if (!sway_tool) { 671 if (!sway_tool) {
@@ -701,8 +720,8 @@ static void handle_tool_axis(struct wl_listener *listener, void *data) {
701 720
702static void handle_tool_tip(struct wl_listener *listener, void *data) { 721static void handle_tool_tip(struct wl_listener *listener, void *data) {
703 struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_tip); 722 struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_tip);
704 struct wlr_event_tablet_tool_tip *event = data; 723 struct wlr_tablet_tool_tip_event *event = data;
705 cursor_handle_activity_from_device(cursor, event->device); 724 cursor_handle_activity_from_device(cursor, &event->tablet->base);
706 725
707 struct sway_tablet_tool *sway_tool = event->tool->data; 726 struct sway_tablet_tool *sway_tool = event->tool->data;
708 struct wlr_tablet_v2_tablet *tablet_v2 = sway_tool->tablet->tablet_v2; 727 struct wlr_tablet_v2_tablet *tablet_v2 = sway_tool->tablet->tablet_v2;
@@ -717,10 +736,9 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) {
717 if (cursor->simulating_pointer_from_tool_tip && 736 if (cursor->simulating_pointer_from_tool_tip &&
718 event->state == WLR_TABLET_TOOL_TIP_UP) { 737 event->state == WLR_TABLET_TOOL_TIP_UP) {
719 cursor->simulating_pointer_from_tool_tip = false; 738 cursor->simulating_pointer_from_tool_tip = false;
720 dispatch_cursor_button(cursor, event->device, event->time_msec, 739 dispatch_cursor_button(cursor, &event->tablet->base, event->time_msec,
721 BTN_LEFT, WLR_BUTTON_RELEASED); 740 BTN_LEFT, WLR_BUTTON_RELEASED);
722 wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); 741 wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
723 transaction_commit_dirty();
724 } else if (!surface || !wlr_surface_accepts_tablet_v2(tablet_v2, surface)) { 742 } else if (!surface || !wlr_surface_accepts_tablet_v2(tablet_v2, surface)) {
725 // If we started holding the tool tip down on a surface that accepts 743 // If we started holding the tool tip down on a surface that accepts
726 // tablet v2, we should notify that surface if it gets released over a 744 // tablet v2, we should notify that surface if it gets released over a
@@ -730,10 +748,9 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) {
730 WLR_TABLET_TOOL_TIP_UP); 748 WLR_TABLET_TOOL_TIP_UP);
731 } else { 749 } else {
732 cursor->simulating_pointer_from_tool_tip = true; 750 cursor->simulating_pointer_from_tool_tip = true;
733 dispatch_cursor_button(cursor, event->device, event->time_msec, 751 dispatch_cursor_button(cursor, &event->tablet->base,
734 BTN_LEFT, WLR_BUTTON_PRESSED); 752 event->time_msec, BTN_LEFT, WLR_BUTTON_PRESSED);
735 wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); 753 wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
736 transaction_commit_dirty();
737 } 754 }
738 } else { 755 } else {
739 seatop_tablet_tool_tip(seat, sway_tool, event->time_msec, event->state); 756 seatop_tablet_tool_tip(seat, sway_tool, event->time_msec, event->state);
@@ -754,12 +771,13 @@ static struct sway_tablet *get_tablet_for_device(struct sway_cursor *cursor,
754static void handle_tool_proximity(struct wl_listener *listener, void *data) { 771static void handle_tool_proximity(struct wl_listener *listener, void *data) {
755 struct sway_cursor *cursor = 772 struct sway_cursor *cursor =
756 wl_container_of(listener, cursor, tool_proximity); 773 wl_container_of(listener, cursor, tool_proximity);
757 struct wlr_event_tablet_tool_proximity *event = data; 774 struct wlr_tablet_tool_proximity_event *event = data;
758 cursor_handle_activity_from_device(cursor, event->device); 775 cursor_handle_activity_from_device(cursor, &event->tablet->base);
759 776
760 struct wlr_tablet_tool *tool = event->tool; 777 struct wlr_tablet_tool *tool = event->tool;
761 if (!tool->data) { 778 if (!tool->data) {
762 struct sway_tablet *tablet = get_tablet_for_device(cursor, event->device); 779 struct sway_tablet *tablet = get_tablet_for_device(cursor,
780 &event->tablet->base);
763 if (!tablet) { 781 if (!tablet) {
764 sway_log(SWAY_ERROR, "no tablet for tablet tool"); 782 sway_log(SWAY_ERROR, "no tablet for tablet tool");
765 return; 783 return;
@@ -784,8 +802,8 @@ static void handle_tool_proximity(struct wl_listener *listener, void *data) {
784 802
785static void handle_tool_button(struct wl_listener *listener, void *data) { 803static void handle_tool_button(struct wl_listener *listener, void *data) {
786 struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_button); 804 struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_button);
787 struct wlr_event_tablet_tool_button *event = data; 805 struct wlr_tablet_tool_button_event *event = data;
788 cursor_handle_activity_from_device(cursor, event->device); 806 cursor_handle_activity_from_device(cursor, &event->tablet->base);
789 807
790 struct sway_tablet_tool *sway_tool = event->tool->data; 808 struct sway_tablet_tool *sway_tool = event->tool->data;
791 if (!sway_tool) { 809 if (!sway_tool) {
@@ -806,21 +824,20 @@ static void handle_tool_button(struct wl_listener *listener, void *data) {
806 switch (event->state) { 824 switch (event->state) {
807 case WLR_BUTTON_PRESSED: 825 case WLR_BUTTON_PRESSED:
808 if (cursor->tool_buttons == 0) { 826 if (cursor->tool_buttons == 0) {
809 dispatch_cursor_button(cursor, event->device, 827 dispatch_cursor_button(cursor, &event->tablet->base,
810 event->time_msec, BTN_RIGHT, event->state); 828 event->time_msec, BTN_RIGHT, event->state);
811 } 829 }
812 cursor->tool_buttons++; 830 cursor->tool_buttons++;
813 break; 831 break;
814 case WLR_BUTTON_RELEASED: 832 case WLR_BUTTON_RELEASED:
815 if (cursor->tool_buttons == 1) { 833 if (cursor->tool_buttons == 1) {
816 dispatch_cursor_button(cursor, event->device, 834 dispatch_cursor_button(cursor, &event->tablet->base,
817 event->time_msec, BTN_RIGHT, event->state); 835 event->time_msec, BTN_RIGHT, event->state);
818 } 836 }
819 cursor->tool_buttons--; 837 cursor->tool_buttons--;
820 break; 838 break;
821 } 839 }
822 wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); 840 wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
823 transaction_commit_dirty();
824 return; 841 return;
825 } 842 }
826 843
@@ -837,8 +854,8 @@ static void check_constraint_region(struct sway_cursor *cursor) {
837 854
838 struct sway_container *con = view->container; 855 struct sway_container *con = view->container;
839 856
840 double sx = cursor->cursor->x - con->content_x + view->geometry.x; 857 double sx = cursor->cursor->x - con->pending.content_x + view->geometry.x;
841 double sy = cursor->cursor->y - con->content_y + view->geometry.y; 858 double sy = cursor->cursor->y - con->pending.content_y + view->geometry.y;
842 859
843 if (!pixman_region32_contains_point(region, 860 if (!pixman_region32_contains_point(region,
844 floor(sx), floor(sy), NULL)) { 861 floor(sx), floor(sy), NULL)) {
@@ -849,8 +866,8 @@ static void check_constraint_region(struct sway_cursor *cursor) {
849 double sy = (boxes[0].y1 + boxes[0].y2) / 2.; 866 double sy = (boxes[0].y1 + boxes[0].y2) / 2.;
850 867
851 wlr_cursor_warp_closest(cursor->cursor, NULL, 868 wlr_cursor_warp_closest(cursor->cursor, NULL,
852 sx + con->content_x - view->geometry.x, 869 sx + con->pending.content_x - view->geometry.x,
853 sy + con->content_y - view->geometry.y); 870 sy + con->pending.content_y - view->geometry.y);
854 871
855 cursor_rebase(cursor); 872 cursor_rebase(cursor);
856 } 873 }
@@ -911,59 +928,68 @@ static void handle_request_pointer_set_cursor(struct wl_listener *listener,
911 event->hotspot_y, focused_client); 928 event->hotspot_y, focused_client);
912} 929}
913 930
931static void handle_pointer_hold_begin(struct wl_listener *listener, void *data) {
932 struct sway_cursor *cursor = wl_container_of(
933 listener, cursor, hold_begin);
934 struct wlr_pointer_hold_begin_event *event = data;
935 cursor_handle_activity_from_device(cursor, &event->pointer->base);
936 seatop_hold_begin(cursor->seat, event);
937}
938
939static void handle_pointer_hold_end(struct wl_listener *listener, void *data) {
940 struct sway_cursor *cursor = wl_container_of(
941 listener, cursor, hold_end);
942 struct wlr_pointer_hold_end_event *event = data;
943 cursor_handle_activity_from_device(cursor, &event->pointer->base);
944 seatop_hold_end(cursor->seat, event);
945}
946
914static void handle_pointer_pinch_begin(struct wl_listener *listener, void *data) { 947static void handle_pointer_pinch_begin(struct wl_listener *listener, void *data) {
915 struct sway_cursor *cursor = wl_container_of( 948 struct sway_cursor *cursor = wl_container_of(
916 listener, cursor, pinch_begin); 949 listener, cursor, pinch_begin);
917 struct wlr_event_pointer_pinch_begin *event = data; 950 struct wlr_pointer_pinch_begin_event *event = data;
918 wlr_pointer_gestures_v1_send_pinch_begin( 951 cursor_handle_activity_from_device(cursor, &event->pointer->base);
919 cursor->pointer_gestures, cursor->seat->wlr_seat, 952 seatop_pinch_begin(cursor->seat, event);
920 event->time_msec, event->fingers);
921} 953}
922 954
923static void handle_pointer_pinch_update(struct wl_listener *listener, void *data) { 955static void handle_pointer_pinch_update(struct wl_listener *listener, void *data) {
924 struct sway_cursor *cursor = wl_container_of( 956 struct sway_cursor *cursor = wl_container_of(
925 listener, cursor, pinch_update); 957 listener, cursor, pinch_update);
926 struct wlr_event_pointer_pinch_update *event = data; 958 struct wlr_pointer_pinch_update_event *event = data;
927 wlr_pointer_gestures_v1_send_pinch_update( 959 cursor_handle_activity_from_device(cursor, &event->pointer->base);
928 cursor->pointer_gestures, cursor->seat->wlr_seat, 960 seatop_pinch_update(cursor->seat, event);
929 event->time_msec, event->dx, event->dy,
930 event->scale, event->rotation);
931} 961}
932 962
933static void handle_pointer_pinch_end(struct wl_listener *listener, void *data) { 963static void handle_pointer_pinch_end(struct wl_listener *listener, void *data) {
934 struct sway_cursor *cursor = wl_container_of( 964 struct sway_cursor *cursor = wl_container_of(
935 listener, cursor, pinch_end); 965 listener, cursor, pinch_end);
936 struct wlr_event_pointer_pinch_end *event = data; 966 struct wlr_pointer_pinch_end_event *event = data;
937 wlr_pointer_gestures_v1_send_pinch_end( 967 cursor_handle_activity_from_device(cursor, &event->pointer->base);
938 cursor->pointer_gestures, cursor->seat->wlr_seat, 968 seatop_pinch_end(cursor->seat, event);
939 event->time_msec, event->cancelled);
940} 969}
941 970
942static void handle_pointer_swipe_begin(struct wl_listener *listener, void *data) { 971static void handle_pointer_swipe_begin(struct wl_listener *listener, void *data) {
943 struct sway_cursor *cursor = wl_container_of( 972 struct sway_cursor *cursor = wl_container_of(
944 listener, cursor, swipe_begin); 973 listener, cursor, swipe_begin);
945 struct wlr_event_pointer_swipe_begin *event = data; 974 struct wlr_pointer_swipe_begin_event *event = data;
946 wlr_pointer_gestures_v1_send_swipe_begin( 975 cursor_handle_activity_from_device(cursor, &event->pointer->base);
947 cursor->pointer_gestures, cursor->seat->wlr_seat, 976 seatop_swipe_begin(cursor->seat, event);
948 event->time_msec, event->fingers);
949} 977}
950 978
951static void handle_pointer_swipe_update(struct wl_listener *listener, void *data) { 979static void handle_pointer_swipe_update(struct wl_listener *listener, void *data) {
952 struct sway_cursor *cursor = wl_container_of( 980 struct sway_cursor *cursor = wl_container_of(
953 listener, cursor, swipe_update); 981 listener, cursor, swipe_update);
954 struct wlr_event_pointer_swipe_update *event = data; 982 struct wlr_pointer_swipe_update_event *event = data;
955 wlr_pointer_gestures_v1_send_swipe_update( 983 cursor_handle_activity_from_device(cursor, &event->pointer->base);
956 cursor->pointer_gestures, cursor->seat->wlr_seat, 984 seatop_swipe_update(cursor->seat, event);
957 event->time_msec, event->dx, event->dy);
958} 985}
959 986
960static void handle_pointer_swipe_end(struct wl_listener *listener, void *data) { 987static void handle_pointer_swipe_end(struct wl_listener *listener, void *data) {
961 struct sway_cursor *cursor = wl_container_of( 988 struct sway_cursor *cursor = wl_container_of(
962 listener, cursor, swipe_end); 989 listener, cursor, swipe_end);
963 struct wlr_event_pointer_swipe_end *event = data; 990 struct wlr_pointer_swipe_end_event *event = data;
964 wlr_pointer_gestures_v1_send_swipe_end( 991 cursor_handle_activity_from_device(cursor, &event->pointer->base);
965 cursor->pointer_gestures, cursor->seat->wlr_seat, 992 seatop_swipe_end(cursor->seat, event);
966 event->time_msec, event->cancelled);
967} 993}
968 994
969static void handle_image_surface_destroy(struct wl_listener *listener, 995static void handle_image_surface_destroy(struct wl_listener *listener,
@@ -1037,6 +1063,8 @@ void sway_cursor_destroy(struct sway_cursor *cursor) {
1037 wl_event_source_remove(cursor->hide_source); 1063 wl_event_source_remove(cursor->hide_source);
1038 1064
1039 wl_list_remove(&cursor->image_surface_destroy.link); 1065 wl_list_remove(&cursor->image_surface_destroy.link);
1066 wl_list_remove(&cursor->hold_begin.link);
1067 wl_list_remove(&cursor->hold_end.link);
1040 wl_list_remove(&cursor->pinch_begin.link); 1068 wl_list_remove(&cursor->pinch_begin.link);
1041 wl_list_remove(&cursor->pinch_update.link); 1069 wl_list_remove(&cursor->pinch_update.link);
1042 wl_list_remove(&cursor->pinch_end.link); 1070 wl_list_remove(&cursor->pinch_end.link);
@@ -1051,6 +1079,7 @@ void sway_cursor_destroy(struct sway_cursor *cursor) {
1051 wl_list_remove(&cursor->touch_down.link); 1079 wl_list_remove(&cursor->touch_down.link);
1052 wl_list_remove(&cursor->touch_up.link); 1080 wl_list_remove(&cursor->touch_up.link);
1053 wl_list_remove(&cursor->touch_motion.link); 1081 wl_list_remove(&cursor->touch_motion.link);
1082 wl_list_remove(&cursor->touch_frame.link);
1054 wl_list_remove(&cursor->tool_axis.link); 1083 wl_list_remove(&cursor->tool_axis.link);
1055 wl_list_remove(&cursor->tool_tip.link); 1084 wl_list_remove(&cursor->tool_tip.link);
1056 wl_list_remove(&cursor->tool_button.link); 1085 wl_list_remove(&cursor->tool_button.link);
@@ -1085,19 +1114,27 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) {
1085 wl_list_init(&cursor->image_surface_destroy.link); 1114 wl_list_init(&cursor->image_surface_destroy.link);
1086 cursor->image_surface_destroy.notify = handle_image_surface_destroy; 1115 cursor->image_surface_destroy.notify = handle_image_surface_destroy;
1087 1116
1117 // gesture events
1088 cursor->pointer_gestures = wlr_pointer_gestures_v1_create(server.wl_display); 1118 cursor->pointer_gestures = wlr_pointer_gestures_v1_create(server.wl_display);
1089 cursor->pinch_begin.notify = handle_pointer_pinch_begin; 1119
1120 wl_signal_add(&wlr_cursor->events.hold_begin, &cursor->hold_begin);
1121 cursor->hold_begin.notify = handle_pointer_hold_begin;
1122 wl_signal_add(&wlr_cursor->events.hold_end, &cursor->hold_end);
1123 cursor->hold_end.notify = handle_pointer_hold_end;
1124
1090 wl_signal_add(&wlr_cursor->events.pinch_begin, &cursor->pinch_begin); 1125 wl_signal_add(&wlr_cursor->events.pinch_begin, &cursor->pinch_begin);
1091 cursor->pinch_update.notify = handle_pointer_pinch_update; 1126 cursor->pinch_begin.notify = handle_pointer_pinch_begin;
1092 wl_signal_add(&wlr_cursor->events.pinch_update, &cursor->pinch_update); 1127 wl_signal_add(&wlr_cursor->events.pinch_update, &cursor->pinch_update);
1093 cursor->pinch_end.notify = handle_pointer_pinch_end; 1128 cursor->pinch_update.notify = handle_pointer_pinch_update;
1094 wl_signal_add(&wlr_cursor->events.pinch_end, &cursor->pinch_end); 1129 wl_signal_add(&wlr_cursor->events.pinch_end, &cursor->pinch_end);
1095 cursor->swipe_begin.notify = handle_pointer_swipe_begin; 1130 cursor->pinch_end.notify = handle_pointer_pinch_end;
1131
1096 wl_signal_add(&wlr_cursor->events.swipe_begin, &cursor->swipe_begin); 1132 wl_signal_add(&wlr_cursor->events.swipe_begin, &cursor->swipe_begin);
1097 cursor->swipe_update.notify = handle_pointer_swipe_update; 1133 cursor->swipe_begin.notify = handle_pointer_swipe_begin;
1098 wl_signal_add(&wlr_cursor->events.swipe_update, &cursor->swipe_update); 1134 wl_signal_add(&wlr_cursor->events.swipe_update, &cursor->swipe_update);
1099 cursor->swipe_end.notify = handle_pointer_swipe_end; 1135 cursor->swipe_update.notify = handle_pointer_swipe_update;
1100 wl_signal_add(&wlr_cursor->events.swipe_end, &cursor->swipe_end); 1136 wl_signal_add(&wlr_cursor->events.swipe_end, &cursor->swipe_end);
1137 cursor->swipe_end.notify = handle_pointer_swipe_end;
1101 1138
1102 // input events 1139 // input events
1103 wl_signal_add(&wlr_cursor->events.motion, &cursor->motion); 1140 wl_signal_add(&wlr_cursor->events.motion, &cursor->motion);
@@ -1126,6 +1163,9 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) {
1126 &cursor->touch_motion); 1163 &cursor->touch_motion);
1127 cursor->touch_motion.notify = handle_touch_motion; 1164 cursor->touch_motion.notify = handle_touch_motion;
1128 1165
1166 wl_signal_add(&wlr_cursor->events.touch_frame, &cursor->touch_frame);
1167 cursor->touch_frame.notify = handle_touch_frame;
1168
1129 wl_signal_add(&wlr_cursor->events.tablet_tool_axis, 1169 wl_signal_add(&wlr_cursor->events.tablet_tool_axis,
1130 &cursor->tool_axis); 1170 &cursor->tool_axis);
1131 cursor->tool_axis.notify = handle_tool_axis; 1171 cursor->tool_axis.notify = handle_tool_axis;
@@ -1170,8 +1210,8 @@ void cursor_warp_to_container(struct sway_cursor *cursor,
1170 return; 1210 return;
1171 } 1211 }
1172 1212
1173 double x = container->x + container->width / 2.0; 1213 double x = container->pending.x + container->pending.width / 2.0;
1174 double y = container->y + container->height / 2.0; 1214 double y = container->pending.y + container->pending.height / 2.0;
1175 1215
1176 wlr_cursor_warp(cursor->cursor, NULL, x, y); 1216 wlr_cursor_warp(cursor->cursor, NULL, x, y);
1177 cursor_unhide(cursor); 1217 cursor_unhide(cursor);
@@ -1284,8 +1324,8 @@ static void warp_to_constraint_cursor_hint(struct sway_cursor *cursor) {
1284 struct sway_view *view = view_from_wlr_surface(constraint->surface); 1324 struct sway_view *view = view_from_wlr_surface(constraint->surface);
1285 struct sway_container *con = view->container; 1325 struct sway_container *con = view->container;
1286 1326
1287 double lx = sx + con->content_x - view->geometry.x; 1327 double lx = sx + con->pending.content_x - view->geometry.x;
1288 double ly = sy + con->content_y - view->geometry.y; 1328 double ly = sy + con->pending.content_y - view->geometry.y;
1289 1329
1290 wlr_cursor_warp(cursor->cursor, NULL, lx, ly); 1330 wlr_cursor_warp(cursor->cursor, NULL, lx, ly);
1291 1331
@@ -1333,7 +1373,7 @@ void handle_pointer_constraint(struct wl_listener *listener, void *data) {
1333 wl_signal_add(&constraint->events.destroy, &sway_constraint->destroy); 1373 wl_signal_add(&constraint->events.destroy, &sway_constraint->destroy);
1334 1374
1335 struct sway_node *focus = seat_get_focus(seat); 1375 struct sway_node *focus = seat_get_focus(seat);
1336 if (focus && focus->type == N_CONTAINER && focus->sway_container->view) { 1376 if (focus && node_is_view(focus)) {
1337 struct wlr_surface *surface = focus->sway_container->view->surface; 1377 struct wlr_surface *surface = focus->sway_container->view->surface;
1338 if (surface == constraint->surface) { 1378 if (surface == constraint->surface) {
1339 sway_cursor_constrain(seat->cursor, constraint); 1379 sway_cursor_constrain(seat->cursor, constraint);