bind{code,sym}: utilize mouse button helpers
This modifies `bindcode` and `bindsym` to use `get_mouse_bindcode` and `get_mouse_bindsym`, respectively, to parse mouse buttons. Additionally, the `BINDING_MOUSE` type has been split into `BINDING_MOUSECODE` and `BINDING_MOUSESYM` to match keys and allow for mouse bindcodes to be used. Between the two commands, all button syms and codes should be supported, including x11 axis buttons.
This commit is contained in:
parent
6f6a9af60e
commit
eefa6b1ad3
|
@ -27,7 +27,8 @@ struct sway_variable {
|
|||
enum binding_input_type {
|
||||
BINDING_KEYCODE,
|
||||
BINDING_KEYSYM,
|
||||
BINDING_MOUSE,
|
||||
BINDING_MOUSECODE,
|
||||
BINDING_MOUSESYM,
|
||||
};
|
||||
|
||||
enum binding_flags {
|
||||
|
|
|
@ -85,69 +85,91 @@ static int key_qsort_cmp(const void *keyp_a, const void *keyp_b) {
|
|||
*/
|
||||
static struct cmd_results *identify_key(const char* name, bool first_key,
|
||||
uint32_t* key_val, enum binding_input_type* type) {
|
||||
if (*type == BINDING_KEYCODE) {
|
||||
// check for keycode
|
||||
if (*type == BINDING_MOUSECODE) {
|
||||
// check for mouse bindcodes
|
||||
char *message = NULL;
|
||||
uint32_t button = get_mouse_bindcode(name, &message);
|
||||
if (!button) {
|
||||
if (message) {
|
||||
struct cmd_results *error =
|
||||
cmd_results_new(CMD_INVALID, "bindcode", message);
|
||||
free(message);
|
||||
return error;
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID, "bindcode",
|
||||
"Unknown button code %s", name);
|
||||
}
|
||||
}
|
||||
*key_val = button;
|
||||
} else if (*type == BINDING_MOUSESYM) {
|
||||
// check for mouse bindsyms (x11 buttons or event names)
|
||||
char *message = NULL;
|
||||
uint32_t button = get_mouse_bindsym(name, &message);
|
||||
if (!button) {
|
||||
if (message) {
|
||||
struct cmd_results *error =
|
||||
cmd_results_new(CMD_INVALID, "bindsym", message);
|
||||
free(message);
|
||||
return error;
|
||||
} else if (!button) {
|
||||
return cmd_results_new(CMD_INVALID, "bindsym",
|
||||
"Unknown button %s", name);
|
||||
}
|
||||
}
|
||||
*key_val = button;
|
||||
} else if (*type == BINDING_KEYCODE) {
|
||||
// check for keycode. If it is the first key, allow mouse bindcodes
|
||||
if (first_key) {
|
||||
char *message = NULL;
|
||||
uint32_t button = get_mouse_bindcode(name, &message);
|
||||
free(message);
|
||||
if (button) {
|
||||
*type = BINDING_MOUSECODE;
|
||||
*key_val = button;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
xkb_keycode_t keycode = strtol(name, NULL, 10);
|
||||
if (!xkb_keycode_is_legal_ext(keycode)) {
|
||||
return cmd_results_new(CMD_INVALID, "bindcode",
|
||||
"Invalid keycode '%s'", name);
|
||||
if (first_key) {
|
||||
return cmd_results_new(CMD_INVALID, "bindcode",
|
||||
"Invalid keycode or button code '%s'", name);
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID, "bindcode",
|
||||
"Invalid keycode '%s'", name);
|
||||
}
|
||||
}
|
||||
*key_val = keycode;
|
||||
} else {
|
||||
// check for keysym
|
||||
// check for keysym. If it is the first key, allow mouse bindsyms
|
||||
if (first_key) {
|
||||
char *message = NULL;
|
||||
uint32_t button = get_mouse_bindsym(name, &message);
|
||||
if (message) {
|
||||
struct cmd_results *error =
|
||||
cmd_results_new(CMD_INVALID, "bindsym", message);
|
||||
free(message);
|
||||
return error;
|
||||
} else if (button) {
|
||||
*type = BINDING_MOUSESYM;
|
||||
*key_val = button;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
xkb_keysym_t keysym = xkb_keysym_from_name(name,
|
||||
XKB_KEYSYM_CASE_INSENSITIVE);
|
||||
|
||||
// Check for mouse binding
|
||||
uint32_t button = 0;
|
||||
if (strncasecmp(name, "button", strlen("button")) == 0) {
|
||||
// Map to x11 mouse buttons
|
||||
button = name[strlen("button")] - '0';
|
||||
if (button < 1 || button > 9 || strlen(name) > strlen("button0")) {
|
||||
if (!keysym) {
|
||||
if (first_key) {
|
||||
return cmd_results_new(CMD_INVALID, "bindsym",
|
||||
"Only buttons 1-9 are supported. For other mouse "
|
||||
"buttons, use the name of the event code.");
|
||||
}
|
||||
uint32_t buttons[] = {BTN_LEFT, BTN_MIDDLE, BTN_RIGHT,
|
||||
SWAY_SCROLL_UP, SWAY_SCROLL_DOWN, SWAY_SCROLL_LEFT,
|
||||
SWAY_SCROLL_RIGHT, BTN_SIDE, BTN_EXTRA};
|
||||
button = buttons[button - 1];
|
||||
} else if (strncmp(name, "BTN_", strlen("BTN_")) == 0) {
|
||||
// Get event code
|
||||
int code = libevdev_event_code_from_name(EV_KEY, name);
|
||||
if (code == -1) {
|
||||
return cmd_results_new(CMD_INVALID, "bindsym",
|
||||
"Invalid event code name %s", name);
|
||||
}
|
||||
button = code;
|
||||
}
|
||||
|
||||
if (*type == BINDING_KEYSYM) {
|
||||
if (button) {
|
||||
if (first_key) {
|
||||
*type = BINDING_MOUSE;
|
||||
*key_val = button;
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID, "bindsym",
|
||||
"Mixed button '%s' into key sequence", name);
|
||||
}
|
||||
} else if (keysym) {
|
||||
*key_val = keysym;
|
||||
"Unknown key or button '%s'", name);
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID, "bindsym",
|
||||
"Unknown key '%s'", name);
|
||||
}
|
||||
} else {
|
||||
if (button) {
|
||||
*key_val = button;
|
||||
} else if (keysym) {
|
||||
return cmd_results_new(CMD_INVALID, "bindsym",
|
||||
"Mixed keysym '%s' into button sequence", name);
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID, "bindsym",
|
||||
"Unknown button '%s'", name);
|
||||
"Unknown key '%s'", name);
|
||||
}
|
||||
}
|
||||
*key_val = keysym;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -201,7 +223,8 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
|
|||
}
|
||||
if (binding->flags & (BINDING_BORDER | BINDING_CONTENTS | BINDING_TITLEBAR)
|
||||
|| exclude_titlebar) {
|
||||
binding->type = BINDING_MOUSE;
|
||||
binding->type = binding->type == BINDING_KEYCODE ?
|
||||
BINDING_MOUSECODE : BINDING_MOUSESYM;
|
||||
}
|
||||
|
||||
if (argc < 2) {
|
||||
|
@ -249,7 +272,8 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
|
|||
// that this is one
|
||||
if (exclude_titlebar) {
|
||||
binding->flags &= ~BINDING_TITLEBAR;
|
||||
} else if (binding->type == BINDING_MOUSE) {
|
||||
} else if (binding->type == BINDING_MOUSECODE
|
||||
|| binding->type == BINDING_MOUSESYM) {
|
||||
binding->flags |= BINDING_TITLEBAR;
|
||||
}
|
||||
|
||||
|
|
|
@ -445,8 +445,12 @@ void ipc_event_binding(struct sway_binding *binding) {
|
|||
json_object_object_add(json_binding, "input_code", json_object_new_int(input_code));
|
||||
json_object_object_add(json_binding, "symbols", symbols);
|
||||
json_object_object_add(json_binding, "symbol", symbol);
|
||||
json_object_object_add(json_binding, "input_type", binding->type == BINDING_MOUSE ?
|
||||
json_object_new_string("mouse") : json_object_new_string("keyboard"));
|
||||
|
||||
bool mouse = binding->type == BINDING_MOUSECODE ||
|
||||
binding->type == BINDING_MOUSESYM;
|
||||
json_object_object_add(json_binding, "input_type", mouse
|
||||
? json_object_new_string("mouse")
|
||||
: json_object_new_string("keyboard"));
|
||||
|
||||
json_object *json = json_object_new_object();
|
||||
json_object_object_add(json, "change", json_object_new_string("run"));
|
||||
|
|
|
@ -302,7 +302,7 @@ runtime.
|
|||
```
|
||||
|
||||
*bindcode* [--release|--locked] [--input-device=<device>] [--no-warn] <code> <command>
|
||||
is also available for binding with key codes instead of key names.
|
||||
is also available for binding with key/button codes instead of key/button names.
|
||||
|
||||
*client.<class>* <border> <background> <text> <indicator> <child\_border>
|
||||
Configures the color of window borders and title bars. All 5 colors are
|
||||
|
|
Loading…
Reference in a new issue