diff options
author | Florian Franzen <Florian.Franzen@gmail.com> | 2022-04-23 10:27:47 +0200 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2022-05-30 12:20:43 +0200 |
commit | cab2189aa64d04ba79dc2cbf19400435b47cdbd2 (patch) | |
tree | 450ac51fbc75c73ed1dc6728bc05b08366ace785 /sway/input | |
parent | Add a Hindi (हिन्दी) translation to the README (diff) | |
download | sway-cab2189aa64d04ba79dc2cbf19400435b47cdbd2.tar.gz sway-cab2189aa64d04ba79dc2cbf19400435b47cdbd2.tar.zst sway-cab2189aa64d04ba79dc2cbf19400435b47cdbd2.zip |
sway: add bindgesture command
Co-authored-by: Michael Weiser <michael.weiser@gmx.de>
Diffstat (limited to 'sway/input')
-rw-r--r-- | sway/input/cursor.c | 89 | ||||
-rw-r--r-- | sway/input/seat.c | 56 | ||||
-rw-r--r-- | sway/input/seatop_default.c | 310 |
3 files changed, 403 insertions, 52 deletions
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 0b2f03a2..e87594ee 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -928,14 +928,28 @@ static void handle_request_pointer_set_cursor(struct wl_listener *listener, | |||
928 | event->hotspot_y, focused_client); | 928 | event->hotspot_y, focused_client); |
929 | } | 929 | } |
930 | 930 | ||
931 | static void handle_pointer_hold_begin(struct wl_listener *listener, void *data) { | ||
932 | struct sway_cursor *cursor = wl_container_of( | ||
933 | listener, cursor, hold_begin); | ||
934 | struct wlr_pointer_hold_begin_event *event = data; | ||
935 | cursor_handle_activity_from_device(cursor, &event->pointer->base); | ||
936 | seatop_hold_begin(cursor->seat, event); | ||
937 | } | ||
938 | |||
939 | static void handle_pointer_hold_end(struct wl_listener *listener, void *data) { | ||
940 | struct sway_cursor *cursor = wl_container_of( | ||
941 | listener, cursor, hold_end); | ||
942 | struct wlr_pointer_hold_end_event *event = data; | ||
943 | cursor_handle_activity_from_device(cursor, &event->pointer->base); | ||
944 | seatop_hold_end(cursor->seat, event); | ||
945 | } | ||
946 | |||
931 | static void handle_pointer_pinch_begin(struct wl_listener *listener, void *data) { | 947 | static void handle_pointer_pinch_begin(struct wl_listener *listener, void *data) { |
932 | struct sway_cursor *cursor = wl_container_of( | 948 | struct sway_cursor *cursor = wl_container_of( |
933 | listener, cursor, pinch_begin); | 949 | listener, cursor, pinch_begin); |
934 | struct wlr_pointer_pinch_begin_event *event = data; | 950 | struct wlr_pointer_pinch_begin_event *event = data; |
935 | cursor_handle_activity_from_device(cursor, &event->pointer->base); | 951 | cursor_handle_activity_from_device(cursor, &event->pointer->base); |
936 | wlr_pointer_gestures_v1_send_pinch_begin( | 952 | seatop_pinch_begin(cursor->seat, event); |
937 | cursor->pointer_gestures, cursor->seat->wlr_seat, | ||
938 | event->time_msec, event->fingers); | ||
939 | } | 953 | } |
940 | 954 | ||
941 | static void handle_pointer_pinch_update(struct wl_listener *listener, void *data) { | 955 | static void handle_pointer_pinch_update(struct wl_listener *listener, void *data) { |
@@ -943,10 +957,7 @@ static void handle_pointer_pinch_update(struct wl_listener *listener, void *data | |||
943 | listener, cursor, pinch_update); | 957 | listener, cursor, pinch_update); |
944 | struct wlr_pointer_pinch_update_event *event = data; | 958 | struct wlr_pointer_pinch_update_event *event = data; |
945 | cursor_handle_activity_from_device(cursor, &event->pointer->base); | 959 | cursor_handle_activity_from_device(cursor, &event->pointer->base); |
946 | wlr_pointer_gestures_v1_send_pinch_update( | 960 | seatop_pinch_update(cursor->seat, event); |
947 | cursor->pointer_gestures, cursor->seat->wlr_seat, | ||
948 | event->time_msec, event->dx, event->dy, | ||
949 | event->scale, event->rotation); | ||
950 | } | 961 | } |
951 | 962 | ||
952 | static void handle_pointer_pinch_end(struct wl_listener *listener, void *data) { | 963 | static void handle_pointer_pinch_end(struct wl_listener *listener, void *data) { |
@@ -954,9 +965,7 @@ static void handle_pointer_pinch_end(struct wl_listener *listener, void *data) { | |||
954 | listener, cursor, pinch_end); | 965 | listener, cursor, pinch_end); |
955 | struct wlr_pointer_pinch_end_event *event = data; | 966 | struct wlr_pointer_pinch_end_event *event = data; |
956 | cursor_handle_activity_from_device(cursor, &event->pointer->base); | 967 | cursor_handle_activity_from_device(cursor, &event->pointer->base); |
957 | wlr_pointer_gestures_v1_send_pinch_end( | 968 | seatop_pinch_end(cursor->seat, event); |
958 | cursor->pointer_gestures, cursor->seat->wlr_seat, | ||
959 | event->time_msec, event->cancelled); | ||
960 | } | 969 | } |
961 | 970 | ||
962 | static void handle_pointer_swipe_begin(struct wl_listener *listener, void *data) { | 971 | static void handle_pointer_swipe_begin(struct wl_listener *listener, void *data) { |
@@ -964,9 +973,7 @@ static void handle_pointer_swipe_begin(struct wl_listener *listener, void *data) | |||
964 | listener, cursor, swipe_begin); | 973 | listener, cursor, swipe_begin); |
965 | struct wlr_pointer_swipe_begin_event *event = data; | 974 | struct wlr_pointer_swipe_begin_event *event = data; |
966 | cursor_handle_activity_from_device(cursor, &event->pointer->base); | 975 | cursor_handle_activity_from_device(cursor, &event->pointer->base); |
967 | wlr_pointer_gestures_v1_send_swipe_begin( | 976 | seatop_swipe_begin(cursor->seat, event); |
968 | cursor->pointer_gestures, cursor->seat->wlr_seat, | ||
969 | event->time_msec, event->fingers); | ||
970 | } | 977 | } |
971 | 978 | ||
972 | static void handle_pointer_swipe_update(struct wl_listener *listener, void *data) { | 979 | static void handle_pointer_swipe_update(struct wl_listener *listener, void *data) { |
@@ -974,9 +981,7 @@ static void handle_pointer_swipe_update(struct wl_listener *listener, void *data | |||
974 | listener, cursor, swipe_update); | 981 | listener, cursor, swipe_update); |
975 | struct wlr_pointer_swipe_update_event *event = data; | 982 | struct wlr_pointer_swipe_update_event *event = data; |
976 | cursor_handle_activity_from_device(cursor, &event->pointer->base); | 983 | cursor_handle_activity_from_device(cursor, &event->pointer->base); |
977 | wlr_pointer_gestures_v1_send_swipe_update( | 984 | seatop_swipe_update(cursor->seat, event); |
978 | cursor->pointer_gestures, cursor->seat->wlr_seat, | ||
979 | event->time_msec, event->dx, event->dy); | ||
980 | } | 985 | } |
981 | 986 | ||
982 | static void handle_pointer_swipe_end(struct wl_listener *listener, void *data) { | 987 | static void handle_pointer_swipe_end(struct wl_listener *listener, void *data) { |
@@ -984,29 +989,7 @@ static void handle_pointer_swipe_end(struct wl_listener *listener, void *data) { | |||
984 | listener, cursor, swipe_end); | 989 | listener, cursor, swipe_end); |
985 | struct wlr_pointer_swipe_end_event *event = data; | 990 | struct wlr_pointer_swipe_end_event *event = data; |
986 | cursor_handle_activity_from_device(cursor, &event->pointer->base); | 991 | cursor_handle_activity_from_device(cursor, &event->pointer->base); |
987 | wlr_pointer_gestures_v1_send_swipe_end( | 992 | seatop_swipe_end(cursor->seat, event); |
988 | cursor->pointer_gestures, cursor->seat->wlr_seat, | ||
989 | event->time_msec, event->cancelled); | ||
990 | } | ||
991 | |||
992 | static void handle_pointer_hold_begin(struct wl_listener *listener, void *data) { | ||
993 | struct sway_cursor *cursor = wl_container_of( | ||
994 | listener, cursor, hold_begin); | ||
995 | struct wlr_pointer_hold_begin_event *event = data; | ||
996 | cursor_handle_activity_from_device(cursor, &event->pointer->base); | ||
997 | wlr_pointer_gestures_v1_send_hold_begin( | ||
998 | cursor->pointer_gestures, cursor->seat->wlr_seat, | ||
999 | event->time_msec, event->fingers); | ||
1000 | } | ||
1001 | |||
1002 | static void handle_pointer_hold_end(struct wl_listener *listener, void *data) { | ||
1003 | struct sway_cursor *cursor = wl_container_of( | ||
1004 | listener, cursor, hold_end); | ||
1005 | struct wlr_pointer_hold_end_event *event = data; | ||
1006 | cursor_handle_activity_from_device(cursor, &event->pointer->base); | ||
1007 | wlr_pointer_gestures_v1_send_hold_end( | ||
1008 | cursor->pointer_gestures, cursor->seat->wlr_seat, | ||
1009 | event->time_msec, event->cancelled); | ||
1010 | } | 993 | } |
1011 | 994 | ||
1012 | static void handle_image_surface_destroy(struct wl_listener *listener, | 995 | static void handle_image_surface_destroy(struct wl_listener *listener, |
@@ -1080,14 +1063,14 @@ void sway_cursor_destroy(struct sway_cursor *cursor) { | |||
1080 | wl_event_source_remove(cursor->hide_source); | 1063 | wl_event_source_remove(cursor->hide_source); |
1081 | 1064 | ||
1082 | wl_list_remove(&cursor->image_surface_destroy.link); | 1065 | wl_list_remove(&cursor->image_surface_destroy.link); |
1066 | wl_list_remove(&cursor->hold_begin.link); | ||
1067 | wl_list_remove(&cursor->hold_end.link); | ||
1083 | wl_list_remove(&cursor->pinch_begin.link); | 1068 | wl_list_remove(&cursor->pinch_begin.link); |
1084 | wl_list_remove(&cursor->pinch_update.link); | 1069 | wl_list_remove(&cursor->pinch_update.link); |
1085 | wl_list_remove(&cursor->pinch_end.link); | 1070 | wl_list_remove(&cursor->pinch_end.link); |
1086 | wl_list_remove(&cursor->swipe_begin.link); | 1071 | wl_list_remove(&cursor->swipe_begin.link); |
1087 | wl_list_remove(&cursor->swipe_update.link); | 1072 | wl_list_remove(&cursor->swipe_update.link); |
1088 | wl_list_remove(&cursor->swipe_end.link); | 1073 | wl_list_remove(&cursor->swipe_end.link); |
1089 | wl_list_remove(&cursor->hold_begin.link); | ||
1090 | wl_list_remove(&cursor->hold_end.link); | ||
1091 | wl_list_remove(&cursor->motion.link); | 1074 | wl_list_remove(&cursor->motion.link); |
1092 | wl_list_remove(&cursor->motion_absolute.link); | 1075 | wl_list_remove(&cursor->motion_absolute.link); |
1093 | wl_list_remove(&cursor->button.link); | 1076 | wl_list_remove(&cursor->button.link); |
@@ -1131,23 +1114,27 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) { | |||
1131 | wl_list_init(&cursor->image_surface_destroy.link); | 1114 | wl_list_init(&cursor->image_surface_destroy.link); |
1132 | cursor->image_surface_destroy.notify = handle_image_surface_destroy; | 1115 | cursor->image_surface_destroy.notify = handle_image_surface_destroy; |
1133 | 1116 | ||
1117 | // gesture events | ||
1134 | cursor->pointer_gestures = wlr_pointer_gestures_v1_create(server.wl_display); | 1118 | cursor->pointer_gestures = wlr_pointer_gestures_v1_create(server.wl_display); |
1135 | cursor->pinch_begin.notify = handle_pointer_pinch_begin; | 1119 | |
1120 | wl_signal_add(&wlr_cursor->events.hold_begin, &cursor->hold_begin); | ||
1121 | cursor->hold_begin.notify = handle_pointer_hold_begin; | ||
1122 | wl_signal_add(&wlr_cursor->events.hold_end, &cursor->hold_end); | ||
1123 | cursor->hold_end.notify = handle_pointer_hold_end; | ||
1124 | |||
1136 | wl_signal_add(&wlr_cursor->events.pinch_begin, &cursor->pinch_begin); | 1125 | wl_signal_add(&wlr_cursor->events.pinch_begin, &cursor->pinch_begin); |
1137 | cursor->pinch_update.notify = handle_pointer_pinch_update; | 1126 | cursor->pinch_begin.notify = handle_pointer_pinch_begin; |
1138 | wl_signal_add(&wlr_cursor->events.pinch_update, &cursor->pinch_update); | 1127 | wl_signal_add(&wlr_cursor->events.pinch_update, &cursor->pinch_update); |
1139 | cursor->pinch_end.notify = handle_pointer_pinch_end; | 1128 | cursor->pinch_update.notify = handle_pointer_pinch_update; |
1140 | wl_signal_add(&wlr_cursor->events.pinch_end, &cursor->pinch_end); | 1129 | wl_signal_add(&wlr_cursor->events.pinch_end, &cursor->pinch_end); |
1141 | cursor->swipe_begin.notify = handle_pointer_swipe_begin; | 1130 | cursor->pinch_end.notify = handle_pointer_pinch_end; |
1131 | |||
1142 | wl_signal_add(&wlr_cursor->events.swipe_begin, &cursor->swipe_begin); | 1132 | wl_signal_add(&wlr_cursor->events.swipe_begin, &cursor->swipe_begin); |
1143 | cursor->swipe_update.notify = handle_pointer_swipe_update; | 1133 | cursor->swipe_begin.notify = handle_pointer_swipe_begin; |
1144 | wl_signal_add(&wlr_cursor->events.swipe_update, &cursor->swipe_update); | 1134 | wl_signal_add(&wlr_cursor->events.swipe_update, &cursor->swipe_update); |
1145 | cursor->swipe_end.notify = handle_pointer_swipe_end; | 1135 | cursor->swipe_update.notify = handle_pointer_swipe_update; |
1146 | wl_signal_add(&wlr_cursor->events.swipe_end, &cursor->swipe_end); | 1136 | wl_signal_add(&wlr_cursor->events.swipe_end, &cursor->swipe_end); |
1147 | cursor->hold_begin.notify = handle_pointer_hold_begin; | 1137 | cursor->swipe_end.notify = handle_pointer_swipe_end; |
1148 | wl_signal_add(&wlr_cursor->events.hold_begin, &cursor->hold_begin); | ||
1149 | cursor->hold_end.notify = handle_pointer_hold_end; | ||
1150 | wl_signal_add(&wlr_cursor->events.hold_end, &cursor->hold_end); | ||
1151 | 1138 | ||
1152 | // input events | 1139 | // input events |
1153 | wl_signal_add(&wlr_cursor->events.motion, &cursor->motion); | 1140 | wl_signal_add(&wlr_cursor->events.motion, &cursor->motion); |
diff --git a/sway/input/seat.c b/sway/input/seat.c index 11c78154..fe61e0fe 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -1614,6 +1614,62 @@ void seatop_tablet_tool_motion(struct sway_seat *seat, | |||
1614 | } | 1614 | } |
1615 | } | 1615 | } |
1616 | 1616 | ||
1617 | void seatop_hold_begin(struct sway_seat *seat, | ||
1618 | struct wlr_pointer_hold_begin_event *event) { | ||
1619 | if (seat->seatop_impl->hold_begin) { | ||
1620 | seat->seatop_impl->hold_begin(seat, event); | ||
1621 | } | ||
1622 | } | ||
1623 | |||
1624 | void seatop_hold_end(struct sway_seat *seat, | ||
1625 | struct wlr_pointer_hold_end_event *event) { | ||
1626 | if (seat->seatop_impl->hold_end) { | ||
1627 | seat->seatop_impl->hold_end(seat, event); | ||
1628 | } | ||
1629 | } | ||
1630 | |||
1631 | void seatop_pinch_begin(struct sway_seat *seat, | ||
1632 | struct wlr_pointer_pinch_begin_event *event) { | ||
1633 | if (seat->seatop_impl->pinch_begin) { | ||
1634 | seat->seatop_impl->pinch_begin(seat, event); | ||
1635 | } | ||
1636 | } | ||
1637 | |||
1638 | void seatop_pinch_update(struct sway_seat *seat, | ||
1639 | struct wlr_pointer_pinch_update_event *event) { | ||
1640 | if (seat->seatop_impl->pinch_update) { | ||
1641 | seat->seatop_impl->pinch_update(seat, event); | ||
1642 | } | ||
1643 | } | ||
1644 | |||
1645 | void seatop_pinch_end(struct sway_seat *seat, | ||
1646 | struct wlr_pointer_pinch_end_event *event) { | ||
1647 | if (seat->seatop_impl->pinch_end) { | ||
1648 | seat->seatop_impl->pinch_end(seat, event); | ||
1649 | } | ||
1650 | } | ||
1651 | |||
1652 | void seatop_swipe_begin(struct sway_seat *seat, | ||
1653 | struct wlr_pointer_swipe_begin_event *event) { | ||
1654 | if (seat->seatop_impl->swipe_begin) { | ||
1655 | seat->seatop_impl->swipe_begin(seat, event); | ||
1656 | } | ||
1657 | } | ||
1658 | |||
1659 | void seatop_swipe_update(struct sway_seat *seat, | ||
1660 | struct wlr_pointer_swipe_update_event *event) { | ||
1661 | if (seat->seatop_impl->swipe_update) { | ||
1662 | seat->seatop_impl->swipe_update(seat, event); | ||
1663 | } | ||
1664 | } | ||
1665 | |||
1666 | void seatop_swipe_end(struct sway_seat *seat, | ||
1667 | struct wlr_pointer_swipe_end_event *event) { | ||
1668 | if (seat->seatop_impl->swipe_end) { | ||
1669 | seat->seatop_impl->swipe_end(seat, event); | ||
1670 | } | ||
1671 | } | ||
1672 | |||
1617 | void seatop_rebase(struct sway_seat *seat, uint32_t time_msec) { | 1673 | void seatop_rebase(struct sway_seat *seat, uint32_t time_msec) { |
1618 | if (seat->seatop_impl->rebase) { | 1674 | if (seat->seatop_impl->rebase) { |
1619 | seat->seatop_impl->rebase(seat, time_msec); | 1675 | seat->seatop_impl->rebase(seat, time_msec); |
diff --git a/sway/input/seatop_default.c b/sway/input/seatop_default.c index 15d1ca8b..2684e55a 100644 --- a/sway/input/seatop_default.c +++ b/sway/input/seatop_default.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <wlr/types/wlr_cursor.h> | 4 | #include <wlr/types/wlr_cursor.h> |
5 | #include <wlr/types/wlr_tablet_v2.h> | 5 | #include <wlr/types/wlr_tablet_v2.h> |
6 | #include <wlr/types/wlr_xcursor_manager.h> | 6 | #include <wlr/types/wlr_xcursor_manager.h> |
7 | #include "gesture.h" | ||
7 | #include "sway/desktop/transaction.h" | 8 | #include "sway/desktop/transaction.h" |
8 | #include "sway/input/cursor.h" | 9 | #include "sway/input/cursor.h" |
9 | #include "sway/input/seat.h" | 10 | #include "sway/input/seat.h" |
@@ -20,6 +21,7 @@ struct seatop_default_event { | |||
20 | struct sway_node *previous_node; | 21 | struct sway_node *previous_node; |
21 | uint32_t pressed_buttons[SWAY_CURSOR_PRESSED_BUTTONS_CAP]; | 22 | uint32_t pressed_buttons[SWAY_CURSOR_PRESSED_BUTTONS_CAP]; |
22 | size_t pressed_button_count; | 23 | size_t pressed_button_count; |
24 | struct gesture_tracker gestures; | ||
23 | }; | 25 | }; |
24 | 26 | ||
25 | /*-----------------------------------------\ | 27 | /*-----------------------------------------\ |
@@ -750,6 +752,304 @@ static void handle_pointer_axis(struct sway_seat *seat, | |||
750 | } | 752 | } |
751 | } | 753 | } |
752 | 754 | ||
755 | /*------------------------------------\ | ||
756 | * Functions used by gesture support / | ||
757 | *----------------------------------*/ | ||
758 | |||
759 | /** | ||
760 | * Check gesture binding for a specific gesture type and finger count. | ||
761 | * Returns true if binding is present, false otherwise | ||
762 | */ | ||
763 | static bool gesture_binding_check(list_t *bindings, enum gesture_type type, | ||
764 | uint8_t fingers, struct sway_input_device *device) { | ||
765 | char *input = | ||
766 | device ? input_device_get_identifier(device->wlr_device) : strdup("*"); | ||
767 | |||
768 | for (int i = 0; i < bindings->length; ++i) { | ||
769 | struct sway_gesture_binding *binding = bindings->items[i]; | ||
770 | |||
771 | // Check type and finger count | ||
772 | if (!gesture_check(&binding->gesture, type, fingers)) { | ||
773 | continue; | ||
774 | } | ||
775 | |||
776 | // Check that input matches | ||
777 | if (strcmp(binding->input, "*") != 0 && | ||
778 | strcmp(binding->input, input) != 0) { | ||
779 | continue; | ||
780 | } | ||
781 | |||
782 | free(input); | ||
783 | |||
784 | return true; | ||
785 | } | ||
786 | |||
787 | free(input); | ||
788 | |||
789 | return false; | ||
790 | } | ||
791 | |||
792 | /** | ||
793 | * Return the gesture binding which matches gesture type, finger count | ||
794 | * and direction, otherwise return null. | ||
795 | */ | ||
796 | static struct sway_gesture_binding* gesture_binding_match( | ||
797 | list_t *bindings, struct gesture *gesture, const char *input) { | ||
798 | struct sway_gesture_binding *current = NULL; | ||
799 | |||
800 | // Find best matching binding | ||
801 | for (int i = 0; i < bindings->length; ++i) { | ||
802 | struct sway_gesture_binding *binding = bindings->items[i]; | ||
803 | bool exact = binding->flags & BINDING_EXACT; | ||
804 | |||
805 | // Check gesture matching | ||
806 | if (!gesture_match(&binding->gesture, gesture, exact)) { | ||
807 | continue; | ||
808 | } | ||
809 | |||
810 | // Check input matching | ||
811 | if (strcmp(binding->input, "*") != 0 && | ||
812 | strcmp(binding->input, input) != 0) { | ||
813 | continue; | ||
814 | } | ||
815 | |||
816 | // If we already have a match ... | ||
817 | if (current) { | ||
818 | // ... check if input matching is equivalent | ||
819 | if (strcmp(current->input, binding->input) == 0) { | ||
820 | |||
821 | // ... - do not override an exact binding | ||
822 | if (!exact && current->flags & BINDING_EXACT) { | ||
823 | continue; | ||
824 | } | ||
825 | |||
826 | // ... - and ensure direction matching is better or equal | ||
827 | if (gesture_compare(¤t->gesture, &binding->gesture) > 0) { | ||
828 | continue; | ||
829 | } | ||
830 | } else if (strcmp(binding->input, "*") == 0) { | ||
831 | // ... do not accept worse input match | ||
832 | continue; | ||
833 | } | ||
834 | } | ||
835 | |||
836 | // Accept newer or better match | ||
837 | current = binding; | ||
838 | |||
839 | // If exact binding and input is found, quit search | ||
840 | if (strcmp(current->input, input) == 0 && | ||
841 | gesture_compare(¤t->gesture, gesture) == 0) { | ||
842 | break; | ||
843 | } | ||
844 | } // for all gesture bindings | ||
845 | |||
846 | return current; | ||
847 | } | ||
848 | |||
849 | // Wrapper around gesture_tracker_end to use tracker with sway bindings | ||
850 | static struct sway_gesture_binding* gesture_tracker_end_and_match( | ||
851 | struct gesture_tracker *tracker, struct sway_input_device* device) { | ||
852 | // Determine name of input that received gesture | ||
853 | char *input = device | ||
854 | ? input_device_get_identifier(device->wlr_device) | ||
855 | : strdup("*"); | ||
856 | |||
857 | // Match tracking result to binding | ||
858 | struct gesture *gesture = gesture_tracker_end(tracker); | ||
859 | struct sway_gesture_binding *binding = gesture_binding_match( | ||
860 | config->current_mode->gesture_bindings, gesture, input); | ||
861 | free(gesture); | ||
862 | free(input); | ||
863 | |||
864 | return binding; | ||
865 | } | ||
866 | |||
867 | // Small wrapper around seat_execute_command to work on gesture bindings | ||
868 | static void gesture_binding_execute(struct sway_seat *seat, | ||
869 | struct sway_gesture_binding *binding) { | ||
870 | struct sway_binding *dummy_binding = | ||
871 | calloc(1, sizeof(struct sway_binding)); | ||
872 | dummy_binding->type = BINDING_GESTURE; | ||
873 | dummy_binding->command = binding->command; | ||
874 | |||
875 | char *description = gesture_to_string(&binding->gesture); | ||
876 | sway_log(SWAY_DEBUG, "executing gesture binding: %s", description); | ||
877 | free(description); | ||
878 | |||
879 | seat_execute_command(seat, dummy_binding); | ||
880 | |||
881 | free(dummy_binding); | ||
882 | } | ||
883 | |||
884 | static void handle_hold_begin(struct sway_seat *seat, | ||
885 | struct wlr_pointer_hold_begin_event *event) { | ||
886 | // Start tracking gesture if there is a matching binding ... | ||
887 | struct sway_input_device *device = | ||
888 | event->pointer ? event->pointer->base.data : NULL; | ||
889 | list_t *bindings = config->current_mode->gesture_bindings; | ||
890 | if (gesture_binding_check(bindings, GESTURE_TYPE_HOLD, event->fingers, device)) { | ||
891 | struct seatop_default_event *seatop = seat->seatop_data; | ||
892 | gesture_tracker_begin(&seatop->gestures, GESTURE_TYPE_HOLD, event->fingers); | ||
893 | } else { | ||
894 | // ... otherwise forward to client | ||
895 | struct sway_cursor *cursor = seat->cursor; | ||
896 | wlr_pointer_gestures_v1_send_hold_begin( | ||
897 | cursor->pointer_gestures, cursor->seat->wlr_seat, | ||
898 | event->time_msec, event->fingers); | ||
899 | } | ||
900 | } | ||
901 | |||
902 | static void handle_hold_end(struct sway_seat *seat, | ||
903 | struct wlr_pointer_hold_end_event *event) { | ||
904 | // Ensure that gesture is being tracked and was not cancelled | ||
905 | struct seatop_default_event *seatop = seat->seatop_data; | ||
906 | if (!gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_HOLD)) { | ||
907 | struct sway_cursor *cursor = seat->cursor; | ||
908 | wlr_pointer_gestures_v1_send_hold_end( | ||
909 | cursor->pointer_gestures, cursor->seat->wlr_seat, | ||
910 | event->time_msec, event->cancelled); | ||
911 | return; | ||
912 | } | ||
913 | if (event->cancelled) { | ||
914 | gesture_tracker_cancel(&seatop->gestures); | ||
915 | return; | ||
916 | } | ||
917 | |||
918 | // End gesture tracking and execute matched binding | ||
919 | struct sway_input_device *device = | ||
920 | event->pointer ? event->pointer->base.data : NULL; | ||
921 | struct sway_gesture_binding *binding = gesture_tracker_end_and_match( | ||
922 | &seatop->gestures, device); | ||
923 | |||
924 | if (binding) { | ||
925 | gesture_binding_execute(seat, binding); | ||
926 | } | ||
927 | } | ||
928 | |||
929 | static void handle_pinch_begin(struct sway_seat *seat, | ||
930 | struct wlr_pointer_pinch_begin_event *event) { | ||
931 | // Start tracking gesture if there is a matching binding ... | ||
932 | struct sway_input_device *device = | ||
933 | event->pointer ? event->pointer->base.data : NULL; | ||
934 | list_t *bindings = config->current_mode->gesture_bindings; | ||
935 | if (gesture_binding_check(bindings, GESTURE_TYPE_PINCH, event->fingers, device)) { | ||
936 | struct seatop_default_event *seatop = seat->seatop_data; | ||
937 | gesture_tracker_begin(&seatop->gestures, GESTURE_TYPE_PINCH, event->fingers); | ||
938 | } else { | ||
939 | // ... otherwise forward to client | ||
940 | struct sway_cursor *cursor = seat->cursor; | ||
941 | wlr_pointer_gestures_v1_send_pinch_begin( | ||
942 | cursor->pointer_gestures, cursor->seat->wlr_seat, | ||
943 | event->time_msec, event->fingers); | ||
944 | } | ||
945 | } | ||
946 | |||
947 | static void handle_pinch_update(struct sway_seat *seat, | ||
948 | struct wlr_pointer_pinch_update_event *event) { | ||
949 | // Update any ongoing tracking ... | ||
950 | struct seatop_default_event *seatop = seat->seatop_data; | ||
951 | if (gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_PINCH)) { | ||
952 | gesture_tracker_update(&seatop->gestures, event->dx, event->dy, | ||
953 | event->scale, event->rotation); | ||
954 | } else { | ||
955 | // ... otherwise forward to client | ||
956 | struct sway_cursor *cursor = seat->cursor; | ||
957 | wlr_pointer_gestures_v1_send_pinch_update( | ||
958 | cursor->pointer_gestures, | ||
959 | cursor->seat->wlr_seat, | ||
960 | event->time_msec, event->dx, event->dy, | ||
961 | event->scale, event->rotation); | ||
962 | } | ||
963 | } | ||
964 | |||
965 | static void handle_pinch_end(struct sway_seat *seat, | ||
966 | struct wlr_pointer_pinch_end_event *event) { | ||
967 | // Ensure that gesture is being tracked and was not cancelled | ||
968 | struct seatop_default_event *seatop = seat->seatop_data; | ||
969 | if (!gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_PINCH)) { | ||
970 | struct sway_cursor *cursor = seat->cursor; | ||
971 | wlr_pointer_gestures_v1_send_pinch_end( | ||
972 | cursor->pointer_gestures, cursor->seat->wlr_seat, | ||
973 | event->time_msec, event->cancelled); | ||
974 | return; | ||
975 | } | ||
976 | if (event->cancelled) { | ||
977 | gesture_tracker_cancel(&seatop->gestures); | ||
978 | return; | ||
979 | } | ||
980 | |||
981 | // End gesture tracking and execute matched binding | ||
982 | struct sway_input_device *device = | ||
983 | event->pointer ? event->pointer->base.data : NULL; | ||
984 | struct sway_gesture_binding *binding = gesture_tracker_end_and_match( | ||
985 | &seatop->gestures, device); | ||
986 | |||
987 | if (binding) { | ||
988 | gesture_binding_execute(seat, binding); | ||
989 | } | ||
990 | } | ||
991 | |||
992 | static void handle_swipe_begin(struct sway_seat *seat, | ||
993 | struct wlr_pointer_swipe_begin_event *event) { | ||
994 | // Start tracking gesture if there is a matching binding ... | ||
995 | struct sway_input_device *device = | ||
996 | event->pointer ? event->pointer->base.data : NULL; | ||
997 | list_t *bindings = config->current_mode->gesture_bindings; | ||
998 | if (gesture_binding_check(bindings, GESTURE_TYPE_SWIPE, event->fingers, device)) { | ||
999 | struct seatop_default_event *seatop = seat->seatop_data; | ||
1000 | gesture_tracker_begin(&seatop->gestures, GESTURE_TYPE_SWIPE, event->fingers); | ||
1001 | } else { | ||
1002 | // ... otherwise forward to client | ||
1003 | struct sway_cursor *cursor = seat->cursor; | ||
1004 | wlr_pointer_gestures_v1_send_swipe_begin( | ||
1005 | cursor->pointer_gestures, cursor->seat->wlr_seat, | ||
1006 | event->time_msec, event->fingers); | ||
1007 | } | ||
1008 | } | ||
1009 | |||
1010 | static void handle_swipe_update(struct sway_seat *seat, | ||
1011 | struct wlr_pointer_swipe_update_event *event) { | ||
1012 | |||
1013 | // Update any ongoing tracking ... | ||
1014 | struct seatop_default_event *seatop = seat->seatop_data; | ||
1015 | if (gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_SWIPE)) { | ||
1016 | gesture_tracker_update(&seatop->gestures, | ||
1017 | event->dx, event->dy, NAN, NAN); | ||
1018 | } else { | ||
1019 | // ... otherwise forward to client | ||
1020 | struct sway_cursor *cursor = seat->cursor; | ||
1021 | wlr_pointer_gestures_v1_send_swipe_update( | ||
1022 | cursor->pointer_gestures, cursor->seat->wlr_seat, | ||
1023 | event->time_msec, event->dx, event->dy); | ||
1024 | } | ||
1025 | } | ||
1026 | |||
1027 | static void handle_swipe_end(struct sway_seat *seat, | ||
1028 | struct wlr_pointer_swipe_end_event *event) { | ||
1029 | // Ensure gesture is being tracked and was not cancelled | ||
1030 | struct seatop_default_event *seatop = seat->seatop_data; | ||
1031 | if (!gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_SWIPE)) { | ||
1032 | struct sway_cursor *cursor = seat->cursor; | ||
1033 | wlr_pointer_gestures_v1_send_swipe_end(cursor->pointer_gestures, | ||
1034 | cursor->seat->wlr_seat, event->time_msec, event->cancelled); | ||
1035 | return; | ||
1036 | } | ||
1037 | if (event->cancelled) { | ||
1038 | gesture_tracker_cancel(&seatop->gestures); | ||
1039 | return; | ||
1040 | } | ||
1041 | |||
1042 | // End gesture tracking and execute matched binding | ||
1043 | struct sway_input_device *device = | ||
1044 | event->pointer ? event->pointer->base.data : NULL; | ||
1045 | struct sway_gesture_binding *binding = gesture_tracker_end_and_match( | ||
1046 | &seatop->gestures, device); | ||
1047 | |||
1048 | if (binding) { | ||
1049 | gesture_binding_execute(seat, binding); | ||
1050 | } | ||
1051 | } | ||
1052 | |||
753 | /*----------------------------------\ | 1053 | /*----------------------------------\ |
754 | * Functions used by handle_rebase / | 1054 | * Functions used by handle_rebase / |
755 | *--------------------------------*/ | 1055 | *--------------------------------*/ |
@@ -779,6 +1079,14 @@ static const struct sway_seatop_impl seatop_impl = { | |||
779 | .pointer_axis = handle_pointer_axis, | 1079 | .pointer_axis = handle_pointer_axis, |
780 | .tablet_tool_tip = handle_tablet_tool_tip, | 1080 | .tablet_tool_tip = handle_tablet_tool_tip, |
781 | .tablet_tool_motion = handle_tablet_tool_motion, | 1081 | .tablet_tool_motion = handle_tablet_tool_motion, |
1082 | .hold_begin = handle_hold_begin, | ||
1083 | .hold_end = handle_hold_end, | ||
1084 | .pinch_begin = handle_pinch_begin, | ||
1085 | .pinch_update = handle_pinch_update, | ||
1086 | .pinch_end = handle_pinch_end, | ||
1087 | .swipe_begin = handle_swipe_begin, | ||
1088 | .swipe_update = handle_swipe_update, | ||
1089 | .swipe_end = handle_swipe_end, | ||
782 | .rebase = handle_rebase, | 1090 | .rebase = handle_rebase, |
783 | .allow_set_cursor = true, | 1091 | .allow_set_cursor = true, |
784 | }; | 1092 | }; |
@@ -789,8 +1097,8 @@ void seatop_begin_default(struct sway_seat *seat) { | |||
789 | struct seatop_default_event *e = | 1097 | struct seatop_default_event *e = |
790 | calloc(1, sizeof(struct seatop_default_event)); | 1098 | calloc(1, sizeof(struct seatop_default_event)); |
791 | sway_assert(e, "Unable to allocate seatop_default_event"); | 1099 | sway_assert(e, "Unable to allocate seatop_default_event"); |
1100 | |||
792 | seat->seatop_impl = &seatop_impl; | 1101 | seat->seatop_impl = &seatop_impl; |
793 | seat->seatop_data = e; | 1102 | seat->seatop_data = e; |
794 | |||
795 | seatop_rebase(seat, 0); | 1103 | seatop_rebase(seat, 0); |
796 | } | 1104 | } |