i3 - improved tiling WM


Feature: mouse bindings over container decorations

Patch status: superseded

Patch by Tony Crisci

Long description:

A configured mouse binding (for example `bindsym button3 kill`) runs
its command when the mouse button is pressed over container
decorations. This behavior overrides the default button press action.
The clicked container will be selected by criteria.

To apply this patch, use:
curl http://cr.i3wm.org/patch/564/raw.patch | git am

b/include/bindings.h

20
@@ -61,9 +61,10 @@ void switch_mode(const char *new_mode);
21
 void check_for_duplicate_bindings(struct context *context);
22
 
23
 /**
24
- * Runs the given binding and handles parse errors. Returns a CommandResult for
25
- * running the binding's command. Caller should render tree if
26
- * needs_tree_render is true. Free with command_result_free().
27
+ * Runs the given binding and handles parse errors. If con is passed, it will
28
+ * execute the command binding with that container selected by criteria.
29
+ * Returns a CommandResult for running the binding's command. Caller should
30
+ * render tree if needs_tree_render is true. Free with command_result_free().
31
  *
32
  */
33
-CommandResult *run_binding(Binding *bind);
34
+CommandResult *run_binding(Binding *bind, Con *con);

b/src/bindings.c

39
@@ -383,18 +383,25 @@ void check_for_duplicate_bindings(struct context *context) {
40
 }
41
 
42
 /*
43
- * Runs the given binding and handles parse errors. Returns a CommandResult for
44
- * running the binding's command. Caller should render tree if
45
- * needs_tree_render is true. Free with command_result_free().
46
+ * Runs the given binding and handles parse errors. If con is passed, it will
47
+ * execute the command binding with that container selected by criteria.
48
+ * Returns a CommandResult for running the binding's command. Caller should
49
+ * render tree if needs_tree_render is true. Free with command_result_free().
50
  *
51
  */
52
-CommandResult *run_binding(Binding *bind) {
53
+CommandResult *run_binding(Binding *bind, Con *con) {
54
+    char *command;
55
+
56
     /* We need to copy the command since “reload” may be part of the command,
57
      * and then the memory that bind->command points to may not contain the
58
      * same data anymore. */
59
-    char *command_copy = sstrdup(bind->command);
60
-    CommandResult *result = parse_command(command_copy, NULL);
61
-    free(command_copy);
62
+    if (con == NULL)
63
+        command = sstrdup(bind->command);
64
+    else
65
+        sasprintf(&command, "[con_id=\"%d\"] %s", con, bind->command);
66
+
67
+    CommandResult *result = parse_command(command, NULL);
68
+    free(command);
69
 
70
     if (result->needs_tree_render)
71
         tree_render();

b/src/click.c

76
@@ -173,11 +173,26 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod
77
 
78
     /* if focus changes, we must rerender */
79
     Con *initially_focused = focused;
80
+    bool needs_tree_render = false;
81
 
82
     /* don’t handle dockarea cons, they must not be focused */
83
     if (con->parent->type == CT_DOCKAREA)
84
         goto done;
85
 
86
+    /* if the user has bound an action to this click, it should override the
87
+     * default behavior. */
88
+    if (dest == CLICK_DECORATION) {
89
+        /* TODO: bindings for clicking other parts of the con, like the window
90
+         * area. */
91
+        Binding *bind = get_binding_from_xcb_event((xcb_generic_event_t *)event);
92
+        if (bind) {
93
+            CommandResult *result = run_binding(bind, con);
94
+            needs_tree_render = (needs_tree_render || result->needs_tree_render);
95
+            command_result_free(result);
96
+            goto done;
97
+        }
98
+    }
99
+
100
     /* Any click in a workspace should focus that workspace. If the
101
      * workspace is on another output we need to do a workspace_show in
102
      * order for i3bar (and others) to notice the change in workspace. */
103
@@ -301,7 +316,7 @@ done:
104
     xcb_allow_events(conn, XCB_ALLOW_REPLAY_POINTER, event->time);
105
     xcb_flush(conn);
106
 
107
-    if (initially_focused != focused)
108
+    if (needs_tree_render || initially_focused != focused)
109
         tree_render();
110
 
111
     return 0;

b/src/key_press.c

116
@@ -30,7 +30,7 @@ void handle_key_press(xcb_key_press_event_t *event) {
117
     if (bind == NULL)
118
         return;
119
 
120
-    CommandResult *result = run_binding(bind);
121
+    CommandResult *result = run_binding(bind, NULL);
122
 
123
     if (result->needs_tree_render)
124
         tree_render();