From 1f3ce940275db3f641424b465936d669221ccccb Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 7 Mar 2009 05:49:13 +0100 Subject: [PATCH] Bugfix: Correctly place new windows while other windows are in fullscreen mode --- src/layout.c | 42 +++++++++++++++++++++++++++++++++--------- src/mainx.c | 13 +++++++++---- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/layout.c b/src/layout.c index 48cb5ab1..912673b2 100644 --- a/src/layout.c +++ b/src/layout.c @@ -292,6 +292,12 @@ void render_container(xcb_connection_t *conn, Container *container) { if (container->mode == MODE_DEFAULT) { LOG("got %d clients in this default container.\n", num_clients); CIRCLEQ_FOREACH(client, &(container->clients), clients) { + /* If the client is in fullscreen mode, it does not get reconfigured */ + if (container->workspace->fullscreen_client == client) { + current_client++; + continue; + } + /* Check if we changed client->x or client->y by updating it. * Note the bitwise OR instead of logical OR to force evaluation of both statements */ if (client->force_reconfigure | @@ -326,15 +332,30 @@ void render_container(xcb_connection_t *conn, Container *container) { update_if_necessary(&(stack_win->rect.width), container->width) | update_if_necessary(&(stack_win->rect.height), decoration_height * num_clients)) { + /* Configuration can happen in two slightly different ways: + + If there is no client in fullscreen mode, 5 parameters are passed + (x, y, width, height, stack mode is set to above which means top-most position). + + If there is a fullscreen client, the fourth parameter is set to to the + fullscreen window as sibling and the stack mode is set to below, which means + that the stack_window will be placed just below the sibling, that is, under + the fullscreen window. + */ uint32_t values[] = { stack_win->rect.x, stack_win->rect.y, stack_win->rect.width, stack_win->rect.height, - XCB_STACK_MODE_ABOVE }; + XCB_STACK_MODE_ABOVE, XCB_STACK_MODE_BELOW }; + uint32_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | + XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT | + XCB_CONFIG_WINDOW_STACK_MODE; - xcb_configure_window(conn, stack_win->window, - XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | - XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT | - XCB_CONFIG_WINDOW_STACK_MODE, - values); + /* If there is no fullscreen client, we raise the stack window */ + if (container->workspace->fullscreen_client != NULL) { + mask |= XCB_CONFIG_WINDOW_SIBLING; + values[4] = container->workspace->fullscreen_client->frame; + } + + xcb_configure_window(conn, stack_win->window, mask, values); } /* Reconfigure the currently focused client, if necessary. It is the only visible one */ @@ -347,6 +368,12 @@ void render_container(xcb_connection_t *conn, Container *container) { /* Render the decorations of all clients */ CIRCLEQ_FOREACH(client, &(container->clients), clients) { + /* If the client is in fullscreen mode, it does not get reconfigured */ + if (container->workspace->fullscreen_client == client) { + current_client++; + continue; + } + /* Check if we changed client->x or client->y by updating it. * Note the bitwise OR instead of logical OR to force evaluation of both statements */ if (client->force_reconfigure | @@ -445,9 +472,6 @@ void render_layout(xcb_connection_t *conn) { Workspace *r_ws = &(workspaces[screen->current_workspace]); LOG("Rendering screen %d\n", screen->num); - if (r_ws->fullscreen_client != NULL) - /* This is easy: A client has entered fullscreen mode, so we don’t render at all */ - continue; int width = r_ws->rect.width; int height = r_ws->rect.height; diff --git a/src/mainx.c b/src/mainx.c index 7b8d27f0..7adf9cbf 100644 --- a/src/mainx.c +++ b/src/mainx.c @@ -207,8 +207,6 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child, return; } - CUR_CELL->currently_focused = new; - /* Put our data structure (Client) into the table */ table_put(byParent, new->frame, new); table_put(byChild, child, new); @@ -219,8 +217,15 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child, 1 /* left mouse button */, XCB_BUTTON_MASK_ANY /* don’t filter for any modifiers */); - /* Focus the new window */ - xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, new->child, XCB_CURRENT_TIME); + /* Focus the new window if we’re not in fullscreen mode */ + if (CUR_CELL->workspace->fullscreen_client == NULL) { + CUR_CELL->currently_focused = new; + xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, new->child, XCB_CURRENT_TIME); + } else { + /* If we are in fullscreen, we should lower the window to not be annoying */ + uint32_t values[] = { XCB_STACK_MODE_BELOW }; + xcb_configure_window(conn, new->frame, XCB_CONFIG_WINDOW_STACK_MODE, values); + } /* Get _NET_WM_WINDOW_TYPE (to see if it’s a dock) */ xcb_atom_t *atom;