]> git.sur5r.net Git - i3/i3/commitdiff
Check duplicated bindings after translating keysym 1959/head
authorhwangcc23 <hwangcc@csie.nctu.edu.tw>
Fri, 25 Sep 2015 14:20:28 +0000 (22:20 +0800)
committerhwangcc23 <hwangcc@csie.nctu.edu.tw>
Fri, 2 Oct 2015 14:09:53 +0000 (22:09 +0800)
1). See the issue #1926. For example, the second keybinding is not detected as a duplicate:
        bindcode Mod4+24 sticky toggle
        bindsym Mod4+q focus parent
2). To fix it, check duplicated bindings when translating the keysym to keycodes.

include/config_parser.h
src/bindings.c
src/config_parser.c

index 28c28e4882e7f2b6fa220cfe98ca4d4b391f1819..9c23a11df56be737c559087da84a81bc471cd96c 100644 (file)
@@ -31,6 +31,11 @@ struct ConfigResultIR {
 
 struct ConfigResultIR *parse_config(const char *input, struct context *context);
 
+/**
+ * launch nagbar to indicate errors in the configuration file.
+ */
+void start_config_error_nagbar(const char *configpath, bool has_errors);
+
 /**
  * Parses the given file by first replacing the variables, then calling
  * parse_config and launching i3-nagbar if use_nagbar is true.
index 32aac05af3d605e5c9c0f6fa4b7442e6db726e23..086d230adefd7c8f433fc342f7289e28ae950cee 100644 (file)
@@ -319,6 +319,7 @@ void translate_keysyms(void) {
         return;
     }
 
+    bool has_errors = false;
     Binding *bind;
     TAILQ_FOREACH(bind, bindings, bindings) {
         if (bind->input_type == B_MOUSE) {
@@ -389,6 +390,21 @@ void translate_keysyms(void) {
             sasprintf(&tmp, "%s %d", keycodes, bind->translated_to[n]);
             free(keycodes);
             keycodes = tmp;
+
+            /* check for duplicate bindings */
+            Binding *check;
+            TAILQ_FOREACH(check, bindings, bindings) {
+                if (check == bind)
+                    continue;
+                if (check->symbol != NULL)
+                    continue;
+                if (check->keycode != bind->translated_to[n] ||
+                    check->event_state_mask != bind->event_state_mask ||
+                    check->release != bind->release)
+                    continue;
+                has_errors = true;
+                ELOG("Duplicate keybinding in config file:\n  keysym = %s, keycode = %d, state_mask = 0x%x\n", bind->symbol, check->keycode, bind->event_state_mask);
+            }
         }
         DLOG("state=0x%x, cfg=\"%s\", sym=0x%x → keycodes%s (%d)\n",
              bind->event_state_mask, bind->symbol, keysym, keycodes, bind->number_keycodes);
@@ -396,6 +412,10 @@ void translate_keysyms(void) {
     }
 
     xkb_state_unref(dummy_state);
+
+    if (has_errors) {
+        start_config_error_nagbar(current_configpath, true);
+    }
 }
 
 /*
@@ -514,8 +534,6 @@ void check_for_duplicate_bindings(struct context *context) {
 
             /* Check if one is using keysym while the other is using bindsym.
              * If so, skip. */
-            /* XXX: It should be checked at a later place (when translating the
-             * keysym to keycodes) if there are any duplicates */
             if ((bind->symbol == NULL && current->symbol != NULL) ||
                 (bind->symbol != NULL && current->symbol == NULL))
                 continue;
index ea00412d78b2d2533c5dd0b87486aaa3da7e9f4e..2b4572b017fb32dc061cea9ae0f19088dcbe291f 100644 (file)
@@ -830,6 +830,34 @@ static char *migrate_config(char *input, off_t size) {
     return converted;
 }
 
+/**
+ * Launch nagbar to indicate errors in the configuration file.
+ */
+void start_config_error_nagbar(const char *configpath, bool has_errors) {
+    char *editaction, *pageraction;
+    sasprintf(&editaction, "i3-sensible-editor \"%s\" && i3-msg reload\n", configpath);
+    sasprintf(&pageraction, "i3-sensible-pager \"%s\"\n", errorfilename);
+    char *argv[] = {
+        NULL, /* will be replaced by the executable path */
+        "-f",
+        (config.font.pattern ? config.font.pattern : "fixed"),
+        "-t",
+        (has_errors ? "error" : "warning"),
+        "-m",
+        (has_errors ? "You have an error in your i3 config file!" : "Your config is outdated. Please fix the warnings to make sure everything works."),
+        "-b",
+        "edit config",
+        editaction,
+        (errorfilename ? "-b" : NULL),
+        (has_errors ? "show errors" : "show warnings"),
+        pageraction,
+        NULL};
+
+    start_nagbar(&config_error_nagbar_pid, argv);
+    free(editaction);
+    free(pageraction);
+}
+
 /*
  * Parses the given file by first replacing the variables, then calling
  * parse_config and possibly launching i3-nagbar.
@@ -1005,29 +1033,7 @@ bool parse_file(const char *f, bool use_nagbar) {
         if (version == 3)
             ELOG("Please convert your configfile first, then fix any remaining errors (see above).\n");
 
-        char *editaction,
-            *pageraction;
-        sasprintf(&editaction, "i3-sensible-editor \"%s\" && i3-msg reload\n", f);
-        sasprintf(&pageraction, "i3-sensible-pager \"%s\"\n", errorfilename);
-        char *argv[] = {
-            NULL, /* will be replaced by the executable path */
-            "-f",
-            (config.font.pattern ? config.font.pattern : "fixed"),
-            "-t",
-            (context->has_errors ? "error" : "warning"),
-            "-m",
-            (context->has_errors ? "You have an error in your i3 config file!" : "Your config is outdated. Please fix the warnings to make sure everything works."),
-            "-b",
-            "edit config",
-            editaction,
-            (errorfilename ? "-b" : NULL),
-            (context->has_errors ? "show errors" : "show warnings"),
-            pageraction,
-            NULL};
-
-        start_nagbar(&config_error_nagbar_pid, argv);
-        free(editaction);
-        free(pageraction);
+        start_config_error_nagbar(f, context->has_errors);
     }
 
     bool has_errors = context->has_errors;