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/input/cursor.c | |
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/input/cursor.c')
-rw-r--r-- | sway/input/cursor.c | 96 |
1 files changed, 56 insertions, 40 deletions
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 | ||