29 if (strcmp(mode->
name, name) == 0)
50 const char *release,
const char *command,
const char *modename) {
52 DLOG(
"bindtype %s, modifiers %s, input code %s, release %s\n", bindtype, modifiers, input_code, release);
53 new_binding->
release = (release != NULL ? B_UPON_KEYRELEASE : B_UPON_KEYPRESS);
54 if (strcmp(bindtype,
"bindsym") == 0) {
55 new_binding->
input_type = (strncasecmp(input_code,
"button", (
sizeof(
"button") - 1)) == 0
62 new_binding->
keycode = atoi(input_code);
64 if (new_binding->
keycode == 0) {
65 ELOG(
"Could not parse \"%s\" as an input code, ignoring this binding.\n", input_code);
83 DLOG(
"Grabbing %d with modifiers %d (with mod_mask_lock %d)\n", keycode, bind->
mods, bind->
mods | XCB_MOD_MASK_LOCK);
85 #define GRAB_KEY(modifier) \
87 xcb_grab_key(conn, 0, root, modifier, keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); \
89 int mods = bind->
mods;
93 mods = XCB_MOD_MASK_ANY;
139 if (bind->
release == B_UPON_KEYRELEASE_IGNORE_MODS)
140 bind->
release = B_UPON_KEYRELEASE;
150 if (bind->
mods != modifiers &&
151 (bind->
release != B_UPON_KEYRELEASE_IGNORE_MODS ||
161 &input_code,
sizeof(xcb_keycode_t)) == NULL)
165 if (bind->
keycode != input_code)
173 if (bind->
release == B_UPON_KEYRELEASE && !is_release)
174 bind->
release = B_UPON_KEYRELEASE_IGNORE_MODS;
177 if ((bind->
release == B_UPON_KEYPRESS && is_release) ||
178 (bind->
release >= B_UPON_KEYRELEASE && !is_release))
193 bool is_release = (
event->response_type == XCB_KEY_RELEASE ||
event->response_type == XCB_BUTTON_RELEASE);
195 input_type_t input_type = ((
event->response_type == XCB_BUTTON_RELEASE ||
event->response_type == XCB_BUTTON_PRESS)
199 uint16_t event_state = ((xcb_key_press_event_t *)event)->state;
200 uint16_t event_detail = ((xcb_key_press_event_t *)event)->detail;
203 uint16_t state_filtered = event_state & ~(
xcb_numlock_mask | XCB_MOD_MASK_LOCK);
204 DLOG(
"(removed numlock, state = %d)\n", state_filtered);
207 state_filtered &= 0xFF;
208 DLOG(
"(removed upper 8 bits, state = %d)\n", state_filtered);
213 DLOG(
"(checked mode_switch, state %d)\n", state_filtered);
224 DLOG(
"no match, new state_filtered = %d\n", state_filtered);
225 if ((bind =
get_binding(state_filtered, is_release, event_detail, input_type)) == NULL) {
230 DLOG(
"Could not lookup key binding (modifiers %d, keycode %d)\n",
231 state_filtered, event_detail);
246 xcb_keycode_t i, min_keycode, max_keycode;
248 min_keycode = xcb_get_setup(
conn)->min_keycode;
249 max_keycode = xcb_get_setup(
conn)->max_keycode;
253 int button = atoi(bind->
symbol + (
sizeof(
"button") - 1));
257 ELOG(
"Could not translate string to button: \"%s\"\n", bind->
symbol);
266 keysym = XStringToKeysym(bind->
symbol);
267 if (keysym == NoSymbol) {
268 ELOG(
"Could not translate string to key symbol: \"%s\"\n",
282 for (i = min_keycode; i && i <= max_keycode; i++) {
283 if ((xcb_key_symbols_get_keysym(
keysyms, i, col) != keysym) &&
284 (xcb_key_symbols_get_keysym(
keysyms, i, col + 1) != keysym))
288 (
sizeof(xcb_keycode_t) *
293 DLOG(
"Translated symbol \"%s\" to %d keycode\n", bind->
symbol,
305 DLOG(
"Switching to mode %s\n", new_mode);
308 if (strcasecmp(mode->
name, new_mode) != 0)
325 ELOG(
"ERROR: Mode not found\n");
352 if ((bind->
symbol == NULL && current->
symbol != NULL) ||
358 if (bind->
symbol != NULL &&
371 ELOG(
"Duplicate keybinding in config file:\n modmask %d with keycode %d, command \"%s\"\n",
374 ELOG(
"Duplicate keybinding in config file:\n modmask %d with keysym %s, command \"%s\"\n",
408 "The configured command for this shortcut could not be run successfully.",
char * sstrdup(const char *str)
Safe-wrapper around strdup which exits if malloc returns NULL (meaning that there is no more memory a...
#define SLIST_FOREACH(var, head, field)
char * symbol
Symbol the user specified in configfile, if any.
void tree_render(void)
Renders the tree, that is rendering all outputs using render_con() and pushing the changes to X11 usi...
void check_for_duplicate_bindings(struct context *context)
Checks for duplicate key bindings (the same keycode or keysym is configured more than once)...
const char * DEFAULT_BINDING_MODE
CommandResult * run_binding(Binding *bind)
Runs the given binding and handles parse errors.
void translate_keysyms(void)
Translates keysymbols to keycodes for all bindings which use keysyms.
CommandResult * parse_command(const char *input, yajl_gen gen)
Parses and executes the given command.
#define SLIST_INSERT_HEAD(head, elm, field)
static Binding * get_binding(uint16_t modifiers, bool is_release, uint16_t input_code, input_type_t input_type)
static void grab_keycode_for_binding(xcb_connection_t *conn, Binding *bind, uint32_t keycode)
uint32_t modifiers_from_str(const char *str)
A utility function to convert a string of modifiers to the corresponding bit mask.
static struct Mode * mode_from_name(const char *name)
void grab_all_keys(xcb_connection_t *conn, bool bind_mode_switch)
Grab the bound keys (tell X to send us keypress events for those keycodes)
Holds a keybinding, consisting of a keycode combined with modifiers and the command which is executed...
void ipc_send_event(const char *event, uint32_t message_type, const char *payload)
Sends the specified event to all IPC clients which are currently connected and subscribed to this kin...
pid_t command_error_nagbar_pid
void switch_mode(const char *new_mode)
Switches the key bindings to the given mode, if the mode exists.
struct bindings_head * bindings
A struct that contains useful information about the result of a command as a whole (e...
char * command
Command, like in command mode.
int sasprintf(char **strp, const char *fmt,...)
Safe-wrapper around asprintf which exits if it returns -1 (meaning that there is no more memory avail...
The configuration file can contain multiple sets of bindings.
enum Binding::@10 release
If true, the binding should be executed upon a KeyRelease event, not a KeyPress (the default)...
void start_nagbar(pid_t *nagbar_pid, char *argv[])
Starts an i3-nagbar instance with the given parameters.
Used during the config file lexing/parsing to keep the state of the lexer in order to provide useful ...
input_type_t
Binding input types.
char * pattern
The pattern/name used to load the font.
Binding * configure_binding(const char *bindtype, const char *modifiers, const char *input_code, const char *release, const char *command, const char *modename)
Adds a binding from config parameters given as strings and returns a pointer to the binding structure...
void ungrab_all_keys(xcb_connection_t *conn)
Ungrabs all keys, to be called before re-grabbing the keys because of a mapping_notify event or a con...
#define GRAB_KEY(modifier)
unsigned int xcb_numlock_mask
void * scalloc(size_t size)
Safe-wrapper around calloc which exits if malloc returns NULL (meaning that there is no more memory a...
struct bindings_head * bindings
uint32_t keycode
Keycode to bind.
Binding * get_binding_from_xcb_event(xcb_generic_event_t *event)
Returns a pointer to the Binding that matches the given xcb event or NULL if no such binding exists...
#define TAILQ_INSERT_TAIL(head, elm, field)
uint32_t mods
Bitmask consisting of BIND_MOD_1, BIND_MODE_SWITCH, …
xcb_key_symbols_t * keysyms
#define TAILQ_FOREACH(var, head, field)
xcb_keycode_t * translated_to
Only in use if symbol != NULL.
void * srealloc(void *ptr, size_t size)
Safe-wrapper around realloc which exits if realloc returns NULL (meaning that there is no more memory...