M_HIDE = 1,
M_INVISIBLE = 2 } bar_display_mode_t;
-typedef struct mouse_command_t {
- int button;
+typedef struct binding_t {
+ int input_code;
char *command;
- TAILQ_ENTRY(mouse_command_t) commands;
-} mouse_command_t;
+ TAILQ_ENTRY(binding_t) bindings;
+} binding_t;
typedef struct config_t {
int modifier;
- TAILQ_HEAD(mouse_commands_head, mouse_command_t) mouse_commands;
+ TAILQ_HEAD(bindings_head, binding_t) bindings;
position_t position;
int verbose;
struct xcb_color_strings_t colors;
#include "common.h"
static char *cur_key;
-static bool parsing_mouse_commands;
+static bool parsing_bindings;
/*
* Parse a key.
strncpy(cur_key, (const char *)keyVal, keyLen);
cur_key[keyLen] = '\0';
- if (strcmp(cur_key, "mouse_commands") == 0)
- parsing_mouse_commands = true;
+ if (strcmp(cur_key, "bindings") == 0)
+ parsing_bindings = true;
return 1;
}
-static int config_end_map_cb(void *params_) {
- parsing_mouse_commands = false;
+static int config_end_array_cb(void *params_) {
+ parsing_bindings = false;
return 1;
}
if (!strcmp(cur_key, "id") || !strcmp(cur_key, "socket_path"))
return 1;
- if (parsing_mouse_commands) {
- int button = atoi(cur_key + sizeof("button") - 1);
+ if (parsing_bindings) {
+ if (strcmp(cur_key, "command") == 0) {
+ binding_t *binding = TAILQ_LAST(&(config.bindings), bindings_head);
+ if (binding == NULL) {
+ ELOG("There is no binding to put the current command onto. This is a bug in i3.\n");
+ return 0;
+ }
- mouse_command_t *current;
- TAILQ_FOREACH(current, &(config.mouse_commands), commands) {
- if (current->button == button) {
- FREE(current->command);
- sasprintf(&(current->command), "%.*s", len, val);
- return 1;
+ if (binding->command != NULL) {
+ ELOG("The binding for input_code = %d already has a command. This is a bug in i3.\n", binding->input_code);
+ return 0;
}
+
+ sasprintf(&(binding->command), "%.*s", len, val);
+ return 1;
}
- mouse_command_t *command = scalloc(sizeof(mouse_command_t));
- command->button = button;
- sasprintf(&(command->command), "%.*s", len, val);
- TAILQ_INSERT_TAIL(&(config.mouse_commands), command, commands);
- return 1;
+ ELOG("Unknown key \"%s\" while parsing bar bindings.\n", cur_key);
+ return 0;
}
if (!strcmp(cur_key, "mode")) {
return 0;
}
+/*
+ * Parse an integer value
+ *
+ */
+static int config_integer_cb(void *params_, long long val) {
+ if (parsing_bindings) {
+ if (strcmp(cur_key, "input_code") == 0) {
+ binding_t *binding = scalloc(sizeof(binding_t));
+ binding->input_code = val;
+ TAILQ_INSERT_TAIL(&(config.bindings), binding, bindings);
+
+ return 1;
+ }
+
+ ELOG("Unknown key \"%s\" while parsing bar bindings.\n", cur_key);
+ return 0;
+ }
+
+ return 0;
+}
+
/* A datastructure to pass all these callbacks to yajl */
static yajl_callbacks outputs_callbacks = {
.yajl_null = config_null_cb,
.yajl_boolean = config_boolean_cb,
+ .yajl_integer = config_integer_cb,
.yajl_string = config_string_cb,
- .yajl_end_map = config_end_map_cb,
+ .yajl_end_array = config_end_array_cb,
.yajl_map_key = config_map_key_cb,
};
yajl_status state;
handle = yajl_alloc(&outputs_callbacks, NULL, NULL);
- TAILQ_INIT(&(config.mouse_commands));
+ TAILQ_INIT(&(config.bindings));
state = yajl_parse(handle, (const unsigned char *)json, strlen(json));
/* If a custom command was specified for this mouse button, it overrides
* the default behavior. */
- mouse_command_t *command;
- TAILQ_FOREACH(command, &(config.mouse_commands), commands) {
- if (command->button != event->detail)
+ binding_t *binding;
+ TAILQ_FOREACH(binding, &(config.bindings), bindings) {
+ if (binding->input_code != event->detail)
continue;
- i3_send_msg(I3_IPC_MESSAGE_TYPE_COMMAND, command->command);
+ i3_send_msg(I3_IPC_MESSAGE_TYPE_COMMAND, binding->command);
return;
}
M_MOD5 = 7
} modifier;
- TAILQ_HEAD(mouse_commands_head, Mousecommand) mouse_commands;
+ TAILQ_HEAD(bar_bindings_head, Barbinding) bar_bindings;
/** Bar position (bottom by default). */
enum { P_BOTTOM = 0,
* clicking on the non-statusline part of i3bar.
*
*/
-struct Mousecommand {
- /** The button for this command (e.g., "button1") */
- char *button;
+struct Barbinding {
+ /** The button to be used (e.g., 1 for "button1"). */
+ int input_code;
/** The command which is to be executed for this button. */
char *command;
- TAILQ_ENTRY(Mousecommand) commands;
+ TAILQ_ENTRY(Barbinding) bindings;
};
/**
current_bar.modifier = M_SHIFT;
}
-static void bar_configure_mouse_command(const char *button, const char *command) {
- if (strncasecmp(button, "button", sizeof("button") - 1) != 0) {
- ELOG("unknown button \"%s\" for mouse command, ignoring.\n", button);
+static void bar_configure_binding(const char *button, const char *command) {
+ if (strncasecmp(button, "button", strlen("button")) != 0) {
+ ELOG("Bindings for a bar can only be mouse bindings, not \"%s\", ignoring.\n", button);
return;
}
- struct Mousecommand *current;
- TAILQ_FOREACH(current, &(current_bar.mouse_commands), commands) {
- if (strcasecmp(current->button, button) == 0) {
+ int input_code = atoi(button + strlen("button"));
+ if (input_code < 1) {
+ ELOG("Button \"%s\" does not seem to be in format 'buttonX'.\n", button);
+ return;
+ }
+
+ struct Barbinding *current;
+ TAILQ_FOREACH(current, &(current_bar.bar_bindings), bindings) {
+ if (current->input_code == input_code) {
ELOG("command for button %s was already specified, ignoring.\n", button);
return;
}
}
- struct Mousecommand *new_command = scalloc(sizeof(struct Mousecommand));
- new_command->button = sstrdup(button);
- new_command->command = sstrdup(command);
- TAILQ_INSERT_TAIL(&(current_bar.mouse_commands), new_command, commands);
+ struct Barbinding *new_binding = scalloc(sizeof(struct Barbinding));
+ new_binding->input_code = input_code;
+ new_binding->command = sstrdup(command);
+ TAILQ_INSERT_TAIL(&(current_bar.bar_bindings), new_binding, bindings);
}
CFGFUN(bar_wheel_up_cmd, const char *command) {
ELOG("'wheel_up_cmd' is deprecated. Please us 'bindsym button4 %s' instead.\n", command);
- bar_configure_mouse_command("button4", command);
+ bar_configure_binding("button4", command);
}
CFGFUN(bar_wheel_down_cmd, const char *command) {
ELOG("'wheel_down_cmd' is deprecated. Please us 'bindsym button5 %s' instead.\n", command);
- bar_configure_mouse_command("button5", command);
+ bar_configure_binding("button5", command);
}
CFGFUN(bar_bindsym, const char *button, const char *command) {
- bar_configure_mouse_command(button, command);
+ bar_configure_binding(button, command);
}
CFGFUN(bar_position, const char *position) {
}
CFGFUN(bar_start) {
- TAILQ_INIT(&(current_bar.mouse_commands));
+ TAILQ_INIT(&(current_bar.bar_bindings));
}
CFGFUN(bar_finish) {
y(map_close);
}
-static void dump_mouse_commands(yajl_gen gen, Barconfig *config) {
- ystr("mouse_commands");
- y(map_open);
+static void dump_bar_bindings(yajl_gen gen, Barconfig *config) {
+ if (TAILQ_EMPTY(&(config->bar_bindings)))
+ return;
+
+ ystr("bindings");
+ y(array_open);
+
+ struct Barbinding *current;
+ TAILQ_FOREACH(current, &(config->bar_bindings), bindings) {
+ y(map_open);
- struct Mousecommand *current;
- TAILQ_FOREACH(current, &(config->mouse_commands), commands) {
- ystr(current->button);
+ ystr("input_code");
+ y(integer, current->input_code);
+ ystr("command");
ystr(current->command);
+
+ y(map_close);
}
- y(map_close);
+ y(array_close);
}
static void dump_bar_config(yajl_gen gen, Barconfig *config) {
break;
}
- dump_mouse_commands(gen, config);
+ dump_bar_bindings(gen, config);
ystr("position");
if (config->position == P_BOTTOM)