This commit is contained in:
Samuel Grahn 2019-04-25 18:00:57 +00:00 committed by GitHub
commit 50fbc3b9db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 653 additions and 5 deletions

View file

@ -134,6 +134,7 @@ sway_cmd cmd_force_display_urgency_hint;
sway_cmd cmd_force_focus_wrapping; sway_cmd cmd_force_focus_wrapping;
sway_cmd cmd_fullscreen; sway_cmd cmd_fullscreen;
sway_cmd cmd_gaps; sway_cmd cmd_gaps;
sway_cmd cmd_gesture;
sway_cmd cmd_hide_edge_borders; sway_cmd cmd_hide_edge_borders;
sway_cmd cmd_include; sway_cmd cmd_include;
sway_cmd cmd_inhibit_idle; sway_cmd cmd_inhibit_idle;
@ -184,6 +185,7 @@ sway_cmd cmd_titlebar_padding;
sway_cmd cmd_unbindcode; sway_cmd cmd_unbindcode;
sway_cmd cmd_unbindswitch; sway_cmd cmd_unbindswitch;
sway_cmd cmd_unbindsym; sway_cmd cmd_unbindsym;
sway_cmd cmd_touch;
sway_cmd cmd_unmark; sway_cmd cmd_unmark;
sway_cmd cmd_urgent; sway_cmd cmd_urgent;
sway_cmd cmd_workspace; sway_cmd cmd_workspace;
@ -278,6 +280,18 @@ sway_cmd seat_cmd_fallback;
sway_cmd seat_cmd_hide_cursor; sway_cmd seat_cmd_hide_cursor;
sway_cmd seat_cmd_pointer_constraint; sway_cmd seat_cmd_pointer_constraint;
sway_cmd touch_cmd_gesture;
sway_cmd touch_cmd_binding;
sway_cmd touch_cmd_target;
sway_cmd touch_gesture_cmd_touch;
sway_cmd touch_gesture_cmd_threshold;
sway_cmd touch_gesture_cmd_target;
sway_cmd touch_gesture_cmd_swipe;
sway_cmd touch_gesture_cmd_pinch;
sway_cmd touch_gesture_cmd_rotate;
sway_cmd touch_gesture_cmd_delay;
sway_cmd cmd_ipc_cmd; sway_cmd cmd_ipc_cmd;
sway_cmd cmd_ipc_events; sway_cmd cmd_ipc_events;
sway_cmd cmd_ipc_event_cmd; sway_cmd cmd_ipc_event_cmd;

View file

@ -91,6 +91,7 @@ struct sway_mode {
list_t *keycode_bindings; list_t *keycode_bindings;
list_t *mouse_bindings; list_t *mouse_bindings;
list_t *switch_bindings; list_t *switch_bindings;
list_t *gesture_bindings;
bool pango; bool pango;
}; };
@ -100,6 +101,17 @@ struct input_config_mapped_from_region {
bool mm; bool mm;
}; };
struct gesture_config {
char *identifier;
struct libtouch_gesture *gesture;
char *command;
};
struct gesture_target_config {
char *identifier;
struct libtouch_target *target;
};
/** /**
* options for input devices * options for input devices
*/ */
@ -420,6 +432,8 @@ struct sway_config {
list_t *output_configs; list_t *output_configs;
list_t *input_configs; list_t *input_configs;
list_t *input_type_configs; list_t *input_type_configs;
list_t *gesture_configs;
list_t *gesture_target_configs;
list_t *seat_configs; list_t *seat_configs;
list_t *criteria; list_t *criteria;
list_t *no_focus; list_t *no_focus;
@ -508,6 +522,7 @@ struct sway_config {
list_t *feature_policies; list_t *feature_policies;
list_t *ipc_policies; list_t *ipc_policies;
struct libtouch_engine *gesture_engine;
// Context for command handlers // Context for command handlers
struct { struct {
struct input_config *input_config; struct input_config *input_config;
@ -517,6 +532,10 @@ struct sway_config {
struct sway_node *node; struct sway_node *node;
struct sway_container *container; struct sway_container *container;
struct sway_workspace *workspace; struct sway_workspace *workspace;
struct gesture_config *current_gesture;
struct libtouch_action *current_gesture_action;
bool using_criteria; bool using_criteria;
struct { struct {
int argc; int argc;
@ -641,6 +660,20 @@ void free_bar_binding(struct bar_binding *binding);
void free_workspace_config(struct workspace_config *wsc); 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);
int gesture_target_identifier_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);
struct gesture_target_config *get_gesture_target_config(const char* identifier);
struct gesture_target_config *create_gesture_target_config(const char* identifier);
/** /**
* Updates the value of config->font_height based on the max title height * Updates the value of config->font_height based on the max title height
* reported by each container. If recalculate is true, the containers will * reported by each container. If recalculate is true, the containers will

View file

@ -36,6 +36,7 @@ struct sway_cursor {
struct wl_listener axis; struct wl_listener axis;
struct wl_listener frame; struct wl_listener frame;
struct libtouch_progress_tracker *gesture_tracker;
struct wl_listener touch_down; struct wl_listener touch_down;
struct wl_listener touch_up; struct wl_listener touch_up;
struct wl_listener touch_motion; struct wl_listener touch_motion;

View file

@ -37,6 +37,7 @@ if is_freebsd
add_project_arguments('-D_C11_SOURCE', language: 'c') add_project_arguments('-D_C11_SOURCE', language: 'c')
endif endif
libtouch = dependency('libtouch')
jsonc = dependency('json-c', version: '>=0.13') jsonc = dependency('json-c', version: '>=0.13')
pcre = dependency('libpcre') pcre = dependency('libpcre')
wayland_server = dependency('wayland-server') wayland_server = dependency('wayland-server')

View file

@ -92,6 +92,7 @@ static struct cmd_handler handlers[] = {
{ "title_align", cmd_title_align }, { "title_align", cmd_title_align },
{ "titlebar_border_thickness", cmd_titlebar_border_thickness }, { "titlebar_border_thickness", cmd_titlebar_border_thickness },
{ "titlebar_padding", cmd_titlebar_padding }, { "titlebar_padding", cmd_titlebar_padding },
{ "touch", cmd_touch },
{ "unbindcode", cmd_unbindcode }, { "unbindcode", cmd_unbindcode },
{ "unbindswitch", cmd_unbindswitch }, { "unbindswitch", cmd_unbindswitch },
{ "unbindsym", cmd_unbindsym }, { "unbindsym", cmd_unbindsym },

36
sway/commands/touch.c Normal file
View file

@ -0,0 +1,36 @@
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include <libtouch.h>
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/ipc-server.h"
#include "list.h"
#include "log.h"
#include "stringop.h"
// Must be in alphabetical order for bsearch
static struct cmd_handler touch_handlers[] = {
{ "binding", touch_cmd_binding },
{ "gesture", touch_cmd_gesture },
{ "target", touch_cmd_target },
};
struct cmd_results *cmd_touch(int argc, char **argv) {
struct cmd_results *error = NULL;
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");
}
if (find_handler(argv[0], touch_handlers, sizeof(touch_handlers))) {
return config_subcommand(
argv,argc,touch_handlers, sizeof(touch_handlers));
}
return cmd_results_new(CMD_INVALID, "Invalid subcommand: %s", argv[0]);
};

View file

@ -0,0 +1,29 @@
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include <libtouch.h>
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/ipc-server.h"
#include "list.h"
#include "log.h"
#include "stringop.h"
struct cmd_results *touch_cmd_binding(int argc, char **argv) {
struct cmd_results *error = NULL;
if((error = checkarg(argc, "binding", EXPECTED_AT_LEAST, 2))) {
return error;
}
struct gesture_config *config = get_gesture_config(argv[0]);
if (!config) {
return cmd_results_new(
CMD_INVALID, "Unknown gesture %s", argv[0]);
}
sway_log(SWAY_DEBUG, "libtouch: Bound gesture %s", argv[0]);
config->command = join_args(argv + 1, argc - 1);
return cmd_results_new(CMD_SUCCESS, NULL);
};

View file

@ -0,0 +1,49 @@
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/ipc-server.h"
#include "list.h"
#include "log.h"
#include "stringop.h"
#include <libtouch.h>
static struct cmd_handler gesture_handlers[] = {
{ "delay", touch_gesture_cmd_delay },
{ "pinch", touch_gesture_cmd_pinch },
{ "rotate", touch_gesture_cmd_rotate },
{ "swipe", touch_gesture_cmd_swipe },
{ "target", touch_gesture_cmd_target },
{ "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, 2))) {
return error;
}
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 + 1,argc - 1,
gesture_handlers, sizeof(gesture_handlers));
}
return cmd_results_new(CMD_FAILURE,
"Invalid Subcommand: %s",
argv[1]);
};

View file

@ -0,0 +1,38 @@
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/ipc-server.h"
#include "list.h"
#include "log.h"
#include "stringop.h"
#include <libtouch.h>
struct cmd_results *touch_gesture_cmd_delay(int argc, char **argv) {
struct cmd_results *error = NULL;
if((error = checkarg(argc, "delay", EXPECTED_EQUAL_TO, 1))) {
return error;
}
long int delay = strtol(argv[0],NULL,10);
if(delay == 0) {
return cmd_results_new(
CMD_INVALID, "Invalid delay %s", argv[0]);
}
if(!config->handler_context.current_gesture) {
return cmd_results_new(
CMD_FAILURE, "No current gesture");
}
struct libtouch_gesture *gesture =
config->handler_context.current_gesture->gesture;
struct libtouch_action *action =
libtouch_gesture_add_delay(gesture, delay);
config->handler_context.current_gesture_action = action;
return cmd_results_new(CMD_SUCCESS, NULL);
};

View file

@ -0,0 +1,38 @@
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/ipc-server.h"
#include "list.h"
#include "log.h"
#include "stringop.h"
#include <libtouch.h>
struct cmd_results *touch_gesture_cmd_pinch(int argc, char **argv) {
struct cmd_results *error = NULL;
if((error = checkarg(argc, "pinch", EXPECTED_EQUAL_TO, 1))) {
return error;
}
uint32_t mode;
if(strcmp(argv[0],"in") == 0) {
mode = LIBTOUCH_PINCH_IN;
} else if (strcmp(argv[0],"out") == 0) {
mode = LIBTOUCH_PINCH_OUT;
} else {
return cmd_results_new(CMD_INVALID, "pinch: %s is not in or out", argv[0]);
}
if(!config->handler_context.current_gesture) {
return cmd_results_new(CMD_FAILURE, "No current gesture");
}
struct libtouch_gesture *gesture = config->handler_context.current_gesture->gesture;
struct libtouch_action *action = libtouch_gesture_add_pinch(gesture, mode);
config->handler_context.current_gesture_action = action;
return cmd_results_new(CMD_SUCCESS, "Created new touch");
};

View file

@ -0,0 +1,45 @@
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/ipc-server.h"
#include "list.h"
#include "log.h"
#include "stringop.h"
#include <libtouch.h>
struct cmd_results *touch_gesture_cmd_rotate(int argc, char **argv) {
struct cmd_results *error = NULL;
if((error = checkarg(argc, "rotate", EXPECTED_EQUAL_TO, 1))) {
return error;
}
uint32_t mode;
if(strcmp(argv[0],"clockwise") == 0) {
mode = LIBTOUCH_ROTATE_CLOCKWISE;
} else if (strcmp(argv[0],"counterclockwise") == 0) {
mode = LIBTOUCH_ROTATE_ANTICLOCKWISE;
} else {
return cmd_results_new(
CMD_INVALID,
"rotate %s is not (anti)clockwise", 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_rotate(gesture, mode);
config->handler_context.current_gesture_action = action;
return cmd_results_new(CMD_SUCCESS, "Created new rotation");
};

View file

@ -0,0 +1,45 @@
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/ipc-server.h"
#include "list.h"
#include "log.h"
#include "stringop.h"
#include <libtouch.h>
struct cmd_results *touch_gesture_cmd_swipe(int argc, char **argv) {
struct cmd_results *error = NULL;
if((error = checkarg(argc, "swipe", EXPECTED_EQUAL_TO, 1))) {
return error;
}
uint32_t direction = 0;
if (strstr(argv[0], "west")) {
direction |= LIBTOUCH_MOVE_NEGATIVE_X;
}
if (strstr(argv[0], "east")) {
direction |= LIBTOUCH_MOVE_POSITIVE_X;
}
if (strstr(argv[0], "north")) {
direction |= LIBTOUCH_MOVE_POSITIVE_Y;
}
if (strstr(argv[0], "south")) {
direction |= LIBTOUCH_MOVE_NEGATIVE_Y;
}
sway_log(SWAY_DEBUG, "Direction: %d", direction);
if (direction == 0) {
return cmd_results_new(CMD_INVALID, "Direction %s invalid", argv[0]);
}
struct libtouch_gesture *gesture = config->handler_context.current_gesture->gesture;
struct libtouch_action *action = libtouch_gesture_add_move(gesture, direction);
config->handler_context.current_gesture_action = action;
return cmd_results_new(CMD_SUCCESS, "Created new swipe");
}

View file

@ -0,0 +1,38 @@
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/ipc-server.h"
#include "list.h"
#include "log.h"
#include "stringop.h"
#include <libtouch.h>
struct cmd_results *touch_gesture_cmd_target(int argc, char **argv) {
struct cmd_results *error = NULL;
if((error = checkarg(argc, "target", EXPECTED_AT_LEAST, 1))) {
return error;
}
struct gesture_target_config *target = get_gesture_target_config(argv[0]);
if(!target) {
return cmd_results_new(CMD_FAILURE, "Could not find gesture target %s", argv[0]);
}
if(!config->handler_context.current_gesture_action) {
return cmd_results_new(CMD_FAILURE,
"No action created for target %s", argv[0]);
}
libtouch_action_set_target(
config->handler_context.current_gesture_action,
target->target);
return cmd_results_new(CMD_SUCCESS, "Bound target %s to action", argv[0]);
}

View file

@ -0,0 +1,33 @@
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/ipc-server.h"
#include "list.h"
#include "log.h"
#include "stringop.h"
#include <libtouch.h>
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");
}
long int threshold = strtol(argv[0], NULL, 10);
if(threshold == 0) {
return cmd_results_new(
CMD_INVALID, "Invalid threshold: %s", argv[0]);
}
sway_log(SWAY_DEBUG, "Set threshold %ld", threshold);
libtouch_action_set_threshold(current, threshold);
return cmd_results_new(CMD_SUCCESS,
"Set threshold");
}

View file

@ -0,0 +1,40 @@
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/ipc-server.h"
#include "list.h"
#include "log.h"
#include "stringop.h"
#include <libtouch.h>
struct cmd_results *touch_gesture_cmd_touch(int argc, char **argv) {
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 touch");
};

View file

@ -0,0 +1,50 @@
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/ipc-server.h"
#include "list.h"
#include "log.h"
#include "stringop.h"
#include <libtouch.h>
struct cmd_results *touch_cmd_target(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "target", EXPECTED_EQUAL_TO, 5))) {
return error;
}
sway_log(SWAY_DEBUG, "Trying to convert");
double x = strtod(argv[1], NULL);
double y = strtod(argv[2], NULL);
double w = strtod(argv[3], NULL);
double h = strtod(argv[4], NULL);
sway_log(SWAY_DEBUG, "Converted: %f, %f, %f, %f", x,y,w,h);
if(!config->gesture_engine) {
return cmd_results_new(CMD_FAILURE, "No engine exists!");
}
struct gesture_target_config *conf = get_gesture_target_config(argv[0]);
if(!conf) {
return cmd_results_new(
CMD_FAILURE, "Could not create target: %s", argv[0]);
}
if(conf->target != NULL) {
return cmd_results_new(
CMD_FAILURE, "target %s already bound", argv[0]);
}
struct libtouch_target *target =
libtouch_target_create(config->gesture_engine, x,y,w,h);
if(!target) {
return cmd_results_new(CMD_FAILURE, "Could not create target");
}
conf->target = target;
return cmd_results_new(CMD_SUCCESS, "Created target: %s", argv[0]);
};

View file

@ -4,6 +4,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <libgen.h> #include <libgen.h>
#include <libtouch.h>
#include <wordexp.h> #include <wordexp.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
@ -142,6 +143,7 @@ void free_config(struct sway_config *config) {
free(config->floating_scroll_left_cmd); free(config->floating_scroll_left_cmd);
free(config->floating_scroll_right_cmd); free(config->floating_scroll_right_cmd);
free(config->font); free(config->font);
free(config->gesture_engine);
free(config->swaybg_command); free(config->swaybg_command);
free(config->swaynag_command); free(config->swaynag_command);
free((char *)config->current_config_path); free((char *)config->current_config_path);
@ -188,7 +190,8 @@ static void config_defaults(struct sway_config *config) {
"--button-no-terminal 'Exit sway' 'swaymsg exit' " "--button-no-terminal 'Exit sway' 'swaymsg exit' "
"--button-no-terminal 'Reload sway' 'swaymsg reload'"; "--button-no-terminal 'Reload sway' 'swaymsg reload'";
config->swaynag_config_errors.detailed = true; config->swaynag_config_errors.detailed = true;
if (!(config->gesture_configs = create_list())) goto cleanup;
if (!(config->gesture_target_configs = create_list())) goto cleanup;
if (!(config->symbols = create_list())) goto cleanup; if (!(config->symbols = create_list())) goto cleanup;
if (!(config->modes = create_list())) goto cleanup; if (!(config->modes = create_list())) goto cleanup;
if (!(config->bars = create_list())) goto cleanup; if (!(config->bars = create_list())) goto cleanup;
@ -312,6 +315,7 @@ static void config_defaults(struct sway_config *config) {
set_color(config->border_colors.background, 0xFFFFFF); set_color(config->border_colors.background, 0xFFFFFF);
if (!(config->gesture_engine = libtouch_engine_create())) goto cleanup;
// Security // Security
if (!(config->command_policies = create_list())) goto cleanup; if (!(config->command_policies = create_list())) goto cleanup;
if (!(config->feature_policies = create_list())) goto cleanup; if (!(config->feature_policies = create_list())) goto cleanup;

51
sway/config/gesture.c Normal file
View file

@ -0,0 +1,51 @@
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <limits.h>
#include <float.h>
#include "sway/config.h"
#include "log.h"
#include <libtouch.h>
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");
cfg = config->gesture_configs->items[i];
} else {
sway_log(SWAY_DEBUG, "Adding new gesture");
cfg = new_gesture_config(identifier);
}
return cfg;
}
struct gesture_config *new_gesture_config(const char *identifier) {
struct gesture_config *cfg = calloc(sizeof(struct gesture_config), 1);
if (!cfg) {
sway_log(SWAY_ERROR, "Failed to allocate gesture_config");
return NULL;
}
cfg->identifier = strdup(identifier);
cfg->gesture = libtouch_gesture_create(config->gesture_engine);
return cfg;
}
int gesture_identifier_cmp(const void *item, const void *data) {
const struct gesture_config *gc = item;
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;
if(gc->gesture == g) {
return 0;
} else {
return -1;
}
}

39
sway/config/target.c Normal file
View file

@ -0,0 +1,39 @@
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <limits.h>
#include <float.h>
#include "sway/config.h"
#include "log.h"
#include <libtouch.h>
struct gesture_target_config *get_gesture_target_config(const char* identifier) {
int i = list_seq_find(config->gesture_target_configs, gesture_target_identifier_cmp, identifier);
struct gesture_target_config *cfg = NULL;
if(i >= 0) {
cfg = config->gesture_target_configs->items[i];
} else {
cfg = create_gesture_target_config(identifier);
list_add(config->gesture_target_configs, cfg);
}
return cfg;
}
struct gesture_target_config *create_gesture_target_config(const char* identifier) {
struct gesture_target_config *cfg =
calloc(sizeof(struct gesture_target_config), 1);
if (!cfg) {
sway_log(
SWAY_ERROR, "Could not allocate gesture_target_config");
}
cfg->identifier = strdup(identifier);
return cfg;
}
int gesture_target_identifier_cmp(const void *item, const void *data) {
const struct gesture_target_config *tc = item;
const char* identifier = data;
return strcmp(identifier, tc->identifier);
}

View file

@ -28,6 +28,7 @@
#include "sway/tree/view.h" #include "sway/tree/view.h"
#include "sway/tree/workspace.h" #include "sway/tree/workspace.h"
#include "wlr-layer-shell-unstable-v1-protocol.h" #include "wlr-layer-shell-unstable-v1-protocol.h"
#include <libtouch.h>
static uint32_t get_current_time_msec(void) { static uint32_t get_current_time_msec(void) {
struct timespec now; struct timespec now;
@ -331,6 +332,23 @@ static void handle_cursor_frame(struct wl_listener *listener, void *data) {
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
} }
static void handle_gestures(struct libtouch_progress_tracker *tracker, struct sway_seat *seat) {
struct libtouch_gesture *complete;
while ((complete = libtouch_handle_finished_gesture(tracker)) != NULL) {
int idx = list_seq_find(config->gesture_configs,
gesture_libtouch_cmp, complete);
if (idx >= 0) {
struct gesture_config *cfg;
cfg = config->gesture_configs->items[idx];
if (cfg->command) {
execute_command(cfg->command, seat, NULL);
}
} else {
sway_log(SWAY_ERROR, "Gesture unbound!");
}
}
}
static void handle_touch_down(struct wl_listener *listener, void *data) { static void handle_touch_down(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_down); struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_down);
wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat); wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat);
@ -350,6 +368,14 @@ static void handle_touch_down(struct wl_listener *listener, void *data) {
seat->touch_x = lx; seat->touch_x = lx;
seat->touch_y = ly; seat->touch_y = ly;
libtouch_progress_register_touch(
cursor->gesture_tracker,
event->time_msec,
event->touch_id, LIBTOUCH_TOUCH_DOWN,
lx, ly);
handle_gestures(cursor->gesture_tracker, seat);
if (!surface) { if (!surface) {
return; return;
} }
@ -360,6 +386,7 @@ static void handle_touch_down(struct wl_listener *listener, void *data) {
event->touch_id, sx, sy); event->touch_id, sx, sy);
cursor_set_image(cursor, NULL, NULL); cursor_set_image(cursor, NULL, NULL);
} }
} }
static void handle_touch_up(struct wl_listener *listener, void *data) { static void handle_touch_up(struct wl_listener *listener, void *data) {
@ -369,6 +396,10 @@ static void handle_touch_up(struct wl_listener *listener, void *data) {
struct wlr_seat *seat = cursor->seat->wlr_seat; struct wlr_seat *seat = cursor->seat->wlr_seat;
// TODO: fall back to cursor simulation if client has not bound to touch // TODO: fall back to cursor simulation if client has not bound to touch
wlr_seat_touch_notify_up(seat, event->time_msec, event->touch_id); wlr_seat_touch_notify_up(seat, event->time_msec, event->touch_id);
libtouch_progress_register_touch(cursor->gesture_tracker, event->time_msec,
event->touch_id, LIBTOUCH_TOUCH_UP, 0, 0);
handle_gestures(cursor->gesture_tracker, cursor->seat);
} }
static void handle_touch_motion(struct wl_listener *listener, void *data) { static void handle_touch_motion(struct wl_listener *listener, void *data) {
@ -387,6 +418,12 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) {
double sx, sy; double sx, sy;
node_at_coords(cursor->seat, lx, ly, &surface, &sx, &sy); node_at_coords(cursor->seat, lx, ly, &surface, &sx, &sy);
sway_log(SWAY_DEBUG, "move gesture");
libtouch_progress_register_move(cursor->gesture_tracker, event->time_msec,
event->touch_id, lx,ly);
handle_gestures(cursor->gesture_tracker, seat);
if (seat->touch_id == event->touch_id) { if (seat->touch_id == event->touch_id) {
seat->touch_x = lx; seat->touch_x = lx;
seat->touch_y = ly; seat->touch_y = ly;

View file

@ -24,6 +24,7 @@
#include "sway/tree/root.h" #include "sway/tree/root.h"
#include "sway/tree/view.h" #include "sway/tree/view.h"
#include "sway/tree/workspace.h" #include "sway/tree/workspace.h"
#include <libtouch.h>
static void seat_device_destroy(struct sway_seat_device *seat_device) { static void seat_device_destroy(struct sway_seat_device *seat_device) {
if (!seat_device) { if (!seat_device) {
@ -1190,6 +1191,16 @@ void seat_apply_config(struct sway_seat *seat,
seat_configure_device(seat, seat_device->input_device); seat_configure_device(seat, seat_device->input_device);
} }
if(config->gesture_engine) {
sway_log(SWAY_DEBUG, "gesture engine exists");
if(seat->cursor->gesture_tracker) {
free(seat->cursor->gesture_tracker);
}
sway_log(SWAY_DEBUG, "Gesture progress tracker created");
seat->cursor->gesture_tracker = libtouch_progress_tracker_create(
config->gesture_engine);
}
cursor_handle_activity(seat->cursor); cursor_handle_activity(seat->cursor);
} }

View file

@ -36,6 +36,8 @@ sway_sources = files(
'config/output.c', 'config/output.c',
'config/seat.c', 'config/seat.c',
'config/input.c', 'config/input.c',
'config/gesture.c',
'config/target.c',
'commands/assign.c', 'commands/assign.c',
'commands/bar.c', 'commands/bar.c',
@ -62,6 +64,7 @@ sway_sources = files(
'commands/force_focus_wrapping.c', 'commands/force_focus_wrapping.c',
'commands/fullscreen.c', 'commands/fullscreen.c',
'commands/gaps.c', 'commands/gaps.c',
'commands/touch.c',
'commands/hide_edge_borders.c', 'commands/hide_edge_borders.c',
'commands/inhibit_idle.c', 'commands/inhibit_idle.c',
'commands/kill.c', 'commands/kill.c',
@ -175,6 +178,17 @@ sway_sources = files(
'commands/output/subpixel.c', 'commands/output/subpixel.c',
'commands/output/transform.c', 'commands/output/transform.c',
'commands/touch/binding.c',
'commands/touch/gesture.c',
'commands/touch/target.c',
'commands/touch/gesture/touch.c',
'commands/touch/gesture/threshold.c',
'commands/touch/gesture/target.c',
'commands/touch/gesture/swipe.c',
'commands/touch/gesture/rotate.c',
'commands/touch/gesture/pinch.c',
'commands/touch/gesture/delay.c',
'tree/arrange.c', 'tree/arrange.c',
'tree/container.c', 'tree/container.c',
'tree/node.c', 'tree/node.c',
@ -185,6 +199,7 @@ sway_sources = files(
) )
sway_deps = [ sway_deps = [
libtouch,
cairo, cairo,
jsonc, jsonc,
libevdev, libevdev,