diff --git a/include/sway/commands.h b/include/sway/commands.h index 06c7802ec..3e7a03eb3 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -284,7 +284,7 @@ sway_cmd touch_cmd_gesture; sway_cmd touch_cmd_binding; sway_cmd touch_gesture_cmd_touch; - +sway_cmd touch_gesture_cmd_threshold; sway_cmd cmd_ipc_cmd; sway_cmd cmd_ipc_events; diff --git a/include/sway/config.h b/include/sway/config.h index 2f12fe969..d8f8189d3 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -528,7 +528,7 @@ struct sway_config { struct sway_workspace *workspace; struct gesture_config *current_gesture; - + struct libtouch_action *current_gesture_action; bool using_criteria; struct { @@ -656,6 +656,8 @@ void free_workspace_config(struct workspace_config *wsc); int gesture_identifier_cmp(const void *item, const void *data); +int gesture_libtouch_cmp(const void *item, const void *data); + struct gesture_config *get_gesture_config(const char *identifier); struct gesture_config *new_gesture_config(const char *identifier); diff --git a/sway/commands/touch.c b/sway/commands/touch.c index 859d58d31..0b08aa09b 100644 --- a/sway/commands/touch.c +++ b/sway/commands/touch.c @@ -10,9 +10,10 @@ #include "stringop.h" #include +// Must be in alphabetical order for bsearch static struct cmd_handler touch_handlers[] = { - { "gesture", touch_cmd_gesture }, { "binding", touch_cmd_binding }, + { "gesture", touch_cmd_gesture }, }; @@ -21,15 +22,18 @@ struct cmd_results *cmd_touch(int argc, char **argv) { if ((error = checkarg(argc, "touch", EXPECTED_AT_LEAST, 2))) { return error; } + if(!config->gesture_engine) { config->gesture_engine = libtouch_engine_create(); + sway_log(SWAY_DEBUG, "Created a new gesture engine"); } struct cmd_handler *cmd = find_handler(argv[0], touch_handlers, sizeof(touch_handlers)); if( cmd ) { return config_subcommand(argv, argc, touch_handlers, sizeof(touch_handlers)); } return cmd_results_new(CMD_FAILURE, - "Invalid subcommand"); + "Invalid subcommand: %s", + argv[0]); }; diff --git a/sway/commands/touch/binding.c b/sway/commands/touch/binding.c index 3a7d66e20..dacd26601 100644 --- a/sway/commands/touch/binding.c +++ b/sway/commands/touch/binding.c @@ -17,13 +17,13 @@ struct cmd_results *touch_cmd_binding(int argc, char **argv) { return error; } - struct gesture_config *config = get_gesture_config(argv[1]); + struct gesture_config *config = get_gesture_config(argv[0]); if (!config) { - return cmd_results_new(CMD_FAILURE, "Unable to bind gesture %s", argv[1]); + return cmd_results_new(CMD_FAILURE, "Unable to bind gesture %s", argv[0]); } - config->command = join_args(argv+2, argc); + config->command = join_args(argv + 1, argc - 1); return cmd_results_new(CMD_SUCCESS, NULL); }; diff --git a/sway/commands/touch/gesture.c b/sway/commands/touch/gesture.c index 11221211c..4450a2764 100644 --- a/sway/commands/touch/gesture.c +++ b/sway/commands/touch/gesture.c @@ -11,31 +11,33 @@ #include static struct cmd_handler gesture_handlers[] = { + { "threshold", touch_gesture_cmd_threshold }, { "touch", touch_gesture_cmd_touch }, }; struct cmd_results *touch_cmd_gesture(int argc, char **argv) { struct cmd_results *error = NULL; - if((error = checkarg(argc, "gesture", EXPECTED_AT_LEAST, 1))) { + if((error = checkarg(argc, "gesture", EXPECTED_AT_LEAST, 2))) { return error; } + sway_log(SWAY_DEBUG, "Getting gesture conf"); - sway_log(SWAY_DEBUG, "entering gesture block: %s", argv[0]); struct gesture_config *gesture = get_gesture_config(argv[0]); - + if(!gesture) { return cmd_results_new(CMD_FAILURE, "Could not create/find gesture config"); } config->handler_context.current_gesture = gesture; - + struct cmd_handler *cmd = find_handler(argv[1], gesture_handlers, sizeof(gesture_handlers)); if (cmd) { - return config_subcommand(argv,argc,gesture_handlers, sizeof(gesture_handlers)); + return config_subcommand(argv + 1,argc - 1,gesture_handlers, sizeof(gesture_handlers)); } return cmd_results_new(CMD_FAILURE, - "Invalid Subcommand"); + "Invalid Subcommand: %s", + argv[1]); }; diff --git a/sway/commands/touch/gesture/threshold.c b/sway/commands/touch/gesture/threshold.c new file mode 100644 index 000000000..c0510e147 --- /dev/null +++ b/sway/commands/touch/gesture/threshold.c @@ -0,0 +1,31 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include +#include "sway/commands.h" +#include "sway/config.h" +#include "sway/ipc-server.h" +#include "list.h" +#include "log.h" +#include "stringop.h" +#include + +struct cmd_results *touch_gesture_cmd_threshold(int argc, char **argv) { + struct cmd_results *error = NULL; + if((error = checkarg(argc, "touch", EXPECTED_EQUAL_TO, 1))) { + return error; + } + struct libtouch_action *current = config->handler_context.current_gesture_action; + if(!current) { + return cmd_results_new(CMD_FAILURE, "No action created"); + } + + int threshold = atoi(argv[0]); + if(threshold < 0) { + return cmd_results_new(CMD_INVALID, + "Invalid threshold: %s", argv[0]); + } + libtouch_action_set_threshold(current, threshold); + return cmd_results_new(CMD_SUCCESS, + "Set threshold"); +} diff --git a/sway/commands/touch/gesture/touch.c b/sway/commands/touch/gesture/touch.c index 539ebd8f1..546d1f443 100644 --- a/sway/commands/touch/gesture/touch.c +++ b/sway/commands/touch/gesture/touch.c @@ -11,5 +11,30 @@ #include struct cmd_results *touch_gesture_cmd_touch(int argc, char **argv) { - return NULL; + struct cmd_results *error = NULL; + if((error = checkarg(argc, "touch", EXPECTED_EQUAL_TO, 1))) { + return error; + } + + uint32_t mode; + if(strcmp(argv[0],"down") == 0) { + mode = LIBTOUCH_TOUCH_DOWN; + } else if (strcmp(argv[0],"up") == 0) { + mode = LIBTOUCH_TOUCH_UP; + } else { + return cmd_results_new(CMD_FAILURE, "Touch: %s is not up or down", argv[0]); + } + + if(!config->handler_context.current_gesture) { + return cmd_results_new(CMD_FAILURE, "No current gesture"); + } else if (!config->handler_context.current_gesture->gesture) { + return cmd_results_new(CMD_FAILURE, "No gesture in gesture config"); + } + struct libtouch_gesture *gesture = config->handler_context.current_gesture->gesture; + + struct libtouch_action *action = libtouch_gesture_add_touch(gesture, mode); + + config->handler_context.current_gesture_action = action; + + return cmd_results_new(CMD_SUCCESS, "Created new action"); }; diff --git a/sway/config/gesture.c b/sway/config/gesture.c index 153e9d18e..5514098c5 100644 --- a/sway/config/gesture.c +++ b/sway/config/gesture.c @@ -8,7 +8,7 @@ struct gesture_config *get_gesture_config(const char* identifier) { int i = list_seq_find(config->gesture_configs, gesture_identifier_cmp, identifier); - + struct gesture_config *cfg = NULL; if(i >= 0) { sway_log(SWAY_DEBUG, "Retrieving existing gesture"); @@ -36,3 +36,9 @@ int gesture_identifier_cmp(const void *item, const void *data) { const char *identifier = data; return strcmp(gc->identifier, identifier); } + +int gesture_libtouch_cmp(const void *item, const void *data) { + const struct gesture_config *gc = item; + const struct libtouch_gesture *g = data; + return gc->gesture == g; +} diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 0962c3efa..5468c404b 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -332,6 +332,21 @@ static void handle_cursor_frame(struct wl_listener *listener, void *data) { wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); } +static void handle_gestures(struct libtouch_engine *engine, struct sway_seat *seat) { + struct libtouch_gesture *complete; + struct gesture_config *cfg; + int idx; + while((complete = libtouch_handle_finished_gesture(engine))){ + idx = list_seq_find(config->gesture_configs, gesture_libtouch_cmp, complete); + if(idx >= 0) { + cfg = config->gesture_configs->items[idx]; + if(cfg->command) { + execute_command(cfg->command, seat, seat_get_focused_container(seat)); + } + } + } +} + static void handle_touch_down(struct wl_listener *listener, void *data) { struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_down); wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat); @@ -363,6 +378,7 @@ static void handle_touch_down(struct wl_listener *listener, void *data) { libtouch_engine_register_touch(cursor->gesture_engine, event->time_msec, event->touch_id, LIBTOUCH_TOUCH_DOWN, event->x, event->y); + handle_gestures(cursor->gesture_engine, seat); } @@ -375,6 +391,7 @@ static void handle_touch_up(struct wl_listener *listener, void *data) { wlr_seat_touch_notify_up(seat, event->time_msec, event->touch_id); libtouch_engine_register_touch(cursor->gesture_engine, event->time_msec, event->touch_id, LIBTOUCH_TOUCH_UP, 0, 0); + handle_gestures(cursor->gesture_engine, seat); } static void handle_touch_motion(struct wl_listener *listener, void *data) { @@ -416,8 +433,11 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) { libtouch_engine_register_move(cursor->gesture_engine, event->time_msec, event->touch_id, event->x, event->y); + handle_gestures(cursor->gesture_engine, seat); } + + static double apply_mapping_from_coord(double low, double high, double value) { if (isnan(value)) { return value; diff --git a/sway/meson.build b/sway/meson.build index 9f890ed88..3c6ce0385 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -180,6 +180,7 @@ sway_sources = files( 'commands/touch/binding.c', 'commands/touch/gesture.c', 'commands/touch/gesture/touch.c', + 'commands/touch/gesture/threshold.c', 'tree/arrange.c', 'tree/container.c',