]> git.sur5r.net Git - i3/i3/blobdiff - src/key_press.c
Merge branch 'master' into next
[i3/i3] / src / key_press.c
index e8fbe17cce1c5114c6c7be0bb86d4c40a022917f..5919e64c7d06ab2baac84f2af36c6b7163dfad17 100644 (file)
@@ -1,4 +1,5 @@
-#line 2 "key_press.c"
+#undef I3__FILE__
+#define I3__FILE__ "key_press.c"
 /*
  * vim:ts=4:sw=4:expandtab
  *
@@ -15,7 +16,7 @@
 #include "all.h"
 
 static int current_nesting_level;
-static bool success_key;
+static bool parse_error_key;
 static bool command_failed;
 
 /* XXX: I don’t want to touch too much of the nagbar code at once, but we
@@ -183,9 +184,9 @@ void kill_commanderror_nagbar(bool wait_for_it) {
 }
 
 static int json_boolean(void *ctx, int boolval) {
-    DLOG("Got bool: %d, success_key %d, nesting_level %d\n", boolval, success_key, current_nesting_level);
+    DLOG("Got bool: %d, parse_error_key %d, nesting_level %d\n", boolval, parse_error_key, current_nesting_level);
 
-    if (success_key && current_nesting_level == 1 && !boolval)
+    if (parse_error_key && current_nesting_level == 1 && boolval)
         command_failed = true;
 
     return 1;
@@ -196,8 +197,8 @@ static int json_map_key(void *ctx, const unsigned char *stringval, size_t string
 #else
 static int json_map_key(void *ctx, const unsigned char *stringval, unsigned int stringlen) {
 #endif
-    success_key = (stringlen >= strlen("success") &&
-                   strncmp((const char*)stringval, "success", strlen("success")) == 0);
+    parse_error_key = (stringlen >= strlen("parse_error") &&
+                       strncmp((const char*)stringval, "parse_error", strlen("parse_error")) == 0);
     return 1;
 }
 
@@ -226,15 +227,17 @@ static yajl_callbacks command_error_callbacks = {
 };
 
 /*
- * There was a key press. We compare this key code with our bindings table and pass
- * the bound action to parse_command().
+ * There was a KeyPress or KeyRelease (both events have the same fields). We
+ * compare this key code with our bindings table and pass the bound action to
+ * parse_command().
  *
  */
 void handle_key_press(xcb_key_press_event_t *event) {
+    bool key_release = (event->response_type == XCB_KEY_RELEASE);
 
     last_timestamp = event->time;
 
-    DLOG("Keypress %d, state raw = %d\n", event->detail, event->state);
+    DLOG("%s %d, state raw = %d\n", (key_release ? "KeyRelease" : "KeyPress"), event->detail, event->state);
 
     /* Remove the numlock bit, all other bits are modifiers we can bind to */
     uint16_t state_filtered = event->state & ~(xcb_numlock_mask | XCB_MOD_MASK_LOCK);
@@ -250,7 +253,7 @@ void handle_key_press(xcb_key_press_event_t *event) {
     DLOG("(checked mode_switch, state %d)\n", state_filtered);
 
     /* Find the binding */
-    Binding *bind = get_binding(state_filtered, event->detail);
+    Binding *bind = get_binding(state_filtered, key_release, event->detail);
 
     /* No match? Then the user has Mode_switch enabled but does not have a
      * specific keybinding. Fall back to the default keybindings (without
@@ -259,8 +262,13 @@ void handle_key_press(xcb_key_press_event_t *event) {
     if (bind == NULL) {
         state_filtered &= ~(BIND_MODE_SWITCH);
         DLOG("no match, new state_filtered = %d\n", state_filtered);
-        if ((bind = get_binding(state_filtered, event->detail)) == NULL) {
-            ELOG("Could not lookup key binding (modifiers %d, keycode %d)\n",
+        if ((bind = get_binding(state_filtered, key_release, event->detail)) == NULL) {
+            /* This is not a real error since we can have release and
+             * non-release keybindings. On a KeyPress event for which there is
+             * only a !release-binding, but no release-binding, the
+             * corresponding KeyRelease event will trigger this. No problem,
+             * though. */
+            DLOG("Could not lookup key binding (modifiers %d, keycode %d)\n",
                  state_filtered, event->detail);
             return;
         }
@@ -288,7 +296,7 @@ void handle_key_press(xcb_key_press_event_t *event) {
     yajl_gen_get_buf(command_output->json_gen, &reply, &length);
 
     current_nesting_level = 0;
-    success_key = false;
+    parse_error_key = false;
     command_failed = false;
     yajl_status state = yajl_parse(handle, reply, length);
     if (state != yajl_status_ok) {