X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcfgparse.y;h=9a417f2aba0b54aeb65cd059f9947d756e617c6d;hb=6420b2b102bab214ad0bf1fa0f5e190f02984e82;hp=fd23597e28bd2bff4ec965066c12b0125ff6434f;hpb=f0a0236b7b4ac57bc9155edf438e90ea44715778;p=i3%2Fi3 diff --git a/src/cfgparse.y b/src/cfgparse.y index fd23597e..9a417f2a 100644 --- a/src/cfgparse.y +++ b/src/cfgparse.y @@ -188,6 +188,7 @@ static char *migrate_config(char *input, off_t size) { ret = read(readpipe[0], converted + read_bytes, conv_size - read_bytes); if (ret == -1) { warn("Cannot read from pipe"); + FREE(converted); return NULL; } read_bytes += ret; @@ -239,6 +240,23 @@ static void nagbar_exited(EV_P_ ev_child *watcher, int revents) { configerror_pid = -1; } +/* We need ev >= 4 for the following code. Since it is not *that* important (it + * only makes sure that there are no i3-nagbar instances left behind) we still + * support old systems with libev 3. */ +#if EV_VERSION_MAJOR >= 4 +/* + * Cleanup handler. Will be called when i3 exits. Kills i3-nagbar with signal + * SIGKILL (9) to make sure there are no left-over i3-nagbar processes. + * + */ +static void nagbar_cleanup(EV_P_ ev_cleanup *watcher, int revent) { + if (configerror_pid != -1) { + LOG("Sending SIGKILL (9) to i3-nagbar with PID %d\n", configerror_pid); + kill(configerror_pid, SIGKILL); + } +} +#endif + /* * 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 @@ -258,9 +276,9 @@ static void start_configerror_nagbar(const char *config_path) { if (configerror_pid == 0) { char *editaction, *pageraction; - if (asprintf(&editaction, TERM_EMU " -e sh -c \"${EDITOR:-vi} \"%s\" && i3-msg reload\"", config_path) == -1) + if (asprintf(&editaction, "i3-sensible-terminal -e sh -c \"i3-sensible-editor \\\"%s\\\" && i3-msg reload\"", config_path) == -1) exit(1); - if (asprintf(&pageraction, TERM_EMU " -e sh -c \"${PAGER:-less} \"%s\"\"", errorfilename) == -1) + if (asprintf(&pageraction, "i3-sensible-terminal -e i3-sensible-pager \"%s\"", errorfilename) == -1) exit(1); char *argv[] = { NULL, /* will be replaced by the executable path */ @@ -282,6 +300,17 @@ static void start_configerror_nagbar(const char *config_path) { ev_child *child = smalloc(sizeof(ev_child)); ev_child_init(child, &nagbar_exited, configerror_pid, 0); ev_child_start(main_loop, child); + +/* We need ev >= 4 for the following code. Since it is not *that* important (it + * only makes sure that there are no i3-nagbar instances left behind) we still + * support old systems with libev 3. */ +#if EV_VERSION_MAJOR >= 4 + /* install a cleanup watcher (will be called when i3 exits and i3-nagbar is + * still running) */ + ev_cleanup *cleanup = smalloc(sizeof(ev_cleanup)); + ev_cleanup_init(cleanup, nagbar_cleanup); + ev_cleanup_start(main_loop, cleanup); +#endif } /* @@ -404,12 +433,14 @@ void parse_file(const char *f) { /* get key/value for this variable */ char *v_key = value, *v_value; - if ((v_value = strstr(value, " ")) == NULL && - (v_value = strstr(value, "\t")) == NULL) { + if (strstr(value, " ") == NULL && strstr(value, "\t") == NULL) { ELOG("Malformed variable assignment, need a value\n"); continue; } + if (!(v_value = strstr(value, " "))) + v_value = strstr(value, "\t"); + *(v_value++) = '\0'; struct Variable *new = scalloc(sizeof(struct Variable)); @@ -434,7 +465,8 @@ void parse_file(const char *f) { int extra = (strlen(current->value) - strlen(current->key)); char *next; for (next = bufcopy; - (next = strcasestr(bufcopy + (next - bufcopy), current->key)) != NULL; + next < (bufcopy + stbuf.st_size) && + (next = strcasestr(next, current->key)) != NULL; next += strlen(current->key)) { *next = '_'; extra_bytes += extra; @@ -590,6 +622,7 @@ void parse_file(const char *f) { %token TOK_1PIXEL "1pixel" %token TOKFOCUSFOLLOWSMOUSE "focus_follows_mouse" %token TOK_FORCE_FOCUS_WRAPPING "force_focus_wrapping" +%token TOK_FORCE_XINERAMA "force_xinerama" %token TOKWORKSPACEBAR "workspace_bar" %token TOK_DEFAULT "default" %token TOK_STACKING "stacking" @@ -603,6 +636,7 @@ void parse_file(const char *f) { %token TOK_MARK "mark" %token TOK_CLASS "class" %token TOK_INSTANCE "instance" +%token TOK_WINDOW_ROLE "window_role" %token TOK_ID "id" %token TOK_CON_ID "con_id" %token TOK_TITLE "title" @@ -644,6 +678,7 @@ line: | new_float | focus_follows_mouse | force_focus_wrapping + | force_xinerama | workspace_bar | workspace | assign @@ -710,6 +745,10 @@ bindsym: for_window: TOK_FOR_WINDOW match command { + if (match_is_empty(¤t_match)) { + ELOG("Match is empty, ignoring this for_window statement\n"); + break; + } printf("\t should execute command %s for the criteria mentioned above\n", $3); Assignment *assignment = scalloc(sizeof(Assignment)); assignment->type = A_COMMAND; @@ -750,12 +789,20 @@ criterion: TOK_CLASS '=' STR { printf("criteria: class = %s\n", $3); - current_match.class = $3; + current_match.class = regex_new($3); + free($3); } | TOK_INSTANCE '=' STR { printf("criteria: instance = %s\n", $3); - current_match.instance = $3; + current_match.instance = regex_new($3); + free($3); + } + | TOK_WINDOW_ROLE '=' STR + { + printf("criteria: window_role = %s\n", $3); + current_match.role = regex_new($3); + free($3); } | TOK_CON_ID '=' STR { @@ -790,12 +837,14 @@ criterion: | TOK_MARK '=' STR { printf("criteria: mark = %s\n", $3); - current_match.mark = $3; + current_match.mark = regex_new($3); + free($3); } | TOK_TITLE '=' STR { printf("criteria: title = %s\n", $3); - current_match.title = $3; + current_match.title = regex_new($3); + free($3); } ; @@ -978,6 +1027,14 @@ force_focus_wrapping: } ; +force_xinerama: + TOK_FORCE_XINERAMA bool + { + DLOG("force xinerama = %d\n", $2); + config.force_xinerama = $2; + } + ; + workspace_bar: TOKWORKSPACEBAR bool { @@ -1053,6 +1110,13 @@ workspace_name: assign: TOKASSIGN window_class STR { + /* This is the old, deprecated form of assignments. It’s provided for + * compatibility in version (4.1, 4.2, 4.3) and will be removed + * afterwards. It triggers an i3-nagbar warning starting from 4.1. */ + ELOG("You are using the old assign syntax (without criteria). " + "Please see the User's Guide for the new syntax and fix " + "your config file.\n"); + context->has_errors = true; printf("assignment of %s to *%s*\n", $2, $3); char *workspace = $3; char *criteria = $2; @@ -1064,15 +1128,27 @@ assign: char *separator = NULL; if ((separator = strchr(criteria, '/')) != NULL) { *(separator++) = '\0'; - match->title = sstrdup(separator); + char *pattern; + if (asprintf(&pattern, "(?i)%s", separator) == -1) { + ELOG("asprintf failed\n"); + break; + } + match->title = regex_new(pattern); + free(pattern); + printf(" title = %s\n", separator); + } + if (*criteria != '\0') { + char *pattern; + if (asprintf(&pattern, "(?i)%s", criteria) == -1) { + ELOG("asprintf failed\n"); + break; + } + match->class = regex_new(pattern); + free(pattern); + printf(" class = %s\n", criteria); } - if (*criteria != '\0') - match->class = sstrdup(criteria); free(criteria); - printf(" class = %s\n", match->class); - printf(" title = %s\n", match->title); - /* Compatibility with older versions: If the assignment target starts * with ~, we create the equivalent of: * @@ -1100,6 +1176,19 @@ assign: assignment->dest.workspace = workspace; TAILQ_INSERT_TAIL(&assignments, assignment, assignments); } + | TOKASSIGN match STR + { + if (match_is_empty(¤t_match)) { + ELOG("Match is empty, ignoring this assignment\n"); + break; + } + printf("new assignment, using above criteria, to workspace %s\n", $3); + Assignment *assignment = scalloc(sizeof(Assignment)); + assignment->match = current_match; + assignment->type = A_TO_WORKSPACE; + assignment->dest.workspace = $3; + TAILQ_INSERT_TAIL(&assignments, assignment, assignments); + } ; window_class: