]> git.sur5r.net Git - i3/i3/commitdiff
Various code improvements
authorMichael Stapelberg <michael+git@stapelberg.de>
Sat, 14 Feb 2009 01:19:04 +0000 (02:19 +0100)
committerMichael Stapelberg <michael+git@stapelberg.de>
Sat, 14 Feb 2009 01:19:04 +0000 (02:19 +0100)
include/data.h
src/layout.c
src/mainx.c

index 203e79072daf5d2fe03972017afe8f64b3c72cfc..1fd856b3ad54125e5d5071853f09b14619af5912 100644 (file)
@@ -101,8 +101,8 @@ struct Client {
        /* Backpointer. A client is inside a container */
        Container *container;
 
-       int x, y;
-       int width, height;
+       uint32_t x, y;
+       uint32_t width, height;
 
        /* Name */
        char *name;
index cac32ff2d37c726d7266dc9cffe2947b417e6a71..d98dc181e7e754b2e48b5c8f9fc5b2daf7ffa46f 100644 (file)
@@ -81,13 +81,8 @@ void decorate_window(xcb_connection_t *conn, Client *client) {
        free(label);
 }
 
-void render_container(xcb_connection_t *connection, Container *container) {
+static void render_container(xcb_connection_t *connection, Container *container) {
        Client *client;
-       uint32_t values[4];
-       uint32_t mask = XCB_CONFIG_WINDOW_X |
-                       XCB_CONFIG_WINDOW_Y |
-                       XCB_CONFIG_WINDOW_WIDTH |
-                       XCB_CONFIG_WINDOW_HEIGHT;
        i3Font *font = load_font(connection, pattern);
 
        if (container->mode == MODE_DEFAULT) {
@@ -98,46 +93,48 @@ void render_container(xcb_connection_t *connection, Container *container) {
 
                int current_client = 0;
                CIRCLEQ_FOREACH(client, &(container->clients), clients) {
-                       /* TODO: rewrite this block so that the need to puke vanishes :) */
-                       /* TODO: at the moment, every column/row is 200px. This
+                       /* TODO: at the moment, every column/row is screen / num_cols. This
                         * needs to be changed to "percentage of the screen" by
                         * default and adjustable by the user if necessary.
                         */
-                       values[0] = container->x + (container->col * container->width); /* x */
-                       values[1] = container->y + (container->row * container->height +
-                               (container->height / num_clients) * current_client); /* y */
-
-                       if (client->x != values[0] || client->y != values[1]) {
-                               printf("frame needs to be pushed to %dx%d\n",
-                                               values[0], values[1]);
-                               client->x = values[0];
-                               client->y = values[1];
+
+                        /* 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->x != (client->x = container->x + (container->col * container->width))) |
+                            (client->y != (client->y = container->y + (container->row * container->height +
+                                          (container->height / num_clients) * current_client)))) {
+                               printf("frame needs to be pushed to %dx%d\n", client->x, client->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(connection, client->frame,
-                                               XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, values);
+                                               XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, &(client->x));
                        }
-                       /* TODO: vertical default layout */
-                       values[0] = container->width; /* width */
-                       values[1] = container->height / num_clients; /* height */
 
-                       if (client->width != values[0] || client->height != values[1]) {
-                               client->width = values[0];
-                               client->height = values[1];
+                       /* TODO: vertical default layout */
+                       if ((client->width != (client->width = container->width)) |
+                            (client->height != (client->height = container->height / num_clients))) {
                                xcb_configure_window(connection, client->frame,
-                                               XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values);
+                                               XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
+                                                &(client->width));
+
+                               /* Adjust the position of the child inside its frame.
+                                * The coordinates of the child are relative to its frame, we
+                                * add a border of 2 pixel to each value */
+                                uint32_t mask = XCB_CONFIG_WINDOW_X |
+                                                XCB_CONFIG_WINDOW_Y |
+                                                XCB_CONFIG_WINDOW_WIDTH |
+                                                XCB_CONFIG_WINDOW_HEIGHT;
+                                uint32_t values[4] = {2,                                              /* x */
+                                                      font->height + 2 + 2,                           /* y */
+                                                      client->width - (2 + 2),                        /* width */
+                                                      client->height - ((font->height + 2 + 2) + 2)}; /* height */
+
+                               printf("child itself will be at %dx%d with size %dx%d\n",
+                                               values[0], values[1], values[2], values[3]);
+
+                               xcb_configure_window(connection, client->child, mask, values);
                        }
 
-                       /* TODO: hmm, only do this for new wins */
-                       /* The coordinates of the child are relative to its frame, we
-                        * add a border of 2 pixel to each value */
-                       values[0] = 2;
-                       values[1] = font->height + 2 + 2;
-                       values[2] = client->width - (values[0] + 2);
-                       values[3] = client->height - (values[1] + 2);
-                       printf("child itself will be at %dx%d with size %dx%d\n",
-                                       values[0], values[1], values[2], values[3]);
-
-                       xcb_configure_window(connection, client->child, mask, values);
-
                        decorate_window(connection, client);
                        current_client++;
                }
index 2d2188e33ebac5da3679230a564856bc58f2e3fa..03be0a3db207fbb49bacc347f59cd537b751a711 100644 (file)
@@ -37,11 +37,6 @@ Display *xkbdpy;
 TAILQ_HEAD(bindings_head, Binding) bindings;
 xcb_event_handlers_t evenths;
 
-static const int TOP = 20;
-static const int LEFT = 5;
-static const int BOTTOM = 5;
-static const int RIGHT = 5;
-
 /* hm, xcb_wm wants us to implement this. */
 table_t *byChild = 0;
 table_t *byParent = 0;
@@ -106,7 +101,10 @@ void manage_window(xcb_property_handlers_t *prophs, xcb_connection_t *c, xcb_win
 }
 
 /*
- * Let’s own this window…
+ * reparent_window() gets called when a new window was opened and becomes a child of the root
+ * window, or it gets called by us when we manage the already existing windows at startup.
+ *
+ * Essentially, this is the point, where we take over control.
  *
  */
 void reparent_window(xcb_connection_t *conn, xcb_window_t child,
@@ -115,8 +113,11 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child,
 
        Client *new = table_get(byChild, child);
        if (new == NULL) {
+               /* TODO: When does this happen for existing clients? Is that a bug? */
                printf("oh, it's new\n");
                new = calloc(sizeof(Client), 1);
+               /* We initialize x and y with the invalid coordinates -1 so that they will
+                  get updated at the next render_layout() at any case */
                new->x = -1;
                new->y = -1;
        }
@@ -126,7 +127,7 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child,
        /* Insert into the currently active container */
        CIRCLEQ_INSERT_TAIL(&(CUR_CELL->clients), new, clients);
 
-       printf("currently_focused = %p\n", new);
+       /* Update the data structures */
        CUR_CELL->currently_focused = new;
        new->container = CUR_CELL;
 
@@ -141,13 +142,15 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child,
 
        /* We want to know when… */
        mask |= XCB_CW_EVENT_MASK;
-       values[1] =     XCB_EVENT_MASK_BUTTON_PRESS | /* …mouse is pressed/released */
+       values[1] =     XCB_EVENT_MASK_BUTTON_PRESS |   /* …mouse is pressed/released */
                        XCB_EVENT_MASK_BUTTON_RELEASE |
-                       XCB_EVENT_MASK_EXPOSURE | /* …our window needs to be redrawn */
-                       XCB_EVENT_MASK_ENTER_WINDOW /* …user moves cursor inside our window */;
+                       XCB_EVENT_MASK_EXPOSURE |       /* …our window needs to be redrawn */
+                       XCB_EVENT_MASK_ENTER_WINDOW;    /* …user moves cursor inside our window */
 
        printf("Reparenting 0x%08x under 0x%08x.\n", child, new->frame);
 
+       i3Font *font = load_font(conn, pattern);
+
        /* Yo dawg, I heard you like windows, so I create a window around your window… */
        xcb_create_window(conn,
                        depth,
@@ -155,9 +158,9 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child,
                        root,
                        x,
                        y,
-                       width + LEFT + RIGHT,
-                       height + TOP + BOTTOM,
-                       /* border_width */ 0,
+                       width + 2 + 2,                  /* 2 px border at each side */
+                       height + 2 + 2 + font->height,  /* 2 px border plus font’s height */
+                       0,                              /* border_width = 0, we draw our own borders */
                        XCB_WINDOW_CLASS_INPUT_OUTPUT,
                        visual,
                        mask,
@@ -171,15 +174,11 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child,
        new->titlegc = xcb_generate_id(conn);
        xcb_create_gc(conn, new->titlegc, new->frame, 0, 0);
 
-       /* Draw decorations */
-       decorate_window(conn, new);
-
        /* Put our data structure (Client) into the table */
        table_put(byParent, new->frame, new);
        table_put(byChild, child, new);
 
        /* Moves the original window into the new frame we've created for it */
-       i3Font *font = load_font(conn, pattern);
        xcb_reparent_window(conn, child, new->frame, 0, font->height);
 
        /* We are interested in property changes */
@@ -192,7 +191,8 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child,
 
        /* We need to grab the mouse buttons for click to focus */
        xcb_grab_button(conn, false, child, XCB_EVENT_MASK_BUTTON_PRESS,
-                       XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE, 1 /* left mouse button */,
+                       XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE,
+                       1 /* left mouse button */,
                        XCB_BUTTON_MASK_ANY /* don’t filter for any modifiers */);
 
        /* Focus the new window */