aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Las <las@protonmail.ch>2019-01-26 00:45:06 +0100
committerLibravatar emersion <contact@emersion.fr>2019-01-30 19:53:59 +0100
commitcedde21c967ae5be0d1a9c7656ab8c6b3186ae42 (patch)
tree26c784ea3d6546d762a96b131a2cf23cee9a9c38
parentcriteria & scratchpad verify if show in another workspace (#3522) (diff)
downloadsway-cedde21c967ae5be0d1a9c7656ab8c6b3186ae42.tar.gz
sway-cedde21c967ae5be0d1a9c7656ab8c6b3186ae42.tar.zst
sway-cedde21c967ae5be0d1a9c7656ab8c6b3186ae42.zip
Implement pointer-constraints-unstable-v1
-rw-r--r--include/sway/input/cursor.h13
-rw-r--r--include/sway/input/seat.h6
-rw-r--r--include/sway/server.h4
-rw-r--r--protocols/meson.build1
-rw-r--r--sway/input/cursor.c235
-rw-r--r--sway/input/seat.c6
-rw-r--r--sway/input/seatop_down.c11
-rw-r--r--sway/server.c9
8 files changed, 261 insertions, 24 deletions
diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h
index c87d8332..072a56ca 100644
--- a/include/sway/input/cursor.h
+++ b/include/sway/input/cursor.h
@@ -2,6 +2,7 @@
2#define _SWAY_INPUT_CURSOR_H 2#define _SWAY_INPUT_CURSOR_H
3#include <stdbool.h> 3#include <stdbool.h>
4#include <stdint.h> 4#include <stdint.h>
5#include <wlr/types/wlr_pointer_constraints_v1.h>
5#include <wlr/types/wlr_surface.h> 6#include <wlr/types/wlr_surface.h>
6#include "sway/input/seat.h" 7#include "sway/input/seat.h"
7 8
@@ -26,6 +27,9 @@ struct sway_cursor {
26 struct wlr_surface *image_surface; 27 struct wlr_surface *image_surface;
27 int hotspot_x, hotspot_y; 28 int hotspot_x, hotspot_y;
28 29
30 struct wlr_pointer_constraint_v1 *active_constraint;
31 pixman_region32_t confine; // invalid if active_constraint == NULL
32
29 struct wl_listener motion; 33 struct wl_listener motion;
30 struct wl_listener motion_absolute; 34 struct wl_listener motion_absolute;
31 struct wl_listener button; 35 struct wl_listener button;
@@ -43,6 +47,8 @@ struct sway_cursor {
43 47
44 struct wl_listener request_set_cursor; 48 struct wl_listener request_set_cursor;
45 49
50 struct wl_listener constraint_commit;
51
46 struct wl_event_source *hide_source; 52 struct wl_event_source *hide_source;
47 bool hidden; 53 bool hidden;
48 54
@@ -75,7 +81,8 @@ int cursor_get_timeout(struct sway_cursor *cursor);
75 * Like cursor_rebase, but also allows focus to change when the cursor enters a 81 * Like cursor_rebase, but also allows focus to change when the cursor enters a
76 * new container. 82 * new container.
77 */ 83 */
78void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec); 84void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
85 struct sway_node *node, struct wlr_surface *surface, double sx, double sy);
79 86
80void dispatch_cursor_button(struct sway_cursor *cursor, 87void dispatch_cursor_button(struct sway_cursor *cursor,
81 struct wlr_input_device *device, uint32_t time_msec, uint32_t button, 88 struct wlr_input_device *device, uint32_t time_msec, uint32_t button,
@@ -97,6 +104,10 @@ void cursor_warp_to_container(struct sway_cursor *cursor,
97void cursor_warp_to_workspace(struct sway_cursor *cursor, 104void cursor_warp_to_workspace(struct sway_cursor *cursor,
98 struct sway_workspace *workspace); 105 struct sway_workspace *workspace);
99 106
107
108void sway_cursor_constrain(struct sway_cursor *cursor,
109 struct wlr_pointer_constraint_v1 *constraint);
110
100uint32_t get_mouse_bindsym(const char *name, char **error); 111uint32_t get_mouse_bindsym(const char *name, char **error);
101 112
102uint32_t get_mouse_bindcode(const char *name, char **error); 113uint32_t get_mouse_bindcode(const char *name, char **error);
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h
index ef85b67f..1c9354df 100644
--- a/include/sway/input/seat.h
+++ b/include/sway/input/seat.h
@@ -84,6 +84,12 @@ struct sway_seat {
84 struct wl_list link; // input_manager::seats 84 struct wl_list link; // input_manager::seats
85}; 85};
86 86
87struct sway_pointer_constraint {
88 struct wlr_pointer_constraint_v1 *constraint;
89
90 struct wl_listener destroy;
91};
92
87struct sway_seat *seat_create(const char *seat_name); 93struct sway_seat *seat_create(const char *seat_name);
88 94
89void seat_destroy(struct sway_seat *seat); 95void seat_destroy(struct sway_seat *seat);
diff --git a/include/sway/server.h b/include/sway/server.h
index 9242ceb7..fa2c6557 100644
--- a/include/sway/server.h
+++ b/include/sway/server.h
@@ -61,6 +61,9 @@ struct sway_server {
61 61
62 struct wlr_presentation *presentation; 62 struct wlr_presentation *presentation;
63 63
64 struct wlr_pointer_constraints_v1 *pointer_constraints;
65 struct wl_listener pointer_constraint;
66
64 size_t txn_timeout_ms; 67 size_t txn_timeout_ms;
65 list_t *transactions; 68 list_t *transactions;
66 list_t *dirty_nodes; 69 list_t *dirty_nodes;
@@ -86,5 +89,6 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data);
86#endif 89#endif
87void handle_server_decoration(struct wl_listener *listener, void *data); 90void handle_server_decoration(struct wl_listener *listener, void *data);
88void handle_xdg_decoration(struct wl_listener *listener, void *data); 91void handle_xdg_decoration(struct wl_listener *listener, void *data);
92void handle_pointer_constraint(struct wl_listener *listener, void *data);
89 93
90#endif 94#endif
diff --git a/protocols/meson.build b/protocols/meson.build
index a031245c..c438b078 100644
--- a/protocols/meson.build
+++ b/protocols/meson.build
@@ -39,6 +39,7 @@ server_protocols = [
39 [wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'], 39 [wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
40 [wl_protocol_dir, 'unstable/xdg-shell/xdg-shell-unstable-v6.xml'], 40 [wl_protocol_dir, 'unstable/xdg-shell/xdg-shell-unstable-v6.xml'],
41 [wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'], 41 [wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
42 [wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'],
42 ['wlr-layer-shell-unstable-v1.xml'], 43 ['wlr-layer-shell-unstable-v1.xml'],
43 ['wlr-input-inhibitor-unstable-v1.xml'], 44 ['wlr-input-inhibitor-unstable-v1.xml'],
44] 45]
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index c84d6c40..c87efc2b 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -1,4 +1,5 @@
1#define _POSIX_C_SOURCE 200809L 1#define _POSIX_C_SOURCE 200809L
2#include <assert.h>
2#include <math.h> 3#include <math.h>
3#include <libevdev/libevdev.h> 4#include <libevdev/libevdev.h>
4#include <linux/input-event-codes.h> 5#include <linux/input-event-codes.h>
@@ -6,10 +7,11 @@
6#include <float.h> 7#include <float.h>
7#include <limits.h> 8#include <limits.h>
8#include <strings.h> 9#include <strings.h>
10#include <wlr/types/wlr_box.h>
9#include <wlr/types/wlr_cursor.h> 11#include <wlr/types/wlr_cursor.h>
10#include <wlr/types/wlr_xcursor_manager.h>
11#include <wlr/types/wlr_idle.h> 12#include <wlr/types/wlr_idle.h>
12#include <wlr/types/wlr_box.h> 13#include <wlr/types/wlr_xcursor_manager.h>
14#include <wlr/util/region.h>
13#include "list.h" 15#include "list.h"
14#include "log.h" 16#include "log.h"
15#include "config.h" 17#include "config.h"
@@ -327,8 +329,9 @@ void cursor_unhide(struct sway_cursor *cursor) {
327 cursor_rebase(cursor); 329 cursor_rebase(cursor);
328} 330}
329 331
330void cursor_send_pointer_motion(struct sway_cursor *cursor, 332void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
331 uint32_t time_msec) { 333 struct sway_node *node, struct wlr_surface *surface,
334 double sx, double sy) {
332 if (time_msec == 0) { 335 if (time_msec == 0) {
333 time_msec = get_current_time_msec(); 336 time_msec = get_current_time_msec();
334 } 337 }
@@ -343,12 +346,7 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor,
343 return; 346 return;
344 } 347 }
345 348
346 struct wlr_surface *surface = NULL;
347 double sx, sy;
348
349 struct sway_node *prev_node = cursor->previous.node; 349 struct sway_node *prev_node = cursor->previous.node;
350 struct sway_node *node = node_at_coords(seat,
351 cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
352 350
353 // Update the stored previous position 351 // Update the stored previous position
354 cursor->previous.x = cursor->cursor->x; 352 cursor->previous.x = cursor->cursor->x;
@@ -401,9 +399,62 @@ static void handle_cursor_motion(struct wl_listener *listener, void *data) {
401 struct sway_cursor *cursor = wl_container_of(listener, cursor, motion); 399 struct sway_cursor *cursor = wl_container_of(listener, cursor, motion);
402 struct wlr_event_pointer_motion *event = data; 400 struct wlr_event_pointer_motion *event = data;
403 cursor_handle_activity(cursor); 401 cursor_handle_activity(cursor);
404 wlr_cursor_move(cursor->cursor, event->device, 402
405 event->delta_x, event->delta_y); 403 double dx = event->delta_x;
406 cursor_send_pointer_motion(cursor, event->time_msec); 404 double dy = event->delta_y;
405
406 struct wlr_surface *surface = NULL;
407 double sx, sy;
408 struct sway_node *node = node_at_coords(cursor->seat,
409 cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
410
411 if (cursor->active_constraint) {
412 if (cursor->active_constraint->surface != surface) {
413 return;
414 }
415
416 double sx_confined, sy_confined;
417 if (!wlr_region_confine(&cursor->confine, sx, sy, sx + dx, sy + dy,
418 &sx_confined, &sy_confined)) {
419 return;
420 }
421
422 dx = sx_confined - sx;
423 dy = sy_confined - sy;
424 }
425
426 wlr_cursor_move(cursor->cursor, event->device, dx, dy);
427 cursor_send_pointer_motion(cursor, event->time_msec, node, surface,
428 sx + dx, sy + dy);
429 transaction_commit_dirty();
430}
431
432static void cursor_motion_absolute(struct sway_cursor *cursor,
433 uint32_t time_msec, struct wlr_input_device *dev,
434 double x, double y) {
435 cursor_handle_activity(cursor);
436
437 double lx, ly;
438 wlr_cursor_absolute_to_layout_coords(cursor->cursor, dev,
439 x, y, &lx, &ly);
440
441 struct wlr_surface *surface = NULL;
442 double sx, sy;
443 struct sway_node *node = node_at_coords(cursor->seat,
444 lx, ly, &surface, &sx, &sy);
445
446 if (cursor->active_constraint) {
447 if (cursor->active_constraint->surface != surface) {
448 return;
449 }
450 if (!pixman_region32_contains_point(&cursor->confine,
451 floor(sx), floor(sy), NULL)) {
452 return;
453 }
454 }
455
456 wlr_cursor_warp_closest(cursor->cursor, dev, lx, ly);
457 cursor_send_pointer_motion(cursor, time_msec, node, surface, sx, sy);
407 transaction_commit_dirty(); 458 transaction_commit_dirty();
408} 459}
409 460
@@ -412,10 +463,9 @@ static void handle_cursor_motion_absolute(
412 struct sway_cursor *cursor = 463 struct sway_cursor *cursor =
413 wl_container_of(listener, cursor, motion_absolute); 464 wl_container_of(listener, cursor, motion_absolute);
414 struct wlr_event_pointer_motion_absolute *event = data; 465 struct wlr_event_pointer_motion_absolute *event = data;
415 cursor_handle_activity(cursor); 466
416 wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y); 467 cursor_motion_absolute(cursor, event->time_msec, event->device,
417 cursor_send_pointer_motion(cursor, event->time_msec); 468 event->x, event->y);
418 transaction_commit_dirty();
419} 469}
420 470
421/** 471/**
@@ -961,9 +1011,7 @@ static void handle_tool_axis(struct wl_listener *listener, void *data) {
961 apply_mapping_from_region(event->device, ic->mapped_from_region, &x, &y); 1011 apply_mapping_from_region(event->device, ic->mapped_from_region, &x, &y);
962 } 1012 }
963 1013
964 wlr_cursor_warp_absolute(cursor->cursor, event->device, x, y); 1014 cursor_motion_absolute(cursor, event->time_msec, event->device, x, y);
965 cursor_send_pointer_motion(cursor, event->time_msec);
966 transaction_commit_dirty();
967} 1015}
968 1016
969static void handle_tool_tip(struct wl_listener *listener, void *data) { 1017static void handle_tool_tip(struct wl_listener *listener, void *data) {
@@ -1001,6 +1049,49 @@ static void handle_tool_button(struct wl_listener *listener, void *data) {
1001 transaction_commit_dirty(); 1049 transaction_commit_dirty();
1002} 1050}
1003 1051
1052static void check_constraint_region(struct sway_cursor *cursor) {
1053 struct wlr_pointer_constraint_v1 *constraint = cursor->active_constraint;
1054 pixman_region32_t *region = &constraint->region;
1055 struct sway_view *view = view_from_wlr_surface(constraint->surface);
1056 if (view) {
1057 struct sway_container *con = view->container;
1058
1059 double sx = cursor->cursor->x - con->content_x + view->geometry.x;
1060 double sy = cursor->cursor->y - con->content_y + view->geometry.y;
1061
1062 if (!pixman_region32_contains_point(region,
1063 floor(sx), floor(sy), NULL)) {
1064 int nboxes;
1065 pixman_box32_t *boxes = pixman_region32_rectangles(region, &nboxes);
1066 if (nboxes > 0) {
1067 double sx = (boxes[0].x1 + boxes[0].x2) / 2.;
1068 double sy = (boxes[0].y1 + boxes[0].y2) / 2.;
1069
1070 wlr_cursor_warp_closest(cursor->cursor, NULL,
1071 sx + con->content_x - view->geometry.x,
1072 sy + con->content_y - view->geometry.y);
1073 }
1074 }
1075 }
1076
1077 // A locked pointer will result in an empty region, thus disallowing all movement
1078 if (constraint->type == WLR_POINTER_CONSTRAINT_V1_CONFINED) {
1079 pixman_region32_copy(&cursor->confine, region);
1080 } else {
1081 pixman_region32_clear(&cursor->confine);
1082 }
1083}
1084
1085static void handle_constraint_commit(struct wl_listener *listener,
1086 void *data) {
1087 struct sway_cursor *cursor =
1088 wl_container_of(listener, cursor, constraint_commit);
1089 struct wlr_pointer_constraint_v1 *constraint = cursor->active_constraint;
1090 assert(constraint->surface == data);
1091
1092 check_constraint_region(cursor);
1093}
1094
1004static void handle_request_set_cursor(struct wl_listener *listener, 1095static void handle_request_set_cursor(struct wl_listener *listener,
1005 void *data) { 1096 void *data) {
1006 struct sway_cursor *cursor = 1097 struct sway_cursor *cursor =
@@ -1162,6 +1253,8 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) {
1162 &cursor->request_set_cursor); 1253 &cursor->request_set_cursor);
1163 cursor->request_set_cursor.notify = handle_request_set_cursor; 1254 cursor->request_set_cursor.notify = handle_request_set_cursor;
1164 1255
1256 wl_list_init(&cursor->constraint_commit.link);
1257
1165 cursor->cursor = wlr_cursor; 1258 cursor->cursor = wlr_cursor;
1166 1259
1167 return cursor; 1260 return cursor;
@@ -1284,3 +1377,107 @@ const char *get_mouse_button_name(uint32_t button) {
1284 } 1377 }
1285 return name; 1378 return name;
1286} 1379}
1380
1381static void warp_to_constraint_cursor_hint(struct sway_cursor *cursor) {
1382 struct wlr_pointer_constraint_v1 *constraint = cursor->active_constraint;
1383
1384 if (constraint->current.committed &
1385 WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT) {
1386 double sx = constraint->current.cursor_hint.x;
1387 double sy = constraint->current.cursor_hint.y;
1388
1389 struct sway_view *view = view_from_wlr_surface(constraint->surface);
1390 struct sway_container *con = view->container;
1391
1392 double lx = sx + con->content_x - view->geometry.x;
1393 double ly = sy + con->content_y - view->geometry.y;
1394
1395 wlr_cursor_warp(cursor->cursor, NULL, lx, ly);
1396 }
1397}
1398
1399void handle_constraint_destroy(struct wl_listener *listener, void *data) {
1400 struct sway_pointer_constraint *sway_constraint =
1401 wl_container_of(listener, sway_constraint, destroy);
1402 struct wlr_pointer_constraint_v1 *constraint = data;
1403 struct sway_seat *seat = constraint->seat->data;
1404 struct sway_cursor *cursor = seat->cursor;
1405
1406 wl_list_remove(&sway_constraint->destroy.link);
1407
1408 if (cursor->active_constraint == constraint) {
1409 warp_to_constraint_cursor_hint(cursor);
1410
1411 if (cursor->constraint_commit.link.next != NULL) {
1412 wl_list_remove(&cursor->constraint_commit.link);
1413 }
1414 wl_list_init(&cursor->constraint_commit.link);
1415 cursor->active_constraint = NULL;
1416 }
1417
1418 free(sway_constraint);
1419}
1420
1421void handle_pointer_constraint(struct wl_listener *listener, void *data) {
1422 struct wlr_pointer_constraint_v1 *constraint = data;
1423 struct sway_seat *seat = constraint->seat->data;
1424
1425 struct sway_pointer_constraint *sway_constraint =
1426 calloc(1, sizeof(struct sway_pointer_constraint));
1427 sway_constraint->constraint = constraint;
1428
1429 sway_constraint->destroy.notify = handle_constraint_destroy;
1430 wl_signal_add(&constraint->events.destroy, &sway_constraint->destroy);
1431
1432 struct sway_node *focus = seat_get_focus(seat);
1433 if (focus && focus->type == N_CONTAINER && focus->sway_container->view) {
1434 struct wlr_surface *surface = focus->sway_container->view->surface;
1435 if (surface == constraint->surface) {
1436 sway_cursor_constrain(seat->cursor, constraint);
1437 }
1438 }
1439}
1440
1441void sway_cursor_constrain(struct sway_cursor *cursor,
1442 struct wlr_pointer_constraint_v1 *constraint) {
1443 if (cursor->active_constraint == constraint) {
1444 return;
1445 }
1446
1447 wl_list_remove(&cursor->constraint_commit.link);
1448 if (cursor->active_constraint) {
1449 if (constraint == NULL) {
1450 warp_to_constraint_cursor_hint(cursor);
1451 }
1452 wlr_pointer_constraint_v1_send_deactivated(
1453 cursor->active_constraint);
1454 }
1455
1456 cursor->active_constraint = constraint;
1457
1458 if (constraint == NULL) {
1459 wl_list_init(&cursor->constraint_commit.link);
1460 return;
1461 }
1462
1463 // FIXME: Big hack, stolen from wlr_pointer_constraints_v1.c:121.
1464 // This is necessary because the focus may be set before the surface
1465 // has finished committing, which means that warping won't work properly,
1466 // since this code will be run *after* the focus has been set.
1467 // That is why we duplicate the code here.
1468 if (pixman_region32_not_empty(&constraint->current.region)) {
1469 pixman_region32_intersect(&constraint->region,
1470 &constraint->surface->input_region, &constraint->current.region);
1471 } else {
1472 pixman_region32_copy(&constraint->region,
1473 &constraint->surface->input_region);
1474 }
1475
1476 check_constraint_region(cursor);
1477
1478 wlr_pointer_constraint_v1_send_activated(constraint);
1479
1480 cursor->constraint_commit.notify = handle_constraint_commit;
1481 wl_signal_add(&constraint->surface->events.commit,
1482 &cursor->constraint_commit);
1483}
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 8cb1d8e9..d159da22 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -105,6 +105,11 @@ static void seat_send_focus(struct sway_node *node, struct sway_seat *seat) {
105 wlr_seat_keyboard_notify_enter( 105 wlr_seat_keyboard_notify_enter(
106 seat->wlr_seat, view->surface, NULL, 0, NULL); 106 seat->wlr_seat, view->surface, NULL, 0, NULL);
107 } 107 }
108
109 struct wlr_pointer_constraint_v1 *constraint =
110 wlr_pointer_constraints_v1_constraint_for_surface(
111 server.pointer_constraints, view->surface, seat->wlr_seat);
112 sway_cursor_constrain(seat->cursor, constraint);
108 } 113 }
109} 114}
110 115
@@ -684,6 +689,7 @@ static void send_unfocus(struct sway_container *con, void *data) {
684 689
685// Unfocus the container and any children (eg. when leaving `focus parent`) 690// Unfocus the container and any children (eg. when leaving `focus parent`)
686static void seat_send_unfocus(struct sway_node *node, struct sway_seat *seat) { 691static void seat_send_unfocus(struct sway_node *node, struct sway_seat *seat) {
692 sway_cursor_constrain(seat->cursor, NULL);
687 wlr_seat_keyboard_clear_focus(seat->wlr_seat); 693 wlr_seat_keyboard_clear_focus(seat->wlr_seat);
688 if (node->type == N_WORKSPACE) { 694 if (node->type == N_WORKSPACE) {
689 workspace_for_each_container(node->sway_workspace, send_unfocus, seat); 695 workspace_for_each_container(node->sway_workspace, send_unfocus, seat);
diff --git a/sway/input/seatop_down.c b/sway/input/seatop_down.c
index c491e9c2..c2256c9a 100644
--- a/sway/input/seatop_down.c
+++ b/sway/input/seatop_down.c
@@ -26,14 +26,19 @@ static void handle_motion(struct sway_seat *seat, uint32_t time_msec) {
26 26
27static void handle_finish(struct sway_seat *seat) { 27static void handle_finish(struct sway_seat *seat) {
28 struct seatop_down_event *e = seat->seatop_data; 28 struct seatop_down_event *e = seat->seatop_data;
29 struct sway_cursor *cursor = seat->cursor;
29 // Set the cursor's previous coords to the x/y at the start of the 30 // Set the cursor's previous coords to the x/y at the start of the
30 // operation, so the container change will be detected if using 31 // operation, so the container change will be detected if using
31 // focus_follows_mouse and the cursor moved off the original container 32 // focus_follows_mouse and the cursor moved off the original container
32 // during the operation. 33 // during the operation.
33 seat->cursor->previous.x = e->ref_lx; 34 cursor->previous.x = e->ref_lx;
34 seat->cursor->previous.y = e->ref_ly; 35 cursor->previous.y = e->ref_ly;
35 if (e->moved) { 36 if (e->moved) {
36 cursor_send_pointer_motion(seat->cursor, 0); 37 struct wlr_surface *surface = NULL;
38 double sx, sy;
39 struct sway_node *node = node_at_coords(seat,
40 cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
41 cursor_send_pointer_motion(cursor, 0, node, surface, sx, sy);
37 } 42 }
38} 43}
39 44
diff --git a/sway/server.c b/sway/server.c
index 43dc3900..82262585 100644
--- a/sway/server.c
+++ b/sway/server.c
@@ -10,11 +10,12 @@
10#include <wlr/types/wlr_compositor.h> 10#include <wlr/types/wlr_compositor.h>
11#include <wlr/types/wlr_data_control_v1.h> 11#include <wlr/types/wlr_data_control_v1.h>
12#include <wlr/types/wlr_export_dmabuf_v1.h> 12#include <wlr/types/wlr_export_dmabuf_v1.h>
13#include <wlr/types/wlr_gamma_control_v1.h>
14#include <wlr/types/wlr_gamma_control.h> 13#include <wlr/types/wlr_gamma_control.h>
14#include <wlr/types/wlr_gamma_control_v1.h>
15#include <wlr/types/wlr_gtk_primary_selection.h> 15#include <wlr/types/wlr_gtk_primary_selection.h>
16#include <wlr/types/wlr_idle.h> 16#include <wlr/types/wlr_idle.h>
17#include <wlr/types/wlr_layer_shell_v1.h> 17#include <wlr/types/wlr_layer_shell_v1.h>
18#include <wlr/types/wlr_pointer_constraints_v1.h>
18#include <wlr/types/wlr_screencopy_v1.h> 19#include <wlr/types/wlr_screencopy_v1.h>
19#include <wlr/types/wlr_server_decoration.h> 20#include <wlr/types/wlr_server_decoration.h>
20#include <wlr/types/wlr_xcursor_manager.h> 21#include <wlr/types/wlr_xcursor_manager.h>
@@ -105,6 +106,12 @@ bool server_init(struct sway_server *server) {
105 server->xdg_decoration.notify = handle_xdg_decoration; 106 server->xdg_decoration.notify = handle_xdg_decoration;
106 wl_list_init(&server->xdg_decorations); 107 wl_list_init(&server->xdg_decorations);
107 108
109 server->pointer_constraints =
110 wlr_pointer_constraints_v1_create(server->wl_display);
111 server->pointer_constraint.notify = handle_pointer_constraint;
112 wl_signal_add(&server->pointer_constraints->events.new_constraint,
113 &server->pointer_constraint);
114
108 server->presentation = 115 server->presentation =
109 wlr_presentation_create(server->wl_display, server->backend); 116 wlr_presentation_create(server->wl_display, server->backend);
110 117