Add mouse binding pointer position configuration

Add the `--whole-window` switch for mouse bindings. This switch controls
what part of the container the pointer must be over to trigger a mouse
binding. The default is to only trigger mouse bindings over the
titlebars. With this switch, a mouse binding will be triggered over the
main part of the window as well.

This is a breaking change to the previous behavior, which would trigger
a mouse binding with a modifier over any part of the window.

fixes #1429
This commit is contained in:
Tony Crisci 2015-01-29 20:52:52 -05:00 committed by Michael Stapelberg
parent f28ce227e3
commit 74b69d6d02
9 changed files with 34 additions and 22 deletions

View File

@ -404,12 +404,12 @@ can configure mouse bindings in a similar way to key bindings.
*Syntax*: *Syntax*:
---------------------------------- ----------------------------------
bindsym [Modifiers+]button[n] command bindsym [--whole-window] [Modifiers+]button[n] command
---------------------------------- ----------------------------------
If the binding has no modifiers, it will only run when you click on the By default, the binding will only run when you click on the titlebar of the
titlebar of the window. Otherwise, it will run when any part of the window is window. If the +--whole-window+ flag is given, it will run when any part of the
clicked. window is clicked.
*Examples*: *Examples*:
-------------------------------- --------------------------------
@ -417,7 +417,7 @@ clicked.
bindsym button2 kill bindsym button2 kill
# The middle button and a modifer over any part of the window kills the window # The middle button and a modifer over any part of the window kills the window
bindsym $mod+button2 kill bindsym --whole-window $mod+button2 kill
# The right button toggles floating # The right button toggles floating
bindsym button3 floating toggle bindsym button3 floating toggle

View File

@ -24,7 +24,7 @@ const char *DEFAULT_BINDING_MODE;
* *
*/ */
Binding *configure_binding(const char *bindtype, const char *modifiers, const char *input_code, Binding *configure_binding(const char *bindtype, const char *modifiers, const char *input_code,
const char *release, const char *command, const char *mode); const char *release, const char *whole_window, const char *command, const char *mode);
/** /**
* Grab the bound keys (tell X to send us keypress events for those keycodes) * Grab the bound keys (tell X to send us keypress events for those keycodes)

View File

@ -61,10 +61,10 @@ CFGFUN(color_single, const char *colorclass, const char *color);
CFGFUN(floating_modifier, const char *modifiers); CFGFUN(floating_modifier, const char *modifiers);
CFGFUN(new_window, const char *windowtype, const char *border, const long width); CFGFUN(new_window, const char *windowtype, const char *border, const long width);
CFGFUN(workspace, const char *workspace, const char *output); CFGFUN(workspace, const char *workspace, const char *output);
CFGFUN(binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *command); CFGFUN(binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *whole_window, const char *command);
CFGFUN(enter_mode, const char *mode); CFGFUN(enter_mode, const char *mode);
CFGFUN(mode_binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *command); CFGFUN(mode_binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *whole_window, const char *command);
CFGFUN(bar_font, const char *font); CFGFUN(bar_font, const char *font);
CFGFUN(bar_mode, const char *mode); CFGFUN(bar_mode, const char *mode);

View File

@ -255,6 +255,11 @@ struct Binding {
B_UPON_KEYRELEASE_IGNORE_MODS = 2, B_UPON_KEYRELEASE_IGNORE_MODS = 2,
} release; } release;
/** If this is true for a mouse binding, the binding should be executed
* when the button is pressed over any part of the window, not just the
* title bar (default). */
bool whole_window;
uint32_t number_keycodes; uint32_t number_keycodes;
/** Keycode to bind */ /** Keycode to bind */

View File

@ -278,6 +278,8 @@ state FONT:
state BINDING: state BINDING:
release = '--release' release = '--release'
-> ->
whole_window = '--whole-window'
->
modifiers = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Shift', 'Control', 'Ctrl', 'Mode_switch', '$mod' modifiers = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Shift', 'Control', 'Ctrl', 'Mode_switch', '$mod'
-> ->
'+' '+'
@ -288,8 +290,10 @@ state BINDING:
state BINDCOMMAND: state BINDCOMMAND:
release = '--release' release = '--release'
-> ->
whole_window = '--whole-window'
->
command = string command = string
-> call cfg_binding($bindtype, $modifiers, $key, $release, $command) -> call cfg_binding($bindtype, $modifiers, $key, $release, $whole_window, $command)
################################################################################ ################################################################################
# Mode configuration # Mode configuration
@ -333,8 +337,10 @@ state MODE_BINDING:
state MODE_BINDCOMMAND: state MODE_BINDCOMMAND:
release = '--release' release = '--release'
-> ->
whole_window = '--whole-window'
->
command = string command = string
-> call cfg_mode_binding($bindtype, $modifiers, $key, $release, $command); MODE -> call cfg_mode_binding($bindtype, $modifiers, $key, $release, $whole_window, $command); MODE
################################################################################ ################################################################################
# Bar configuration (i3bar) # Bar configuration (i3bar)

View File

@ -49,10 +49,11 @@ static struct Mode *mode_from_name(const char *name) {
* *
*/ */
Binding *configure_binding(const char *bindtype, const char *modifiers, const char *input_code, Binding *configure_binding(const char *bindtype, const char *modifiers, const char *input_code,
const char *release, const char *command, const char *modename) { const char *release, const char *whole_window, const char *command, const char *modename) {
Binding *new_binding = scalloc(sizeof(Binding)); Binding *new_binding = scalloc(sizeof(Binding));
DLOG("bindtype %s, modifiers %s, input code %s, release %s\n", bindtype, modifiers, input_code, release); DLOG("bindtype %s, modifiers %s, input code %s, release %s\n", bindtype, modifiers, input_code, release);
new_binding->release = (release != NULL ? B_UPON_KEYRELEASE : B_UPON_KEYPRESS); new_binding->release = (release != NULL ? B_UPON_KEYRELEASE : B_UPON_KEYPRESS);
new_binding->whole_window = (whole_window != NULL);
if (strcmp(bindtype, "bindsym") == 0) { if (strcmp(bindtype, "bindsym") == 0) {
new_binding->input_type = (strncasecmp(input_code, "button", (sizeof("button") - 1)) == 0 new_binding->input_type = (strncasecmp(input_code, "button", (sizeof("button") - 1)) == 0
? B_MOUSE ? B_MOUSE

View File

@ -182,9 +182,9 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod
if (dest == CLICK_DECORATION || dest == CLICK_INSIDE) { if (dest == CLICK_DECORATION || dest == CLICK_INSIDE) {
Binding *bind = get_binding_from_xcb_event((xcb_generic_event_t *)event); Binding *bind = get_binding_from_xcb_event((xcb_generic_event_t *)event);
/* clicks over a window decoration will always trigger the binding and /* clicks over a window decoration will always trigger the binding and
* clicks on the inside of the window will only trigger a binding if it * clicks on the inside of the window will only trigger a binding if
* has modifiers. */ * the --whole-window flag was given for the binding. */
if (bind && (dest == CLICK_DECORATION || (bind->mods && dest == CLICK_INSIDE))) { if (bind && (dest == CLICK_DECORATION || bind->whole_window)) {
CommandResult *result = run_binding(bind, con); CommandResult *result = run_binding(bind, con);
/* ASYNC_POINTER eats the event */ /* ASYNC_POINTER eats the event */

View File

@ -171,8 +171,8 @@ CFGFUN(font, const char *font) {
font_pattern = sstrdup(font); font_pattern = sstrdup(font);
} }
CFGFUN(binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *command) { CFGFUN(binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *whole_window, const char *command) {
configure_binding(bindtype, modifiers, key, release, command, DEFAULT_BINDING_MODE); configure_binding(bindtype, modifiers, key, release, whole_window, command, DEFAULT_BINDING_MODE);
} }
/******************************************************************************* /*******************************************************************************
@ -181,8 +181,8 @@ CFGFUN(binding, const char *bindtype, const char *modifiers, const char *key, co
static char *current_mode; static char *current_mode;
CFGFUN(mode_binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *command) { CFGFUN(mode_binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *whole_window, const char *command) {
configure_binding(bindtype, modifiers, key, release, command, current_mode); configure_binding(bindtype, modifiers, key, release, whole_window, command, current_mode);
} }
CFGFUN(enter_mode, const char *modename) { CFGFUN(enter_mode, const char *modename) {

View File

@ -50,9 +50,9 @@ EOT
my $expected = <<'EOT'; my $expected = <<'EOT';
cfg_enter_mode(meh) cfg_enter_mode(meh)
cfg_mode_binding(bindsym, Mod1,Shift, x, (null), resize grow) cfg_mode_binding(bindsym, Mod1,Shift, x, (null), (null), resize grow)
cfg_mode_binding(bindcode, Mod1, 44, (null), resize shrink) cfg_mode_binding(bindcode, Mod1, 44, (null), (null), resize shrink)
cfg_mode_binding(bindsym, Mod1, x, --release, exec foo) cfg_mode_binding(bindsym, Mod1, x, --release, (null), exec foo)
EOT EOT
is(parser_calls($config), is(parser_calls($config),
@ -618,7 +618,7 @@ EOT
$expected = <<'EOT'; $expected = <<'EOT';
cfg_enter_mode(yo) cfg_enter_mode(yo)
cfg_mode_binding(bindsym, (null), x, (null), resize shrink left) cfg_mode_binding(bindsym, (null), x, (null), (null), resize shrink left)
ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set', 'bindsym', 'bindcode', 'bind', '}' ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set', 'bindsym', 'bindcode', 'bind', '}'
ERROR: CONFIG: (in file <stdin>) ERROR: CONFIG: (in file <stdin>)
ERROR: CONFIG: Line 1: mode "yo" { ERROR: CONFIG: Line 1: mode "yo" {