summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-10-19 00:04:21 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-10-19 22:47:54 +1000
commit9ea71f292b2270f37cf7ca641b7bae628ef41ed7 (patch)
treefbeb938d3bb175013a0224e95ab50bdf0a678ae8
parentMerge pull request #2882 from RyanDwyer/fix-mouse-warp-logic (diff)
downloadsway-9ea71f292b2270f37cf7ca641b7bae628ef41ed7.tar.gz
sway-9ea71f292b2270f37cf7ca641b7bae628ef41ed7.tar.zst
sway-9ea71f292b2270f37cf7ca641b7bae628ef41ed7.zip
Introduce cursor_rebase
This function "rebases" the cursor on top of whatever is underneath it, without triggering any focus changes.
-rw-r--r--include/sway/input/cursor.h16
-rw-r--r--sway/commands/border.c2
-rw-r--r--sway/commands/focus.c2
-rw-r--r--sway/commands/seat/cursor.c4
-rw-r--r--sway/input/cursor.c96
-rw-r--r--sway/input/seat.c4
-rw-r--r--sway/tree/view.c3
-rw-r--r--sway/tree/workspace.c2
8 files changed, 78 insertions, 51 deletions
diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h
index 299721f0..50ac453b 100644
--- a/include/sway/input/cursor.h
+++ b/include/sway/input/cursor.h
@@ -40,8 +40,20 @@ struct sway_cursor {
40 40
41void sway_cursor_destroy(struct sway_cursor *cursor); 41void sway_cursor_destroy(struct sway_cursor *cursor);
42struct sway_cursor *sway_cursor_create(struct sway_seat *seat); 42struct sway_cursor *sway_cursor_create(struct sway_seat *seat);
43void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, 43
44 bool allow_refocusing); 44/**
45 * "Rebase" a cursor on top of whatever view is underneath it.
46 *
47 * This chooses a cursor icon and sends a motion event to the surface.
48 */
49void cursor_rebase(struct sway_cursor *cursor);
50
51/**
52 * Like cursor_rebase, but also allows focus to change when the cursor enters a
53 * new container.
54 */
55void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec);
56
45void dispatch_cursor_button(struct sway_cursor *cursor, 57void dispatch_cursor_button(struct sway_cursor *cursor,
46 struct wlr_input_device *device, uint32_t time_msec, uint32_t button, 58 struct wlr_input_device *device, uint32_t time_msec, uint32_t button,
47 enum wlr_button_state state); 59 enum wlr_button_state state);
diff --git a/sway/commands/border.c b/sway/commands/border.c
index 2eed27bd..a50f7a1c 100644
--- a/sway/commands/border.c
+++ b/sway/commands/border.c
@@ -96,7 +96,7 @@ struct cmd_results *cmd_border(int argc, char **argv) {
96 96
97 struct sway_seat *seat = input_manager_current_seat(input_manager); 97 struct sway_seat *seat = input_manager_current_seat(input_manager);
98 if (seat->cursor) { 98 if (seat->cursor) {
99 cursor_send_pointer_motion(seat->cursor, 0, false); 99 cursor_rebase(seat->cursor);
100 } 100 }
101 101
102 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 102 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
diff --git a/sway/commands/focus.c b/sway/commands/focus.c
index b6f29fec..7dfa8814 100644
--- a/sway/commands/focus.c
+++ b/sway/commands/focus.c
@@ -236,7 +236,7 @@ struct cmd_results *cmd_focus(int argc, char **argv) {
236 if (argc == 0 && container) { 236 if (argc == 0 && container) {
237 seat_set_focus_container(seat, container); 237 seat_set_focus_container(seat, container);
238 seat_consider_warp_to_focus(seat); 238 seat_consider_warp_to_focus(seat);
239 cursor_send_pointer_motion(seat->cursor, 0, true); 239 cursor_rebase(seat->cursor);
240 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 240 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
241 } 241 }
242 242
diff --git a/sway/commands/seat/cursor.c b/sway/commands/seat/cursor.c
index 595e9bc6..1d41a94e 100644
--- a/sway/commands/seat/cursor.c
+++ b/sway/commands/seat/cursor.c
@@ -36,7 +36,7 @@ struct cmd_results *seat_cmd_cursor(int argc, char **argv) {
36 int delta_x = strtol(argv[1], NULL, 10); 36 int delta_x = strtol(argv[1], NULL, 10);
37 int delta_y = strtol(argv[2], NULL, 10); 37 int delta_y = strtol(argv[2], NULL, 10);
38 wlr_cursor_move(cursor->cursor, NULL, delta_x, delta_y); 38 wlr_cursor_move(cursor->cursor, NULL, delta_x, delta_y);
39 cursor_send_pointer_motion(cursor, 0, true); 39 cursor_rebase(cursor);
40 } else if (strcasecmp(argv[0], "set") == 0) { 40 } else if (strcasecmp(argv[0], "set") == 0) {
41 if (argc < 3) { 41 if (argc < 3) {
42 return cmd_results_new(CMD_INVALID, "cursor", expected_syntax); 42 return cmd_results_new(CMD_INVALID, "cursor", expected_syntax);
@@ -45,7 +45,7 @@ struct cmd_results *seat_cmd_cursor(int argc, char **argv) {
45 float x = strtof(argv[1], NULL) / root->width; 45 float x = strtof(argv[1], NULL) / root->width;
46 float y = strtof(argv[2], NULL) / root->height; 46 float y = strtof(argv[2], NULL) / root->height;
47 wlr_cursor_warp_absolute(cursor->cursor, NULL, x, y); 47 wlr_cursor_warp_absolute(cursor->cursor, NULL, x, y);
48 cursor_send_pointer_motion(cursor, 0, true); 48 cursor_rebase(cursor);
49 } else { 49 } else {
50 if (argc < 2) { 50 if (argc < 2) {
51 return cmd_results_new(CMD_INVALID, "cursor", expected_syntax); 51 return cmd_results_new(CMD_INVALID, "cursor", expected_syntax);
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 7ac5013d..756f2f8c 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -543,8 +543,57 @@ static void handle_resize_tiling_motion(struct sway_seat *seat,
543 } 543 }
544} 544}
545 545
546void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, 546static void cursor_do_rebase(struct sway_cursor *cursor, uint32_t time_msec,
547 bool allow_refocusing) { 547 struct sway_node *node, struct wlr_surface *surface,
548 double sx, double sy) {
549 // Handle cursor image
550 if (surface) {
551 // Reset cursor if switching between clients
552 struct wl_client *client = wl_resource_get_client(surface->resource);
553 if (client != cursor->image_client) {
554 cursor_set_image(cursor, "left_ptr", client);
555 }
556 } else if (node && node->type == N_CONTAINER) {
557 // Try a node's resize edge
558 enum wlr_edges edge = find_resize_edge(node->sway_container, cursor);
559 if (edge == WLR_EDGE_NONE) {
560 cursor_set_image(cursor, "left_ptr", NULL);
561 } else if (container_is_floating(node->sway_container)) {
562 cursor_set_image(cursor, wlr_xcursor_get_resize_name(edge), NULL);
563 } else {
564 if (edge & (WLR_EDGE_LEFT | WLR_EDGE_RIGHT)) {
565 cursor_set_image(cursor, "col-resize", NULL);
566 } else {
567 cursor_set_image(cursor, "row-resize", NULL);
568 }
569 }
570 } else {
571 cursor_set_image(cursor, "left_ptr", NULL);
572 }
573
574 // Send pointer enter/leave
575 struct wlr_seat *wlr_seat = cursor->seat->wlr_seat;
576 if (surface) {
577 if (seat_is_input_allowed(cursor->seat, surface)) {
578 wlr_seat_pointer_notify_enter(wlr_seat, surface, sx, sy);
579 wlr_seat_pointer_notify_motion(wlr_seat, time_msec, sx, sy);
580 }
581 } else {
582 wlr_seat_pointer_clear_focus(wlr_seat);
583 }
584}
585
586void cursor_rebase(struct sway_cursor *cursor) {
587 uint32_t time_msec = get_current_time_msec();
588 struct wlr_surface *surface;
589 double sx, sy;
590 cursor->previous.node = node_at_coords(cursor->seat,
591 cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
592 cursor_do_rebase(cursor, time_msec, cursor->previous.node, surface, sx, sy);
593}
594
595void cursor_send_pointer_motion(struct sway_cursor *cursor,
596 uint32_t time_msec) {
548 if (time_msec == 0) { 597 if (time_msec == 0) {
549 time_msec = get_current_time_msec(); 598 time_msec = get_current_time_msec();
550 } 599 }
@@ -589,7 +638,7 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
589 cursor->previous.y = cursor->cursor->y; 638 cursor->previous.y = cursor->cursor->y;
590 cursor->previous.node = node; 639 cursor->previous.node = node;
591 640
592 if (node && config->focus_follows_mouse && allow_refocusing) { 641 if (node && config->focus_follows_mouse) {
593 struct sway_node *focus = seat_get_focus(seat); 642 struct sway_node *focus = seat_get_focus(seat);
594 if (focus && node->type == N_WORKSPACE) { 643 if (focus && node->type == N_WORKSPACE) {
595 // Only follow the mouse if it would move to a new output 644 // Only follow the mouse if it would move to a new output
@@ -620,40 +669,7 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
620 } 669 }
621 } 670 }
622 671
623 // Handle cursor image 672 cursor_do_rebase(cursor, time_msec, node, surface, sx, sy);
624 if (surface) {
625 // Reset cursor if switching between clients
626 struct wl_client *client = wl_resource_get_client(surface->resource);
627 if (client != cursor->image_client) {
628 cursor_set_image(cursor, "left_ptr", client);
629 }
630 } else if (node && node->type == N_CONTAINER) {
631 // Try a node's resize edge
632 enum wlr_edges edge = find_resize_edge(node->sway_container, cursor);
633 if (edge == WLR_EDGE_NONE) {
634 cursor_set_image(cursor, "left_ptr", NULL);
635 } else if (container_is_floating(node->sway_container)) {
636 cursor_set_image(cursor, wlr_xcursor_get_resize_name(edge), NULL);
637 } else {
638 if (edge & (WLR_EDGE_LEFT | WLR_EDGE_RIGHT)) {
639 cursor_set_image(cursor, "col-resize", NULL);
640 } else {
641 cursor_set_image(cursor, "row-resize", NULL);
642 }
643 }
644 } else {
645 cursor_set_image(cursor, "left_ptr", NULL);
646 }
647
648 // send pointer enter/leave
649 if (surface != NULL) {
650 if (seat_is_input_allowed(seat, surface)) {
651 wlr_seat_pointer_notify_enter(wlr_seat, surface, sx, sy);
652 wlr_seat_pointer_notify_motion(wlr_seat, time_msec, sx, sy);
653 }
654 } else {
655 wlr_seat_pointer_clear_focus(wlr_seat);
656 }
657 673
658 struct wlr_drag_icon *wlr_drag_icon; 674 struct wlr_drag_icon *wlr_drag_icon;
659 wl_list_for_each(wlr_drag_icon, &wlr_seat->drag_icons, link) { 675 wl_list_for_each(wlr_drag_icon, &wlr_seat->drag_icons, link) {
@@ -668,7 +684,7 @@ static void handle_cursor_motion(struct wl_listener *listener, void *data) {
668 struct wlr_event_pointer_motion *event = data; 684 struct wlr_event_pointer_motion *event = data;
669 wlr_cursor_move(cursor->cursor, event->device, 685 wlr_cursor_move(cursor->cursor, event->device,
670 event->delta_x, event->delta_y); 686 event->delta_x, event->delta_y);
671 cursor_send_pointer_motion(cursor, event->time_msec, true); 687 cursor_send_pointer_motion(cursor, event->time_msec);
672 transaction_commit_dirty(); 688 transaction_commit_dirty();
673} 689}
674 690
@@ -679,7 +695,7 @@ static void handle_cursor_motion_absolute(
679 wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat); 695 wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat);
680 struct wlr_event_pointer_motion_absolute *event = data; 696 struct wlr_event_pointer_motion_absolute *event = data;
681 wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y); 697 wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y);
682 cursor_send_pointer_motion(cursor, event->time_msec, true); 698 cursor_send_pointer_motion(cursor, event->time_msec);
683 transaction_commit_dirty(); 699 transaction_commit_dirty();
684} 700}
685 701
@@ -1134,7 +1150,7 @@ static void handle_tool_axis(struct wl_listener *listener, void *data) {
1134 } 1150 }
1135 1151
1136 wlr_cursor_warp_absolute(cursor->cursor, event->device, x, y); 1152 wlr_cursor_warp_absolute(cursor->cursor, event->device, x, y);
1137 cursor_send_pointer_motion(cursor, event->time_msec, true); 1153 cursor_send_pointer_motion(cursor, event->time_msec);
1138 transaction_commit_dirty(); 1154 transaction_commit_dirty();
1139} 1155}
1140 1156
diff --git a/sway/input/seat.c b/sway/input/seat.c
index cffceaae..25f454bd 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -1173,7 +1173,7 @@ void seat_end_mouse_operation(struct sway_seat *seat) {
1173 seat->cursor->previous.x = seat->op_ref_lx; 1173 seat->cursor->previous.x = seat->op_ref_lx;
1174 seat->cursor->previous.y = seat->op_ref_ly; 1174 seat->cursor->previous.y = seat->op_ref_ly;
1175 if (seat->op_moved) { 1175 if (seat->op_moved) {
1176 cursor_send_pointer_motion(seat->cursor, 0, true); 1176 cursor_send_pointer_motion(seat->cursor, 0);
1177 } 1177 }
1178 } else { 1178 } else {
1179 cursor_set_image(seat->cursor, "left_ptr", NULL); 1179 cursor_set_image(seat->cursor, "left_ptr", NULL);
@@ -1207,5 +1207,5 @@ void seat_consider_warp_to_focus(struct sway_seat *seat) {
1207 } else { 1207 } else {
1208 cursor_warp_to_workspace(seat->cursor, focus->sway_workspace); 1208 cursor_warp_to_workspace(seat->cursor, focus->sway_workspace);
1209 } 1209 }
1210 cursor_send_pointer_motion(seat->cursor, 0, false); 1210 cursor_rebase(seat->cursor);
1211} 1211}
diff --git a/sway/tree/view.c b/sway/tree/view.c
index 85998547..43a9d510 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -653,9 +653,8 @@ void view_unmap(struct sway_view *view) {
653 } else if (node && node->type == N_WORKSPACE) { 653 } else if (node && node->type == N_WORKSPACE) {
654 cursor_warp_to_workspace(seat->cursor, node->sway_workspace); 654 cursor_warp_to_workspace(seat->cursor, node->sway_workspace);
655 } 655 }
656 } else {
657 cursor_send_pointer_motion(seat->cursor, 0, true);
658 } 656 }
657 cursor_rebase(seat->cursor);
659 } 658 }
660 659
661 transaction_commit_dirty(); 660 transaction_commit_dirty();
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index a1282c1e..2a00824d 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -399,7 +399,7 @@ bool workspace_switch(struct sway_workspace *workspace,
399 } 399 }
400 seat_set_focus(seat, next); 400 seat_set_focus(seat, next);
401 arrange_workspace(workspace); 401 arrange_workspace(workspace);
402 cursor_send_pointer_motion(seat->cursor, 0, true); 402 cursor_rebase(seat->cursor);
403 return true; 403 return true;
404} 404}
405 405