sway/bar: add bindgesture support

This commit is contained in:
Florian Franzen 2022-01-20 22:12:09 +01:00
parent cab2189aa6
commit b896841824
8 changed files with 169 additions and 0 deletions

View file

@ -202,6 +202,7 @@ sway_cmd cmd_ws_auto_back_and_forth;
sway_cmd cmd_xwayland;
sway_cmd bar_cmd_bindcode;
sway_cmd bar_cmd_bindgesture;
sway_cmd bar_cmd_binding_mode_indicator;
sway_cmd bar_cmd_bindsym;
sway_cmd bar_cmd_colors;
@ -228,6 +229,7 @@ sway_cmd bar_cmd_tray_bindsym;
sway_cmd bar_cmd_tray_output;
sway_cmd bar_cmd_tray_padding;
sway_cmd bar_cmd_unbindcode;
sway_cmd bar_cmd_unbindgesture;
sway_cmd bar_cmd_unbindsym;
sway_cmd bar_cmd_wrap_scroll;
sway_cmd bar_cmd_workspace_buttons;

View file

@ -355,6 +355,7 @@ struct bar_config {
list_t *outputs;
char *position;
list_t *bindings;
list_t *gestures;
char *status_command;
enum pango_markup_config pango_markup;
char *font;
@ -408,6 +409,11 @@ struct bar_binding {
char *command;
};
struct bar_gesture {
struct gesture gesture;
char *command;
};
#if HAVE_TRAY
struct tray_binding {
uint32_t button;
@ -717,6 +723,8 @@ void free_bar_config(struct bar_config *bar);
void free_bar_binding(struct bar_binding *binding);
void free_bar_gesture(struct bar_gesture *binding);
void free_workspace_config(struct workspace_config *wsc);
/**

View file

@ -10,6 +10,7 @@
// Must be in alphabetical order for bsearch
static const struct cmd_handler bar_handlers[] = {
{ "bindcode", bar_cmd_bindcode },
{ "bindgesture", bar_cmd_bindgesture },
{ "binding_mode_indicator", bar_cmd_binding_mode_indicator },
{ "bindsym", bar_cmd_bindsym },
{ "colors", bar_cmd_colors },
@ -34,6 +35,7 @@ static const struct cmd_handler bar_handlers[] = {
{ "tray_output", bar_cmd_tray_output },
{ "tray_padding", bar_cmd_tray_padding },
{ "unbindcode", bar_cmd_unbindcode },
{ "unbindgesture", bar_cmd_unbindgesture },
{ "unbindsym", bar_cmd_unbindsym },
{ "workspace_buttons", bar_cmd_workspace_buttons },
{ "workspace_min_width", bar_cmd_workspace_min_width },

109
sway/commands/bar/gesture.c Normal file
View file

@ -0,0 +1,109 @@
#define _POSIX_C_SOURCE 200809L
#include "sway/config.h"
#include <stdbool.h>
#include "log.h"
#include "stringop.h"
#include "sway/commands.h"
/**
* Add gesture binding to config
*/
static struct cmd_results *bar_gesture_add(
struct bar_gesture *binding, const char *name) {
list_t *gestures = config->current_bar->gestures;
// overwrite the binding if it already exists
bool overwritten = false;
for (int i = 0; i < gestures->length; ++i) {
struct bar_gesture *current = gestures->items[i];
if (gesture_equal(&current->gesture, &binding->gesture)) {
overwritten = true;
gestures->items[i] = binding;
free_bar_gesture(current);
sway_log(SWAY_DEBUG, "[bar %s] Updated gesture for %s",
config->current_bar->id, name);
break;
}
}
if (!overwritten) {
list_add(gestures, binding);
sway_log(SWAY_DEBUG, "[bar %s] Added binding for %s",
config->current_bar->id, name);
}
return cmd_results_new(CMD_SUCCESS, NULL);
}
/**
* Remove gesture binding from config
*/
static struct cmd_results *bar_gesture_remove(
struct bar_gesture *binding, const char *name) {
list_t *gestures = config->current_bar->gestures;
for (int i = 0; i < gestures->length; ++i) {
struct bar_gesture *current = gestures->items[i];
if (gesture_equal(&current->gesture, &binding->gesture)) {
sway_log(SWAY_DEBUG, "[bar %s] Unbound binding for %s",
config->current_bar->id, name);
free_bar_gesture(current);
free_bar_gesture(binding);
list_del(gestures, i);
return cmd_results_new(CMD_SUCCESS, NULL);
}
}
free_bar_gesture(binding);
return cmd_results_new(CMD_FAILURE,
"Could not find gesture for [bar %s] %s",
config->current_bar->id, name);
}
/**
* Parse and execute bindgesture or unbindgesture command.
*/
static struct cmd_results *bar_cmd_gesture(int argc, char **argv, bool unbind) {
int minargs = 2;
char *bindtype = "bindgesture";
if (unbind) {
minargs--;
bindtype = "unbindgesture";
}
struct cmd_results *error = NULL;
if ((error = checkarg(argc, bindtype, EXPECTED_AT_LEAST, minargs))) {
return error;
}
struct bar_gesture *binding = calloc(1, sizeof(struct bar_gesture));
if (!binding) {
return cmd_results_new(CMD_FAILURE, "Unable to allocate binding");
}
char *errmsg = NULL;
if ((errmsg = 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 bar_gesture_remove(binding, argv[0]);
}
binding->command = join_args(argv + 1, argc - 1);
return bar_gesture_add(binding, argv[0]);
}
struct cmd_results *bar_cmd_bindgesture(int argc, char **argv) {
return bar_cmd_gesture(argc, argv, false);
}
struct cmd_results *bar_cmd_unbindgesture(int argc, char **argv) {
return bar_cmd_gesture(argc, argv, true);
}

View file

@ -27,6 +27,14 @@ void free_bar_binding(struct bar_binding *binding) {
free(binding);
}
void free_bar_gesture(struct bar_gesture *gesture) {
if (!gesture) {
return;
}
free(gesture->command);
free(gesture);
}
void free_bar_config(struct bar_config *bar) {
if (!bar) {
return;
@ -45,6 +53,12 @@ void free_bar_config(struct bar_config *bar) {
}
}
list_free(bar->bindings);
if (bar->gestures) {
for (int i = 0; i < bar->gestures->length; i++) {
free_bar_gesture(bar->gestures->items[i]);
}
}
list_free(bar->gestures);
list_free_items_and_destroy(bar->outputs);
if (bar->client != NULL) {
wl_client_destroy(bar->client);
@ -115,6 +129,9 @@ struct bar_config *default_bar_config(void) {
if (!(bar->bindings = create_list())) {
goto cleanup;
}
if (!(bar->gestures = create_list())) {
goto cleanup;
}
// set default colors
if (!(bar->colors.background = strndup("#000000ff", 9))) {
goto cleanup;

View file

@ -1241,6 +1241,25 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
json_object_object_add(json, "bindings", bindings);
}
if (bar->gestures->length > 0) {
json_object *gestures = json_object_new_array();
for (int i = 0; i < bar->gestures->length; ++i) {
struct bar_gesture *binding = bar->gestures->items[i];
struct gesture *gesture = &binding->gesture;
json_object *bind = json_object_new_object();
json_object_object_add(bind, "type",
json_object_new_int(gesture->type));
json_object_object_add(bind, "fingers",
json_object_new_int(gesture->fingers));
json_object_object_add(bind, "directions",
json_object_new_int(gesture->directions));
json_object_object_add(bind, "command",
json_object_new_string(binding->command));
json_object_array_add(gestures, bind);
}
json_object_object_add(json, "gestures", gestures);
}
// Add outputs if defined
if (bar->outputs && bar->outputs->length > 0) {
json_object *outputs = json_object_new_array();

View file

@ -128,6 +128,7 @@ sway_sources = files(
'commands/bar/colors.c',
'commands/bar/font.c',
'commands/bar/gaps.c',
'commands/bar/gesture.c',
'commands/bar/height.c',
'commands/bar/hidden_state.c',
'commands/bar/icon_theme.c',

View file

@ -27,6 +27,14 @@ runtime.
an event code, which can be obtaining from *libinput debug-events*. To
disable the default behavior for a button, use the command _nop_.
*bindgesture* <gesture>[:<fingers>][:directions] <command>
Executes _command_ when the _gesture_ has been detected. _gesture_ can be
_hold_, _pinch_ or _swipe_. The optional _fingers_ allows you to limit the
binding to gestures with only a certain number of finger. The optional
_directions_ allows you to limit the binding to a gesture in a certain
direction, i.e. either _up_, _down_, _left_ or _right_ as well as
_inward_, _outward_, _clockwise_ and _counterclockwise_.
*bindsym* [--release] button[1-9]|<event-name> <command>
Executes _command_ when the mouse button has been pressed (or if _released_
is given, when the button has been released). The buttons can be given as a
@ -128,6 +136,9 @@ runtime.
*unbindcode* [--release] <event-code>
Removes the binding with the given <event-code>.
*unbindgesture* <gesture>[:<fingers>][:directions]
Removes the gesture binding with the given <gesture>, etc.
*unbindsym* [--release] button[1-9]|<event-name>
Removes the binding with the given <button> or <event-name>.