mirror of
https://github.com/swaywm/sway.git
synced 2026-04-23 06:46:27 -04:00
sway/bar: add bindgesture support
This commit is contained in:
parent
cab2189aa6
commit
b896841824
8 changed files with 169 additions and 0 deletions
|
|
@ -202,6 +202,7 @@ sway_cmd cmd_ws_auto_back_and_forth;
|
||||||
sway_cmd cmd_xwayland;
|
sway_cmd cmd_xwayland;
|
||||||
|
|
||||||
sway_cmd bar_cmd_bindcode;
|
sway_cmd bar_cmd_bindcode;
|
||||||
|
sway_cmd bar_cmd_bindgesture;
|
||||||
sway_cmd bar_cmd_binding_mode_indicator;
|
sway_cmd bar_cmd_binding_mode_indicator;
|
||||||
sway_cmd bar_cmd_bindsym;
|
sway_cmd bar_cmd_bindsym;
|
||||||
sway_cmd bar_cmd_colors;
|
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_output;
|
||||||
sway_cmd bar_cmd_tray_padding;
|
sway_cmd bar_cmd_tray_padding;
|
||||||
sway_cmd bar_cmd_unbindcode;
|
sway_cmd bar_cmd_unbindcode;
|
||||||
|
sway_cmd bar_cmd_unbindgesture;
|
||||||
sway_cmd bar_cmd_unbindsym;
|
sway_cmd bar_cmd_unbindsym;
|
||||||
sway_cmd bar_cmd_wrap_scroll;
|
sway_cmd bar_cmd_wrap_scroll;
|
||||||
sway_cmd bar_cmd_workspace_buttons;
|
sway_cmd bar_cmd_workspace_buttons;
|
||||||
|
|
|
||||||
|
|
@ -355,6 +355,7 @@ struct bar_config {
|
||||||
list_t *outputs;
|
list_t *outputs;
|
||||||
char *position;
|
char *position;
|
||||||
list_t *bindings;
|
list_t *bindings;
|
||||||
|
list_t *gestures;
|
||||||
char *status_command;
|
char *status_command;
|
||||||
enum pango_markup_config pango_markup;
|
enum pango_markup_config pango_markup;
|
||||||
char *font;
|
char *font;
|
||||||
|
|
@ -408,6 +409,11 @@ struct bar_binding {
|
||||||
char *command;
|
char *command;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct bar_gesture {
|
||||||
|
struct gesture gesture;
|
||||||
|
char *command;
|
||||||
|
};
|
||||||
|
|
||||||
#if HAVE_TRAY
|
#if HAVE_TRAY
|
||||||
struct tray_binding {
|
struct tray_binding {
|
||||||
uint32_t button;
|
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_binding(struct bar_binding *binding);
|
||||||
|
|
||||||
|
void free_bar_gesture(struct bar_gesture *binding);
|
||||||
|
|
||||||
void free_workspace_config(struct workspace_config *wsc);
|
void free_workspace_config(struct workspace_config *wsc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
// Must be in alphabetical order for bsearch
|
// Must be in alphabetical order for bsearch
|
||||||
static const struct cmd_handler bar_handlers[] = {
|
static const struct cmd_handler bar_handlers[] = {
|
||||||
{ "bindcode", bar_cmd_bindcode },
|
{ "bindcode", bar_cmd_bindcode },
|
||||||
|
{ "bindgesture", bar_cmd_bindgesture },
|
||||||
{ "binding_mode_indicator", bar_cmd_binding_mode_indicator },
|
{ "binding_mode_indicator", bar_cmd_binding_mode_indicator },
|
||||||
{ "bindsym", bar_cmd_bindsym },
|
{ "bindsym", bar_cmd_bindsym },
|
||||||
{ "colors", bar_cmd_colors },
|
{ "colors", bar_cmd_colors },
|
||||||
|
|
@ -34,6 +35,7 @@ static const struct cmd_handler bar_handlers[] = {
|
||||||
{ "tray_output", bar_cmd_tray_output },
|
{ "tray_output", bar_cmd_tray_output },
|
||||||
{ "tray_padding", bar_cmd_tray_padding },
|
{ "tray_padding", bar_cmd_tray_padding },
|
||||||
{ "unbindcode", bar_cmd_unbindcode },
|
{ "unbindcode", bar_cmd_unbindcode },
|
||||||
|
{ "unbindgesture", bar_cmd_unbindgesture },
|
||||||
{ "unbindsym", bar_cmd_unbindsym },
|
{ "unbindsym", bar_cmd_unbindsym },
|
||||||
{ "workspace_buttons", bar_cmd_workspace_buttons },
|
{ "workspace_buttons", bar_cmd_workspace_buttons },
|
||||||
{ "workspace_min_width", bar_cmd_workspace_min_width },
|
{ "workspace_min_width", bar_cmd_workspace_min_width },
|
||||||
|
|
|
||||||
109
sway/commands/bar/gesture.c
Normal file
109
sway/commands/bar/gesture.c
Normal 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(¤t->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(¤t->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);
|
||||||
|
}
|
||||||
|
|
@ -27,6 +27,14 @@ void free_bar_binding(struct bar_binding *binding) {
|
||||||
free(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) {
|
void free_bar_config(struct bar_config *bar) {
|
||||||
if (!bar) {
|
if (!bar) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -45,6 +53,12 @@ void free_bar_config(struct bar_config *bar) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list_free(bar->bindings);
|
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);
|
list_free_items_and_destroy(bar->outputs);
|
||||||
if (bar->client != NULL) {
|
if (bar->client != NULL) {
|
||||||
wl_client_destroy(bar->client);
|
wl_client_destroy(bar->client);
|
||||||
|
|
@ -115,6 +129,9 @@ struct bar_config *default_bar_config(void) {
|
||||||
if (!(bar->bindings = create_list())) {
|
if (!(bar->bindings = create_list())) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
if (!(bar->gestures = create_list())) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
// set default colors
|
// set default colors
|
||||||
if (!(bar->colors.background = strndup("#000000ff", 9))) {
|
if (!(bar->colors.background = strndup("#000000ff", 9))) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
|
||||||
|
|
@ -1241,6 +1241,25 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
|
||||||
json_object_object_add(json, "bindings", bindings);
|
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
|
// Add outputs if defined
|
||||||
if (bar->outputs && bar->outputs->length > 0) {
|
if (bar->outputs && bar->outputs->length > 0) {
|
||||||
json_object *outputs = json_object_new_array();
|
json_object *outputs = json_object_new_array();
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,7 @@ sway_sources = files(
|
||||||
'commands/bar/colors.c',
|
'commands/bar/colors.c',
|
||||||
'commands/bar/font.c',
|
'commands/bar/font.c',
|
||||||
'commands/bar/gaps.c',
|
'commands/bar/gaps.c',
|
||||||
|
'commands/bar/gesture.c',
|
||||||
'commands/bar/height.c',
|
'commands/bar/height.c',
|
||||||
'commands/bar/hidden_state.c',
|
'commands/bar/hidden_state.c',
|
||||||
'commands/bar/icon_theme.c',
|
'commands/bar/icon_theme.c',
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,14 @@ runtime.
|
||||||
an event code, which can be obtaining from *libinput debug-events*. To
|
an event code, which can be obtaining from *libinput debug-events*. To
|
||||||
disable the default behavior for a button, use the command _nop_.
|
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>
|
*bindsym* [--release] button[1-9]|<event-name> <command>
|
||||||
Executes _command_ when the mouse button has been pressed (or if _released_
|
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
|
is given, when the button has been released). The buttons can be given as a
|
||||||
|
|
@ -128,6 +136,9 @@ runtime.
|
||||||
*unbindcode* [--release] <event-code>
|
*unbindcode* [--release] <event-code>
|
||||||
Removes the binding with the given <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>
|
*unbindsym* [--release] button[1-9]|<event-name>
|
||||||
Removes the binding with the given <button> or <event-name>.
|
Removes the binding with the given <button> or <event-name>.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue