diff --git a/include/handlers.h b/include/handlers.h index c35defe7..f5ea0591 100644 --- a/include/handlers.h +++ b/include/handlers.h @@ -13,6 +13,9 @@ #include + +void add_ignore_event(const int sequence); + /** * There was a key press. We compare this key code with our bindings table and * pass the bound action to parse_command(). diff --git a/src/con.c b/src/con.c index 528a0f38..75440973 100644 --- a/src/con.c +++ b/src/con.c @@ -123,34 +123,55 @@ Con *con_get_workspace(Con *con) { return result; } +/* + * helper data structure for the breadth-first-search in + * con_get_fullscreen_con() + * + */ +struct bfs_entry { + Con *con; + + TAILQ_ENTRY(bfs_entry) entries; +}; + /* * Returns the first fullscreen node below this node. * */ Con *con_get_fullscreen_con(Con *con) { - Con *current; + Con *current, *child; LOG("looking for fullscreen node\n"); /* TODO: is breadth-first-search really appropriate? (check as soon as * fullscreen levels and fullscreen for containers is implemented) */ - Con **queue = NULL; - int queue_len = 0; - TAILQ_FOREACH(current, &(con->nodes_head), nodes) { - queue_len++; - queue = srealloc(queue, queue_len * sizeof(Con*)); - queue[queue_len-1] = current; - } + TAILQ_HEAD(bfs_head, bfs_entry) bfs_head = TAILQ_HEAD_INITIALIZER(bfs_head); + struct bfs_entry *entry = smalloc(sizeof(struct bfs_entry)); + entry->con = con; + TAILQ_INSERT_TAIL(&bfs_head, entry, entries); - while (queue_len > 0) { - current = queue[queue_len-1]; + while (!TAILQ_EMPTY(&bfs_head)) { + entry = TAILQ_FIRST(&bfs_head); + current = entry->con; LOG("checking %p\n", current); - if (current->fullscreen_mode != CF_NONE) { - free(queue); + if (current != con && current->fullscreen_mode != CF_NONE) { + /* empty the queue */ + while (!TAILQ_EMPTY(&bfs_head)) { + entry = TAILQ_FIRST(&bfs_head); + TAILQ_REMOVE(&bfs_head, entry, entries); + free(entry); + } return current; } + LOG("deleting from queue\n"); - queue_len--; - queue = realloc(queue, queue_len * sizeof(Con*)); + TAILQ_REMOVE(&bfs_head, entry, entries); + free(entry); + + TAILQ_FOREACH(child, &(current->nodes_head), nodes) { + entry = smalloc(sizeof(struct bfs_entry)); + entry->con = child; + TAILQ_INSERT_TAIL(&bfs_head, entry, entries); + } } return NULL; diff --git a/src/handlers.c b/src/handlers.c index 11cbc37c..4d3e88b9 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -19,7 +19,7 @@ changing workspaces */ static SLIST_HEAD(ignore_head, Ignore_Event) ignore_events; -static void add_ignore_event(const int sequence) { +void add_ignore_event(const int sequence) { struct Ignore_Event *event = smalloc(sizeof(struct Ignore_Event)); event->sequence = sequence; @@ -48,8 +48,11 @@ static bool event_is_ignored(const int sequence) { if (event->sequence != sequence) continue; - SLIST_REMOVE(&ignore_events, event, Ignore_Event, ignore_events); - free(event); + /* instead of removing a sequence number we better wait until it gets + * garbage collected. it may generate multiple events (there are multiple + * enter_notifies for one configure_request, for example). */ + //SLIST_REMOVE(&ignore_events, event, Ignore_Event, ignore_events); + //free(event); return true; } diff --git a/src/nc.c b/src/nc.c index 44a43461..2b523ee5 100644 --- a/src/nc.c +++ b/src/nc.c @@ -89,8 +89,11 @@ void parse_command(const char *command) { workspace_show(command + strlen("workspace ")); else if (strcasecmp(command, "stack") == 0) { focused->layout = L_STACKED; - x_push_changes(croot); - + } + else if (strcasecmp(command, "fullscreen") == 0) { + if (focused->fullscreen_mode == CF_NONE) + focused->fullscreen_mode = CF_OUTPUT; + else focused->fullscreen_mode = CF_NONE; } else if (strcasecmp(command, "move before h") == 0) tree_move('p', HORIZ); diff --git a/src/render.c b/src/render.c index b2932f50..c0dbdd5f 100644 --- a/src/render.c +++ b/src/render.c @@ -37,6 +37,18 @@ void render_con(Con *con) { printf("mapped = true\n"); con->mapped = true; + /* if this container contains a window, set the coordinates */ + if (con->window) { + /* depending on the border style, the rect of the child window + * needs to be smaller */ + Rect *inset = &(con->window_rect); + *inset = (Rect){0, 0, con->rect.width, con->rect.height}; + /* TODO: different border styles */ + inset->x += 2; + inset->width -= 2 * 2; + inset->height -= 2; + } + /* Check for fullscreen nodes */ Con *fullscreen = con_get_fullscreen_con(con); if (fullscreen) { @@ -46,7 +58,6 @@ void render_con(Con *con) { return; } - TAILQ_FOREACH(child, &(con->nodes_head), nodes) { /* default layout */ @@ -105,16 +116,6 @@ void render_con(Con *con) { printf("child at (%d, %d) with (%d x %d)\n", child->rect.x, child->rect.y, child->rect.width, child->rect.height); printf("x now %d, y now %d\n", x, y); - if (child->window) { - /* depending on the border style, the rect of the child window - * needs to be smaller */ - Rect *inset = &(child->window_rect); - *inset = (Rect){0, 0, child->rect.width, child->rect.height}; - /* TODO: different border styles */ - inset->x += 2; - inset->width -= 2 * 2; - inset->height -= 2; - } x_raise_con(child); render_con(child); i++; diff --git a/src/xcb.c b/src/xcb.c index 1fd677b7..a57bad04 100644 --- a/src/xcb.c +++ b/src/xcb.c @@ -318,10 +318,13 @@ int predict_text_width(xcb_connection_t *conn, const char *font_pattern, char *t * */ void xcb_set_window_rect(xcb_connection_t *conn, xcb_window_t window, Rect r) { - xcb_configure_window(conn, window, + xcb_void_cookie_t cookie; + cookie = xcb_configure_window(conn, window, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, &(r.x)); + /* ignore events which are generated because we configured a window */ + add_ignore_event(cookie.sequence); }