Skip to content

Commit

Permalink
Moved to bindworkspacegesture instead of bindgesture
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikReider committed Jan 22, 2024
1 parent 0676138 commit 8bfa708
Show file tree
Hide file tree
Showing 8 changed files with 212 additions and 63 deletions.
85 changes: 57 additions & 28 deletions common/gesture.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ char *gesture_parse(const char *input, struct gesture *output) {
output->type = GESTURE_TYPE_PINCH;
} else if (strcmp(split->items[0], "swipe") == 0) {
output->type = GESTURE_TYPE_SWIPE;
} else if (strcmp(split->items[0], "workspace_swipe") == 0) {
output->type = GESTURE_TYPE_WORKSPACE_SWIPE;
} else {
return strformat("expected hold|pinch|swipe, got %s",
split->items[0]);
Expand Down Expand Up @@ -96,10 +94,58 @@ char *gesture_parse(const char *input, struct gesture *output) {
output->directions |= GESTURE_DIRECTION_CLOCKWISE;
} else if (strcmp(item, "counterclockwise") == 0) {
output->directions |= GESTURE_DIRECTION_COUNTERCLOCKWISE;
} else if (strcmp(item, "horizontal") == 0) {
output->directions |= GESTURE_DIRECTION_HORIZONTAL;
} else {
return strformat("expected direction, got %s", item);
}
}
list_free_items_and_destroy(directions);
}
} // if optional args

list_free_items_and_destroy(split);

return NULL;
}

char *workspace_gesture_parse(const char *input, struct gesture *output) {
// Clear output in case of failure
output->type = GESTURE_TYPE_NONE;
output->fingers = GESTURE_FINGERS_ANY;
output->directions = GESTURE_DIRECTION_NONE;

// Split input type, fingers and directions
list_t *split = split_string(input, ":");
if (split->length < 1 || split->length > 3) {
return strformat(
"expected [:<fingers>][:direction], got %s",
input);
}

// Parse optional arguments
if (split->length > 1) {
char *next = split->items[1];

// Try to parse as finger count (1-9)
if (strlen(next) == 1 && '1' <= next[0] && next[0] <= '9') {
output->fingers = atoi(next);

// Move to next if available
next = split->length == 3 ? split->items[2] : NULL;
} else if (split->length == 3) {
// Fail here if argument can only be finger count
return strformat("expected 1-9, got %s", next);
}

// If there is an argument left, try to parse as direction
if (next) {
list_t *directions = split_string(next, "+");

for (int i = 0; i < directions->length; ++i) {
const char *item = directions->items[i];
if (strcmp(item, "horizontal") == 0) {
output->type = GESTURE_TYPE_WORKSPACE_SWIPE_HORIZONTAL;
} else if (strcmp(item, "vertical") == 0) {
output->directions |= GESTURE_DIRECTION_VERTICAL;
output->type = GESTURE_TYPE_WORKSPACE_SWIPE_VERTICAL;
} else {
return strformat("expected direction, got %s", item);
}
Expand All @@ -123,22 +169,15 @@ const char *gesture_type_string(enum gesture_type type) {
return "pinch";
case GESTURE_TYPE_SWIPE:
return "swipe";
case GESTURE_TYPE_WORKSPACE_SWIPE:
return "workspace_swipe";
case GESTURE_TYPE_WORKSPACE_SWIPE_HORIZONTAL:
return "workspace_swipe_horizontal";
case GESTURE_TYPE_WORKSPACE_SWIPE_VERTICAL:
return "workspace_swipe_vertical";
}

return NULL;
}

int gesture_workspace_swipe_command_parse(char *cmd) {
if (strcmp(cmd, "normal") == 0) {
return -1;
} else if (strcmp(cmd, "inverted") == 0) {
return 1;
}
return 0;
}

const char *gesture_direction_string(enum gesture_direction direction) {
switch (direction) {
case GESTURE_DIRECTION_NONE:
Expand All @@ -159,10 +198,6 @@ const char *gesture_direction_string(enum gesture_direction direction) {
return "clockwise";
case GESTURE_DIRECTION_COUNTERCLOCKWISE:
return "counterclockwise";
case GESTURE_DIRECTION_HORIZONTAL:
return "horizontal";
case GESTURE_DIRECTION_VERTICAL:
return "vertical";
}

return NULL;
Expand Down Expand Up @@ -334,14 +369,6 @@ struct gesture *gesture_tracker_end(struct gesture_tracker *tracker) {
result->directions |= GESTURE_DIRECTION_INWARD;
}
__attribute__ ((fallthrough));
// Gestures with dx and dy
case GESTURE_TYPE_WORKSPACE_SWIPE:
if (fabs(tracker->dx) > fabs(tracker->dy)) {
result->directions |= GESTURE_DIRECTION_HORIZONTAL;
} else {
result->directions |= GESTURE_DIRECTION_VERTICAL;
}
__attribute__ ((fallthrough));
case GESTURE_TYPE_SWIPE:
if (fabs(tracker->dx) > fabs(tracker->dy)) {
if (tracker->dx > 0) {
Expand All @@ -358,6 +385,8 @@ struct gesture *gesture_tracker_end(struct gesture_tracker *tracker) {
}
// Gesture without any direction
case GESTURE_TYPE_HOLD:
case GESTURE_TYPE_WORKSPACE_SWIPE_HORIZONTAL:
case GESTURE_TYPE_WORKSPACE_SWIPE_VERTICAL:
break;
// Not tracking any gesture
case GESTURE_TYPE_NONE:
Expand Down
15 changes: 9 additions & 6 deletions include/gesture.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ enum gesture_type {
GESTURE_TYPE_HOLD,
GESTURE_TYPE_PINCH,
GESTURE_TYPE_SWIPE,
GESTURE_TYPE_WORKSPACE_SWIPE,
GESTURE_TYPE_WORKSPACE_SWIPE_HORIZONTAL,
GESTURE_TYPE_WORKSPACE_SWIPE_VERTICAL,
};

// Turns single type enum value to constant string representation.
const char *gesture_type_string(enum gesture_type direction);

int gesture_workspace_swipe_command_parse(char *cmd);

// Value to use to accept any finger count
extern const uint8_t GESTURE_FINGERS_ANY;

Expand All @@ -39,9 +38,6 @@ enum gesture_direction {
// Directions based on rotation
GESTURE_DIRECTION_CLOCKWISE = 1 << 6,
GESTURE_DIRECTION_COUNTERCLOCKWISE = 1 << 7,
// Directions for workspace swipe
GESTURE_DIRECTION_HORIZONTAL = 1 << 8,
GESTURE_DIRECTION_VERTICAL = 1 << 9,
};

// Turns single direction enum value to constant string representation.
Expand All @@ -63,6 +59,13 @@ struct gesture {
*/
char *gesture_parse(const char *input, struct gesture *output);

/**
* Parses workspace gesture from [:<fingers>][:<directions>] string.
*
* Return NULL on success, otherwise error message string
*/
char *workspace_gesture_parse(const char *input, struct gesture *output);

// Turns gesture into string representation
char *gesture_to_string(struct gesture *gesture);

Expand Down
2 changes: 2 additions & 0 deletions include/sway/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ sway_cmd cmd_bindcode;
sway_cmd cmd_bindgesture;
sway_cmd cmd_bindswitch;
sway_cmd cmd_bindsym;
sway_cmd cmd_bindworkspacegesture;
sway_cmd cmd_blur;
sway_cmd cmd_blur_brightness;
sway_cmd cmd_blur_contrast;
Expand Down Expand Up @@ -223,6 +224,7 @@ sway_cmd cmd_unbindcode;
sway_cmd cmd_unbindswitch;
sway_cmd cmd_unbindgesture;
sway_cmd cmd_unbindsym;
sway_cmd cmd_unbindworkspacegesture;
sway_cmd cmd_unmark;
sway_cmd cmd_urgent;
sway_cmd cmd_workspace;
Expand Down
1 change: 1 addition & 0 deletions include/sway/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ enum binding_flags {
BINDING_INHIBITED = 1 << 7, // keyboard only: ignore shortcut inhibitor
BINDING_NOREPEAT = 1 << 8, // keyboard only; do not trigger when repeating a held key
BINDING_EXACT = 1 << 9, // gesture only; only trigger on exact match
BINDING_INVERTED = 1 << 10, // workspace gesture only; gesture is inverted
};

/**
Expand Down
2 changes: 2 additions & 0 deletions sway/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ static const struct cmd_handler handlers[] = {
{ "bindgesture", cmd_bindgesture },
{ "bindswitch", cmd_bindswitch },
{ "bindsym", cmd_bindsym },
{ "bindworkspacegesture", cmd_bindworkspacegesture },
{ "blur", cmd_blur },
{ "blur_brightness", cmd_blur_brightness },
{ "blur_contrast", cmd_blur_contrast },
Expand Down Expand Up @@ -118,6 +119,7 @@ static const struct cmd_handler handlers[] = {
{ "unbindgesture", cmd_unbindgesture },
{ "unbindswitch", cmd_unbindswitch },
{ "unbindsym", cmd_unbindsym },
{ "unbindworkspacegesture", cmd_unbindworkspacegesture },
{ "workspace", cmd_workspace },
{ "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth },
};
Expand Down
86 changes: 73 additions & 13 deletions sway/commands/gesture.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,19 +154,6 @@ static struct cmd_results *cmd_bind_or_unbind_gesture(int argc, char **argv, boo
return gesture_binding_remove(binding, argv[0]);
}
binding->command = join_args(argv + 1, argc - 1);
// Make sure that the gesture command is valid
switch (binding->gesture.type) {
case GESTURE_TYPE_WORKSPACE_SWIPE:
if (gesture_workspace_swipe_command_parse(binding->command) == 0) {
free(binding);
return cmd_results_new(CMD_FAILURE,
"Invalid %s command (%s). Either normal or inverted",
bindtype, errmsg);
}
break;
default:
break;
}
return gesture_binding_add(binding, argv[0], warn);
}

Expand All @@ -177,3 +164,76 @@ struct cmd_results *cmd_bindgesture(int argc, char **argv) {
struct cmd_results *cmd_unbindgesture(int argc, char **argv) {
return cmd_bind_or_unbind_gesture(argc, argv, true);
}

/**
* Parse and execute bindgesture or unbindgesture command.
*/
static struct cmd_results *cmd_bind_or_unbind_workspacegesture(int argc,
char **argv, bool unbind) {
int minargs = 1;
char *bindtype = "bindgesture";
if (unbind) {
bindtype = "unbindgesture";
}

struct cmd_results *error = NULL;
if ((error = checkarg(argc, bindtype, EXPECTED_AT_LEAST, minargs))) {
return error;
}
struct sway_gesture_binding *binding = calloc(1, sizeof(struct sway_gesture_binding));
if (!binding) {
return cmd_results_new(CMD_FAILURE, "Unable to allocate binding");
}
binding->input = strdup("*");

bool warn = true;

// Handle flags
binding->flags |= BINDING_EXACT;
while (argc > 0) {
if (strcmp("--inverted", argv[0]) == 0) {
binding->flags |= BINDING_INVERTED;
} else if (strcmp("--no-warn", argv[0]) == 0) {
warn = false;
} else if (strncmp("--input-device=", argv[0],
strlen("--input-device=")) == 0) {
free(binding->input);
binding->input = strdup(argv[0] + strlen("--input-device="));
} else {
break;
}
argv++;
argc--;
}

if (argc < minargs) {
free(binding);
return cmd_results_new(CMD_FAILURE,
"Invalid %s command (expected at least %d "
"non-option arguments, got %d)", bindtype, minargs, argc);
}

char* errmsg = NULL;
if ((errmsg = workspace_gesture_parse(argv[0], &binding->gesture))) {
free(binding);
struct cmd_results *final = cmd_results_new(CMD_FAILURE,
"Invalid %s command (%s)",
bindtype, errmsg);
free(errmsg);
return final;
}

if (unbind) {
return gesture_binding_remove(binding, argv[0]);
}
binding->command = NULL;
return gesture_binding_add(binding, argv[0], warn);
}

struct cmd_results *cmd_bindworkspacegesture(int argc, char **argv) {
return cmd_bind_or_unbind_workspacegesture(argc, argv, false);
}

struct cmd_results *cmd_unbindworkspacegesture(int argc, char **argv) {
return cmd_bind_or_unbind_workspacegesture(argc, argv, true);
}
Loading

0 comments on commit 8bfa708

Please sign in to comment.