X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmatch.c;h=2449bad7a7e67f2eb755a91679f01f82d73936c2;hb=ac335fcffa06417fe190df97b8fc749f20da0523;hp=603be7bf761f4f348566d4bcb52510f48779903f;hpb=6897e15e72ac222815b4a01d26179e026debd1ba;p=i3%2Fi3 diff --git a/src/match.c b/src/match.c index 603be7bf..2449bad7 100644 --- a/src/match.c +++ b/src/match.c @@ -2,12 +2,34 @@ * vim:ts=4:sw=4:expandtab * * i3 - an improved dynamic tiling window manager - * © 2009-2010 Michael Stapelberg and contributors (see also: LICENSE) + * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE) + * + * A "match" is a data structure which acts like a mask or expression to match + * certain windows or not. For example, when using commands, you can specify a + * command like this: [title="*Firefox*"] kill. The title member of the match + * data structure will then be filled and i3 will check each window using + * match_matches_window() to find the windows affected by this command. * */ #include "all.h" +/* + * Initializes the Match data structure. This function is necessary because the + * members representing boolean values (like dock) need to be initialized with + * -1 instead of 0. + * + */ +void match_init(Match *match) { + memset(match, 0, sizeof(Match)); + match->dock = -1; +} + +/* + * Check if a match is empty. This is necessary while parsing commands to see + * whether the user specified a match at all. + * + */ bool match_is_empty(Match *match) { /* we cannot simply use memcmp() because the structure is part of a * TAILQ and I don’t want to start with things like assuming that the @@ -19,9 +41,33 @@ bool match_is_empty(Match *match) { match->instance == NULL && match->id == XCB_NONE && match->con_id == NULL && + match->dock == -1 && match->floating == M_ANY); } +/* + * Copies the data of a match from src to dest. + * + */ +void match_copy(Match *dest, Match *src) { + memcpy(dest, src, sizeof(Match)); + +#define STRDUP(field) do { \ + if (src->field != NULL) \ + dest->field = sstrdup(src->field); \ +} while (0) + + STRDUP(title); + STRDUP(mark); + STRDUP(application); + STRDUP(class); + STRDUP(instance); +} + +/* + * Check if a match data structure matches the given window. + * + */ bool match_matches_window(Match *match, i3Window *window) { /* TODO: pcre, full matching, … */ if (match->class != NULL && window->class_class != NULL && strcasecmp(match->class, window->class_class) == 0) { @@ -39,8 +85,24 @@ bool match_matches_window(Match *match, i3Window *window) { return true; } + /* TODO: pcre match */ + if (match->title != NULL && window->name_json != NULL && strcasecmp(match->title, window->name_json) == 0) { + LOG("match made by title (%s)\n", window->name_json); + return true; + } + + LOG("match->dock = %d, window->dock = %d\n", match->dock, window->dock); + if (match->dock != -1 && + ((window->dock == W_DOCK_TOP && match->dock == M_DOCK_TOP) || + (window->dock == W_DOCK_BOTTOM && match->dock == M_DOCK_BOTTOM) || + ((window->dock == W_DOCK_TOP || window->dock == W_DOCK_BOTTOM) && + match->dock == M_DOCK_ANY) || + (window->dock == W_NODOCK && match->dock == M_NODOCK))) { + LOG("match made by dock\n"); + return true; + } + LOG("window %d (%s) could not be matched\n", window->id, window->class_class); return false; } -