]> git.sur5r.net Git - i3/i3/commitdiff
Bugfix: Correctly place new windows while other windows are in fullscreen mode
authorMichael Stapelberg <michael+x200@stapelberg.de>
Sat, 7 Mar 2009 04:49:13 +0000 (05:49 +0100)
committerMichael Stapelberg <michael+x200@stapelberg.de>
Sat, 7 Mar 2009 04:49:13 +0000 (05:49 +0100)
src/layout.c
src/mainx.c

index 48cb5ab10a9825d6cd0d184c22b6db21c01e4b07..912673b21c7c6a2eee02bfeb1e25c024befa4d96 100644 (file)
@@ -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;
+
+                        /* 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,
-                                             XCB_CONFIG_WINDOW_X     | XCB_CONFIG_WINDOW_Y      |
-                                             XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT |
-                                             XCB_CONFIG_WINDOW_STACK_MODE,
-                                             values);
+                        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;
index 7b8d27f005fc0077ab9ca8d1c29df2a7cf8c1368..7adf9cbf3504980b9dbdee436857401d7f34eb09 100644 (file)
@@ -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;