+static void render_internal_bar(xcb_connection_t *conn, Workspace *r_ws, int width, int height) {
+ LOG("Rendering internal bar\n");
+ i3Font *font = load_font(conn, config.font);
+ i3Screen *screen = r_ws->screen;
+ enum { SET_NORMAL = 0, SET_FOCUSED = 1 };
+ uint32_t background_color[2],
+ text_color[2],
+ border_color[2],
+ black;
+ char label[3];
+
+ black = get_colorpixel(conn, "#000000");
+
+ background_color[SET_NORMAL] = get_colorpixel(conn, "#222222");
+ text_color[SET_NORMAL] = get_colorpixel(conn, "#888888");
+ border_color[SET_NORMAL] = get_colorpixel(conn, "#333333");
+
+ background_color[SET_FOCUSED] = get_colorpixel(conn, "#285577");
+ text_color[SET_FOCUSED] = get_colorpixel(conn, "#ffffff");
+ border_color[SET_FOCUSED] = get_colorpixel(conn, "#4c7899");
+
+ /* Fill the whole bar in black */
+ xcb_change_gc_single(conn, screen->bargc, XCB_GC_FOREGROUND, black);
+ xcb_rectangle_t rect = {0, 0, width, height};
+ xcb_poly_fill_rectangle(conn, screen->bar, screen->bargc, 1, &rect);
+
+ /* Set font */
+ 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)
+ continue;
+
+ int set = (screen->current_workspace == c ? SET_FOCUSED : SET_NORMAL);
+
+ xcb_draw_rect(conn, screen->bar, screen->bargc, border_color[set],
+ drawn * height, 1, height - 2, height - 2);
+ 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(conn, screen->bargc, XCB_GC_FOREGROUND, text_color[set]);
+ xcb_change_gc_single(conn, screen->bargc, XCB_GC_BACKGROUND, background_color[set]);
+ xcb_image_text_8(conn, strlen(label), screen->bar, screen->bargc, drawn * height + 5 /* X */,
+ font->height + 1 /* Y = baseline of font */, label);
+ drawn++;
+ }
+
+ LOG("done rendering internal\n");
+}
+
+/*
+ * Modifies the event mask of all clients on the given workspace to either ignore or to handle
+ * enter notifies. It is handy to ignore notifies because they will be sent when a window is mapped
+ * under the cursor, thus when the user didn’t enter the window actively at all.
+ *
+ */
+void ignore_enter_notify_forall(xcb_connection_t *conn, Workspace *workspace, bool ignore_enter_notify) {
+ Client *client;
+ uint32_t values[1];
+
+ LOG("Ignore enter_notify = %d\n", ignore_enter_notify);
+
+ FOR_TABLE(workspace)
+ CIRCLEQ_FOREACH(client, &(workspace->table[cols][rows]->clients), clients) {
+ /* Change event mask for the decorations */
+ values[0] = FRAME_EVENT_MASK;
+ if (ignore_enter_notify)
+ values[0] &= ~(XCB_EVENT_MASK_ENTER_WINDOW);
+ xcb_change_window_attributes(conn, client->frame, XCB_CW_EVENT_MASK, values);
+
+ /* Change event mask for the child itself */
+ values[0] = CHILD_EVENT_MASK;
+ if (ignore_enter_notify)
+ values[0] &= ~(XCB_EVENT_MASK_ENTER_WINDOW);
+ xcb_change_window_attributes(conn, client->child, XCB_CW_EVENT_MASK, values);
+ }
+}
+
+/*
+ * Renders the whole layout, that is: Go through each screen, each workspace, each container
+ * and render each client. This also renders the bars.
+ *
+ * If you don’t need to render *everything*, you should call render_container on the container
+ * you want to refresh.
+ *
+ */
+void render_layout(xcb_connection_t *conn) {