From 160c12ed9a1c0ee2f30ed8f71d75fb174242eaf9 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 15 Aug 2010 12:18:27 +0200 Subject: [PATCH] recognize dock windows (and support matching them) --- include/data.h | 4 ++++ include/match.h | 8 ++++++++ src/load_layout.c | 10 +++++++++- src/main.c | 4 +++- src/manage.c | 10 +++++++--- src/match.c | 18 ++++++++++++++++++ 6 files changed, 49 insertions(+), 5 deletions(-) diff --git a/include/data.h b/include/data.h index de29e829..79e0e18a 100644 --- a/include/data.h +++ b/include/data.h @@ -228,6 +228,9 @@ struct Window { /** Whether the application used _NET_WM_NAME */ bool uses_net_wm_name; + + /** Whether the window says it is a dock window */ + bool dock; }; struct Match { @@ -239,6 +242,7 @@ struct Match { char *class; char *instance; char *mark; + int dock; xcb_window_t id; Con *con_id; enum { M_ANY = 0, M_TILING, M_FLOATING } floating; diff --git a/include/match.h b/include/match.h index 923be2e1..ef025172 100644 --- a/include/match.h +++ b/include/match.h @@ -1,6 +1,14 @@ #ifndef _MATCH_H #define _MATCH_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); + /** * Check if a match is empty. This is necessary while parsing commands to see * whether the user specified a match at all. diff --git a/src/load_layout.c b/src/load_layout.c index c7e77eef..b88a49be 100644 --- a/src/load_layout.c +++ b/src/load_layout.c @@ -1,3 +1,7 @@ +/* + * vim:ts=4:sw=4:expandtab + * + */ #include #include #include @@ -16,7 +20,8 @@ static int json_start_map(void *ctx) { LOG("start of map\n"); if (parsing_swallows) { LOG("TODO: create new swallow\n"); - current_swallow = scalloc(sizeof(Match)); + current_swallow = smalloc(sizeof(Match)); + match_init(current_swallow); TAILQ_INSERT_TAIL(&(json_node->swallow_head), current_swallow, matches); } else { if (!parsing_rect) @@ -104,6 +109,9 @@ static int json_int(void *ctx, long val) { if (strcasecmp(last_key, "id") == 0) { current_swallow->id = val; } + if (strcasecmp(last_key, "dock") == 0) { + current_swallow->dock = true; + } } return 1; diff --git a/src/main.c b/src/main.c index a5769d17..076aa277 100644 --- a/src/main.c +++ b/src/main.c @@ -296,7 +296,9 @@ int main(int argc, char *argv[]) { /* proof-of-concept for assignments */ Con *ws = workspace_get("3"); - Match *current_swallow = scalloc(sizeof(Match)); + Match *current_swallow = smalloc(sizeof(Match)); + match_init(current_swallow); + TAILQ_INSERT_TAIL(&(ws->swallow_head), current_swallow, matches); current_swallow->insert_where = M_ACTIVE; diff --git a/src/manage.c b/src/manage.c index 48262642..79200882 100644 --- a/src/manage.c +++ b/src/manage.c @@ -145,6 +145,13 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki window_update_name_legacy(cwindow, xcb_get_property_reply(conn, title_cookie, NULL)); window_update_name(cwindow, xcb_get_property_reply(conn, utf8_title_cookie, NULL)); + xcb_get_property_reply_t *reply = xcb_get_property_reply(conn, wm_type_cookie, NULL); + if (xcb_reply_contains_atom(reply, atoms[_NET_WM_WINDOW_TYPE_DOCK])) { + cwindow->dock = true; + LOG("this window is a dock\n"); + } + + Con *nc; Match *match; @@ -175,9 +182,6 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki nc->window = cwindow; x_reinit(nc); - xcb_get_property_reply_t *reply = xcb_get_property_reply(conn, wm_type_cookie, NULL); - if (xcb_reply_contains_atom(reply, atoms[_NET_WM_WINDOW_TYPE_DOCK])) - LOG("this window is a dock\n"); /* set floating if necessary */ if (xcb_reply_contains_atom(reply, atoms[_NET_WM_WINDOW_TYPE_DIALOG]) || diff --git a/src/match.c b/src/match.c index c384c41a..42eba26e 100644 --- a/src/match.c +++ b/src/match.c @@ -14,6 +14,17 @@ #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. @@ -30,6 +41,7 @@ bool match_is_empty(Match *match) { match->instance == NULL && match->id == XCB_NONE && match->con_id == NULL && + match->dock == -1 && match->floating == M_ANY); } @@ -54,6 +66,12 @@ bool match_matches_window(Match *match, i3Window *window) { return true; } + LOG("match->dock = %d, window->dock = %d\n", match->dock, window->dock); + if (match->dock != -1 && window->dock == match->dock) { + LOG("match made by dock\n"); + return true; + } + LOG("window %d (%s) could not be matched\n", window->id, window->class_class); return false;