]> git.sur5r.net Git - i3/i3/blobdiff - src/cfgparse.y
Make horizontal edge-borders hidable too
[i3/i3] / src / cfgparse.y
index 86d928293e055061b5c605078cb70252802079cc..af7d77cf792cc31c9045d6060d2334b1de0e2989 100644 (file)
@@ -19,6 +19,9 @@ static Barconfig current_bar;
  * store this in a separate variable because in the i3 config struct we just
  * store the i3Font. */
 static char *font_pattern;
+/* The path to the temporary script files used by i3-nagbar. We need to keep
+ * them around to delete the files in the i3-nagbar SIGCHLD handler. */
+static char *edit_script_path, *pager_script_path;
 
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 extern int yylex(struct context *context);
@@ -51,7 +54,7 @@ void yyerror(const char *error_message) {
     ELOG("\n");
 }
 
-int yywrap() {
+int yywrap(void) {
     return 1;
 }
 
@@ -233,6 +236,12 @@ static char *migrate_config(char *input, off_t size) {
  */
 static void nagbar_exited(EV_P_ ev_child *watcher, int revents) {
     ev_child_stop(EV_A_ watcher);
+
+    if (unlink(edit_script_path) != 0)
+        warn("Could not delete temporary i3-nagbar script %s", edit_script_path);
+    if (unlink(pager_script_path) != 0)
+        warn("Could not delete temporary i3-nagbar script %s", pager_script_path);
+
     if (!WIFEXITED(watcher->rstatus)) {
         fprintf(stderr, "ERROR: i3-nagbar did not exit normally.\n");
         return;
@@ -264,6 +273,23 @@ static void nagbar_cleanup(EV_P_ ev_cleanup *watcher, int revent) {
 }
 #endif
 
+/*
+ * Writes the given command as a shell script to path.
+ * Returns true unless something went wrong.
+ *
+ */
+static bool write_nagbar_script(const char *path, const char *command) {
+    int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR);
+    if (fd == -1) {
+        warn("Could not create temporary script to store the nagbar command");
+        return false;
+    }
+    write(fd, "#!/bin/sh\n", strlen("#!/bin/sh\n"));
+    write(fd, command, strlen(command));
+    close(fd);
+    return true;
+}
+
 /*
  * Starts an i3-nagbar process which alerts the user that his configuration
  * file contains one or more errors. Also offers two buttons: One to launch an
@@ -276,6 +302,18 @@ static void start_configerror_nagbar(const char *config_path) {
         return;
 
     fprintf(stderr, "Starting i3-nagbar due to configuration errors\n");
+
+    /* We need to create a custom script containing our actual command
+     * since not every terminal emulator which is contained in
+     * i3-sensible-terminal supports -e with multiple arguments (and not
+     * all of them support -e with one quoted argument either).
+     *
+     * NB: The paths need to be unique, that is, don’t assume users close
+     * their nagbars at any point in time (and they still need to work).
+     * */
+    edit_script_path = get_process_filename("nagbar-cfgerror-edit");
+    pager_script_path = get_process_filename("nagbar-cfgerror-pager");
+
     configerror_pid = fork();
     if (configerror_pid == -1) {
         warn("Could not fork()");
@@ -284,10 +322,17 @@ static void start_configerror_nagbar(const char *config_path) {
 
     /* child */
     if (configerror_pid == 0) {
+        char *edit_command, *pager_command;
+        sasprintf(&edit_command, "i3-sensible-editor \"%s\" && i3-msg reload\n", config_path);
+        sasprintf(&pager_command, "i3-sensible-pager \"%s\"\n", errorfilename);
+        if (!write_nagbar_script(edit_script_path, edit_command) ||
+            !write_nagbar_script(pager_script_path, pager_command))
+            return;
+
         char *editaction,
              *pageraction;
-        sasprintf(&editaction, "i3-sensible-terminal -e sh -c \"i3-sensible-editor \\\"%s\\\" && i3-msg reload\"", config_path);
-        sasprintf(&pageraction, "i3-sensible-terminal -e i3-sensible-pager \"%s\"", errorfilename);
+        sasprintf(&editaction, "i3-sensible-terminal -e \"%s\"", edit_script_path);
+        sasprintf(&pageraction, "i3-sensible-terminal -e \"%s\"", pager_script_path);
         char *argv[] = {
             NULL, /* will be replaced by the executable path */
             "-t",
@@ -664,6 +709,8 @@ void parse_file(const char *f) {
 %token                  TOKCONTROL                  "control"
 %token                  TOKSHIFT                    "shift"
 %token                  TOKFLOATING_MODIFIER        "floating_modifier"
+%token                  TOKFLOATING_MAXIMUM_SIZE    "floating_maximum_size"
+%token                  TOKFLOATING_MINIMUM_SIZE    "floating_minimum_size"
 %token  <string>        QUOTEDSTRING                "<quoted string>"
 %token                  TOKWORKSPACE                "workspace"
 %token                  TOKOUTPUT                   "output"
@@ -688,9 +735,12 @@ void parse_file(const char *f) {
 %token                  TOK_NORMAL                  "normal"
 %token                  TOK_NONE                    "none"
 %token                  TOK_1PIXEL                  "1pixel"
+%token                  TOK_HIDE_EDGE_BORDERS       "hide_edge_borders"
+%token                  TOK_BOTH                    "both"
 %token                  TOKFOCUSFOLLOWSMOUSE        "focus_follows_mouse"
 %token                  TOK_FORCE_FOCUS_WRAPPING    "force_focus_wrapping"
 %token                  TOK_FORCE_XINERAMA          "force_xinerama"
+%token                  TOK_FAKE_OUTPUTS            "fake_outputs"
 %token                  TOK_WORKSPACE_AUTO_BAF      "workspace_auto_back_and_forth"
 %token                  TOKWORKSPACEBAR             "workspace_bar"
 %token                  TOK_DEFAULT                 "default"
@@ -740,6 +790,7 @@ void parse_file(const char *f) {
 %token              TOK_ID              "id"
 %token              TOK_CON_ID          "con_id"
 %token              TOK_TITLE           "title"
+%token              TOK_URGENT          "urgent"
 
 %type   <binding>       binding
 %type   <binding>       bindcode
@@ -750,6 +801,8 @@ void parse_file(const char *f) {
 %type   <number>        layout_mode
 %type   <number>        border_style
 %type   <number>        new_window
+%type   <number>        hide_edge_borders
+%type   <number>        edge_hiding_mode
 %type   <number>        new_float
 %type   <number>        colorpixel
 %type   <number>        bool
@@ -777,14 +830,18 @@ line:
     | for_window
     | mode
     | bar
+    | floating_maximum_size
+    | floating_minimum_size
     | floating_modifier
     | orientation
     | workspace_layout
     | new_window
     | new_float
+    | hide_edge_borders
     | focus_follows_mouse
     | force_focus_wrapping
     | force_xinerama
+    | fake_outputs
     | workspace_back_and_forth
     | workspace_bar
     | workspace
@@ -953,6 +1010,20 @@ criterion:
         current_match.title = regex_new($3);
         free($3);
     }
+    | TOK_URGENT '=' STR
+    {
+        printf("criteria: urgent = %s\n", $3);
+        if (strcasecmp($3, "latest") == 0 ||
+            strcasecmp($3, "newest") == 0 ||
+            strcasecmp($3, "recent") == 0 ||
+            strcasecmp($3, "last") == 0) {
+            current_match.urgent = U_LATEST;
+        } else if (strcasecmp($3, "oldest") == 0 ||
+                   strcasecmp($3, "first") == 0) {
+            current_match.urgent = U_OLDEST;
+        }
+        free($3);
+    }
     ;
 
 qstring_or_number:
@@ -1277,6 +1348,26 @@ bar_color_urgent_workspace:
     }
     ;
 
+floating_maximum_size:
+    TOKFLOATING_MAXIMUM_SIZE NUMBER WORD NUMBER
+    {
+        printf("floating_maximum_width = %d\n", $2);
+        printf("floating_maximum_height = %d\n", $4);
+        config.floating_maximum_width = $2;
+        config.floating_maximum_height = $4;
+    }
+    ;
+
+floating_minimum_size:
+    TOKFLOATING_MINIMUM_SIZE NUMBER WORD NUMBER
+    {
+        printf("floating_minimum_width = %d\n", $2);
+        printf("floating_minimum_height = %d\n", $4);
+        config.floating_minimum_width = $2;
+        config.floating_minimum_height = $4;
+    }
+    ;
+
 floating_modifier:
     TOKFLOATING_MODIFIER binding_modifiers
     {
@@ -1388,6 +1479,22 @@ bool:
     }
     ;
 
+hide_edge_borders:
+    TOK_HIDE_EDGE_BORDERS edge_hiding_mode
+    {
+        DLOG("hide edge borders = %d\n", $2);
+        config.hide_edge_borders = $2;
+    }
+    ;
+
+edge_hiding_mode:
+    TOK_NONE        { $$ = ADJ_NONE; }
+    | TOK_VERT      { $$ = ADJ_LEFT_SCREEN_EDGE | ADJ_RIGHT_SCREEN_EDGE; }
+    | TOK_HORIZ     { $$ = ADJ_UPPER_SCREEN_EDGE | ADJ_LOWER_SCREEN_EDGE; }
+    | TOK_BOTH      { $$ = ADJ_LEFT_SCREEN_EDGE | ADJ_RIGHT_SCREEN_EDGE | ADJ_UPPER_SCREEN_EDGE | ADJ_LOWER_SCREEN_EDGE; }
+    | bool          { $$ = ($1 ? ADJ_LEFT_SCREEN_EDGE | ADJ_RIGHT_SCREEN_EDGE : ADJ_NONE); }
+    ;
+
 focus_follows_mouse:
     TOKFOCUSFOLLOWSMOUSE bool
     {
@@ -1412,6 +1519,14 @@ force_xinerama:
     }
     ;
 
+fake_outputs:
+    TOK_FAKE_OUTPUTS STR
+    {
+        DLOG("fake outputs = %s\n", $2);
+        config.fake_outputs = $2;
+    }
+    ;
+
 workspace_back_and_forth:
     TOK_WORKSPACE_AUTO_BAF bool
     {