X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcmdparse.y;h=04e8b3ca3f4cb0a8f66337a2132b5e2ceb90223f;hb=1717b88174d26ed946bea0a0038a8a999fc2387f;hp=df7b6efeb83f9809e815e72eb872e29177b426e1;hpb=cc5f3ce95a657696e1404618c2cae390cdeb662e;p=i3%2Fi3 diff --git a/src/cmdparse.y b/src/cmdparse.y index df7b6efe..04e8b3ca 100644 --- a/src/cmdparse.y +++ b/src/cmdparse.y @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "all.h" @@ -82,13 +81,13 @@ int cmdyywrap() { } char *parse_cmd(const char *new) { + json_output = NULL; LOG("COMMAND: *%s*\n", new); cmdyy_scan_string(new); match_init(¤t_match); context = scalloc(sizeof(struct context)); context->filename = "cmd"; - FREE(json_output); if (cmdyyparse() != 0) { fprintf(stderr, "Could not parse command\n"); asprintf(&json_output, "{\"success\":false, \"error\":\"%s at position %d\"}", @@ -150,6 +149,7 @@ bool definitelyGreaterThan(float a, float b, float epsilon) { %token TOK_ENABLE "enable" %token TOK_DISABLE "disable" %token TOK_WORKSPACE "workspace" +%token TOK_OUTPUT "output" %token TOK_TOGGLE "toggle" %token TOK_FOCUS "focus" %token TOK_MOVE "move" @@ -176,6 +176,8 @@ bool definitelyGreaterThan(float a, float b, float epsilon) { %token TOK_NOP "nop" %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" @@ -266,10 +268,9 @@ matchend: } } else if (current_match.mark != NULL && current->con->mark != NULL && - strcasecmp(current_match.mark, current->con->mark) == 0) { + regex_matches(current_match.mark, current->con->mark)) { printf("match by mark\n"); - TAILQ_INSERT_TAIL(&owindows, current, owindows); - + TAILQ_INSERT_TAIL(&owindows, current, owindows); } else { if (current->con->window == NULL) continue; @@ -299,7 +300,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 = 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 { @@ -334,12 +348,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); } ; @@ -479,7 +495,7 @@ focus: int to_focus = $2; if ($2 == TOK_MODE_TOGGLE) { current = TAILQ_FIRST(&(ws->focus_head)); - if (current->type == CT_FLOATING_CON) + if (current != NULL && current->type == CT_FLOATING_CON) to_focus = TOK_TILING; else to_focus = TOK_FLOATING; } @@ -528,7 +544,7 @@ kill: else { TAILQ_FOREACH(current, &owindows, owindows) { printf("matching: %p / %s\n", current->con, current->con->name); - tree_close(current->con, $2, false); + tree_close(current->con, $2, false, false); } } @@ -694,7 +710,52 @@ move: TAILQ_FOREACH(current, &owindows, owindows) { printf("matching: %p / %s\n", current->con, current->con->name); - con_move_to_workspace(current->con, ws); + con_move_to_workspace(current->con, ws, true, false); + } + + tree_render(); + } + | TOK_MOVE TOK_OUTPUT STR + { + owindow *current; + + printf("should move window to output %s", $3); + + HANDLE_EMPTY_MATCH; + + /* get the output */ + Output *current_output = NULL; + Output *output; + + TAILQ_FOREACH(current, &owindows, owindows) + current_output = get_output_containing(current->con->rect.x, current->con->rect.y); + + assert(current_output != NULL); + + if (strcasecmp($3, "up") == 0) + output = get_output_next(D_UP, current_output); + else if (strcasecmp($3, "down") == 0) + output = get_output_next(D_DOWN, current_output); + else if (strcasecmp($3, "left") == 0) + output = get_output_next(D_LEFT, current_output); + else if (strcasecmp($3, "right") == 0) + output = get_output_next(D_RIGHT, current_output); + else + output = get_output_by_name($3); + free($3); + + if (!output) + break; + + /* get visible workspace on output */ + Con *ws = NULL; + GREP_FIRST(ws, output_get_content(output->con), workspace_is_visible(child)); + if (!ws) + break; + + TAILQ_FOREACH(current, &owindows, owindows) { + printf("matching: %p / %s\n", current->con, current->con->name); + con_move_to_workspace(current->con, ws, true, false); } tree_render(); @@ -794,39 +855,55 @@ resize: } } else { LOG("tiling resize\n"); + /* get the appropriate current container (skip stacked/tabbed cons) */ + Con *current = focused; + while (current->parent->layout == L_STACKED || + current->parent->layout == L_TABBED) + current = current->parent; /* get the default percentage */ - int children = con_num_children(focused->parent); + int children = con_num_children(current->parent); Con *other; LOG("ins. %d children\n", children); double percentage = 1.0 / children; LOG("default percentage = %f\n", percentage); + orientation_t orientation = current->parent->orientation; + + if ((orientation == HORIZ && + (direction == TOK_UP || direction == TOK_DOWN)) || + (orientation == VERT && + (direction == TOK_LEFT || direction == TOK_RIGHT))) { + LOG("You cannot resize in that direction. Your focus is in a %s split container currently.\n", + (orientation == HORIZ ? "horizontal" : "vertical")); + break; + } + if (direction == TOK_UP || direction == TOK_LEFT) { - other = TAILQ_PREV(focused, nodes_head, nodes); + other = TAILQ_PREV(current, nodes_head, nodes); } else { - other = TAILQ_NEXT(focused, nodes); + other = TAILQ_NEXT(current, nodes); } if (other == TAILQ_END(workspaces)) { LOG("No other container in this direction found, cannot resize.\n"); - return 0; + break; } LOG("other->percent = %f\n", other->percent); - LOG("focused->percent before = %f\n", focused->percent); - if (focused->percent == 0.0) - focused->percent = percentage; + LOG("current->percent before = %f\n", current->percent); + if (current->percent == 0.0) + current->percent = percentage; if (other->percent == 0.0) other->percent = percentage; - double new_focused_percent = focused->percent + ((double)ppt / 100.0); + double new_current_percent = current->percent + ((double)ppt / 100.0); double new_other_percent = other->percent - ((double)ppt / 100.0); - LOG("new_focused_percent = %f\n", new_focused_percent); + LOG("new_current_percent = %f\n", new_current_percent); LOG("new_other_percent = %f\n", new_other_percent); /* Ensure that the new percentages are positive and greater than * 0.05 to have a reasonable minimum size. */ - if (definitelyGreaterThan(new_focused_percent, 0.05, DBL_EPSILON) && + if (definitelyGreaterThan(new_current_percent, 0.05, DBL_EPSILON) && definitelyGreaterThan(new_other_percent, 0.05, DBL_EPSILON)) { - focused->percent += ((double)ppt / 100.0); + current->percent += ((double)ppt / 100.0); other->percent -= ((double)ppt / 100.0); - LOG("focused->percent after = %f\n", focused->percent); + LOG("current->percent after = %f\n", current->percent); LOG("other->percent after = %f\n", other->percent); } else { LOG("Not resizing, already at minimum size\n");