From a36625a482585e86d465df1eaa3669c1c4390a20 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Wed, 15 Aug 2018 16:47:02 +1000 Subject: [PATCH 1/3] Implement mousedown operation This allows you to move the cursor off the surface while dragging its scrollbar. --- include/sway/input/seat.h | 4 ++++ sway/input/cursor.c | 23 +++++++++++++++++++++++ sway/input/seat.c | 24 +++++++++++++++++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index 9dfb0714e..fb03b609b 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h @@ -56,6 +56,7 @@ struct sway_seat { // Operations (drag and resize) enum { OP_NONE, + OP_MOUSEDOWN, OP_MOVE, OP_RESIZE_FLOATING, OP_RESIZE_TILING, @@ -157,6 +158,9 @@ bool seat_is_input_allowed(struct sway_seat *seat, struct wlr_surface *surface); void drag_icon_update_position(struct sway_drag_icon *icon); +void seat_begin_mousedown(struct sway_seat *seat, struct sway_container *con, + uint32_t button, double sx, double sy); + void seat_begin_move(struct sway_seat *seat, struct sway_container *con, uint32_t button); diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 3b70b4713..bd0030f0d 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -215,6 +215,18 @@ static enum wlr_edges find_resize_edge(struct sway_container *cont, return edge; } +static void handle_mousedown_motion(struct sway_seat *seat, + struct sway_cursor *cursor, uint32_t time_msec) { + struct sway_container *con = seat->op_container; + if (seat_is_input_allowed(seat, con->sway_view->surface)) { + double moved_x = cursor->cursor->x - seat->op_ref_lx; + double moved_y = cursor->cursor->y - seat->op_ref_ly; + double sx = seat->op_ref_con_lx + moved_x; + double sy = seat->op_ref_con_ly + moved_y; + wlr_seat_pointer_notify_motion(seat->wlr_seat, time_msec, sx, sy); + } +} + static void handle_move_motion(struct sway_seat *seat, struct sway_cursor *cursor) { struct sway_container *con = seat->op_container; @@ -397,6 +409,9 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, if (seat->operation != OP_NONE) { switch (seat->operation) { + case OP_MOUSEDOWN: + handle_mousedown_motion(seat, cursor, time_msec); + break; case OP_MOVE: handle_move_motion(seat, cursor); break; @@ -743,6 +758,14 @@ void dispatch_cursor_button(struct sway_cursor *cursor, } } + // Handle mousedown on a container surface + if (surface && cont && state == WLR_BUTTON_PRESSED) { + seat_set_focus(seat, cont); + seat_pointer_notify_button(seat, time_msec, button, state); + seat_begin_mousedown(seat, cont, button, sx, sy); + return; + } + // Handle clicking a container surface if (cont) { seat_set_focus(seat, cont); diff --git a/sway/input/seat.c b/sway/input/seat.c index fa41904a1..045bf91a6 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -954,6 +954,17 @@ struct seat_config *seat_get_config(struct sway_seat *seat) { return NULL; } +void seat_begin_mousedown(struct sway_seat *seat, struct sway_container *con, + uint32_t button, double sx, double sy) { + seat->operation = OP_MOUSEDOWN; + seat->op_container = con; + seat->op_button = button; + seat->op_ref_lx = seat->cursor->cursor->x; + seat->op_ref_ly = seat->cursor->cursor->y; + seat->op_ref_con_lx = sx; + seat->op_ref_con_ly = sy; +} + void seat_begin_move(struct sway_seat *seat, struct sway_container *con, uint32_t button) { if (!seat->cursor) { @@ -1007,6 +1018,7 @@ void seat_begin_resize_tiling(struct sway_seat *seat, } void seat_end_mouse_operation(struct sway_seat *seat) { + int operation = seat->operation; if (seat->operation == OP_MOVE) { // We "move" the container to its own location so it discovers its // output again. @@ -1015,7 +1027,17 @@ void seat_end_mouse_operation(struct sway_seat *seat) { } seat->operation = OP_NONE; seat->op_container = NULL; - cursor_set_image(seat->cursor, "left_ptr", NULL); + if (operation == OP_MOUSEDOWN) { + // Set the cursor's previous coords to the x/y at the start of the + // operation, so the container change will be detected if using + // focus_follows_mouse and the cursor moved off the original container + // during the operation. + seat->cursor->previous.x = seat->op_ref_lx; + seat->cursor->previous.y = seat->op_ref_ly; + cursor_send_pointer_motion(seat->cursor, 0, true); + } else { + cursor_set_image(seat->cursor, "left_ptr", NULL); + } } void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, From b637b61a7a25219991280717d9bf8a463ed4d8a8 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 16 Aug 2018 09:12:48 +1000 Subject: [PATCH 2/3] Rename mousedown to down and make seat operation a named enum --- include/sway/input/seat.h | 19 ++++++++++--------- sway/input/cursor.c | 8 ++++---- sway/input/seat.c | 8 ++++---- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index fb03b609b..c07db61c1 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h @@ -35,6 +35,14 @@ struct sway_drag_icon { struct wl_listener destroy; }; +enum sway_seat_operation { + OP_NONE, + OP_DOWN, + OP_MOVE, + OP_RESIZE_FLOATING, + OP_RESIZE_TILING, +}; + struct sway_seat { struct wlr_seat *wlr_seat; struct sway_cursor *cursor; @@ -54,14 +62,7 @@ struct sway_seat { double touch_x, touch_y; // Operations (drag and resize) - enum { - OP_NONE, - OP_MOUSEDOWN, - OP_MOVE, - OP_RESIZE_FLOATING, - OP_RESIZE_TILING, - } operation; - + enum sway_seat_operation operation; struct sway_container *op_container; enum wlr_edges op_resize_edge; uint32_t op_button; @@ -158,7 +159,7 @@ bool seat_is_input_allowed(struct sway_seat *seat, struct wlr_surface *surface); void drag_icon_update_position(struct sway_drag_icon *icon); -void seat_begin_mousedown(struct sway_seat *seat, struct sway_container *con, +void seat_begin_down(struct sway_seat *seat, struct sway_container *con, uint32_t button, double sx, double sy); void seat_begin_move(struct sway_seat *seat, struct sway_container *con, diff --git a/sway/input/cursor.c b/sway/input/cursor.c index bd0030f0d..5a2743e33 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -215,7 +215,7 @@ static enum wlr_edges find_resize_edge(struct sway_container *cont, return edge; } -static void handle_mousedown_motion(struct sway_seat *seat, +static void handle_down_motion(struct sway_seat *seat, struct sway_cursor *cursor, uint32_t time_msec) { struct sway_container *con = seat->op_container; if (seat_is_input_allowed(seat, con->sway_view->surface)) { @@ -409,8 +409,8 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, if (seat->operation != OP_NONE) { switch (seat->operation) { - case OP_MOUSEDOWN: - handle_mousedown_motion(seat, cursor, time_msec); + case OP_DOWN: + handle_down_motion(seat, cursor, time_msec); break; case OP_MOVE: handle_move_motion(seat, cursor); @@ -762,7 +762,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor, if (surface && cont && state == WLR_BUTTON_PRESSED) { seat_set_focus(seat, cont); seat_pointer_notify_button(seat, time_msec, button, state); - seat_begin_mousedown(seat, cont, button, sx, sy); + seat_begin_down(seat, cont, button, sx, sy); return; } diff --git a/sway/input/seat.c b/sway/input/seat.c index 045bf91a6..cc7c28d8a 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -954,9 +954,9 @@ struct seat_config *seat_get_config(struct sway_seat *seat) { return NULL; } -void seat_begin_mousedown(struct sway_seat *seat, struct sway_container *con, +void seat_begin_down(struct sway_seat *seat, struct sway_container *con, uint32_t button, double sx, double sy) { - seat->operation = OP_MOUSEDOWN; + seat->operation = OP_DOWN; seat->op_container = con; seat->op_button = button; seat->op_ref_lx = seat->cursor->cursor->x; @@ -1018,7 +1018,7 @@ void seat_begin_resize_tiling(struct sway_seat *seat, } void seat_end_mouse_operation(struct sway_seat *seat) { - int operation = seat->operation; + enum sway_seat_operation operation = seat->operation; if (seat->operation == OP_MOVE) { // We "move" the container to its own location so it discovers its // output again. @@ -1027,7 +1027,7 @@ void seat_end_mouse_operation(struct sway_seat *seat) { } seat->operation = OP_NONE; seat->op_container = NULL; - if (operation == OP_MOUSEDOWN) { + if (operation == OP_DOWN) { // Set the cursor's previous coords to the x/y at the start of the // operation, so the container change will be detected if using // focus_follows_mouse and the cursor moved off the original container From 07a897b3b797b99022a9dfffffc0af2ff50aea85 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 18 Aug 2018 09:29:18 +1000 Subject: [PATCH 3/3] Don't send motion if the cursor hasn't moved Prevents GTK+ comboboxes from immediately closing. --- include/sway/input/seat.h | 1 + sway/input/cursor.c | 1 + sway/input/seat.c | 5 ++++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index c07db61c1..5c404ecd3 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h @@ -70,6 +70,7 @@ struct sway_seat { double op_ref_lx, op_ref_ly; // cursor's x/y at start of op double op_ref_width, op_ref_height; // container's size at start of op double op_ref_con_lx, op_ref_con_ly; // container's x/y at start of op + bool op_moved; // if the mouse moved during a down op uint32_t last_button; uint32_t last_button_serial; diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 5a2743e33..37fb203d8 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -225,6 +225,7 @@ static void handle_down_motion(struct sway_seat *seat, double sy = seat->op_ref_con_ly + moved_y; wlr_seat_pointer_notify_motion(seat->wlr_seat, time_msec, sx, sy); } + seat->op_moved = true; } static void handle_move_motion(struct sway_seat *seat, diff --git a/sway/input/seat.c b/sway/input/seat.c index cc7c28d8a..9d46e7601 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -963,6 +963,7 @@ void seat_begin_down(struct sway_seat *seat, struct sway_container *con, seat->op_ref_ly = seat->cursor->cursor->y; seat->op_ref_con_lx = sx; seat->op_ref_con_ly = sy; + seat->op_moved = false; } void seat_begin_move(struct sway_seat *seat, struct sway_container *con, @@ -1034,7 +1035,9 @@ void seat_end_mouse_operation(struct sway_seat *seat) { // during the operation. seat->cursor->previous.x = seat->op_ref_lx; seat->cursor->previous.y = seat->op_ref_ly; - cursor_send_pointer_motion(seat->cursor, 0, true); + if (seat->op_moved) { + cursor_send_pointer_motion(seat->cursor, 0, true); + } } else { cursor_set_image(seat->cursor, "left_ptr", NULL); }