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) {
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++;
}
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;
}
/*
- * 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,
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;
}
/* 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;
/* 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,
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,
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 */
/* 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 */