mirror of
https://github.com/swaywm/sway.git
synced 2025-02-26 11:11:21 +00: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 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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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>.
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue