aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/input/seat.h20
-rw-r--r--sway/input/cursor.c24
-rw-r--r--sway/input/seat.c27
3 files changed, 63 insertions, 8 deletions
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h
index 9dfb0714..5c404ecd 100644
--- a/include/sway/input/seat.h
+++ b/include/sway/input/seat.h
@@ -35,6 +35,14 @@ struct sway_drag_icon {
35 struct wl_listener destroy; 35 struct wl_listener destroy;
36}; 36};
37 37
38enum sway_seat_operation {
39 OP_NONE,
40 OP_DOWN,
41 OP_MOVE,
42 OP_RESIZE_FLOATING,
43 OP_RESIZE_TILING,
44};
45
38struct sway_seat { 46struct sway_seat {
39 struct wlr_seat *wlr_seat; 47 struct wlr_seat *wlr_seat;
40 struct sway_cursor *cursor; 48 struct sway_cursor *cursor;
@@ -54,13 +62,7 @@ struct sway_seat {
54 double touch_x, touch_y; 62 double touch_x, touch_y;
55 63
56 // Operations (drag and resize) 64 // Operations (drag and resize)
57 enum { 65 enum sway_seat_operation operation;
58 OP_NONE,
59 OP_MOVE,
60 OP_RESIZE_FLOATING,
61 OP_RESIZE_TILING,
62 } operation;
63
64 struct sway_container *op_container; 66 struct sway_container *op_container;
65 enum wlr_edges op_resize_edge; 67 enum wlr_edges op_resize_edge;
66 uint32_t op_button; 68 uint32_t op_button;
@@ -68,6 +70,7 @@ struct sway_seat {
68 double op_ref_lx, op_ref_ly; // cursor's x/y at start of op 70 double op_ref_lx, op_ref_ly; // cursor's x/y at start of op
69 double op_ref_width, op_ref_height; // container's size at start of op 71 double op_ref_width, op_ref_height; // container's size at start of op
70 double op_ref_con_lx, op_ref_con_ly; // container's x/y at start of op 72 double op_ref_con_lx, op_ref_con_ly; // container's x/y at start of op
73 bool op_moved; // if the mouse moved during a down op
71 74
72 uint32_t last_button; 75 uint32_t last_button;
73 uint32_t last_button_serial; 76 uint32_t last_button_serial;
@@ -157,6 +160,9 @@ bool seat_is_input_allowed(struct sway_seat *seat, struct wlr_surface *surface);
157 160
158void drag_icon_update_position(struct sway_drag_icon *icon); 161void drag_icon_update_position(struct sway_drag_icon *icon);
159 162
163void seat_begin_down(struct sway_seat *seat, struct sway_container *con,
164 uint32_t button, double sx, double sy);
165
160void seat_begin_move(struct sway_seat *seat, struct sway_container *con, 166void seat_begin_move(struct sway_seat *seat, struct sway_container *con,
161 uint32_t button); 167 uint32_t button);
162 168
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 6208ce32..762b8081 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -215,6 +215,19 @@ static enum wlr_edges find_resize_edge(struct sway_container *cont,
215 return edge; 215 return edge;
216} 216}
217 217
218static void handle_down_motion(struct sway_seat *seat,
219 struct sway_cursor *cursor, uint32_t time_msec) {
220 struct sway_container *con = seat->op_container;
221 if (seat_is_input_allowed(seat, con->sway_view->surface)) {
222 double moved_x = cursor->cursor->x - seat->op_ref_lx;
223 double moved_y = cursor->cursor->y - seat->op_ref_ly;
224 double sx = seat->op_ref_con_lx + moved_x;
225 double sy = seat->op_ref_con_ly + moved_y;
226 wlr_seat_pointer_notify_motion(seat->wlr_seat, time_msec, sx, sy);
227 }
228 seat->op_moved = true;
229}
230
218static void handle_move_motion(struct sway_seat *seat, 231static void handle_move_motion(struct sway_seat *seat,
219 struct sway_cursor *cursor) { 232 struct sway_cursor *cursor) {
220 struct sway_container *con = seat->op_container; 233 struct sway_container *con = seat->op_container;
@@ -397,6 +410,9 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
397 410
398 if (seat->operation != OP_NONE) { 411 if (seat->operation != OP_NONE) {
399 switch (seat->operation) { 412 switch (seat->operation) {
413 case OP_DOWN:
414 handle_down_motion(seat, cursor, time_msec);
415 break;
400 case OP_MOVE: 416 case OP_MOVE:
401 handle_move_motion(seat, cursor); 417 handle_move_motion(seat, cursor);
402 break; 418 break;
@@ -743,6 +759,14 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
743 } 759 }
744 } 760 }
745 761
762 // Handle mousedown on a container surface
763 if (surface && cont && state == WLR_BUTTON_PRESSED) {
764 seat_set_focus(seat, cont);
765 seat_pointer_notify_button(seat, time_msec, button, state);
766 seat_begin_down(seat, cont, button, sx, sy);
767 return;
768 }
769
746 // Handle clicking a container surface 770 // Handle clicking a container surface
747 if (cont) { 771 if (cont) {
748 seat_set_focus(seat, cont); 772 seat_set_focus(seat, cont);
diff --git a/sway/input/seat.c b/sway/input/seat.c
index fa41904a..9d46e760 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -954,6 +954,18 @@ struct seat_config *seat_get_config(struct sway_seat *seat) {
954 return NULL; 954 return NULL;
955} 955}
956 956
957void seat_begin_down(struct sway_seat *seat, struct sway_container *con,
958 uint32_t button, double sx, double sy) {
959 seat->operation = OP_DOWN;
960 seat->op_container = con;
961 seat->op_button = button;
962 seat->op_ref_lx = seat->cursor->cursor->x;
963 seat->op_ref_ly = seat->cursor->cursor->y;
964 seat->op_ref_con_lx = sx;
965 seat->op_ref_con_ly = sy;
966 seat->op_moved = false;
967}
968
957void seat_begin_move(struct sway_seat *seat, struct sway_container *con, 969void seat_begin_move(struct sway_seat *seat, struct sway_container *con,
958 uint32_t button) { 970 uint32_t button) {
959 if (!seat->cursor) { 971 if (!seat->cursor) {
@@ -1007,6 +1019,7 @@ void seat_begin_resize_tiling(struct sway_seat *seat,
1007} 1019}
1008 1020
1009void seat_end_mouse_operation(struct sway_seat *seat) { 1021void seat_end_mouse_operation(struct sway_seat *seat) {
1022 enum sway_seat_operation operation = seat->operation;
1010 if (seat->operation == OP_MOVE) { 1023 if (seat->operation == OP_MOVE) {
1011 // We "move" the container to its own location so it discovers its 1024 // We "move" the container to its own location so it discovers its
1012 // output again. 1025 // output again.
@@ -1015,7 +1028,19 @@ void seat_end_mouse_operation(struct sway_seat *seat) {
1015 } 1028 }
1016 seat->operation = OP_NONE; 1029 seat->operation = OP_NONE;
1017 seat->op_container = NULL; 1030 seat->op_container = NULL;
1018 cursor_set_image(seat->cursor, "left_ptr", NULL); 1031 if (operation == OP_DOWN) {
1032 // Set the cursor's previous coords to the x/y at the start of the
1033 // operation, so the container change will be detected if using
1034 // focus_follows_mouse and the cursor moved off the original container
1035 // during the operation.
1036 seat->cursor->previous.x = seat->op_ref_lx;
1037 seat->cursor->previous.y = seat->op_ref_ly;
1038 if (seat->op_moved) {
1039 cursor_send_pointer_motion(seat->cursor, 0, true);
1040 }
1041 } else {
1042 cursor_set_image(seat->cursor, "left_ptr", NULL);
1043 }
1019} 1044}
1020 1045
1021void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, 1046void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec,