printf("ERROR: Couldn't fork()");
exit(EXIT_FAILURE);
case 0:
+ /* Child-process. Reroute stdout and start shell */
close(fd[0]);
dup2(fd[1], STDOUT_FILENO);
execl(shell, shell, "-c", command, (char*) NULL);
return;
default:
+ /* Parent-process. Rerout stdin */
close(fd[1]);
dup2(fd[0], STDIN_FILENO);
}
}
+ /* We set O_NONBLOCK because blocking is evil in event-driven software */
fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
stdin_io = malloc(sizeof(ev_io));
*
*/
void got_command_reply(char *reply) {
- /* FIXME: Error handling for command-replies */
+ /* TODO: Error handling for command-replies */
}
/*
*/
void got_subscribe_reply(char *reply) {
printf("Got Subscribe Reply: %s\n", reply);
- /* FIXME: Error handling for subscribe-commands */
+ /* TODO: Error handling for subscribe-commands */
}
/*
exit(EXIT_FAILURE);
}
+ /* We first parse the fixed-length IPC-header, to know, how much data
+ * we have to expect */
uint32_t rec = 0;
while (rec < header_len) {
int n = read(fd, header + rec, header_len - rec);
exit(EXIT_FAILURE);
}
- /* Know we read the rest of the message */
char *walk = header + strlen(I3_IPC_MAGIC);
uint32_t size = *((uint32_t*) walk);
walk += sizeof(uint32_t);
uint32_t type = *((uint32_t*) walk);
+
+ /* Now that we know, what to expect, we can start read()ing the rest
+ * of the message */
char *buffer = malloc(size + 1);
if (buffer == NULL) {
printf("ERROR: Could not allocate memory!\n");
len = strlen(payload);
}
+ /* We are a wellbehaved client and send a proper header first */
uint32_t to_write = strlen (I3_IPC_MAGIC) + sizeof(uint32_t)*2 + len;
+ /* TODO: I'm not entirely sure if this buffer really has to contain more
+ * than the pure header (why not just write() the payload from *payload?),
+ * but we leave it for now */
char *buffer = malloc(to_write);
if (buffer == NULL) {
printf("ERROR: Could not allocate memory\n");
#include "common.h"
-
+/*
+ * Glob path, i.e. expand ~
+ *
+ */
char *expand_path(char *path) {
static glob_t globbuf;
if (glob(path, GLOB_NOCHECK | GLOB_TILDE, NULL, &globbuf) < 0) {
}
if (fontname == NULL) {
+ /* This is a very restrictive default. More sensefull would be something like
+ * "-misc-*-*-*-*--*-*-*-*-*-*-*-*". But since that produces very ugly results
+ * on my machine, let's stick with this until we have a configfile */
fontname = "-misc-fixed-medium-r-semicondensed--12-110-75-75-c-60-iso10646-1";
}
FREE(socket_path);
+ /* We subscribe to the i3-events we need */
subscribe_events();
+ /* We initiate the main-function by requesting infos about the outputs and
+ * workspaces. Everything else (creating the bars, showing the right workspace-
+ * buttons and more) is taken care of by the event-driveniness of the code */
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
+ /* The name of this function is actually misleading. Even if no -c is specified,
+ * this function initiates the watchers to listen on stdin and react accordingly */
start_child(command);
+ /* From here on everything should run smooth for itself, just start listening for
+ * events. We stop simply stop the event-loop, when we are finished */
ev_loop(main_loop, 0);
kill_child();
query_font_cookie = xcb_query_font(xcb_connection,
xcb_font);
+ /* To grab modifiers without blocking other applications from receiving key-events
+ * involving that modifier, we sadly have to use xkb which is not yet fully supported
+ * in xcb */
if (config.hide_on_modifier) {
int xkb_major, xkb_minor, xkb_errbase, xkb_err;
xkb_major = XkbMajorVersion;
mask,
vals);
+ /* We only generate an id for the pixmap, because the width of it is dependent on the
+ * input we get */
statusline_pm = xcb_generate_id(xcb_connection);
/* The varios Watchers to communicate with xcb */
/* Now we get the atoms and save them in a nice data-structure */
get_atoms();
- /* Now we calculate the font-height */
+ /* Now we save the font-infos */
font_info = xcb_query_font_reply(xcb_connection,
query_font_cookie,
&err);
mask,
values);
+ /* The double-buffer we use to render stuff off-screen */
xcb_void_cookie_t pm_cookie = xcb_create_pixmap_checked(xcb_connection,
xcb_screens->root_depth,
walk->buffer,
walk->rect.w,
walk->rect.h);
- /* We want dock-windows (for now) */
+ /* We want dock-windows (for now). When override_redirect is set, i3 is ignoring
+ * this one */
xcb_void_cookie_t prop_cookie = xcb_change_property(xcb_connection,
XCB_PROP_MODE_REPLACE,
walk->bar,
32,
1,
(unsigned char*) &atoms[_NET_WM_WINDOW_TYPE_DOCK]);
- /* We also want a graphics-context (the "canvas" on which we draw) */
+
+ /* We also want a graphics-context for the bars (it defines the properties
+ * with which we draw to them) */
walk->bargc = xcb_generate_id(xcb_connection);
mask = XCB_GC_FONT;
values[0] = xcb_font;
continue;
}
if (outputs_walk->bar == XCB_NONE) {
+ /* Oh shit, an active output without an own bar. Create it now! */
reconfig_windows();
}
+ /* First things first: clear the backbuffer */
uint32_t color = get_colorpixel("000000");
xcb_change_gc(xcb_connection,
outputs_walk->bargc,
outputs_walk->bargc,
1,
&rect);
+
if (statusline != NULL) {
printf("Printing statusline!\n");
+ /* Luckily we already prepared a seperate pixmap containing the rendered
+ * statusline, we just have to copy the relevant parts to the relevant
+ * position */
xcb_copy_area(xcb_connection,
statusline_pm,
outputs_walk->buffer,