aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input
diff options
context:
space:
mode:
authorLibravatar Florian Franzen <Florian.Franzen@gmail.com>2022-04-23 10:27:47 +0200
committerLibravatar Simon Ser <contact@emersion.fr>2022-05-30 12:20:43 +0200
commitcab2189aa64d04ba79dc2cbf19400435b47cdbd2 (patch)
tree450ac51fbc75c73ed1dc6728bc05b08366ace785 /sway/input
parentAdd a Hindi (हिन्दी) translation to the README (diff)
downloadsway-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.c89
-rw-r--r--sway/input/seat.c56
-rw-r--r--sway/input/seatop_default.c310
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
931static 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
939static 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
931static void handle_pointer_pinch_begin(struct wl_listener *listener, void *data) { 947static 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
941static void handle_pointer_pinch_update(struct wl_listener *listener, void *data) { 955static 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
952static void handle_pointer_pinch_end(struct wl_listener *listener, void *data) { 963static 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
962static void handle_pointer_swipe_begin(struct wl_listener *listener, void *data) { 971static 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
972static void handle_pointer_swipe_update(struct wl_listener *listener, void *data) { 979static 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
982static void handle_pointer_swipe_end(struct wl_listener *listener, void *data) { 987static 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
992static 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
1002static 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
1012static void handle_image_surface_destroy(struct wl_listener *listener, 995static 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
1617void 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
1624void 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
1631void 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
1638void 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
1645void 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
1652void 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
1659void 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
1666void 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
1617void seatop_rebase(struct sway_seat *seat, uint32_t time_msec) { 1673void 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 */
763static 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 */
796static 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(&current->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(&current->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
850static 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
868static 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
884static 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
902static 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
929static 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
947static 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
965static 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
992static 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
1010static 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
1027static 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}