Rect get_unoccupied_space(Workspace *workspace);
void decorate_window(xcb_connection_t *conn, Client *client, xcb_drawable_t drawable, xcb_gcontext_t gc, int offset);
void redecorate_window(xcb_connection_t *conn, Client *client);
-void render_container(xcb_connection_t *connection, Container *container);
+void render_container(xcb_connection_t *conn, Container *container);
void render_layout(xcb_connection_t *conn);
#endif
void *scalloc(size_t size);
char *sstrdup(const char *str);
void start_application(const char *command);
-void check_error(xcb_connection_t *connection, xcb_void_cookie_t cookie, char *err_message);
+void check_error(xcb_connection_t *conn, xcb_void_cookie_t cookie, char *err_message);
void set_focus(xcb_connection_t *conn, Client *client);
void switch_layout_mode(xcb_connection_t *conn, Container *container, int mode);
-void warp_pointer_into(xcb_connection_t *connection, Client *client);
+void warp_pointer_into(xcb_connection_t *conn, Client *client);
void toggle_fullscreen(xcb_connection_t *conn, Client *client);
#endif
UTF8_STRING
};
-i3Font *load_font(xcb_connection_t *connection, const char *pattern);
+i3Font *load_font(xcb_connection_t *conn, const char *pattern);
uint32_t get_colorpixel(xcb_connection_t *conn, Client *client, xcb_window_t window, char *hex);
xcb_window_t create_window(xcb_connection_t *conn, Rect r, uint16_t window_class, uint16_t cursor,
uint32_t mask, uint32_t *values);
void xcb_change_gc_single(xcb_connection_t *conn, xcb_gcontext_t gc, uint32_t mask, uint32_t value);
void xcb_draw_line(xcb_connection_t *conn, xcb_drawable_t drawable, xcb_gcontext_t gc,
uint32_t colorpixel, uint32_t x, uint32_t y, uint32_t to_x, uint32_t to_y);
-void xcb_draw_rect(xcb_connection_t *connection, xcb_drawable_t drawable, xcb_gcontext_t gc,
+void xcb_draw_rect(xcb_connection_t *conn, xcb_drawable_t drawable, xcb_gcontext_t gc,
uint32_t colorpixel, uint32_t x, uint32_t y, uint32_t width, uint32_t height);
#endif
#include "i3.h"
#include "xinerama.h"
-static bool focus_window_in_container(xcb_connection_t *connection, Container *container,
+static bool focus_window_in_container(xcb_connection_t *conn, Container *container,
direction_t direction) {
/* If this container is empty, we’re done */
if (container->currently_focused == NULL)
return false;
/* Set focus if we could successfully move */
- set_focus(connection, candidate);
+ set_focus(conn, candidate);
return true;
}
-static void focus_window(xcb_connection_t *connection, direction_t direction) {
+static void focus_window(xcb_connection_t *conn, direction_t direction) {
printf("focusing direction %d\n", direction);
int new_row = current_row,
/* TODO: for horizontal default layout, this has to be expanded to LEFT/RIGHT */
if (direction == D_UP || direction == D_DOWN) {
/* Let’s see if we can perform up/down focus in the current container */
- if (focus_window_in_container(connection, container, direction))
+ if (focus_window_in_container(conn, container, direction))
return;
if (direction == D_DOWN && cell_exists(current_col, current_row+1))
}
if (t_ws->table[new_col][new_row]->currently_focused != NULL)
- set_focus(connection, t_ws->table[new_col][new_row]->currently_focused);
+ set_focus(conn, t_ws->table[new_col][new_row]->currently_focused);
}
/*
* Returns true if the window could be moved, false otherwise.
*
*/
-static bool move_current_window_in_container(xcb_connection_t *connection, Client *client,
+static bool move_current_window_in_container(xcb_connection_t *conn, Client *client,
direction_t direction) {
assert(client->container != NULL);
if (direction == D_UP)
CIRCLEQ_INSERT_BEFORE(&(client->container->clients), other, client, clients);
else CIRCLEQ_INSERT_AFTER(&(client->container->clients), other, client, clients);
- render_layout(connection);
+ render_layout(conn);
return true;
}
* necessary
*
*/
-static void move_current_window(xcb_connection_t *connection, direction_t direction) {
+static void move_current_window(xcb_connection_t *conn, direction_t direction) {
printf("moving window to direction %s\n", (direction == D_UP ? "up" : (direction == D_DOWN ? "down" :
(direction == D_LEFT ? "left" : "right"))));
/* Get current window */
break;
case D_UP:
/* TODO: if we’re at the up-most position, move the rest of the table down */
- if (move_current_window_in_container(connection, current_client, D_UP) ||
+ if (move_current_window_in_container(conn, current_client, D_UP) ||
current_row == 0)
return;
new = CUR_TABLE[current_col][--current_row];
break;
case D_DOWN:
- if (move_current_window_in_container(connection, current_client, D_DOWN))
+ if (move_current_window_in_container(conn, current_client, D_DOWN))
return;
if (current_row == (c_ws->rows-1))
new->currently_focused = current_client;
/* delete all empty columns/rows */
- cleanup_table(connection, container->workspace);
- render_layout(connection);
+ cleanup_table(conn, container->workspace);
+ render_layout(conn);
- set_focus(connection, current_client);
+ set_focus(conn, current_client);
}
/*
* to the given direction, that is, adjusts cellspan/rowspan
*
*/
-static void snap_current_container(xcb_connection_t *connection, direction_t direction) {
+static void snap_current_container(xcb_connection_t *conn, direction_t direction) {
printf("snapping container to direction %d\n", direction);
Container *container = CUR_CELL;
switch (direction) {
case D_LEFT:
/* Snap to the left is actually a move to the left and then a snap right */
- move_current_window(connection, D_LEFT);
- snap_current_container(connection, D_RIGHT);
+ move_current_window(conn, D_LEFT);
+ snap_current_container(conn, D_RIGHT);
return;
case D_RIGHT:
/* Check if the cell is used */
container->colspan++;
break;
case D_UP:
- move_current_window(connection, D_UP);
- snap_current_container(connection, D_DOWN);
+ move_current_window(conn, D_UP);
+ snap_current_container(conn, D_DOWN);
return;
case D_DOWN:
printf("snapping down\n");
break;
}
- render_layout(connection);
+ render_layout(conn);
}
/*
* Moves the currently selected window to the given workspace
*
*/
-static void move_current_window_to_workspace(xcb_connection_t *connection, int workspace) {
+static void move_current_window_to_workspace(xcb_connection_t *conn, int workspace) {
printf("Moving current window to workspace %d\n", workspace);
Container *container = CUR_CELL;
/* If we’re moving it to an invisible screen, we need to unmap it */
if (to_container->workspace->screen->current_workspace != to_container->workspace->num) {
printf("This workspace is not visible, unmapping\n");
- xcb_unmap_window(connection, current_client->frame);
+ xcb_unmap_window(conn, current_client->frame);
}
/* delete all empty columns/rows */
- cleanup_table(connection, container->workspace);
+ cleanup_table(conn, container->workspace);
- render_layout(connection);
+ render_layout(conn);
}
static void show_workspace(xcb_connection_t *conn, int workspace) {
* so we better clean up before.
*
*/
-int handle_unmap_notify_event(void *data, xcb_connection_t *c, xcb_unmap_notify_event_t *e) {
- xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(c)).data->root;
+int handle_unmap_notify_event(void *data, xcb_connection_t *conn, xcb_unmap_notify_event_t *event) {
+ xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data->root;
- ignore_notify_event = e->sequence;
+ ignore_notify_event = event->sequence;
- Client *client = table_get(byChild, e->window);
+ Client *client = table_get(byChild, event->window);
/* First, we need to check if the client is awaiting an unmap-request which
was generated by us reparenting the window. In that case, we just ignore it. */
if (client != NULL && client->awaiting_useless_unmap) {
client->awaiting_useless_unmap = false;
return 1;
}
- client = table_remove(byChild, e->window);
+ client = table_remove(byChild, event->window);
- printf("UnmapNotify for 0x%08x (received from 0x%08x): ", e->window, e->event);
+ printf("UnmapNotify for 0x%08x (received from 0x%08x): ", event->window, event->event);
if (client == NULL) {
printf("not a managed window. Ignoring.\n");
return 0;
if (con->currently_focused == NULL && con->mode == MODE_STACK) {
struct Stack_Window *stack_win = &(con->stack_win);
stack_win->height = 0;
- xcb_unmap_window(c, stack_win->window);
+ xcb_unmap_window(conn, stack_win->window);
}
/* Remove the client from the list of clients */
/* Actually set focus, if there is a window which should get it */
if (to_focus != NULL)
- set_focus(c, to_focus);
+ set_focus(conn, to_focus);
}
printf("child of 0x%08x.\n", client->frame);
- xcb_reparent_window(c, client->child, root, 0, 0);
- xcb_destroy_window(c, client->frame);
- xcb_flush(c);
+ xcb_reparent_window(conn, client->child, root, 0, 0);
+ xcb_destroy_window(conn, client->frame);
+ xcb_flush(conn);
table_remove(byParent, client->frame);
- cleanup_table(c, client->container->workspace);
+ cleanup_table(conn, client->container->workspace);
free(client);
- render_layout(c);
+ render_layout(conn);
return 1;
}
* Expose event means we should redraw our windows (= title bar)
*
*/
-int handle_expose_event(void *data, xcb_connection_t *conn, xcb_expose_event_t *e) {
+int handle_expose_event(void *data, xcb_connection_t *conn, xcb_expose_event_t *event) {
printf("got expose_event\n");
- /* e->count is the number of minimum remaining expose events for this window, so we
+ /* event->count is the number of minimum remaining expose events for this window, so we
skip all events but the last one */
- if (e->count != 0)
+ if (event->count != 0)
return 1;
- Client *client = table_get(byParent, e->window);
+ Client *client = table_get(byParent, event->window);
if (client == NULL) {
/* There was no client in the table, so this is probably an expose event for
one of our stack_windows. */
struct Stack_Window *stack_win;
SLIST_FOREACH(stack_win, &stack_wins, stack_windows)
- if (stack_win->window == e->window) {
+ if (stack_win->window == event->window) {
render_container(conn, stack_win->container);
return 1;
}
* Pushes the client’s x and y coordinates to X11
*
*/
-static void reposition_client(xcb_connection_t *connection, Client *client) {
+static void reposition_client(xcb_connection_t *conn, Client *client) {
printf("frame needs to be pushed to %dx%d\n", 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(connection, client->frame,
- XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, &(client->rect.x));
+ xcb_configure_window(conn, client->frame, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, &(client->rect.x));
}
/*
* Pushes the client’s width/height to X11 and resizes the child window
*
*/
-static void resize_client(xcb_connection_t *connection, Client *client) {
- i3Font *font = load_font(connection, config.font);
+static void resize_client(xcb_connection_t *conn, Client *client) {
+ i3Font *font = load_font(conn, config.font);
printf("resizing client to %d x %d\n", client->rect.width, client->rect.height);
- xcb_configure_window(connection, client->frame,
+ xcb_configure_window(conn, client->frame,
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
&(client->rect.width));
printf("child will be at %dx%d with size %dx%d\n", rect->x, rect->y, rect->width, rect->height);
- xcb_configure_window(connection, client->child, mask, &(rect->x));
+ xcb_configure_window(conn, client->child, mask, &(rect->x));
/* After configuring a child window we need to fake a configure_notify_event according
to ICCCM 4.2.3. This seems rather broken, especially since X sends exactly the same
event.above_sibling = XCB_NONE;
event.override_redirect = false;
- xcb_send_event(connection, false, client->child, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (char*)&event);
+ xcb_send_event(conn, false, client->child, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (char*)&event);
}
/*
* when focus changes in a stacking container)
*
*/
-void render_container(xcb_connection_t *connection, Container *container) {
+void render_container(xcb_connection_t *conn, Container *container) {
Client *client;
int num_clients = 0, current_client = 0;
HAS_CHANGED(old_value_1, client->rect.x, container->x) |
HAS_CHANGED(old_value_2, client->rect.y, container->y +
(container->height / num_clients) * current_client))
- reposition_client(connection, client);
+ reposition_client(conn, client);
/* TODO: vertical default layout */
if (client->force_reconfigure |
HAS_CHANGED(old_value_1, client->rect.width, container->width) |
HAS_CHANGED(old_value_2, client->rect.height, container->height / num_clients))
- resize_client(connection, client);
+ resize_client(conn, client);
client->force_reconfigure = false;
current_client++;
}
} else {
- i3Font *font = load_font(connection, config.font);
+ i3Font *font = load_font(conn, config.font);
int decoration_height = (font->height + 2 + 2);
struct Stack_Window *stack_win = &(container->stack_win);
/* Check if we need to remap our stack title window, it gets unmapped when the container
is empty in src/handlers.c:unmap_notify() */
if (stack_win->height == 0)
- xcb_map_window(connection, stack_win->window);
+ xcb_map_window(conn, stack_win->window);
/* Check if we need to reconfigure our stack title window */
if (HAS_CHANGED(old_value_1, stack_win->width, container->width) |
HAS_CHANGED(old_value_2, stack_win->height, decoration_height * num_clients)) {
- xcb_configure_window(connection, stack_win->window,
+ xcb_configure_window(conn, stack_win->window,
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, &(stack_win->width));
uint32_t values[] = { XCB_STACK_MODE_ABOVE };
- xcb_configure_window(connection, stack_win->window, XCB_CONFIG_WINDOW_STACK_MODE, values);
+ xcb_configure_window(conn, stack_win->window, XCB_CONFIG_WINDOW_STACK_MODE, values);
}
/* Reconfigure the currently focused client, if necessary. It is the only visible one */
if (client->force_reconfigure |
HAS_CHANGED(old_value_1, client->rect.x, container->x) |
HAS_CHANGED(old_value_2, client->rect.y, container->y + (decoration_height * num_clients)))
- reposition_client(connection, client);
+ reposition_client(conn, client);
if (client->force_reconfigure |
HAS_CHANGED(old_value_1, client->rect.width, container->width) |
HAS_CHANGED(old_value_2, client->rect.height, container->height - (decoration_height * num_clients)))
- resize_client(connection, client);
+ resize_client(conn, client);
client->force_reconfigure = false;
if (container->workspace->fullscreen_client == NULL) {
uint32_t values[] = { XCB_STACK_MODE_ABOVE };
- xcb_configure_window(connection, client->frame, XCB_CONFIG_WINDOW_STACK_MODE, values);
+ xcb_configure_window(conn, client->frame, XCB_CONFIG_WINDOW_STACK_MODE, values);
}
/* Render the decorations of all clients */
CIRCLEQ_FOREACH(client, &(container->clients), clients)
- decorate_window(connection, client, stack_win->window, stack_win->gc,
+ decorate_window(conn, client, stack_win->window, stack_win->gc,
current_client++ * decoration_height);
}
}
-static void render_bars(xcb_connection_t *connection, Workspace *r_ws, int width, int *height) {
+static void render_bars(xcb_connection_t *conn, Workspace *r_ws, int width, int *height) {
Client *client;
SLIST_FOREACH(client, &(r_ws->dock_clients), dock_clients) {
if (client->force_reconfigure |
HAS_CHANGED(old_value_1, client->rect.x, 0) |
HAS_CHANGED(old_value_2, client->rect.y, *height))
- reposition_client(connection, client);
+ reposition_client(conn, client);
if (client->force_reconfigure |
HAS_CHANGED(old_value_1, client->rect.width, width) |
HAS_CHANGED(old_value_2, client->rect.height, client->desired_height))
- resize_client(connection, client);
+ resize_client(conn, client);
client->force_reconfigure = false;
*height += client->desired_height;
}
}
-static void render_internal_bar(xcb_connection_t *connection, Workspace *r_ws, int width, int height) {
+static void render_internal_bar(xcb_connection_t *conn, Workspace *r_ws, int width, int height) {
printf("Rendering internal bar\n");
- i3Font *font = load_font(connection, config.font);
+ i3Font *font = load_font(conn, config.font);
i3Screen *screen = r_ws->screen;
enum { SET_NORMAL = 0, SET_FOCUSED = 1 };
uint32_t background_color[2],
black;
char label[3];
- black = get_colorpixel(connection, NULL, screen->bar, "#000000");
+ black = get_colorpixel(conn, NULL, screen->bar, "#000000");
- background_color[SET_NORMAL] = get_colorpixel(connection, NULL, screen->bar, "#222222");
- text_color[SET_NORMAL] = get_colorpixel(connection, NULL, screen->bar, "#888888");
- border_color[SET_NORMAL] = get_colorpixel(connection, NULL, screen->bar, "#333333");
+ background_color[SET_NORMAL] = get_colorpixel(conn, NULL, screen->bar, "#222222");
+ text_color[SET_NORMAL] = get_colorpixel(conn, NULL, screen->bar, "#888888");
+ border_color[SET_NORMAL] = get_colorpixel(conn, NULL, screen->bar, "#333333");
- background_color[SET_FOCUSED] = get_colorpixel(connection, NULL, screen->bar, "#285577");
- text_color[SET_FOCUSED] = get_colorpixel(connection, NULL, screen->bar, "#ffffff");
- border_color[SET_FOCUSED] = get_colorpixel(connection, NULL, screen->bar, "#4c7899");
+ background_color[SET_FOCUSED] = get_colorpixel(conn, NULL, screen->bar, "#285577");
+ text_color[SET_FOCUSED] = get_colorpixel(conn, NULL, screen->bar, "#ffffff");
+ border_color[SET_FOCUSED] = get_colorpixel(conn, NULL, screen->bar, "#4c7899");
/* Fill the whole bar in black */
- xcb_change_gc_single(connection, screen->bargc, XCB_GC_FOREGROUND, black);
+ xcb_change_gc_single(conn, screen->bargc, XCB_GC_FOREGROUND, black);
xcb_rectangle_t rect = {0, 0, width, height};
- xcb_poly_fill_rectangle(connection, screen->bar, screen->bargc, 1, &rect);
+ xcb_poly_fill_rectangle(conn, screen->bar, screen->bargc, 1, &rect);
/* Set font */
- xcb_change_gc_single(connection, screen->bargc, XCB_GC_FONT, font->id);
+ xcb_change_gc_single(conn, screen->bargc, XCB_GC_FONT, font->id);
int drawn = 0;
for (int c = 0; c < 10; c++) {
if (workspaces[c].screen == screen) {
int set = (screen->current_workspace == c ? SET_FOCUSED : SET_NORMAL);
- xcb_draw_rect(connection, screen->bar, screen->bargc, border_color[set],
+ xcb_draw_rect(conn, screen->bar, screen->bargc, border_color[set],
drawn * height, 1, height - 2, height - 2);
- xcb_draw_rect(connection, screen->bar, screen->bargc, background_color[set],
+ xcb_draw_rect(conn, screen->bar, screen->bargc, background_color[set],
drawn * height + 1, 2, height - 4, height - 4);
snprintf(label, sizeof(label), "%d", c+1);
- xcb_change_gc_single(connection, screen->bargc, XCB_GC_FOREGROUND, text_color[set]);
- xcb_change_gc_single(connection, screen->bargc, XCB_GC_BACKGROUND, background_color[set]);
- xcb_void_cookie_t text_cookie = xcb_image_text_8_checked(connection, strlen(label), screen->bar,
+ xcb_change_gc_single(conn, screen->bargc, XCB_GC_FOREGROUND, text_color[set]);
+ xcb_change_gc_single(conn, screen->bargc, XCB_GC_BACKGROUND, background_color[set]);
+ xcb_void_cookie_t text_cookie = xcb_image_text_8_checked(conn, strlen(label), screen->bar,
screen->bargc, drawn * height + 5 /* X */,
font->height + 1 /* Y = baseline of font */, label);
- check_error(connection, text_cookie, "Could not draw workspace title");
+ check_error(conn, text_cookie, "Could not draw workspace title");
drawn++;
}
}
printf("done rendering internal\n");
}
-void render_layout(xcb_connection_t *connection) {
+void render_layout(xcb_connection_t *conn) {
i3Screen *screen;
- i3Font *font = load_font(connection, config.font);
+ i3Font *font = load_font(conn, config.font);
TAILQ_FOREACH(screen, virtual_screens, screens) {
/* r_ws (rendering workspace) is just a shortcut to the Workspace being currently rendered */
container->height *= container->rowspan;
/* Render the container if it is not empty */
- render_container(connection, container);
+ render_container(conn, container);
xoffset[rows] += container->width;
yoffset[cols] += container->height;
printf("==========\n");
}
- render_bars(connection, r_ws, width, &height);
- render_internal_bar(connection, r_ws, width, 18);
+ render_bars(conn, r_ws, width, &height);
+ render_internal_bar(conn, r_ws, width, 18);
}
- xcb_flush(connection);
+ xcb_flush(conn);
}
* Do some sanity checks and then reparent the window.
*
*/
-void manage_window(xcb_property_handlers_t *prophs, xcb_connection_t *c, xcb_window_t window, window_attributes_t wa) {
+void manage_window(xcb_property_handlers_t *prophs, xcb_connection_t *conn, xcb_window_t window, window_attributes_t wa) {
printf("managing window.\n");
xcb_drawable_t d = { window };
xcb_get_geometry_cookie_t geomc;
if (wa.tag == TAG_COOKIE) {
/* Check if the window is mapped (it could be not mapped when intializing and
calling manage_window() for every window) */
- if ((attr = xcb_get_window_attributes_reply(c, wa.u.cookie, 0)) == NULL)
+ if ((attr = xcb_get_window_attributes_reply(conn, wa.u.cookie, 0)) == NULL)
return;
if (attr->map_state != XCB_MAP_STATE_VIEWABLE)
goto out;
/* Get the initial geometry (position, size, …) */
- geomc = xcb_get_geometry(c, d);
+ geomc = xcb_get_geometry(conn, d);
if (!attr) {
wa.tag = TAG_COOKIE;
- wa.u.cookie = xcb_get_window_attributes(c, window);
- attr = xcb_get_window_attributes_reply(c, wa.u.cookie, 0);
+ wa.u.cookie = xcb_get_window_attributes(conn, window);
+ attr = xcb_get_window_attributes_reply(conn, wa.u.cookie, 0);
}
- geom = xcb_get_geometry_reply(c, geomc, 0);
+ geom = xcb_get_geometry_reply(conn, geomc, 0);
if (attr && geom) {
- reparent_window(c, window, attr->visual, geom->root, geom->depth,
+ reparent_window(conn, window, attr->visual, geom->root, geom->depth,
geom->x, geom->y, geom->width, geom->height);
xcb_property_changed(prophs, XCB_PROPERTY_NEW_VALUE, window, WM_NAME);
}
* Go through all existing windows (if the window manager is restarted) and manage them
*
*/
-void manage_existing_windows(xcb_connection_t *c, xcb_property_handlers_t *prophs, xcb_window_t root) {
+void manage_existing_windows(xcb_connection_t *conn, xcb_property_handlers_t *prophs, xcb_window_t root) {
xcb_query_tree_reply_t *reply;
int i, len;
xcb_window_t *children;
xcb_get_window_attributes_cookie_t *cookies;
/* Get the tree of windows whose parent is the root window (= all) */
- if ((reply = xcb_query_tree_reply(c, xcb_query_tree(c, root), 0)) == NULL)
+ if ((reply = xcb_query_tree_reply(conn, xcb_query_tree(conn, root), 0)) == NULL)
return;
len = xcb_query_tree_children_length(reply);
/* Request the window attributes for every window */
children = xcb_query_tree_children(reply);
for(i = 0; i < len; ++i)
- cookies[i] = xcb_get_window_attributes(c, children[i]);
+ cookies[i] = xcb_get_window_attributes(conn, children[i]);
/* Call manage_window with the attributes for every window */
for(i = 0; i < len; ++i) {
window_attributes_t wa = { TAG_COOKIE, { cookies[i] } };
- manage_window(prophs, c, children[i], wa);
+ manage_window(prophs, conn, children[i], wa);
}
free(reply);
int main(int argc, char *argv[], char *env[]) {
int i, screens;
- xcb_connection_t *c;
+ xcb_connection_t *conn;
xcb_property_handlers_t prophs;
xcb_window_t root;
xcb_intern_atom_cookie_t atom_cookies[NUM_ATOMS];
load_configuration(NULL);
- c = xcb_connect(NULL, &screens);
+ conn = xcb_connect(NULL, &screens);
/* Place requests for the atoms we need as soon as possible */
- #define REQUEST_ATOM(name) atom_cookies[name] = xcb_intern_atom(c, 0, strlen(#name), #name);
+ #define REQUEST_ATOM(name) atom_cookies[name] = xcb_intern_atom(conn, 0, strlen(#name), #name);
REQUEST_ATOM(_NET_SUPPORTED);
REQUEST_ATOM(_NET_WM_STATE_FULLSCREEN);
}
/* end of ugliness */
- xcb_event_handlers_init(c, &evenths);
+ xcb_event_handlers_init(conn, &evenths);
/* DEBUG: Trap all events and print them */
for (i = 2; i < 128; ++i)
xcb_watch_wm_name(&prophs, 128, handle_windowname_change, 0);
/* Get the root window and set the event mask */
- root = xcb_aux_get_screen(c, screens)->root;
+ root = xcb_aux_get_screen(conn, screens)->root;
uint32_t mask = XCB_CW_EVENT_MASK;
uint32_t values[] = { XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
ConfigureNotify */
XCB_EVENT_MASK_PROPERTY_CHANGE |
XCB_EVENT_MASK_ENTER_WINDOW };
- xcb_change_window_attributes(c, root, mask, values);
+ xcb_change_window_attributes(conn, root, mask, values);
/* Setup NetWM atoms */
#define GET_ATOM(name) { \
- xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(c, atom_cookies[name], NULL); \
+ xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, atom_cookies[name], NULL); \
if (!reply) { \
printf("Could not get atom " #name "\n"); \
exit(-1); \
/* TODO: In order to comply with EWMH, we have to watch _NET_WM_STRUT_PARTIAL */
/* Set up the atoms we support */
- check_error(c, xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, root, atoms[_NET_SUPPORTED],
+ check_error(conn, xcb_change_property_checked(conn, XCB_PROP_MODE_REPLACE, root, atoms[_NET_SUPPORTED],
ATOM, 32, 7, atoms), "Could not set _NET_SUPPORTED");
/* Set up the window manager’s name */
- xcb_change_property(c, XCB_PROP_MODE_REPLACE, root, atoms[_NET_SUPPORTING_WM_CHECK], WINDOW, 32, 1, &root);
- xcb_change_property(c, XCB_PROP_MODE_REPLACE, root, atoms[_NET_WM_NAME], atoms[UTF8_STRING], 8, strlen("i3"), "i3");
+ xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, atoms[_NET_SUPPORTING_WM_CHECK], WINDOW, 32, 1, &root);
+ xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, atoms[_NET_WM_NAME], atoms[UTF8_STRING], 8, strlen("i3"), "i3");
/* Grab the bound keys */
Binding *bind;
TAILQ_FOREACH(bind, &bindings, bindings) {
printf("Grabbing %d\n", bind->keycode);
if (bind->mods & BIND_MODE_SWITCH)
- xcb_grab_key(c, 0, root, 0, bind->keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_SYNC);
- else xcb_grab_key(c, 0, root, bind->mods, bind->keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
+ xcb_grab_key(conn, 0, root, 0, bind->keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_SYNC);
+ else xcb_grab_key(conn, 0, root, bind->mods, bind->keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
}
/* check for Xinerama */
printf("Checking for Xinerama...\n");
- initialize_xinerama(c);
+ initialize_xinerama(conn);
/* DEBUG: Start a terminal */
start_application(config.terminal);
- xcb_flush(c);
+ xcb_flush(conn);
- manage_existing_windows(c, &prophs, root);
+ manage_existing_windows(conn, &prophs, root);
/* Get pointer position to see on which screen we’re starting */
xcb_query_pointer_reply_t *reply;
- if ((reply = xcb_query_pointer_reply(c, xcb_query_pointer(c, root), NULL)) == NULL) {
+ if ((reply = xcb_query_pointer_reply(conn, xcb_query_pointer(conn, root), NULL)) == NULL) {
printf("Could not get pointer position\n");
return 1;
}
* was an error.
*
*/
-void check_error(xcb_connection_t *connection, xcb_void_cookie_t cookie, char *err_message) {
- xcb_generic_error_t *error = xcb_request_check(connection, cookie);
+void check_error(xcb_connection_t *conn, xcb_void_cookie_t cookie, char *err_message) {
+ xcb_generic_error_t *error = xcb_request_check(conn, cookie);
if (error != NULL) {
fprintf(stderr, "ERROR: %s : %d\n", err_message , error->error_code);
- xcb_disconnect(connection);
+ xcb_disconnect(conn);
exit(-1);
}
}
* selecting it
*
*/
-void warp_pointer_into(xcb_connection_t *connection, Client *client) {
+void warp_pointer_into(xcb_connection_t *conn, Client *client) {
int mid_x = client->rect.width / 2,
mid_y = client->rect.height / 2;
- xcb_warp_pointer(connection, XCB_NONE, client->child, 0, 0, 0, 0, mid_x, mid_y);
+ xcb_warp_pointer(conn, XCB_NONE, client->child, 0, 0, 0, 0, mid_x, mid_y);
}
/*
* maintains a cache.
*
*/
-i3Font *load_font(xcb_connection_t *connection, const char *pattern) {
+i3Font *load_font(xcb_connection_t *conn, const char *pattern) {
/* Check if we got the font cached */
i3Font *font;
TAILQ_FOREACH(font, &cached_fonts, fonts)
xcb_list_fonts_with_info_cookie_t info_cookie;
/* Send all our requests first */
- new->id = xcb_generate_id(connection);
- font_cookie = xcb_open_font_checked(connection, new->id, strlen(pattern), pattern);
- info_cookie = xcb_list_fonts_with_info(connection, 1, strlen(pattern), pattern);
+ new->id = xcb_generate_id(conn);
+ font_cookie = xcb_open_font_checked(conn, new->id, strlen(pattern), pattern);
+ info_cookie = xcb_list_fonts_with_info(conn, 1, strlen(pattern), pattern);
- check_error(connection, font_cookie, "Could not open font");
+ check_error(conn, font_cookie, "Could not open font");
/* Get information (height/name) for this font */
- xcb_list_fonts_with_info_reply_t *reply = xcb_list_fonts_with_info_reply(connection, info_cookie, NULL);
+ xcb_list_fonts_with_info_reply_t *reply = xcb_list_fonts_with_info_reply(conn, info_cookie, NULL);
exit_if_null(reply, "Could not load font \"%s\"\n", pattern);
if (asprintf(&(new->name), "%.*s", xcb_list_fonts_with_info_name_length(reply),
* Draws a rectangle from x,y with width,height using the given color
*
*/
-void xcb_draw_rect(xcb_connection_t *connection, xcb_drawable_t drawable, xcb_gcontext_t gc,
+void xcb_draw_rect(xcb_connection_t *conn, xcb_drawable_t drawable, xcb_gcontext_t gc,
uint32_t colorpixel, uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
- xcb_change_gc_single(connection, gc, XCB_GC_FOREGROUND, colorpixel);
+ xcb_change_gc_single(conn, gc, XCB_GC_FOREGROUND, colorpixel);
xcb_rectangle_t rect = {x, y, width, height};
- xcb_poly_fill_rectangle(connection, drawable, gc, 1, &rect);
+ xcb_poly_fill_rectangle(conn, drawable, gc, 1, &rect);
}
* Fills virtual_screens with exactly one screen with width/height of the whole X server.
*
*/
-static void disable_xinerama(xcb_connection_t *connection) {
- xcb_screen_t *root_screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data;
+static void disable_xinerama(xcb_connection_t *conn) {
+ xcb_screen_t *root_screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
i3Screen *s = calloc(sizeof(i3Screen), 1);
* Xinerama screen which are configured in clone mode) in the given screenlist
*
*/
-static void query_screens(xcb_connection_t *connection, struct screens_head *screenlist) {
+static void query_screens(xcb_connection_t *conn, struct screens_head *screenlist) {
xcb_xinerama_query_screens_reply_t *reply;
xcb_xinerama_screen_info_t *screen_info;
- reply = xcb_xinerama_query_screens_reply(connection, xcb_xinerama_query_screens_unchecked(connection), NULL);
+ reply = xcb_xinerama_query_screens_reply(conn, xcb_xinerama_query_screens_unchecked(conn), NULL);
if (!reply) {
printf("Couldn't get Xinerama screens\n");
return;
free(reply);
}
-static void initialize_screen(xcb_connection_t *connection, i3Screen *screen, Workspace *workspace) {
- i3Font *font = load_font(connection, config.font);
+static void initialize_screen(xcb_connection_t *conn, i3Screen *screen, Workspace *workspace) {
+ i3Font *font = load_font(conn, config.font);
workspace->screen = screen;
screen->current_workspace = workspace->num;
font->height + 6};
uint32_t mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
uint32_t values[] = {1, XCB_EVENT_MASK_EXPOSURE};
- screen->bar = create_window(connection, bar_rect, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_CURSOR_LEFT_PTR, mask, values);
- screen->bargc = xcb_generate_id(connection);
- xcb_create_gc(connection, screen->bargc, screen->bar, 0, 0);
+ screen->bar = create_window(conn, bar_rect, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_CURSOR_LEFT_PTR, mask, values);
+ screen->bargc = xcb_generate_id(conn);
+ xcb_create_gc(conn, screen->bargc, screen->bar, 0, 0);
/* Copy dimensions */
memcpy(&(workspace->rect), &(screen->rect), sizeof(Rect));
* information to setup workspaces for each screen.
*
*/
-void initialize_xinerama(xcb_connection_t *connection) {
+void initialize_xinerama(xcb_connection_t *conn) {
virtual_screens = scalloc(sizeof(struct screens_head));
TAILQ_INIT(virtual_screens);
- if (!xcb_get_extension_data(connection, &xcb_xinerama_id)->present) {
+ if (!xcb_get_extension_data(conn, &xcb_xinerama_id)->present) {
printf("Xinerama extension not found, disabling.\n");
- disable_xinerama(connection);
+ disable_xinerama(conn);
return;
}
- if (!xcb_xinerama_is_active_reply(connection, xcb_xinerama_is_active(connection), NULL)->state) {
+ if (!xcb_xinerama_is_active_reply(conn, xcb_xinerama_is_active(conn), NULL)->state) {
printf("Xinerama is not active (in your X-Server), disabling.\n");
- disable_xinerama(connection);
+ disable_xinerama(conn);
return;
}
- query_screens(connection, virtual_screens);
+ query_screens(conn, virtual_screens);
i3Screen *s;
num_screens = 0;
/* Just go through each workspace and associate as many screens as we can. */
TAILQ_FOREACH(s, virtual_screens, screens) {
s->num = num_screens;
- initialize_screen(connection, s, &(workspaces[num_screens]));
+ initialize_screen(conn, s, &(workspaces[num_screens]));
num_screens++;
}
}
* number/position of the Xinerama screens could have changed.
*
*/
-void xinerama_requery_screens(xcb_connection_t *connection) {
+void xinerama_requery_screens(xcb_connection_t *conn) {
/* POSSIBLE PROBLEM: Is the order of the Xinerama screens always constant? That is, can
it change when I move the --right-of video projector to --left-of? */
struct screens_head *new_screens = scalloc(sizeof(struct screens_head));
TAILQ_INIT(new_screens);
- query_screens(connection, new_screens);
+ query_screens(conn, new_screens);
i3Screen *first = TAILQ_FIRST(new_screens),
*screen;
for (int c = 0; c < 10; c++)
if (workspaces[c].screen == NULL) {
printf("fix: initializing new workspace, setting num to %d\n", c);
- initialize_screen(connection, screen, &(workspaces[c]));
+ initialize_screen(conn, screen, &(workspaces[c]));
break;
}
}
if ((workspaces[c].screen != NULL) &&
(workspaces[c].screen->num >= num_screens)) {
printf("Closing bar window\n");
- xcb_destroy_window(connection, workspaces[c].screen->bar);
+ xcb_destroy_window(conn, workspaces[c].screen->bar);
printf("Workspace %d's screen out of bounds, assigning to first screen\n", c+1);
workspaces[c].screen = first;
printf("Current workspace is now: %d\n", first->current_workspace);
- render_layout(connection);
+ render_layout(conn);
}