diff options
Diffstat (limited to 'sway/input/seatop_down.c')
-rw-r--r-- | sway/input/seatop_down.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/sway/input/seatop_down.c b/sway/input/seatop_down.c new file mode 100644 index 00000000..ad11c5ca --- /dev/null +++ b/sway/input/seatop_down.c | |||
@@ -0,0 +1,77 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <wlr/types/wlr_cursor.h> | ||
3 | #include "sway/input/cursor.h" | ||
4 | #include "sway/input/seat.h" | ||
5 | #include "sway/tree/view.h" | ||
6 | |||
7 | struct seatop_down_event { | ||
8 | struct sway_container *con; | ||
9 | double ref_lx, ref_ly; // cursor's x/y at start of op | ||
10 | double ref_con_lx, ref_con_ly; // container's x/y at start of op | ||
11 | bool moved; | ||
12 | }; | ||
13 | |||
14 | static void handle_motion(struct sway_seat *seat, uint32_t time_msec) { | ||
15 | struct seatop_down_event *e = seat->seatop_data; | ||
16 | struct sway_container *con = e->con; | ||
17 | if (seat_is_input_allowed(seat, con->view->surface)) { | ||
18 | double moved_x = seat->cursor->cursor->x - e->ref_lx; | ||
19 | double moved_y = seat->cursor->cursor->y - e->ref_ly; | ||
20 | double sx = e->ref_con_lx + moved_x; | ||
21 | double sy = e->ref_con_ly + moved_y; | ||
22 | wlr_seat_pointer_notify_motion(seat->wlr_seat, time_msec, sx, sy); | ||
23 | } | ||
24 | e->moved = true; | ||
25 | } | ||
26 | |||
27 | static void handle_finish(struct sway_seat *seat) { | ||
28 | struct seatop_down_event *e = seat->seatop_data; | ||
29 | // 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 | // focus_follows_mouse and the cursor moved off the original container | ||
32 | // during the operation. | ||
33 | seat->cursor->previous.x = e->ref_lx; | ||
34 | seat->cursor->previous.y = e->ref_ly; | ||
35 | if (e->moved) { | ||
36 | cursor_send_pointer_motion(seat->cursor, 0); | ||
37 | } | ||
38 | } | ||
39 | |||
40 | static void handle_abort(struct sway_seat *seat) { | ||
41 | cursor_set_image(seat->cursor, "left_ptr", NULL); | ||
42 | } | ||
43 | |||
44 | static void handle_unref(struct sway_seat *seat, struct sway_container *con) { | ||
45 | struct seatop_down_event *e = seat->seatop_data; | ||
46 | if (e->con == con) { | ||
47 | seatop_abort(seat); | ||
48 | } | ||
49 | } | ||
50 | |||
51 | static const struct sway_seatop_impl seatop_impl = { | ||
52 | .motion = handle_motion, | ||
53 | .finish = handle_finish, | ||
54 | .abort = handle_abort, | ||
55 | .unref = handle_unref, | ||
56 | }; | ||
57 | |||
58 | void seatop_begin_down(struct sway_seat *seat, | ||
59 | struct sway_container *con, uint32_t button, int sx, int sy) { | ||
60 | seatop_abort(seat); | ||
61 | |||
62 | struct seatop_down_event *e = | ||
63 | calloc(1, sizeof(struct seatop_down_event)); | ||
64 | if (!e) { | ||
65 | return; | ||
66 | } | ||
67 | e->con = con; | ||
68 | e->ref_lx = seat->cursor->cursor->x; | ||
69 | e->ref_ly = seat->cursor->cursor->y; | ||
70 | e->ref_con_lx = sx; | ||
71 | e->ref_con_ly = sy; | ||
72 | e->moved = false; | ||
73 | |||
74 | seat->seatop_impl = &seatop_impl; | ||
75 | seat->seatop_data = e; | ||
76 | seat->seatop_button = button; | ||
77 | } | ||