]> git.sur5r.net Git - i3/i3/blobdiff - src/layout.c
Bugfix: Repeatedly try to find screens if none are available (Thanks mxf)
[i3/i3] / src / layout.c
index ab6b7452bc3b3e8b836aa017822d88d016a63e07..4f132aea8cc2d8d1f54f2f902b2880a1c6429c5a 100644 (file)
@@ -24,6 +24,8 @@
 #include "util.h"
 #include "xinerama.h"
 #include "layout.h"
+#include "client.h"
+#include "floating.h"
 
 /*
  * Updates *destination with new_value and returns true if it was changed or false
@@ -107,9 +109,9 @@ void decorate_window(xcb_connection_t *conn, Client *client, xcb_drawable_t draw
                 return;
 
         LOG("redecorating child %08x\n", client->child);
-        if (client->floating >= FLOATING_AUTO_ON || client->container->currently_focused == client) {
+        if (client_is_floating(client) || client->container->currently_focused == client) {
                 /* Distinguish if the window is currently focused… */
-                if (client->floating >= FLOATING_AUTO_ON || CUR_CELL->currently_focused == client)
+                if (client_is_floating(client) || CUR_CELL->currently_focused == client)
                         color = &(config.client.focused);
                 /* …or if it is the focused window in a not focused container */
                 else color = &(config.client.focused_inactive);
@@ -146,7 +148,7 @@ void decorate_window(xcb_connection_t *conn, Client *client, xcb_drawable_t draw
         /* Draw the lines */
         xcb_draw_line(conn, drawable, gc, color->border, 0, offset, client->rect.width, offset);
         xcb_draw_line(conn, drawable, gc, color->border, 2, offset + font->height + 3,
-                      client->rect.width - 4, offset + font->height + 3);
+                      client->rect.width - 3, offset + font->height + 3);
 
         /* If the client has a title, we draw it */
         if (client->name != NULL) {
@@ -172,10 +174,29 @@ void decorate_window(xcb_connection_t *conn, Client *client, xcb_drawable_t draw
  *
  */
 void reposition_client(xcb_connection_t *conn, Client *client) {
+        i3Screen *screen;
+
         LOG("frame 0x%08x needs to be pushed to %dx%d\n", client->frame, client->rect.x, client->rect.y);
         /* Note: We can use a pointer to client->x like an array of uint32_ts
            because it is followed by client->y by definition */
         xcb_configure_window(conn, client->frame, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, &(client->rect.x));
+
+        if (!client_is_floating(client))
+                return;
+
+        /* If the client is floating, we need to check if we moved it to a different workspace */
+        if (client->workspace->screen == (screen = get_screen_containing(client->rect.x, client->rect.y)))
+                return;
+
+        if (screen == NULL) {
+                LOG("Boundary checking disabled, no screen found for (%d, %d)\n", client->rect.x, client->rect.y);
+                return;
+        }
+
+        LOG("Client is on workspace %p with screen %p\n", client->workspace, client->workspace->screen);
+        LOG("but screen at %d, %d is %p\n", client->rect.x, client->rect.y, screen);
+        floating_assign_to_workspace(client, &workspaces[screen->current_workspace]);
+        LOG("fixed that\n");
 }
 
 /*
@@ -327,8 +348,13 @@ void render_container(xcb_connection_t *conn, Container *container) {
                                         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) {
+                        /* Raise the stack window, but keep it below the first floating client
+                         * and below the fullscreen client (if any) */
+                        Client *first_floating = TAILQ_FIRST(&(container->workspace->floating_clients));
+                        if (first_floating != TAILQ_END(&(container->workspace->floating_clients))) {
+                                mask |= XCB_CONFIG_WINDOW_SIBLING;
+                                values[4] = first_floating->frame;
+                        } else if (container->workspace->fullscreen_client != NULL) {
                                 mask |= XCB_CONFIG_WINDOW_SIBLING;
                                 values[4] = container->workspace->fullscreen_client->frame;
                         }
@@ -336,9 +362,6 @@ void render_container(xcb_connection_t *conn, Container *container) {
                         xcb_configure_window(conn, stack_win->window, mask, values);
                 }
 
-                /* Reconfigure the currently focused client, if necessary. It is the only visible one */
-                client = container->currently_focused;
-
                 /* Render the decorations of all clients */
                 CIRCLEQ_FOREACH(client, &(container->clients), clients) {
                         /* If the client is in fullscreen mode, it does not get reconfigured */