- int width = r_ws->rect.width;
- int height = r_ws->rect.height;
-
- /* Reserve space for dock clients */
- Client *client;
- SLIST_FOREACH(client, &(r_ws->dock_clients), dock_clients)
- height -= client->desired_height;
-
- printf("got %d rows and %d cols\n", r_ws->rows, r_ws->cols);
-
- int xoffset[r_ws->rows];
- int yoffset[r_ws->cols];
- /* Initialize offsets */
- for (int cols = 0; cols < r_ws->cols; cols++)
- yoffset[cols] = r_ws->rect.y;
- for (int rows = 0; rows < r_ws->rows; rows++)
- xoffset[rows] = r_ws->rect.x;
-
- /* Go through the whole table and render what’s necessary */
- for (int cols = 0; cols < r_ws->cols; cols++)
- for (int rows = 0; rows < r_ws->rows; rows++) {
- Container *container = r_ws->table[cols][rows];
- printf("\n========\ncontainer has %d colspan, %d rowspan\n",
- container->colspan, container->rowspan);
- printf("container at %d, %d\n", xoffset[rows], yoffset[cols]);
- /* Update position of the container */
- container->row = rows;
- container->col = cols;
- container->x = xoffset[rows];
- container->y = yoffset[cols];
-
- if (container->width_factor == 0)
- container->width = (width / r_ws->cols);
- else container->width = get_unoccupied_x(r_ws, rows) * container->width_factor;
- container->width *= container->colspan;
-
- if (container->height_factor == 0)
- container->height = (height / r_ws->rows);
- else container->height = get_unoccupied_y(r_ws, cols) * container->height_factor;
- container->height *= container->rowspan;
-
- /* Render the container if it is not empty */
- render_container(connection, container);
-
- xoffset[rows] += container->width;
- yoffset[cols] += container->height;
- printf("==========\n");
- }
+ struct Colortriple *color = (screen->current_workspace == c ? &(config.bar.focused) :
+ &(config.bar.unfocused));
+
+ xcb_draw_rect(conn, screen->bar, screen->bargc, color->border,
+ drawn * height, 1, height - 2, height - 2);
+ xcb_draw_rect(conn, screen->bar, screen->bargc, color->background,
+ 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, color->text);
+ xcb_change_gc_single(conn, screen->bargc, XCB_GC_BACKGROUND, color->background);
+ 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 given workspace on the given screen
+ *
+ */
+void render_workspace(xcb_connection_t *conn, i3Screen *screen, Workspace *r_ws) {
+ i3Font *font = load_font(conn, config.font);
+ int width = r_ws->rect.width;
+ int height = r_ws->rect.height;
+
+ /* Reserve space for dock clients */
+ Client *client;
+ SLIST_FOREACH(client, &(screen->dock_clients), dock_clients)
+ height -= client->desired_height;
+
+ /* Space for the internal bar */
+ height -= (font->height + 6);
+
+ LOG("got %d rows and %d cols\n", r_ws->rows, r_ws->cols);
+
+ int xoffset[r_ws->rows];
+ int yoffset[r_ws->cols];
+ /* Initialize offsets */
+ for (int cols = 0; cols < r_ws->cols; cols++)
+ yoffset[cols] = r_ws->rect.y;
+ for (int rows = 0; rows < r_ws->rows; rows++)
+ xoffset[rows] = r_ws->rect.x;
+
+ dump_table(conn, r_ws);
+
+ ignore_enter_notify_forall(conn, r_ws, true);
+
+ /* Go through the whole table and render what’s necessary */
+ FOR_TABLE(r_ws) {
+ Container *container = r_ws->table[cols][rows];
+ int single_width = -1, single_height;
+ LOG("\n");
+ LOG("========\n");
+ LOG("container has %d colspan, %d rowspan\n",
+ container->colspan, container->rowspan);
+ LOG("container at %d, %d\n", xoffset[rows], yoffset[cols]);
+ /* Update position of the container */
+ container->row = rows;
+ container->col = cols;
+ container->x = xoffset[rows];
+ container->y = yoffset[cols];
+ container->width = 0;
+
+ for (int c = 0; c < container->colspan; c++) {
+ if (r_ws->width_factor[cols+c] == 0)
+ container->width += (width / r_ws->cols);
+ else container->width += get_unoccupied_x(r_ws) * r_ws->width_factor[cols+c];
+
+ if (single_width == -1)
+ single_width = container->width;
+ }
+
+ //if (container->height_factor == 0)
+ container->height = (height / r_ws->rows);
+ //else container->height = get_unoccupied_y(r_ws, cols) * container->height_factor;
+ single_height = container->height;
+ container->height *= container->rowspan;
+
+ /* Render the container if it is not empty */
+ render_container(conn, container);
+
+ xoffset[rows] += single_width;
+ yoffset[cols] += single_height;
+ LOG("==========\n");
+ }