* i3bar - an xcb-based status- and ws-bar for i3
* © 2010-2012 Axel Wagner and contributors (see also: LICENSE)
*
- * child.c: Getting Input for the statusline
+ * child.c: Getting input for the statusline
*
*/
#include <stdlib.h>
first = TAILQ_FIRST(head);
if (free_resources) {
I3STRING_FREE(first->full_text);
+ I3STRING_FREE(first->short_text);
FREE(first->color);
FREE(first->name);
FREE(first->instance);
+ FREE(first->min_width_str);
}
TAILQ_REMOVE(head, first, blocks);
/* Default width of the separator block. */
ctx->block.sep_block_width = logical_px(9);
+ /* Use markup by default */
+ ctx->block.is_markup = true;
+
return 1;
}
if (strcasecmp(ctx->last_map_key, "full_text") == 0) {
ctx->block.full_text = i3string_from_markup_with_length((const char *)val, len);
}
+ if (strcasecmp(ctx->last_map_key, "short_text") == 0) {
+ ctx->block.short_text = i3string_from_markup_with_length((const char *)val, len);
+ }
if (strcasecmp(ctx->last_map_key, "color") == 0) {
sasprintf(&(ctx->block.color), "%.*s", len, val);
}
+ if (strcasecmp(ctx->last_map_key, "markup") == 0) {
+ ctx->block.is_markup = (len == strlen("pango") && !strncasecmp((const char *)val, "pango", strlen("pango")));
+ }
if (strcasecmp(ctx->last_map_key, "align") == 0) {
if (len == strlen("center") && !strncmp((const char *)val, "center", strlen("center"))) {
ctx->block.align = ALIGN_CENTER;
ctx->block.align = ALIGN_LEFT;
}
} else if (strcasecmp(ctx->last_map_key, "min_width") == 0) {
- i3String *text = i3string_from_markup_with_length((const char *)val, len);
- ctx->block.min_width = (uint32_t)predict_text_width(text);
- i3string_free(text);
+ char *copy = (char *)malloc(len + 1);
+ strncpy(copy, (const char *)val, len);
+ copy[len] = 0;
+ ctx->block.min_width_str = copy;
}
if (strcasecmp(ctx->last_map_key, "name") == 0) {
char *copy = (char *)malloc(len + 1);
new_block->full_text = i3string_from_utf8("SPEC VIOLATION: full_text is NULL!");
if (new_block->urgent)
ctx->has_urgent = true;
+
+ if (new_block->min_width_str) {
+ i3String *text = i3string_from_utf8(new_block->min_width_str);
+ i3string_set_markup(text, new_block->is_markup);
+ new_block->min_width = (uint32_t)predict_text_width(text);
+ i3string_free(text);
+ }
+
+ i3string_set_markup(new_block->full_text, new_block->is_markup);
+
+ if (new_block->short_text != NULL)
+ i3string_set_markup(new_block->short_text, new_block->is_markup);
+
TAILQ_INSERT_TAIL(&statusline_buffer, new_block, blocks);
return 1;
}
struct status_block *current;
TAILQ_FOREACH(current, &statusline_head, blocks) {
DLOG("full_text = %s\n", i3string_as_utf8(current->full_text));
+ DLOG("short_text = %s\n", (current->short_text == NULL ? NULL : i3string_as_utf8(current->short_text)));
DLOG("color = %s\n", current->color);
}
DLOG("end of dump\n");
#include "common.h"
#include "libi3.h"
- /* We save the Atoms in an easy to access array, indexed by an enum */
+ /* We save the atoms in an easy to access array, indexed by an enum */
enum {
#define ATOM_DO(name) name,
#include "xcb_atoms.def"
xcb_pixmap_t statusline_pm;
uint32_t statusline_width;
- /* Event-Watchers, to interact with the user */
+ /* Event watchers, to interact with the user */
ev_prepare *xcb_prep;
ev_check *xcb_chk;
ev_io *xcb_io;
* Redraws the statusline to the buffer
*
*/
-void refresh_statusline(void) {
+void refresh_statusline(bool use_short_text) {
struct status_block *block;
uint32_t old_statusline_width = statusline_width;
/* Predict the text width of all blocks (in pixels). */
TAILQ_FOREACH(block, &statusline_head, blocks) {
+ /* Try to use the shorter text if necessary and possible. */
+ if (use_short_text && block->short_text != NULL) {
+ I3STRING_FREE(block->full_text);
+ block->full_text = i3string_copy(block->short_text);
+ }
+
if (i3string_get_num_bytes(block->full_text) == 0)
continue;
redraw_bars();
break;
case XCB_BUTTON_PRESS:
- /* Button press events are mouse-buttons clicked on one of our bars */
+ /* Button press events are mouse buttons clicked on one of our bars */
handle_button((xcb_button_press_event_t *)event);
break;
case XCB_CLIENT_MESSAGE:
}
/*
- * Dummy Callback. We only need this, so that the Prepare- and Check-Watchers
+ * Dummy callback. We only need this, so that the prepare and check watchers
* are triggered
*
*/
*
*/
char *init_xcb_early() {
- /* FIXME: xcb_connect leaks Memory */
+ /* FIXME: xcb_connect leaks memory */
xcb_connection = xcb_connect(NULL, &screen);
if (xcb_connection_has_error(xcb_connection)) {
ELOG("Cannot open display\n");
root_screen->width_in_pixels,
root_screen->height_in_pixels);
- /* The various Watchers to communicate with xcb */
+ /* The various watchers to communicate with xcb */
xcb_io = smalloc(sizeof(ev_io));
xcb_prep = smalloc(sizeof(ev_prepare));
xcb_chk = smalloc(sizeof(ev_check));
/*
* We need to set the _NET_SYSTEM_TRAY_COLORS atom on the tray selection window
- * to make GTK+ 3 applets with Symbolic Icons visible. If the colors are unset,
+ * to make GTK+ 3 applets with symbolic icons visible. If the colors are unset,
* they assume a light background.
* See also https://bugzilla.gnome.org/show_bug.cgi?id=679591
*
DLOG("Drawing bars...\n");
int workspace_width = 0;
- refresh_statusline();
+ refresh_statusline(false);
i3_output *outputs_walk;
SLIST_FOREACH(outputs_walk, outputs, slist) {
if (!TAILQ_EMPTY(&statusline_head)) {
DLOG("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 */
int tray_width = get_tray_width(outputs_walk->trayclients);
+ int max_statusline_width = outputs_walk->rect.w - workspace_width - tray_width - 2 * logical_px(sb_hoff_px);
- int visible_statusline_width = MIN(statusline_width,
- outputs_walk->rect.w - workspace_width - tray_width - 2 * logical_px(sb_hoff_px));
+ /* If the statusline is too long, try to use short texts. */
+ if (statusline_width > max_statusline_width)
+ refresh_statusline(true);
+ /* Luckily we already prepared a seperate pixmap containing the rendered
+ * statusline, we just have to copy the relevant parts to the relevant
+ * position */
+ int visible_statusline_width = MIN(statusline_width, max_statusline_width);
xcb_copy_area(xcb_connection,
statusline_pm,
outputs_walk->buffer,