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.c587
1 files changed, 296 insertions, 291 deletions
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 2fe5b202..3d04826c 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -1,4 +1,3 @@
1#define _POSIX_C_SOURCE 200809L
2#include <assert.h> 1#include <assert.h>
3#include <math.h> 2#include <math.h>
4#include <libevdev/libevdev.h> 3#include <libevdev/libevdev.h>
@@ -7,8 +6,9 @@
7#include <time.h> 6#include <time.h>
8#include <strings.h> 7#include <strings.h>
9#include <wlr/types/wlr_cursor.h> 8#include <wlr/types/wlr_cursor.h>
10#include <wlr/types/wlr_idle.h> 9#include <wlr/types/wlr_cursor_shape_v1.h>
11#include <wlr/types/wlr_pointer.h> 10#include <wlr/types/wlr_pointer.h>
11#include <wlr/types/wlr_relative_pointer_v1.h>
12#include <wlr/types/wlr_touch.h> 12#include <wlr/types/wlr_touch.h>
13#include <wlr/types/wlr_tablet_v2.h> 13#include <wlr/types/wlr_tablet_v2.h>
14#include <wlr/types/wlr_tablet_pad.h> 14#include <wlr/types/wlr_tablet_pad.h>
@@ -19,12 +19,12 @@
19#include "log.h" 19#include "log.h"
20#include "util.h" 20#include "util.h"
21#include "sway/commands.h" 21#include "sway/commands.h"
22#include "sway/desktop.h"
23#include "sway/input/cursor.h" 22#include "sway/input/cursor.h"
24#include "sway/input/keyboard.h" 23#include "sway/input/keyboard.h"
25#include "sway/input/tablet.h" 24#include "sway/input/tablet.h"
26#include "sway/layers.h" 25#include "sway/layers.h"
27#include "sway/output.h" 26#include "sway/output.h"
27#include "sway/scene_descriptor.h"
28#include "sway/tree/container.h" 28#include "sway/tree/container.h"
29#include "sway/tree/root.h" 29#include "sway/tree/root.h"
30#include "sway/tree/view.h" 30#include "sway/tree/view.h"
@@ -37,45 +37,6 @@ static uint32_t get_current_time_msec(void) {
37 return now.tv_sec * 1000 + now.tv_nsec / 1000000; 37 return now.tv_sec * 1000 + now.tv_nsec / 1000000;
38} 38}
39 39
40static struct wlr_surface *layer_surface_at(struct sway_output *output,
41 struct wl_list *layer, double ox, double oy, double *sx, double *sy) {
42 struct sway_layer_surface *sway_layer;
43 wl_list_for_each_reverse(sway_layer, layer, link) {
44 double _sx = ox - sway_layer->geo.x;
45 double _sy = oy - sway_layer->geo.y;
46 struct wlr_surface *sub = wlr_layer_surface_v1_surface_at(
47 sway_layer->layer_surface, _sx, _sy, sx, sy);
48 if (sub) {
49 return sub;
50 }
51 }
52 return NULL;
53}
54
55static bool surface_is_xdg_popup(struct wlr_surface *surface) {
56 if (wlr_surface_is_xdg_surface(surface)) {
57 struct wlr_xdg_surface *xdg_surface =
58 wlr_xdg_surface_from_wlr_surface(surface);
59 return xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP;
60 }
61 return false;
62}
63
64static struct wlr_surface *layer_surface_popup_at(struct sway_output *output,
65 struct wl_list *layer, double ox, double oy, double *sx, double *sy) {
66 struct sway_layer_surface *sway_layer;
67 wl_list_for_each_reverse(sway_layer, layer, link) {
68 double _sx = ox - sway_layer->geo.x;
69 double _sy = oy - sway_layer->geo.y;
70 struct wlr_surface *sub = wlr_layer_surface_v1_surface_at(
71 sway_layer->layer_surface, _sx, _sy, sx, sy);
72 if (sub && surface_is_xdg_popup(sub)) {
73 return sub;
74 }
75 }
76 return NULL;
77}
78
79/** 40/**
80 * Returns the node at the cursor's position. If there is a surface at that 41 * Returns the node at the cursor's position. If there is a surface at that
81 * location, it is stored in **surface (it may not be a view). 42 * location, it is stored in **surface (it may not be a view).
@@ -83,116 +44,101 @@ static struct wlr_surface *layer_surface_popup_at(struct sway_output *output,
83struct sway_node *node_at_coords( 44struct sway_node *node_at_coords(
84 struct sway_seat *seat, double lx, double ly, 45 struct sway_seat *seat, double lx, double ly,
85 struct wlr_surface **surface, double *sx, double *sy) { 46 struct wlr_surface **surface, double *sx, double *sy) {
86 // check for unmanaged views first 47 struct wlr_scene_node *scene_node = NULL;
87#if HAVE_XWAYLAND 48
88 struct wl_list *unmanaged = &root->xwayland_unmanaged; 49 struct wlr_scene_node *node;
89 struct sway_xwayland_unmanaged *unmanaged_surface; 50 wl_list_for_each_reverse(node, &root->layer_tree->children, link) {
90 wl_list_for_each_reverse(unmanaged_surface, unmanaged, link) { 51 struct wlr_scene_tree *layer = wlr_scene_tree_from_node(node);
91 struct wlr_xwayland_surface *xsurface = 52
92 unmanaged_surface->wlr_xwayland_surface; 53 bool non_interactive = scene_descriptor_try_get(&layer->node,
93 54 SWAY_SCENE_DESC_NON_INTERACTIVE);
94 double _sx = lx - unmanaged_surface->lx; 55 if (non_interactive) {
95 double _sy = ly - unmanaged_surface->ly; 56 continue;
96 if (wlr_surface_point_accepts_input(xsurface->surface, _sx, _sy)) { 57 }
97 *surface = xsurface->surface; 58
98 *sx = _sx; 59 scene_node = wlr_scene_node_at(&layer->node, lx, ly, sx, sy);
99 *sy = _sy; 60 if (scene_node) {
100 return NULL; 61 break;
101 } 62 }
102 } 63 }
64
65 if (scene_node) {
66 // determine what wlr_surface we clicked on
67 if (scene_node->type == WLR_SCENE_NODE_BUFFER) {
68 struct wlr_scene_buffer *scene_buffer =
69 wlr_scene_buffer_from_node(scene_node);
70 struct wlr_scene_surface *scene_surface =
71 wlr_scene_surface_try_from_buffer(scene_buffer);
72
73 if (scene_surface) {
74 *surface = scene_surface->surface;
75 }
76 }
77
78 // determine what container we clicked on
79 struct wlr_scene_node *current = scene_node;
80 while (true) {
81 struct sway_container *con = scene_descriptor_try_get(current,
82 SWAY_SCENE_DESC_CONTAINER);
83
84 if (!con) {
85 struct sway_view *view = scene_descriptor_try_get(current,
86 SWAY_SCENE_DESC_VIEW);
87 if (view) {
88 con = view->container;
89 }
90 }
91
92 if (!con) {
93 struct sway_popup_desc *popup =
94 scene_descriptor_try_get(current, SWAY_SCENE_DESC_POPUP);
95 if (popup && popup->view) {
96 con = popup->view->container;
97 }
98 }
99
100 if (con && (!con->view || con->view->surface)) {
101 return &con->node;
102 }
103
104 if (scene_descriptor_try_get(current, SWAY_SCENE_DESC_LAYER_SHELL)) {
105 // We don't want to feed through the current workspace on
106 // layer shells
107 return NULL;
108 }
109
110#if HAVE_XWAYLAND
111 if (scene_descriptor_try_get(current, SWAY_SCENE_DESC_XWAYLAND_UNMANAGED)) {
112 return NULL;
113 }
103#endif 114#endif
104 // find the output the cursor is on 115
116 if (!current->parent) {
117 break;
118 }
119
120 current = &current->parent->node;
121 }
122 }
123
124 // if we aren't on a container, determine what workspace we are on
105 struct wlr_output *wlr_output = wlr_output_layout_output_at( 125 struct wlr_output *wlr_output = wlr_output_layout_output_at(
106 root->output_layout, lx, ly); 126 root->output_layout, lx, ly);
107 if (wlr_output == NULL) { 127 if (wlr_output == NULL) {
108 return NULL; 128 return NULL;
109 } 129 }
130
110 struct sway_output *output = wlr_output->data; 131 struct sway_output *output = wlr_output->data;
111 if (!output || !output->enabled) { 132 if (!output || !output->enabled) {
112 // output is being destroyed or is being enabled 133 // output is being destroyed or is being enabled
113 return NULL; 134 return NULL;
114 } 135 }
115 double ox = lx, oy = ly;
116 wlr_output_layout_output_coords(root->output_layout, wlr_output, &ox, &oy);
117
118 if (root->fullscreen_global) {
119 // Try fullscreen container
120 struct sway_container *con = tiling_container_at(
121 &root->fullscreen_global->node, lx, ly, surface, sx, sy);
122 if (con) {
123 return &con->node;
124 }
125 return NULL;
126 }
127 136
128 // find the focused workspace on the output for this seat
129 struct sway_workspace *ws = output_get_active_workspace(output); 137 struct sway_workspace *ws = output_get_active_workspace(output);
130 if (!ws) { 138 if (!ws) {
131 return NULL; 139 return NULL;
132 } 140 }
133 141
134 if ((*surface = layer_surface_at(output,
135 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
136 ox, oy, sx, sy))) {
137 return NULL;
138 }
139 if (ws->fullscreen) {
140 // Try transient containers
141 for (int i = 0; i < ws->floating->length; ++i) {
142 struct sway_container *floater = ws->floating->items[i];
143 if (container_is_transient_for(floater, ws->fullscreen)) {
144 struct sway_container *con = tiling_container_at(
145 &floater->node, lx, ly, surface, sx, sy);
146 if (con) {
147 return &con->node;
148 }
149 }
150 }
151 // Try fullscreen container
152 struct sway_container *con =
153 tiling_container_at(&ws->fullscreen->node, lx, ly, surface, sx, sy);
154 if (con) {
155 return &con->node;
156 }
157 return NULL;
158 }
159 if ((*surface = layer_surface_popup_at(output,
160 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
161 ox, oy, sx, sy))) {
162 return NULL;
163 }
164 if ((*surface = layer_surface_popup_at(output,
165 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
166 ox, oy, sx, sy))) {
167 return NULL;
168 }
169 if ((*surface = layer_surface_popup_at(output,
170 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
171 ox, oy, sx, sy))) {
172 return NULL;
173 }
174 if ((*surface = layer_surface_at(output,
175 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
176 ox, oy, sx, sy))) {
177 return NULL;
178 }
179
180 struct sway_container *c;
181 if ((c = container_at(ws, lx, ly, surface, sx, sy))) {
182 return &c->node;
183 }
184
185 if ((*surface = layer_surface_at(output,
186 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
187 ox, oy, sx, sy))) {
188 return NULL;
189 }
190 if ((*surface = layer_surface_at(output,
191 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
192 ox, oy, sx, sy))) {
193 return NULL;
194 }
195
196 return &ws->node; 142 return &ws->node;
197} 143}
198 144
@@ -218,7 +164,7 @@ void cursor_update_image(struct sway_cursor *cursor,
218 // Try a node's resize edge 164 // Try a node's resize edge
219 enum wlr_edges edge = find_resize_edge(node->sway_container, NULL, cursor); 165 enum wlr_edges edge = find_resize_edge(node->sway_container, NULL, cursor);
220 if (edge == WLR_EDGE_NONE) { 166 if (edge == WLR_EDGE_NONE) {
221 cursor_set_image(cursor, "left_ptr", NULL); 167 cursor_set_image(cursor, "default", NULL);
222 } else if (container_is_floating(node->sway_container)) { 168 } else if (container_is_floating(node->sway_container)) {
223 cursor_set_image(cursor, wlr_xcursor_get_resize_name(edge), NULL); 169 cursor_set_image(cursor, wlr_xcursor_get_resize_name(edge), NULL);
224 } else { 170 } else {
@@ -229,12 +175,12 @@ void cursor_update_image(struct sway_cursor *cursor,
229 } 175 }
230 } 176 }
231 } else { 177 } else {
232 cursor_set_image(cursor, "left_ptr", NULL); 178 cursor_set_image(cursor, "default", NULL);
233 } 179 }
234} 180}
235 181
236static void cursor_hide(struct sway_cursor *cursor) { 182static void cursor_hide(struct sway_cursor *cursor) {
237 wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0); 183 wlr_cursor_unset_image(cursor->cursor);
238 cursor->hidden = true; 184 cursor->hidden = true;
239 wlr_seat_pointer_notify_clear_focus(cursor->seat->wlr_seat); 185 wlr_seat_pointer_notify_clear_focus(cursor->seat->wlr_seat);
240} 186}
@@ -297,7 +243,7 @@ static enum sway_input_idle_source idle_source_from_device(
297 return IDLE_SOURCE_POINTER; 243 return IDLE_SOURCE_POINTER;
298 case WLR_INPUT_DEVICE_TOUCH: 244 case WLR_INPUT_DEVICE_TOUCH:
299 return IDLE_SOURCE_TOUCH; 245 return IDLE_SOURCE_TOUCH;
300 case WLR_INPUT_DEVICE_TABLET_TOOL: 246 case WLR_INPUT_DEVICE_TABLET:
301 return IDLE_SOURCE_TABLET_TOOL; 247 return IDLE_SOURCE_TABLET_TOOL;
302 case WLR_INPUT_DEVICE_TABLET_PAD: 248 case WLR_INPUT_DEVICE_TABLET_PAD:
303 return IDLE_SOURCE_TABLET_PAD; 249 return IDLE_SOURCE_TABLET_PAD;
@@ -346,7 +292,7 @@ void cursor_unhide(struct sway_cursor *cursor) {
346 wl_event_source_timer_update(cursor->hide_source, cursor_get_timeout(cursor)); 292 wl_event_source_timer_update(cursor->hide_source, cursor_get_timeout(cursor));
347} 293}
348 294
349static void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, 295void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
350 struct wlr_input_device *device, double dx, double dy, 296 struct wlr_input_device *device, double dx, double dy,
351 double dx_unaccel, double dy_unaccel) { 297 double dx_unaccel, double dy_unaccel) {
352 wlr_relative_pointer_manager_v1_send_relative_motion( 298 wlr_relative_pointer_manager_v1_send_relative_motion(
@@ -383,33 +329,34 @@ static void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
383static void handle_pointer_motion_relative( 329static void handle_pointer_motion_relative(
384 struct wl_listener *listener, void *data) { 330 struct wl_listener *listener, void *data) {
385 struct sway_cursor *cursor = wl_container_of(listener, cursor, motion); 331 struct sway_cursor *cursor = wl_container_of(listener, cursor, motion);
386 struct wlr_event_pointer_motion *e = data; 332 struct wlr_pointer_motion_event *e = data;
387 cursor_handle_activity_from_device(cursor, e->device); 333 cursor_handle_activity_from_device(cursor, &e->pointer->base);
388 334
389 pointer_motion(cursor, e->time_msec, e->device, e->delta_x, e->delta_y, 335 pointer_motion(cursor, e->time_msec, &e->pointer->base, e->delta_x,
390 e->unaccel_dx, e->unaccel_dy); 336 e->delta_y, e->unaccel_dx, e->unaccel_dy);
391} 337}
392 338
393static void handle_pointer_motion_absolute( 339static void handle_pointer_motion_absolute(
394 struct wl_listener *listener, void *data) { 340 struct wl_listener *listener, void *data) {
395 struct sway_cursor *cursor = 341 struct sway_cursor *cursor =
396 wl_container_of(listener, cursor, motion_absolute); 342 wl_container_of(listener, cursor, motion_absolute);
397 struct wlr_event_pointer_motion_absolute *event = data; 343 struct wlr_pointer_motion_absolute_event *event = data;
398 cursor_handle_activity_from_device(cursor, event->device); 344 cursor_handle_activity_from_device(cursor, &event->pointer->base);
399 345
400 double lx, ly; 346 double lx, ly;
401 wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device, 347 wlr_cursor_absolute_to_layout_coords(cursor->cursor, &event->pointer->base,
402 event->x, event->y, &lx, &ly); 348 event->x, event->y, &lx, &ly);
403 349
404 double dx = lx - cursor->cursor->x; 350 double dx = lx - cursor->cursor->x;
405 double dy = ly - cursor->cursor->y; 351 double dy = ly - cursor->cursor->y;
406 352
407 pointer_motion(cursor, event->time_msec, event->device, dx, dy, dx, dy); 353 pointer_motion(cursor, event->time_msec, &event->pointer->base, dx, dy,
354 dx, dy);
408} 355}
409 356
410void dispatch_cursor_button(struct sway_cursor *cursor, 357void dispatch_cursor_button(struct sway_cursor *cursor,
411 struct wlr_input_device *device, uint32_t time_msec, uint32_t button, 358 struct wlr_input_device *device, uint32_t time_msec, uint32_t button,
412 enum wlr_button_state state) { 359 enum wl_pointer_button_state state) {
413 if (time_msec == 0) { 360 if (time_msec == 0) {
414 time_msec = get_current_time_msec(); 361 time_msec = get_current_time_msec();
415 } 362 }
@@ -419,9 +366,9 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
419 366
420static void handle_pointer_button(struct wl_listener *listener, void *data) { 367static void handle_pointer_button(struct wl_listener *listener, void *data) {
421 struct sway_cursor *cursor = wl_container_of(listener, cursor, button); 368 struct sway_cursor *cursor = wl_container_of(listener, cursor, button);
422 struct wlr_event_pointer_button *event = data; 369 struct wlr_pointer_button_event *event = data;
423 370
424 if (event->state == WLR_BUTTON_PRESSED) { 371 if (event->state == WL_POINTER_BUTTON_STATE_PRESSED) {
425 cursor->pressed_button_count++; 372 cursor->pressed_button_count++;
426 } else { 373 } else {
427 if (cursor->pressed_button_count > 0) { 374 if (cursor->pressed_button_count > 0) {
@@ -431,20 +378,20 @@ static void handle_pointer_button(struct wl_listener *listener, void *data) {
431 } 378 }
432 } 379 }
433 380
434 cursor_handle_activity_from_device(cursor, event->device); 381 cursor_handle_activity_from_device(cursor, &event->pointer->base);
435 dispatch_cursor_button(cursor, event->device, 382 dispatch_cursor_button(cursor, &event->pointer->base,
436 event->time_msec, event->button, event->state); 383 event->time_msec, event->button, event->state);
437} 384}
438 385
439void dispatch_cursor_axis(struct sway_cursor *cursor, 386void dispatch_cursor_axis(struct sway_cursor *cursor,
440 struct wlr_event_pointer_axis *event) { 387 struct wlr_pointer_axis_event *event) {
441 seatop_pointer_axis(cursor->seat, event); 388 seatop_pointer_axis(cursor->seat, event);
442} 389}
443 390
444static void handle_pointer_axis(struct wl_listener *listener, void *data) { 391static void handle_pointer_axis(struct wl_listener *listener, void *data) {
445 struct sway_cursor *cursor = wl_container_of(listener, cursor, axis); 392 struct sway_cursor *cursor = wl_container_of(listener, cursor, axis);
446 struct wlr_event_pointer_axis *event = data; 393 struct wlr_pointer_axis_event *event = data;
447 cursor_handle_activity_from_device(cursor, event->device); 394 cursor_handle_activity_from_device(cursor, &event->pointer->base);
448 dispatch_cursor_axis(cursor, event); 395 dispatch_cursor_axis(cursor, event);
449} 396}
450 397
@@ -455,93 +402,76 @@ static void handle_pointer_frame(struct wl_listener *listener, void *data) {
455 402
456static void handle_touch_down(struct wl_listener *listener, void *data) { 403static void handle_touch_down(struct wl_listener *listener, void *data) {
457 struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_down); 404 struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_down);
458 struct wlr_event_touch_down *event = data; 405 struct wlr_touch_down_event *event = data;
459 cursor_handle_activity_from_device(cursor, event->device); 406 cursor_handle_activity_from_device(cursor, &event->touch->base);
460 cursor_hide(cursor); 407 cursor_hide(cursor);
461 408
462 struct sway_seat *seat = cursor->seat; 409 struct sway_seat *seat = cursor->seat;
463 struct wlr_seat *wlr_seat = seat->wlr_seat;
464 struct wlr_surface *surface = NULL;
465 410
466 double lx, ly; 411 double lx, ly;
467 wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device, 412 wlr_cursor_absolute_to_layout_coords(cursor->cursor, &event->touch->base,
468 event->x, event->y, &lx, &ly); 413 event->x, event->y, &lx, &ly);
469 double sx, sy;
470 struct sway_node *focused_node = node_at_coords(seat, lx, ly, &surface, &sx, &sy);
471 414
472 seat->touch_id = event->touch_id; 415 seat->touch_id = event->touch_id;
473 seat->touch_x = lx; 416 seat->touch_x = lx;
474 seat->touch_y = ly; 417 seat->touch_y = ly;
475 418
476 if (surface && wlr_surface_accepts_touch(wlr_seat, surface)) { 419 seatop_touch_down(seat, event, lx, ly);
477 if (seat_is_input_allowed(seat, surface)) { 420}
478 wlr_seat_touch_notify_down(wlr_seat, surface, event->time_msec, 421
479 event->touch_id, sx, sy); 422static void handle_touch_up(struct wl_listener *listener, void *data) {
423 struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_up);
424 struct wlr_touch_up_event *event = data;
425 cursor_handle_activity_from_device(cursor, &event->touch->base);
480 426
481 if (focused_node) { 427 struct sway_seat *seat = cursor->seat;
482 seat_set_focus(seat, focused_node); 428
483 } 429 if (cursor->simulating_pointer_from_touch) {
430 if (cursor->pointer_touch_id == cursor->seat->touch_id) {
431 cursor->pointer_touch_up = true;
432 dispatch_cursor_button(cursor, &event->touch->base,
433 event->time_msec, BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED);
484 } 434 }
485 } else if (!cursor->simulating_pointer_from_touch && 435 } else {
486 (!surface || seat_is_input_allowed(seat, surface))) { 436 seatop_touch_up(seat, event);
487 // Fallback to cursor simulation.
488 // The pointer_touch_id state is needed, so drags are not aborted when over
489 // a surface supporting touch and multi touch events don't interfere.
490 cursor->simulating_pointer_from_touch = true;
491 cursor->pointer_touch_id = seat->touch_id;
492 double dx, dy;
493 dx = lx - cursor->cursor->x;
494 dy = ly - cursor->cursor->y;
495 pointer_motion(cursor, event->time_msec, event->device, dx, dy, dx, dy);
496 dispatch_cursor_button(cursor, event->device, event->time_msec,
497 BTN_LEFT, WLR_BUTTON_PRESSED);
498 } 437 }
499} 438}
500 439
501static void handle_touch_up(struct wl_listener *listener, void *data) { 440static void handle_touch_cancel(struct wl_listener *listener, void *data) {
502 struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_up); 441 struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_cancel);
503 struct wlr_event_touch_up *event = data; 442 struct wlr_touch_cancel_event *event = data;
504 cursor_handle_activity_from_device(cursor, event->device); 443 cursor_handle_activity_from_device(cursor, &event->touch->base);
505 444
506 struct wlr_seat *wlr_seat = cursor->seat->wlr_seat; 445 struct sway_seat *seat = cursor->seat;
507 446
508 if (cursor->simulating_pointer_from_touch) { 447 if (cursor->simulating_pointer_from_touch) {
509 if (cursor->pointer_touch_id == cursor->seat->touch_id) { 448 if (cursor->pointer_touch_id == cursor->seat->touch_id) {
510 cursor->pointer_touch_up = true; 449 cursor->pointer_touch_up = true;
511 dispatch_cursor_button(cursor, event->device, event->time_msec, 450 dispatch_cursor_button(cursor, &event->touch->base,
512 BTN_LEFT, WLR_BUTTON_RELEASED); 451 event->time_msec, BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED);
513 } 452 }
514 } else { 453 } else {
515 wlr_seat_touch_notify_up(wlr_seat, event->time_msec, event->touch_id); 454 seatop_touch_cancel(seat, event);
516 } 455 }
517} 456}
518 457
519static void handle_touch_motion(struct wl_listener *listener, void *data) { 458static void handle_touch_motion(struct wl_listener *listener, void *data) {
520 struct sway_cursor *cursor = 459 struct sway_cursor *cursor =
521 wl_container_of(listener, cursor, touch_motion); 460 wl_container_of(listener, cursor, touch_motion);
522 struct wlr_event_touch_motion *event = data; 461 struct wlr_touch_motion_event *event = data;
523 cursor_handle_activity_from_device(cursor, event->device); 462 cursor_handle_activity_from_device(cursor, &event->touch->base);
524 463
525 struct sway_seat *seat = cursor->seat; 464 struct sway_seat *seat = cursor->seat;
526 struct wlr_seat *wlr_seat = seat->wlr_seat;
527 struct wlr_surface *surface = NULL;
528 465
529 double lx, ly; 466 double lx, ly;
530 wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device, 467 wlr_cursor_absolute_to_layout_coords(cursor->cursor, &event->touch->base,
531 event->x, event->y, &lx, &ly); 468 event->x, event->y, &lx, &ly);
532 double sx, sy;
533 node_at_coords(cursor->seat, lx, ly, &surface, &sx, &sy);
534 469
535 if (seat->touch_id == event->touch_id) { 470 if (seat->touch_id == event->touch_id) {
536 seat->touch_x = lx; 471 seat->touch_x = lx;
537 seat->touch_y = ly; 472 seat->touch_y = ly;
538 473
539 struct sway_drag_icon *drag_icon; 474 drag_icons_update_position(seat);
540 wl_list_for_each(drag_icon, &root->drag_icons, link) {
541 if (drag_icon->seat == seat) {
542 drag_icon_update_position(drag_icon);
543 }
544 }
545 } 475 }
546 476
547 if (cursor->simulating_pointer_from_touch) { 477 if (cursor->simulating_pointer_from_touch) {
@@ -549,11 +479,11 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) {
549 double dx, dy; 479 double dx, dy;
550 dx = lx - cursor->cursor->x; 480 dx = lx - cursor->cursor->x;
551 dy = ly - cursor->cursor->y; 481 dy = ly - cursor->cursor->y;
552 pointer_motion(cursor, event->time_msec, event->device, dx, dy, dx, dy); 482 pointer_motion(cursor, event->time_msec, &event->touch->base,
483 dx, dy, dx, dy);
553 } 484 }
554 } else if (surface) { 485 } else {
555 wlr_seat_touch_notify_motion(wlr_seat, event->time_msec, 486 seatop_touch_motion(seat, event, lx, ly);
556 event->touch_id, sx, sy);
557 } 487 }
558} 488}
559 489
@@ -588,14 +518,15 @@ static void apply_mapping_from_region(struct wlr_input_device *device,
588 double x1 = region->x1, x2 = region->x2; 518 double x1 = region->x1, x2 = region->x2;
589 double y1 = region->y1, y2 = region->y2; 519 double y1 = region->y1, y2 = region->y2;
590 520
591 if (region->mm) { 521 if (region->mm && device->type == WLR_INPUT_DEVICE_TABLET) {
592 if (device->width_mm == 0 || device->height_mm == 0) { 522 struct wlr_tablet *tablet = wlr_tablet_from_input_device(device);
523 if (tablet->width_mm == 0 || tablet->height_mm == 0) {
593 return; 524 return;
594 } 525 }
595 x1 /= device->width_mm; 526 x1 /= tablet->width_mm;
596 x2 /= device->width_mm; 527 x2 /= tablet->width_mm;
597 y1 /= device->height_mm; 528 y1 /= tablet->height_mm;
598 y2 /= device->height_mm; 529 y2 /= tablet->height_mm;
599 } 530 }
600 531
601 *x = apply_mapping_from_coord(x1, x2, *x); 532 *x = apply_mapping_from_coord(x1, x2, *x);
@@ -657,8 +588,8 @@ static void handle_tablet_tool_position(struct sway_cursor *cursor,
657 588
658static void handle_tool_axis(struct wl_listener *listener, void *data) { 589static void handle_tool_axis(struct wl_listener *listener, void *data) {
659 struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_axis); 590 struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_axis);
660 struct wlr_event_tablet_tool_axis *event = data; 591 struct wlr_tablet_tool_axis_event *event = data;
661 cursor_handle_activity_from_device(cursor, event->device); 592 cursor_handle_activity_from_device(cursor, &event->tablet->base);
662 593
663 struct sway_tablet_tool *sway_tool = event->tool->data; 594 struct sway_tablet_tool *sway_tool = event->tool->data;
664 if (!sway_tool) { 595 if (!sway_tool) {
@@ -713,8 +644,8 @@ static void handle_tool_axis(struct wl_listener *listener, void *data) {
713 644
714static void handle_tool_tip(struct wl_listener *listener, void *data) { 645static void handle_tool_tip(struct wl_listener *listener, void *data) {
715 struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_tip); 646 struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_tip);
716 struct wlr_event_tablet_tool_tip *event = data; 647 struct wlr_tablet_tool_tip_event *event = data;
717 cursor_handle_activity_from_device(cursor, event->device); 648 cursor_handle_activity_from_device(cursor, &event->tablet->base);
718 649
719 struct sway_tablet_tool *sway_tool = event->tool->data; 650 struct sway_tablet_tool *sway_tool = event->tool->data;
720 struct wlr_tablet_v2_tablet *tablet_v2 = sway_tool->tablet->tablet_v2; 651 struct wlr_tablet_v2_tablet *tablet_v2 = sway_tool->tablet->tablet_v2;
@@ -729,8 +660,8 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) {
729 if (cursor->simulating_pointer_from_tool_tip && 660 if (cursor->simulating_pointer_from_tool_tip &&
730 event->state == WLR_TABLET_TOOL_TIP_UP) { 661 event->state == WLR_TABLET_TOOL_TIP_UP) {
731 cursor->simulating_pointer_from_tool_tip = false; 662 cursor->simulating_pointer_from_tool_tip = false;
732 dispatch_cursor_button(cursor, event->device, event->time_msec, 663 dispatch_cursor_button(cursor, &event->tablet->base, event->time_msec,
733 BTN_LEFT, WLR_BUTTON_RELEASED); 664 BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED);
734 wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); 665 wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
735 } else if (!surface || !wlr_surface_accepts_tablet_v2(tablet_v2, surface)) { 666 } else if (!surface || !wlr_surface_accepts_tablet_v2(tablet_v2, surface)) {
736 // If we started holding the tool tip down on a surface that accepts 667 // If we started holding the tool tip down on a surface that accepts
@@ -741,8 +672,8 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) {
741 WLR_TABLET_TOOL_TIP_UP); 672 WLR_TABLET_TOOL_TIP_UP);
742 } else { 673 } else {
743 cursor->simulating_pointer_from_tool_tip = true; 674 cursor->simulating_pointer_from_tool_tip = true;
744 dispatch_cursor_button(cursor, event->device, event->time_msec, 675 dispatch_cursor_button(cursor, &event->tablet->base,
745 BTN_LEFT, WLR_BUTTON_PRESSED); 676 event->time_msec, BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED);
746 wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); 677 wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
747 } 678 }
748 } else { 679 } else {
@@ -764,12 +695,13 @@ static struct sway_tablet *get_tablet_for_device(struct sway_cursor *cursor,
764static void handle_tool_proximity(struct wl_listener *listener, void *data) { 695static void handle_tool_proximity(struct wl_listener *listener, void *data) {
765 struct sway_cursor *cursor = 696 struct sway_cursor *cursor =
766 wl_container_of(listener, cursor, tool_proximity); 697 wl_container_of(listener, cursor, tool_proximity);
767 struct wlr_event_tablet_tool_proximity *event = data; 698 struct wlr_tablet_tool_proximity_event *event = data;
768 cursor_handle_activity_from_device(cursor, event->device); 699 cursor_handle_activity_from_device(cursor, &event->tablet->base);
769 700
770 struct wlr_tablet_tool *tool = event->tool; 701 struct wlr_tablet_tool *tool = event->tool;
771 if (!tool->data) { 702 if (!tool->data) {
772 struct sway_tablet *tablet = get_tablet_for_device(cursor, event->device); 703 struct sway_tablet *tablet = get_tablet_for_device(cursor,
704 &event->tablet->base);
773 if (!tablet) { 705 if (!tablet) {
774 sway_log(SWAY_ERROR, "no tablet for tablet tool"); 706 sway_log(SWAY_ERROR, "no tablet for tablet tool");
775 return; 707 return;
@@ -794,8 +726,8 @@ static void handle_tool_proximity(struct wl_listener *listener, void *data) {
794 726
795static void handle_tool_button(struct wl_listener *listener, void *data) { 727static void handle_tool_button(struct wl_listener *listener, void *data) {
796 struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_button); 728 struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_button);
797 struct wlr_event_tablet_tool_button *event = data; 729 struct wlr_tablet_tool_button_event *event = data;
798 cursor_handle_activity_from_device(cursor, event->device); 730 cursor_handle_activity_from_device(cursor, &event->tablet->base);
799 731
800 struct sway_tablet_tool *sway_tool = event->tool->data; 732 struct sway_tablet_tool *sway_tool = event->tool->data;
801 if (!sway_tool) { 733 if (!sway_tool) {
@@ -810,31 +742,71 @@ static void handle_tool_button(struct wl_listener *listener, void *data) {
810 node_at_coords(cursor->seat, cursor->cursor->x, cursor->cursor->y, 742 node_at_coords(cursor->seat, cursor->cursor->x, cursor->cursor->y,
811 &surface, &sx, &sy); 743 &surface, &sx, &sy);
812 744
813 if (!surface || !wlr_surface_accepts_tablet_v2(tablet_v2, surface)) { 745 // TODO: floating resize should support graphics tablet events
746 struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(cursor->seat->wlr_seat);
747 uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
748 bool mod_pressed = modifiers & config->floating_mod;
749
750 bool surface_supports_tablet_events =
751 surface && wlr_surface_accepts_tablet_v2(tablet_v2, surface);
752
753 // Simulate pointer when:
754 // 1. The modifier key is pressed, OR
755 // 2. The surface under the cursor does not support tablet events.
756 bool should_simulate_pointer = mod_pressed || !surface_supports_tablet_events;
757
758 // Similar to tool tip, we need to selectively simulate mouse events, but we
759 // want to make sure that it is always consistent. Because all tool buttons
760 // currently map to BTN_RIGHT, we need to keep count of how many tool
761 // buttons are currently pressed down so we can send consistent events.
762 //
763 // The logic follows:
764 // - If we are already simulating the pointer, we should continue to do so
765 // until at least no tool button is held down.
766 // - If we should simulate the pointer and no tool button is currently held
767 // down, begin simulating the pointer.
768 // - If neither of the above are true, send the tablet events.
769 if ((cursor->tool_buttons > 0 && cursor->simulating_pointer_from_tool_button)
770 || (cursor->tool_buttons == 0 && should_simulate_pointer)) {
771 cursor->simulating_pointer_from_tool_button = true;
772
814 // TODO: the user may want to configure which tool buttons are mapped to 773 // TODO: the user may want to configure which tool buttons are mapped to
815 // which simulated pointer buttons 774 // which simulated pointer buttons
816 switch (event->state) { 775 switch (event->state) {
817 case WLR_BUTTON_PRESSED: 776 case WLR_BUTTON_PRESSED:
818 if (cursor->tool_buttons == 0) { 777 if (cursor->tool_buttons == 0) {
819 dispatch_cursor_button(cursor, event->device, 778 dispatch_cursor_button(cursor, &event->tablet->base,
820 event->time_msec, BTN_RIGHT, event->state); 779 event->time_msec, BTN_RIGHT, WL_POINTER_BUTTON_STATE_PRESSED);
821 } 780 }
822 cursor->tool_buttons++;
823 break; 781 break;
824 case WLR_BUTTON_RELEASED: 782 case WLR_BUTTON_RELEASED:
825 if (cursor->tool_buttons == 1) { 783 if (cursor->tool_buttons <= 1) {
826 dispatch_cursor_button(cursor, event->device, 784 dispatch_cursor_button(cursor, &event->tablet->base,
827 event->time_msec, BTN_RIGHT, event->state); 785 event->time_msec, BTN_RIGHT, WL_POINTER_BUTTON_STATE_RELEASED);
828 } 786 }
829 cursor->tool_buttons--;
830 break; 787 break;
831 } 788 }
832 wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); 789 wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
833 return; 790 } else {
791 cursor->simulating_pointer_from_tool_button = false;
792
793 wlr_tablet_v2_tablet_tool_notify_button(sway_tool->tablet_v2_tool,
794 event->button, (enum zwp_tablet_pad_v2_button_state)event->state);
834 } 795 }
835 796
836 wlr_tablet_v2_tablet_tool_notify_button(sway_tool->tablet_v2_tool, 797 // Update tool button count.
837 event->button, (enum zwp_tablet_pad_v2_button_state)event->state); 798 switch (event->state) {
799 case WLR_BUTTON_PRESSED:
800 cursor->tool_buttons++;
801 break;
802 case WLR_BUTTON_RELEASED:
803 if (cursor->tool_buttons == 0) {
804 sway_log(SWAY_ERROR, "inconsistent tablet tool button events");
805 } else {
806 cursor->tool_buttons--;
807 }
808 break;
809 }
838} 810}
839 811
840static void check_constraint_region(struct sway_cursor *cursor) { 812static void check_constraint_region(struct sway_cursor *cursor) {
@@ -920,59 +892,68 @@ static void handle_request_pointer_set_cursor(struct wl_listener *listener,
920 event->hotspot_y, focused_client); 892 event->hotspot_y, focused_client);
921} 893}
922 894
895static void handle_pointer_hold_begin(struct wl_listener *listener, void *data) {
896 struct sway_cursor *cursor = wl_container_of(
897 listener, cursor, hold_begin);
898 struct wlr_pointer_hold_begin_event *event = data;
899 cursor_handle_activity_from_device(cursor, &event->pointer->base);
900 seatop_hold_begin(cursor->seat, event);
901}
902
903static void handle_pointer_hold_end(struct wl_listener *listener, void *data) {
904 struct sway_cursor *cursor = wl_container_of(
905 listener, cursor, hold_end);
906 struct wlr_pointer_hold_end_event *event = data;
907 cursor_handle_activity_from_device(cursor, &event->pointer->base);
908 seatop_hold_end(cursor->seat, event);
909}
910
923static void handle_pointer_pinch_begin(struct wl_listener *listener, void *data) { 911static void handle_pointer_pinch_begin(struct wl_listener *listener, void *data) {
924 struct sway_cursor *cursor = wl_container_of( 912 struct sway_cursor *cursor = wl_container_of(
925 listener, cursor, pinch_begin); 913 listener, cursor, pinch_begin);
926 struct wlr_event_pointer_pinch_begin *event = data; 914 struct wlr_pointer_pinch_begin_event *event = data;
927 wlr_pointer_gestures_v1_send_pinch_begin( 915 cursor_handle_activity_from_device(cursor, &event->pointer->base);
928 cursor->pointer_gestures, cursor->seat->wlr_seat, 916 seatop_pinch_begin(cursor->seat, event);
929 event->time_msec, event->fingers);
930} 917}
931 918
932static void handle_pointer_pinch_update(struct wl_listener *listener, void *data) { 919static void handle_pointer_pinch_update(struct wl_listener *listener, void *data) {
933 struct sway_cursor *cursor = wl_container_of( 920 struct sway_cursor *cursor = wl_container_of(
934 listener, cursor, pinch_update); 921 listener, cursor, pinch_update);
935 struct wlr_event_pointer_pinch_update *event = data; 922 struct wlr_pointer_pinch_update_event *event = data;
936 wlr_pointer_gestures_v1_send_pinch_update( 923 cursor_handle_activity_from_device(cursor, &event->pointer->base);
937 cursor->pointer_gestures, cursor->seat->wlr_seat, 924 seatop_pinch_update(cursor->seat, event);
938 event->time_msec, event->dx, event->dy,
939 event->scale, event->rotation);
940} 925}
941 926
942static void handle_pointer_pinch_end(struct wl_listener *listener, void *data) { 927static void handle_pointer_pinch_end(struct wl_listener *listener, void *data) {
943 struct sway_cursor *cursor = wl_container_of( 928 struct sway_cursor *cursor = wl_container_of(
944 listener, cursor, pinch_end); 929 listener, cursor, pinch_end);
945 struct wlr_event_pointer_pinch_end *event = data; 930 struct wlr_pointer_pinch_end_event *event = data;
946 wlr_pointer_gestures_v1_send_pinch_end( 931 cursor_handle_activity_from_device(cursor, &event->pointer->base);
947 cursor->pointer_gestures, cursor->seat->wlr_seat, 932 seatop_pinch_end(cursor->seat, event);
948 event->time_msec, event->cancelled);
949} 933}
950 934
951static void handle_pointer_swipe_begin(struct wl_listener *listener, void *data) { 935static void handle_pointer_swipe_begin(struct wl_listener *listener, void *data) {
952 struct sway_cursor *cursor = wl_container_of( 936 struct sway_cursor *cursor = wl_container_of(
953 listener, cursor, swipe_begin); 937 listener, cursor, swipe_begin);
954 struct wlr_event_pointer_swipe_begin *event = data; 938 struct wlr_pointer_swipe_begin_event *event = data;
955 wlr_pointer_gestures_v1_send_swipe_begin( 939 cursor_handle_activity_from_device(cursor, &event->pointer->base);
956 cursor->pointer_gestures, cursor->seat->wlr_seat, 940 seatop_swipe_begin(cursor->seat, event);
957 event->time_msec, event->fingers);
958} 941}
959 942
960static void handle_pointer_swipe_update(struct wl_listener *listener, void *data) { 943static void handle_pointer_swipe_update(struct wl_listener *listener, void *data) {
961 struct sway_cursor *cursor = wl_container_of( 944 struct sway_cursor *cursor = wl_container_of(
962 listener, cursor, swipe_update); 945 listener, cursor, swipe_update);
963 struct wlr_event_pointer_swipe_update *event = data; 946 struct wlr_pointer_swipe_update_event *event = data;
964 wlr_pointer_gestures_v1_send_swipe_update( 947 cursor_handle_activity_from_device(cursor, &event->pointer->base);
965 cursor->pointer_gestures, cursor->seat->wlr_seat, 948 seatop_swipe_update(cursor->seat, event);
966 event->time_msec, event->dx, event->dy);
967} 949}
968 950
969static void handle_pointer_swipe_end(struct wl_listener *listener, void *data) { 951static void handle_pointer_swipe_end(struct wl_listener *listener, void *data) {
970 struct sway_cursor *cursor = wl_container_of( 952 struct sway_cursor *cursor = wl_container_of(
971 listener, cursor, swipe_end); 953 listener, cursor, swipe_end);
972 struct wlr_event_pointer_swipe_end *event = data; 954 struct wlr_pointer_swipe_end_event *event = data;
973 wlr_pointer_gestures_v1_send_swipe_end( 955 cursor_handle_activity_from_device(cursor, &event->pointer->base);
974 cursor->pointer_gestures, cursor->seat->wlr_seat, 956 seatop_swipe_end(cursor->seat, event);
975 event->time_msec, event->cancelled);
976} 957}
977 958
978static void handle_image_surface_destroy(struct wl_listener *listener, 959static void handle_image_surface_destroy(struct wl_listener *listener,
@@ -1011,10 +992,9 @@ void cursor_set_image(struct sway_cursor *cursor, const char *image,
1011 } 992 }
1012 993
1013 if (!image) { 994 if (!image) {
1014 wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0); 995 wlr_cursor_unset_image(cursor->cursor);
1015 } else if (!current_image || strcmp(current_image, image) != 0) { 996 } else if (!current_image || strcmp(current_image, image) != 0) {
1016 wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, image, 997 wlr_cursor_set_xcursor(cursor->cursor, cursor->xcursor_manager, image);
1017 cursor->cursor);
1018 } 998 }
1019} 999}
1020 1000
@@ -1046,6 +1026,8 @@ void sway_cursor_destroy(struct sway_cursor *cursor) {
1046 wl_event_source_remove(cursor->hide_source); 1026 wl_event_source_remove(cursor->hide_source);
1047 1027
1048 wl_list_remove(&cursor->image_surface_destroy.link); 1028 wl_list_remove(&cursor->image_surface_destroy.link);
1029 wl_list_remove(&cursor->hold_begin.link);
1030 wl_list_remove(&cursor->hold_end.link);
1049 wl_list_remove(&cursor->pinch_begin.link); 1031 wl_list_remove(&cursor->pinch_begin.link);
1050 wl_list_remove(&cursor->pinch_update.link); 1032 wl_list_remove(&cursor->pinch_update.link);
1051 wl_list_remove(&cursor->pinch_end.link); 1033 wl_list_remove(&cursor->pinch_end.link);
@@ -1059,6 +1041,7 @@ void sway_cursor_destroy(struct sway_cursor *cursor) {
1059 wl_list_remove(&cursor->frame.link); 1041 wl_list_remove(&cursor->frame.link);
1060 wl_list_remove(&cursor->touch_down.link); 1042 wl_list_remove(&cursor->touch_down.link);
1061 wl_list_remove(&cursor->touch_up.link); 1043 wl_list_remove(&cursor->touch_up.link);
1044 wl_list_remove(&cursor->touch_cancel.link);
1062 wl_list_remove(&cursor->touch_motion.link); 1045 wl_list_remove(&cursor->touch_motion.link);
1063 wl_list_remove(&cursor->touch_frame.link); 1046 wl_list_remove(&cursor->touch_frame.link);
1064 wl_list_remove(&cursor->tool_axis.link); 1047 wl_list_remove(&cursor->tool_axis.link);
@@ -1095,19 +1078,24 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) {
1095 wl_list_init(&cursor->image_surface_destroy.link); 1078 wl_list_init(&cursor->image_surface_destroy.link);
1096 cursor->image_surface_destroy.notify = handle_image_surface_destroy; 1079 cursor->image_surface_destroy.notify = handle_image_surface_destroy;
1097 1080
1098 cursor->pointer_gestures = wlr_pointer_gestures_v1_create(server.wl_display); 1081 wl_signal_add(&wlr_cursor->events.hold_begin, &cursor->hold_begin);
1099 cursor->pinch_begin.notify = handle_pointer_pinch_begin; 1082 cursor->hold_begin.notify = handle_pointer_hold_begin;
1083 wl_signal_add(&wlr_cursor->events.hold_end, &cursor->hold_end);
1084 cursor->hold_end.notify = handle_pointer_hold_end;
1085
1100 wl_signal_add(&wlr_cursor->events.pinch_begin, &cursor->pinch_begin); 1086 wl_signal_add(&wlr_cursor->events.pinch_begin, &cursor->pinch_begin);
1101 cursor->pinch_update.notify = handle_pointer_pinch_update; 1087 cursor->pinch_begin.notify = handle_pointer_pinch_begin;
1102 wl_signal_add(&wlr_cursor->events.pinch_update, &cursor->pinch_update); 1088 wl_signal_add(&wlr_cursor->events.pinch_update, &cursor->pinch_update);
1103 cursor->pinch_end.notify = handle_pointer_pinch_end; 1089 cursor->pinch_update.notify = handle_pointer_pinch_update;
1104 wl_signal_add(&wlr_cursor->events.pinch_end, &cursor->pinch_end); 1090 wl_signal_add(&wlr_cursor->events.pinch_end, &cursor->pinch_end);
1105 cursor->swipe_begin.notify = handle_pointer_swipe_begin; 1091 cursor->pinch_end.notify = handle_pointer_pinch_end;
1092
1106 wl_signal_add(&wlr_cursor->events.swipe_begin, &cursor->swipe_begin); 1093 wl_signal_add(&wlr_cursor->events.swipe_begin, &cursor->swipe_begin);
1107 cursor->swipe_update.notify = handle_pointer_swipe_update; 1094 cursor->swipe_begin.notify = handle_pointer_swipe_begin;
1108 wl_signal_add(&wlr_cursor->events.swipe_update, &cursor->swipe_update); 1095 wl_signal_add(&wlr_cursor->events.swipe_update, &cursor->swipe_update);
1109 cursor->swipe_end.notify = handle_pointer_swipe_end; 1096 cursor->swipe_update.notify = handle_pointer_swipe_update;
1110 wl_signal_add(&wlr_cursor->events.swipe_end, &cursor->swipe_end); 1097 wl_signal_add(&wlr_cursor->events.swipe_end, &cursor->swipe_end);
1098 cursor->swipe_end.notify = handle_pointer_swipe_end;
1111 1099
1112 // input events 1100 // input events
1113 wl_signal_add(&wlr_cursor->events.motion, &cursor->motion); 1101 wl_signal_add(&wlr_cursor->events.motion, &cursor->motion);
@@ -1132,6 +1120,9 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) {
1132 wl_signal_add(&wlr_cursor->events.touch_up, &cursor->touch_up); 1120 wl_signal_add(&wlr_cursor->events.touch_up, &cursor->touch_up);
1133 cursor->touch_up.notify = handle_touch_up; 1121 cursor->touch_up.notify = handle_touch_up;
1134 1122
1123 wl_signal_add(&wlr_cursor->events.touch_cancel, &cursor->touch_cancel);
1124 cursor->touch_cancel.notify = handle_touch_cancel;
1125
1135 wl_signal_add(&wlr_cursor->events.touch_motion, 1126 wl_signal_add(&wlr_cursor->events.touch_motion,
1136 &cursor->touch_motion); 1127 &cursor->touch_motion);
1137 cursor->touch_motion.notify = handle_touch_motion; 1128 cursor->touch_motion.notify = handle_touch_motion;
@@ -1224,11 +1215,7 @@ uint32_t get_mouse_bindsym(const char *name, char **error) {
1224 // Get event code from name 1215 // Get event code from name
1225 int code = libevdev_event_code_from_name(EV_KEY, name); 1216 int code = libevdev_event_code_from_name(EV_KEY, name);
1226 if (code == -1) { 1217 if (code == -1) {
1227 size_t len = snprintf(NULL, 0, "Unknown event %s", name) + 1; 1218 *error = format_str("Unknown event %s", name);
1228 *error = malloc(len);
1229 if (*error) {
1230 snprintf(*error, len, "Unknown event %s", name);
1231 }
1232 return 0; 1219 return 0;
1233 } 1220 }
1234 return code; 1221 return code;
@@ -1250,13 +1237,8 @@ uint32_t get_mouse_bindcode(const char *name, char **error) {
1250 } 1237 }
1251 const char *event = libevdev_event_code_get_name(EV_KEY, code); 1238 const char *event = libevdev_event_code_get_name(EV_KEY, code);
1252 if (!event || strncmp(event, "BTN_", strlen("BTN_")) != 0) { 1239 if (!event || strncmp(event, "BTN_", strlen("BTN_")) != 0) {
1253 size_t len = snprintf(NULL, 0, "Event code %d (%s) is not a button", 1240 *error = format_str("Event code %d (%s) is not a button",
1254 code, event ? event : "(null)") + 1; 1241 code, event ? event : "(null)");
1255 *error = malloc(len);
1256 if (*error) {
1257 snprintf(*error, len, "Event code %d (%s) is not a button",
1258 code, event ? event : "(null)");
1259 }
1260 return 0; 1242 return 0;
1261 } 1243 }
1262 return code; 1244 return code;
@@ -1289,12 +1271,15 @@ const char *get_mouse_button_name(uint32_t button) {
1289static void warp_to_constraint_cursor_hint(struct sway_cursor *cursor) { 1271static void warp_to_constraint_cursor_hint(struct sway_cursor *cursor) {
1290 struct wlr_pointer_constraint_v1 *constraint = cursor->active_constraint; 1272 struct wlr_pointer_constraint_v1 *constraint = cursor->active_constraint;
1291 1273
1292 if (constraint->current.committed & 1274 if (constraint->current.cursor_hint.enabled) {
1293 WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT) {
1294 double sx = constraint->current.cursor_hint.x; 1275 double sx = constraint->current.cursor_hint.x;
1295 double sy = constraint->current.cursor_hint.y; 1276 double sy = constraint->current.cursor_hint.y;
1296 1277
1297 struct sway_view *view = view_from_wlr_surface(constraint->surface); 1278 struct sway_view *view = view_from_wlr_surface(constraint->surface);
1279 if (!view) {
1280 return;
1281 }
1282
1298 struct sway_container *con = view->container; 1283 struct sway_container *con = view->container;
1299 1284
1300 double lx = sx + con->pending.content_x - view->geometry.x; 1285 double lx = sx + con->pending.content_x - view->geometry.x;
@@ -1345,12 +1330,9 @@ void handle_pointer_constraint(struct wl_listener *listener, void *data) {
1345 sway_constraint->destroy.notify = handle_constraint_destroy; 1330 sway_constraint->destroy.notify = handle_constraint_destroy;
1346 wl_signal_add(&constraint->events.destroy, &sway_constraint->destroy); 1331 wl_signal_add(&constraint->events.destroy, &sway_constraint->destroy);
1347 1332
1348 struct sway_node *focus = seat_get_focus(seat); 1333 struct wlr_surface *surface = seat->wlr_seat->keyboard_state.focused_surface;
1349 if (focus && focus->type == N_CONTAINER && focus->sway_container->view) { 1334 if (surface && surface == constraint->surface) {
1350 struct wlr_surface *surface = focus->sway_container->view->surface; 1335 sway_cursor_constrain(seat->cursor, constraint);
1351 if (surface == constraint->surface) {
1352 sway_cursor_constrain(seat->cursor, constraint);
1353 }
1354 } 1336 }
1355} 1337}
1356 1338
@@ -1408,3 +1390,26 @@ void sway_cursor_constrain(struct sway_cursor *cursor,
1408 wl_signal_add(&constraint->surface->events.commit, 1390 wl_signal_add(&constraint->surface->events.commit,
1409 &cursor->constraint_commit); 1391 &cursor->constraint_commit);
1410} 1392}
1393
1394void handle_request_set_cursor_shape(struct wl_listener *listener, void *data) {
1395 const struct wlr_cursor_shape_manager_v1_request_set_shape_event *event = data;
1396 struct sway_seat *seat = event->seat_client->seat->data;
1397
1398 if (!seatop_allows_set_cursor(seat)) {
1399 return;
1400 }
1401
1402 struct wl_client *focused_client = NULL;
1403 struct wlr_surface *focused_surface = seat->wlr_seat->pointer_state.focused_surface;
1404 if (focused_surface != NULL) {
1405 focused_client = wl_resource_get_client(focused_surface->resource);
1406 }
1407
1408 // TODO: check cursor mode
1409 if (focused_client == NULL || event->seat_client->client != focused_client) {
1410 sway_log(SWAY_DEBUG, "denying request to set cursor from unfocused client");
1411 return;
1412 }
1413
1414 cursor_set_image(seat->cursor, wlr_cursor_shape_v1_name(event->shape), focused_client);
1415}