]> git.sur5r.net Git - i3/i3/blob - src/match.c
recognize dock windows (and support matching them)
[i3/i3] / src / match.c
1 /*
2  * vim:ts=4:sw=4:expandtab
3  *
4  * i3 - an improved dynamic tiling window manager
5  * © 2009-2010 Michael Stapelberg and contributors (see also: LICENSE)
6  *
7  * A "match" is a data structure which acts like a mask or expression to match
8  * certain windows or not. For example, when using commands, you can specify a
9  * command like this: [title="*Firefox*"] kill. The title member of the match
10  * data structure will then be filled and i3 will check each window using
11  * match_matches_window() to find the windows affected by this command.
12  *
13  */
14
15 #include "all.h"
16
17 /*
18  * Initializes the Match data structure. This function is necessary because the
19  * members representing boolean values (like dock) need to be initialized with
20  * -1 instead of 0.
21  *
22  */
23 void match_init(Match *match) {
24     memset(match, 0, sizeof(Match));
25     match->dock = -1;
26 }
27
28 /*
29  * Check if a match is empty. This is necessary while parsing commands to see
30  * whether the user specified a match at all.
31  *
32  */
33 bool match_is_empty(Match *match) {
34     /* we cannot simply use memcmp() because the structure is part of a
35      * TAILQ and I don’t want to start with things like assuming that the
36      * last member of a struct really is at the end in memory… */
37     return (match->title == NULL &&
38             match->mark == NULL &&
39             match->application == NULL &&
40             match->class == NULL &&
41             match->instance == NULL &&
42             match->id == XCB_NONE &&
43             match->con_id == NULL &&
44             match->dock == -1 &&
45             match->floating == M_ANY);
46 }
47
48 /*
49  * Check if a match data structure matches the given window.
50  *
51  */
52 bool match_matches_window(Match *match, i3Window *window) {
53     /* TODO: pcre, full matching, … */
54     if (match->class != NULL && window->class_class != NULL && strcasecmp(match->class, window->class_class) == 0) {
55         LOG("match made by window class (%s)\n", window->class_class);
56         return true;
57     }
58
59     if (match->instance != NULL && window->class_instance != NULL && strcasecmp(match->instance, window->class_instance) == 0) {
60         LOG("match made by window instance (%s)\n", window->class_instance);
61         return true;
62     }
63
64     if (match->id != XCB_NONE && window->id == match->id) {
65         LOG("match made by window id (%d)\n", window->id);
66         return true;
67     }
68
69     LOG("match->dock = %d, window->dock = %d\n", match->dock, window->dock);
70     if (match->dock != -1 && window->dock == match->dock) {
71         LOG("match made by dock\n");
72         return true;
73     }
74
75     LOG("window %d (%s) could not be matched\n", window->id, window->class_class);
76
77     return false;
78 }
79