]> git.sur5r.net Git - i3/i3/blobdiff - src/cfgparse.y
Merge branch 'master' into next
[i3/i3] / src / cfgparse.y
index ecfa665859c51520d8bbe557633192e561a03266..68173757589f50e90e666751bfd59391e2bfea16 100644 (file)
@@ -8,7 +8,6 @@
 #include <sys/wait.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <limits.h>
 
 #include "all.h"
 
@@ -115,7 +114,7 @@ next:
 }
 
 /*
- * Calls i3-migrate-config-to-v4.pl to migrate a configuration file (input
+ * Calls i3-migrate-config-to-v4 to migrate a configuration file (input
  * buffer).
  *
  * Returns the converted config file or NULL if there was an error (for
@@ -153,7 +152,7 @@ static char *migrate_config(char *input, off_t size) {
             NULL, /* will be replaced by the executable path */
             NULL
         };
-        exec_i3_utility("i3-migrate-config-to-v4.pl", argv);
+        exec_i3_utility("i3-migrate-config-to-v4", argv);
     }
 
     /* parent */
@@ -311,6 +310,53 @@ void kill_configerror_nagbar(bool wait_for_it) {
     waitpid(configerror_pid, NULL, 0);
 }
 
+/*
+ * Checks for duplicate key bindings (the same keycode or keysym is configured
+ * more than once). If a duplicate binding is found, a message is printed to
+ * stderr and the has_errors variable is set to true, which will start
+ * i3-nagbar.
+ *
+ */
+static void check_for_duplicate_bindings(struct context *context) {
+    Binding *bind, *current;
+    TAILQ_FOREACH(current, bindings, bindings) {
+        TAILQ_FOREACH(bind, bindings, bindings) {
+            /* Abort when we reach the current keybinding, only check the
+             * bindings before */
+            if (bind == current)
+                break;
+
+            /* 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;
+
+            /* If bind is NULL, current has to be NULL, too (see above).
+             * If the keycodes differ, it can't be a duplicate. */
+            if (bind->symbol != NULL &&
+                strcasecmp(bind->symbol, current->symbol) != 0)
+                continue;
+
+            /* Check if the keycodes or modifiers are different. If so, they
+             * can't be duplicate */
+            if (bind->keycode != current->keycode ||
+                bind->mods != current->mods)
+                continue;
+            context->has_errors = true;
+            if (current->keycode != 0) {
+                ELOG("Duplicate keybinding in config file:\n  modmask %d with keycode %d, command \"%s\"\n",
+                     current->mods, current->keycode, current->command);
+            } else {
+                ELOG("Duplicate keybinding in config file:\n  modmask %d with keysym %s, command \"%s\"\n",
+                     current->mods, current->symbol, current->command);
+            }
+        }
+    }
+}
+
 void parse_file(const char *f) {
     SLIST_HEAD(variables_head, Variable) variables = SLIST_HEAD_INITIALIZER(&variables);
     int fd, ret, read_bytes = 0;
@@ -438,7 +484,7 @@ void parse_file(const char *f) {
             printf("\n");
             printf("Please convert your config file to v4. You can use this command:\n");
             printf("    mv %s %s.O\n", f, f);
-            printf("    i3-migrate-config-to-v4.pl %s.O > %s\n", f, f);
+            printf("    i3-migrate-config-to-v4 %s.O > %s\n", f, f);
             printf("****************************************************************\n");
             printf("\n");
             free(new);
@@ -446,7 +492,7 @@ void parse_file(const char *f) {
         } else {
             printf("\n");
             printf("**********************************************************************\n");
-            printf("ERROR: Could not convert config file. Maybe i3-migrate-config-to-v4.pl\n");
+            printf("ERROR: Could not convert config file. Maybe i3-migrate-config-to-v4\n");
             printf("was not correctly installed on your system?\n");
             printf("**********************************************************************\n");
             printf("\n");
@@ -464,6 +510,8 @@ void parse_file(const char *f) {
         exit(1);
     }
 
+    check_for_duplicate_bindings(context);
+
     if (context->has_errors) {
         start_configerror_nagbar(f);
     }
@@ -548,6 +596,7 @@ void parse_file(const char *f) {
 
 %token              TOK_MARK            "mark"
 %token              TOK_CLASS           "class"
+%token              TOK_INSTANCE        "instance"
 %token              TOK_ID              "id"
 %token              TOK_CON_ID          "con_id"
 %token              TOK_TITLE           "title"
@@ -685,11 +734,21 @@ matchend:
     ;
 
 criteria:
+    criteria criterion
+    | criterion
+    ;
+
+criterion:
     TOK_CLASS '=' STR
     {
         printf("criteria: class = %s\n", $3);
         current_match.class = $3;
     }
+    | TOK_INSTANCE '=' STR
+    {
+        printf("criteria: instance = %s\n", $3);
+        current_match.instance = $3;
+    }
     | TOK_CON_ID '=' STR
     {
         printf("criteria: id = %s\n", $3);
@@ -986,7 +1045,7 @@ assign:
         /* Compatibility with older versions: If the assignment target starts
          * with ~, we create the equivalent of:
          *
-         * for_window [class="foo"] mode floating
+         * for_window [class="foo"] floating enable
          */
         if (*workspace == '~') {
             workspace++;
@@ -1091,6 +1150,7 @@ colorpixel:
         char *hex;
         if (asprintf(&hex, "#%s", $2) == -1)
             die("asprintf()");
+        free($2);
         $$ = get_colorpixel(hex);
         free(hex);
     }