]> git.sur5r.net Git - i3/i3/commitdiff
Merge pull request #1632 from Deiz/binding-border
authorMichael Stapelberg <stapelberg@users.noreply.github.com>
Sun, 19 Apr 2015 16:28:08 +0000 (09:28 -0700)
committerMichael Stapelberg <stapelberg@users.noreply.github.com>
Sun, 19 Apr 2015 16:28:08 +0000 (09:28 -0700)
Add a --border flag to enable mouse binds to trigger on border click

docs/userguide
include/bindings.h
include/config_directives.h
include/data.h
parser-specs/config.spec
src/bindings.c
src/click.c
src/config_directives.c
testcases/t/201-config-parser.t

index 687dff10e5221c48ebfd3f3f1207eff76c4199c8..96b369024d40a7c2eeb98554cf469aae98f4d614 100644 (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*:
 --------------------------------
index 19345f8c82ad6c6144d8c7bbde53f849bceb86eb..c20152e92ea90ae63580064da9609f0dc874db3f 100644 (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)
index f50396244db58571219c91aabe2df1ca7c79f412..e24c834b096ade4279094fb6cf16c6e6800ada9f 100644 (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);
index 50e1f1807bfc4cf2b16459a3d154f0883024f27f..4386226389afd0d5886931e0399ae16d91967375 100644 (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). */
index d27e0792127a6f78b863995941994cf66523439b..da534a3825d58283f9850aa887c737dd97f51911 100644 (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)
index cbac2dfd96dfd0f3826dcb669ab9b5400fb720f1..e83e0accbdc987ffb874de54eefe8ae6d5ea3a8c 100644 (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
index 3cd367cc725ee8b439cde59b35f4829a92892ad8..40884c34bc71ddba5b5674eb1d30e71077634062 100644 (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 */
index 398e53bb7c8cb9c7186f2050ba80b6686708e76b..daf4339ba947dc16a8ab615349931365698f0a40 100644 (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) {
index 9ec8b5ebe75de6f4f4b9265541a5f8f73c50dd7f..7568de48394e4ba4c09edcce2af289fca191ee32 100644 (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" {