diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-10-19 00:04:21 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-10-19 22:47:54 +1000 |
commit | 9ea71f292b2270f37cf7ca641b7bae628ef41ed7 (patch) | |
tree | fbeb938d3bb175013a0224e95ab50bdf0a678ae8 /sway | |
parent | Merge pull request #2882 from RyanDwyer/fix-mouse-warp-logic (diff) | |
download | sway-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.
Diffstat (limited to 'sway')
-rw-r--r-- | sway/commands/border.c | 2 | ||||
-rw-r--r-- | sway/commands/focus.c | 2 | ||||
-rw-r--r-- | sway/commands/seat/cursor.c | 4 | ||||
-rw-r--r-- | sway/input/cursor.c | 96 | ||||
-rw-r--r-- | sway/input/seat.c | 4 | ||||
-rw-r--r-- | sway/tree/view.c | 3 | ||||
-rw-r--r-- | sway/tree/workspace.c | 2 |
7 files changed, 64 insertions, 49 deletions
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 | ||
546 | void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, | 546 | static 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 | |||
586 | void 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 | |||
595 | void 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 | ||