Merge pull request #1632 from Deiz/binding-border

Add a --border flag to enable mouse binds to trigger on border click
This commit is contained in:
Michael Stapelberg 2015-04-19 09:28:08 -07:00
commit 8a608ee63a
9 changed files with 45 additions and 22 deletions

View File

@ -405,13 +405,16 @@ can configure mouse bindings in a similar way to key bindings.
*Syntax*:
----------------------------------
bindsym [--release] [--whole-window] [Modifiers+]button[n] command
bindsym [--release] [--border] [--whole-window] [Modifiers+]button[n] command
----------------------------------
By default, the binding will only run when you click on the titlebar of the
window. If the +--whole-window+ flag is given, it will run when any part of the
window is clicked. If the +--release+ flag is given, it will run when the mouse
button is released.
window. If the +--release+ flag is given, it will run when the mouse button
is released.
If the +--whole-window+ flag is given, the binding will also run when any part
of the window is clicked, with the exception of the border. To have a bind run
when the border is clicked, specify the +--border+ flag.
*Examples*:
--------------------------------

View File

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

View File

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

View File

@ -255,6 +255,10 @@ struct Binding {
B_UPON_KEYRELEASE_IGNORE_MODS = 2,
} release;
/** If this is true for a mouse binding, the binding should be executed
* when the button is pressed over the window border. */
bool border;
/** 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). */

View File

@ -300,6 +300,8 @@ state FONT:
state BINDING:
release = '--release'
->
border = '--border'
->
whole_window = '--whole-window'
->
modifiers = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Shift', 'Control', 'Ctrl', 'Mode_switch', '$mod'
@ -312,10 +314,12 @@ state BINDING:
state BINDCOMMAND:
release = '--release'
->
border = '--border'
->
whole_window = '--whole-window'
->
command = string
-> call cfg_binding($bindtype, $modifiers, $key, $release, $whole_window, $command)
-> call cfg_binding($bindtype, $modifiers, $key, $release, $border, $whole_window, $command)
################################################################################
# Mode configuration
@ -349,6 +353,8 @@ state MODE_IGNORE_LINE:
state MODE_BINDING:
release = '--release'
->
border = '--border'
->
whole_window = '--whole-window'
->
modifiers = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Shift', 'Control', 'Ctrl', 'Mode_switch', '$mod'
@ -361,10 +367,12 @@ state MODE_BINDING:
state MODE_BINDCOMMAND:
release = '--release'
->
border = '--border'
->
whole_window = '--whole-window'
->
command = string
-> call cfg_mode_binding($bindtype, $modifiers, $key, $release, $whole_window, $command); MODE
-> call cfg_mode_binding($bindtype, $modifiers, $key, $release, $border, $whole_window, $command); MODE
################################################################################
# Bar configuration (i3bar)

View File

@ -49,10 +49,12 @@ static struct Mode *mode_from_name(const char *name) {
*
*/
Binding *configure_binding(const char *bindtype, const char *modifiers, const char *input_code,
const char *release, const char *whole_window, const char *command, const char *modename) {
const char *release, const char *border, const char *whole_window,
const char *command, const char *modename) {
Binding *new_binding = scalloc(sizeof(Binding));
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->border = (border != NULL);
new_binding->whole_window = (whole_window != NULL);
if (strcmp(bindtype, "bindsym") == 0) {
new_binding->input_type = (strncasecmp(input_code, "button", (sizeof("button") - 1)) == 0

View File

@ -185,12 +185,13 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod
/* if the user has bound an action to this click, it should override the
* default behavior. */
if (dest == CLICK_DECORATION || dest == CLICK_INSIDE) {
if (dest == CLICK_DECORATION || dest == CLICK_INSIDE || dest == CLICK_BORDER) {
Binding *bind = get_binding_from_xcb_event((xcb_generic_event_t *)event);
/* clicks over a window decoration will always trigger the binding and
* clicks on the inside of the window will only trigger a binding if
* the --whole-window flag was given for the binding. */
if (bind && (dest == CLICK_DECORATION || bind->whole_window)) {
if (bind && ((dest == CLICK_DECORATION || bind->whole_window) ||
(dest == CLICK_BORDER && bind->border))) {
CommandResult *result = run_binding(bind, con);
/* ASYNC_POINTER eats the event */

View File

@ -171,8 +171,8 @@ CFGFUN(font, const char *font) {
font_pattern = sstrdup(font);
}
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, whole_window, command, DEFAULT_BINDING_MODE);
CFGFUN(binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *border, const char *whole_window, const char *command) {
configure_binding(bindtype, modifiers, key, release, border, 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;
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, whole_window, command, current_mode);
CFGFUN(mode_binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *border, const char *whole_window, const char *command) {
configure_binding(bindtype, modifiers, key, release, border, whole_window, command, current_mode);
}
CFGFUN(enter_mode, const char *modename) {

View File

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