i3bar: implement custom mouse wheel commands

Users can specify a command to run when a button was pressed on i3bar to
override the default behavior. Currently only the mouse wheel buttons
are supported. This is useful for disabling the scroll wheel action or
running scripts that implement custom behavior for these buttons.

Example:

bar {
    wheel_up_cmd nop
    wheel_down_cmd exec ~/.i3/scripts/custom_wheel_down
}

fixes #1104
This commit is contained in:
Tony Crisci 2014-07-04 05:53:22 -04:00 committed by Michael Stapelberg
parent 0514be8d4b
commit 8e23dc881b
10 changed files with 94 additions and 1 deletions

View File

@ -1104,6 +1104,27 @@ bar {
Available modifiers are Mod1-Mod5, Shift, Control (see +xmodmap(1)+). Available modifiers are Mod1-Mod5, Shift, Control (see +xmodmap(1)+).
=== Mouse button commands
Specifies a command to run when a button was pressed on i3bar to override the
default behavior. Currently only the mouse wheel buttons are supported. This is
useful for disabling the scroll wheel action or running scripts that implement
custom behavior for these buttons.
*Syntax*:
---------------------
wheel_up_cmd <command>
wheel_down_cmd <command>
---------------------
*Example*:
---------------------
bar {
wheel_up_cmd nop
wheel_down_cmd exec ~/.i3/scripts/custom_wheel_down
}
---------------------
=== Bar ID === Bar ID
Specifies the bar ID for the configured bar instance. If this option is missing, Specifies the bar ID for the configured bar instance. If this option is missing,

View File

@ -24,6 +24,8 @@ typedef enum { M_DOCK = 0,
typedef struct config_t { typedef struct config_t {
int modifier; int modifier;
char *wheel_up_cmd;
char *wheel_down_cmd;
position_t position; position_t position;
int verbose; int verbose;
struct xcb_color_strings_t colors; struct xcb_color_strings_t colors;

View File

@ -112,6 +112,20 @@ static int config_string_cb(void *params_, const unsigned char *val, size_t _len
return 1; return 1;
} }
if (!strcmp(cur_key, "wheel_up_cmd")) {
DLOG("wheel_up_cmd = %.*s\n", len, val);
FREE(config.wheel_up_cmd);
sasprintf(&config.wheel_up_cmd, "%.*s", len, val);
return 1;
}
if (!strcmp(cur_key, "wheel_down_cmd")) {
DLOG("wheel_down_cmd = %.*s\n", len, val);
FREE(config.wheel_down_cmd);
sasprintf(&config.wheel_down_cmd, "%.*s", len, val);
return 1;
}
if (!strcmp(cur_key, "position")) { if (!strcmp(cur_key, "position")) {
DLOG("position = %.*s\n", len, val); DLOG("position = %.*s\n", len, val);
config.position = (len == 3 && !strncmp((const char *)val, "top", strlen("top")) ? POS_TOP : POS_BOT); config.position = (len == 3 && !strncmp((const char *)val, "top", strlen("top")) ? POS_TOP : POS_BOT);

View File

@ -370,6 +370,14 @@ void handle_button(xcb_button_press_event_t *event) {
* If there is no more workspace, dont even send the workspace * If there is no more workspace, dont even send the workspace
* command, otherwise (with workspace auto_back_and_forth) wed end * command, otherwise (with workspace auto_back_and_forth) wed end
* up on the wrong workspace. */ * up on the wrong workspace. */
/* If `wheel_up_cmd [COMMAND]` was specified, it should override
* the default behavior */
if (config.wheel_up_cmd) {
i3_send_msg(I3_IPC_MESSAGE_TYPE_COMMAND, config.wheel_up_cmd);
return;
}
if (cur_ws == TAILQ_FIRST(walk->workspaces)) if (cur_ws == TAILQ_FIRST(walk->workspaces))
return; return;
@ -380,6 +388,14 @@ void handle_button(xcb_button_press_event_t *event) {
* If there is no more workspace, dont even send the workspace * If there is no more workspace, dont even send the workspace
* command, otherwise (with workspace auto_back_and_forth) wed end * command, otherwise (with workspace auto_back_and_forth) wed end
* up on the wrong workspace. */ * up on the wrong workspace. */
/* if `wheel_down_cmd [COMMAND]` was specified, it should override
* the default behavior */
if (config.wheel_down_cmd) {
i3_send_msg(I3_IPC_MESSAGE_TYPE_COMMAND, config.wheel_down_cmd);
return;
}
if (cur_ws == TAILQ_LAST(walk->workspaces, ws_head)) if (cur_ws == TAILQ_LAST(walk->workspaces, ws_head))
return; return;

View File

@ -261,6 +261,14 @@ struct Barconfig {
M_MOD5 = 7 M_MOD5 = 7
} modifier; } modifier;
/** Command that should be run when mouse wheel up button is pressed over
* i3bar to override the default behavior. */
char *wheel_up_cmd;
/** Command that should be run when mouse wheel down button is pressed over
* i3bar to override the default behavior. */
char *wheel_down_cmd;
/** Bar position (bottom by default). */ /** Bar position (bottom by default). */
enum { P_BOTTOM = 0, enum { P_BOTTOM = 0,
P_TOP = 1 } position; P_TOP = 1 } position;

View File

@ -73,6 +73,8 @@ CFGFUN(bar_id, const char *bar_id);
CFGFUN(bar_output, const char *output); CFGFUN(bar_output, const char *output);
CFGFUN(bar_verbose, const char *verbose); CFGFUN(bar_verbose, const char *verbose);
CFGFUN(bar_modifier, const char *modifier); CFGFUN(bar_modifier, const char *modifier);
CFGFUN(bar_wheel_up_cmd, const char *command);
CFGFUN(bar_wheel_down_cmd, const char *command);
CFGFUN(bar_position, const char *position); CFGFUN(bar_position, const char *position);
CFGFUN(bar_i3bar_command, const char *i3bar_command); CFGFUN(bar_i3bar_command, const char *i3bar_command);
CFGFUN(bar_color, const char *colorclass, const char *border, const char *background, const char *text); CFGFUN(bar_color, const char *colorclass, const char *border, const char *background, const char *text);

View File

@ -358,6 +358,8 @@ state BAR:
'hidden_state' -> BAR_HIDDEN_STATE 'hidden_state' -> BAR_HIDDEN_STATE
'id' -> BAR_ID 'id' -> BAR_ID
'modifier' -> BAR_MODIFIER 'modifier' -> BAR_MODIFIER
'wheel_up_cmd' -> BAR_WHEEL_UP_CMD
'wheel_down_cmd' -> BAR_WHEEL_DOWN_CMD
'position' -> BAR_POSITION 'position' -> BAR_POSITION
'output' -> BAR_OUTPUT 'output' -> BAR_OUTPUT
'tray_output' -> BAR_TRAY_OUTPUT 'tray_output' -> BAR_TRAY_OUTPUT
@ -403,6 +405,14 @@ state BAR_MODIFIER:
modifier = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Control', 'Ctrl', 'Shift' modifier = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Control', 'Ctrl', 'Shift'
-> call cfg_bar_modifier($modifier); BAR -> call cfg_bar_modifier($modifier); BAR
state BAR_WHEEL_UP_CMD:
command = string
-> call cfg_bar_wheel_up_cmd($command); BAR
state BAR_WHEEL_DOWN_CMD:
command = string
-> call cfg_bar_wheel_down_cmd($command); BAR
state BAR_POSITION: state BAR_POSITION:
position = 'top', 'bottom' position = 'top', 'bottom'
-> call cfg_bar_position($position); BAR -> call cfg_bar_position($position); BAR

View File

@ -459,6 +459,16 @@ CFGFUN(bar_modifier, const char *modifier) {
current_bar.modifier = M_SHIFT; current_bar.modifier = M_SHIFT;
} }
CFGFUN(bar_wheel_up_cmd, const char *command) {
FREE(current_bar.wheel_up_cmd);
current_bar.wheel_up_cmd = sstrdup(command);
}
CFGFUN(bar_wheel_down_cmd, const char *command) {
FREE(current_bar.wheel_down_cmd);
current_bar.wheel_down_cmd = sstrdup(command);
}
CFGFUN(bar_position, const char *position) { CFGFUN(bar_position, const char *position) {
current_bar.position = (strcmp(position, "top") == 0 ? P_TOP : P_BOTTOM); current_bar.position = (strcmp(position, "top") == 0 ? P_TOP : P_BOTTOM);
} }

View File

@ -512,6 +512,16 @@ static void dump_bar_config(yajl_gen gen, Barconfig *config) {
break; break;
} }
if (config->wheel_up_cmd) {
ystr("wheel_up_cmd");
ystr(config->wheel_up_cmd);
}
if (config->wheel_down_cmd) {
ystr("wheel_down_cmd");
ystr(config->wheel_down_cmd);
}
ystr("position"); ystr("position");
if (config->position == P_BOTTOM) if (config->position == P_BOTTOM)
ystr("bottom"); ystr("bottom");

View File

@ -645,7 +645,7 @@ EOT
$expected = <<'EOT'; $expected = <<'EOT';
cfg_bar_output(LVDS-1) cfg_bar_output(LVDS-1)
ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set', 'i3bar_command', 'status_command', 'socket_path', 'mode', 'hidden_state', 'id', 'modifier', 'position', 'output', 'tray_output', 'font', 'binding_mode_indicator', 'workspace_buttons', 'strip_workspace_numbers', 'verbose', 'colors', '}' ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set', 'i3bar_command', 'status_command', 'socket_path', 'mode', 'hidden_state', 'id', 'modifier', 'wheel_up_cmd', 'wheel_down_cmd', 'position', 'output', 'tray_output', 'font', 'binding_mode_indicator', 'workspace_buttons', 'strip_workspace_numbers', 'verbose', 'colors', '}'
ERROR: CONFIG: (in file <stdin>) ERROR: CONFIG: (in file <stdin>)
ERROR: CONFIG: Line 1: bar { ERROR: CONFIG: Line 1: bar {
ERROR: CONFIG: Line 2: output LVDS-1 ERROR: CONFIG: Line 2: output LVDS-1