i3bar: use Pango markup
Parse text within workspace buttons and the i3bar statusline as Pango markup. This lets people specify things like font weight, text color, background color, font size, and font family in the text of i3bar. fixes #1468
This commit is contained in:
parent
fbe25297b7
commit
e18e2b9f98
@ -119,7 +119,8 @@ click_events::
|
||||
full_text::
|
||||
The most simple block you can think of is one which just includes the
|
||||
only required key, the +full_text+ key. i3bar will display the string
|
||||
value and that’s it.
|
||||
value parsed as
|
||||
https://developer.gnome.org/pango/stable/PangoMarkupFormat.html[Pango markup].
|
||||
short_text::
|
||||
Where appropriate, the +short_text+ (string) entry should also be
|
||||
provided. It will be used in case the status line needs to be shortened
|
||||
|
@ -1625,6 +1625,10 @@ container to the next/previous workspace and +move container to workspace curren
|
||||
See <<move_to_outputs>> for how to move a container/workspace to a different
|
||||
RandR output.
|
||||
|
||||
Workspace names are parsed as
|
||||
https://developer.gnome.org/pango/stable/PangoMarkupFormat.html[Pango markup]
|
||||
by i3bar.
|
||||
|
||||
[[back_and_forth]]
|
||||
To switch back to the previously focused workspace, use +workspace
|
||||
back_and_forth+; likewise, you can move containers to the previously focused
|
||||
@ -1646,6 +1650,7 @@ move [window|container] [to] workspace <prev|next|current>
|
||||
-------------------------
|
||||
bindsym $mod+1 workspace 1
|
||||
bindsym $mod+2 workspace 2
|
||||
bindsym $mod+3 workspace 3:<span foreground="red">vim</span>
|
||||
...
|
||||
|
||||
bindsym $mod+Shift+1 move container to workspace 1
|
||||
|
@ -182,7 +182,7 @@ static int stdin_boolean(void *context, int val) {
|
||||
static int stdin_string(void *context, const unsigned char *val, size_t len) {
|
||||
parser_ctx *ctx = context;
|
||||
if (strcasecmp(ctx->last_map_key, "full_text") == 0) {
|
||||
ctx->block.full_text = i3string_from_utf8_with_length((const char *)val, len);
|
||||
ctx->block.full_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);
|
||||
@ -196,7 +196,7 @@ static int stdin_string(void *context, const unsigned char *val, size_t len) {
|
||||
ctx->block.align = ALIGN_LEFT;
|
||||
}
|
||||
} else if (strcasecmp(ctx->last_map_key, "min_width") == 0) {
|
||||
i3String *text = i3string_from_utf8_with_length((const char *)val, len);
|
||||
i3String *text = i3string_from_markup_with_length((const char *)val, len);
|
||||
ctx->block.min_width = (uint32_t)predict_text_width(text);
|
||||
i3string_free(text);
|
||||
}
|
||||
@ -304,7 +304,7 @@ static void read_flat_input(char *buffer, int length) {
|
||||
buffer[length - 1] = '\0';
|
||||
else
|
||||
buffer[length] = '\0';
|
||||
first->full_text = i3string_from_utf8(buffer);
|
||||
first->full_text = i3string_from_markup(buffer);
|
||||
}
|
||||
|
||||
static bool read_json_input(unsigned char *input, int length) {
|
||||
|
@ -123,12 +123,12 @@ static int workspaces_string_cb(void *params_, const unsigned char *val, size_t
|
||||
|
||||
/* Offset may be equal to length, in which case display the number */
|
||||
params->workspaces_walk->name = (offset < len
|
||||
? i3string_from_utf8_with_length(ws_name + offset, len - offset)
|
||||
: i3string_from_utf8(ws_num));
|
||||
? i3string_from_markup_with_length(ws_name + offset, len - offset)
|
||||
: i3string_from_markup(ws_num));
|
||||
|
||||
} else {
|
||||
/* Default case: just save the name */
|
||||
params->workspaces_walk->name = i3string_from_utf8_with_length(ws_name, len);
|
||||
params->workspaces_walk->name = i3string_from_markup_with_length(ws_name, len);
|
||||
}
|
||||
|
||||
/* Save its rendered width */
|
||||
|
@ -141,6 +141,12 @@ int sasprintf(char **strp, const char *fmt, ...);
|
||||
*/
|
||||
i3String *i3string_from_utf8(const char *from_utf8);
|
||||
|
||||
/**
|
||||
* Build an i3String from an UTF-8 encoded string in Pango markup.
|
||||
*
|
||||
*/
|
||||
i3String *i3string_from_markup(const char *from_markup);
|
||||
|
||||
/**
|
||||
* Build an i3String from an UTF-8 encoded string with fixed length.
|
||||
* To be used when no proper NUL-terminaison is available.
|
||||
@ -149,6 +155,13 @@ i3String *i3string_from_utf8(const char *from_utf8);
|
||||
*/
|
||||
i3String *i3string_from_utf8_with_length(const char *from_utf8, size_t num_bytes);
|
||||
|
||||
/**
|
||||
* Build an i3String from an UTF-8 encoded string in Pango markup with fixed
|
||||
* length.
|
||||
*
|
||||
*/
|
||||
i3String *i3string_from_markup_with_length(const char *from_markup, size_t num_bytes);
|
||||
|
||||
/**
|
||||
* Build an i3String from an UCS-2 encoded string.
|
||||
* Returns the newly-allocated i3String.
|
||||
@ -193,6 +206,11 @@ const xcb_char2b_t *i3string_as_ucs2(i3String *str);
|
||||
*/
|
||||
size_t i3string_get_num_bytes(i3String *str);
|
||||
|
||||
/**
|
||||
* Whether the given i3String is in Pango markup.
|
||||
*/
|
||||
bool i3string_is_markup(i3String *str);
|
||||
|
||||
/**
|
||||
* Returns the number of glyphs in an i3String.
|
||||
*
|
||||
|
24
libi3/font.c
24
libi3/font.c
@ -102,7 +102,8 @@ static bool load_pango_font(i3Font *font, const char *desc) {
|
||||
*
|
||||
*/
|
||||
static void draw_text_pango(const char *text, size_t text_len,
|
||||
xcb_drawable_t drawable, int x, int y, int max_width) {
|
||||
xcb_drawable_t drawable, int x, int y,
|
||||
int max_width, bool is_markup) {
|
||||
/* Create the Pango layout */
|
||||
/* root_visual_type is cached in load_pango_font */
|
||||
cairo_surface_t *surface = cairo_xcb_surface_create(conn, drawable,
|
||||
@ -116,7 +117,10 @@ static void draw_text_pango(const char *text, size_t text_len,
|
||||
pango_layout_set_wrap(layout, PANGO_WRAP_CHAR);
|
||||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
|
||||
|
||||
pango_layout_set_text(layout, text, text_len);
|
||||
if (is_markup)
|
||||
pango_layout_set_markup(layout, text, text_len);
|
||||
else
|
||||
pango_layout_set_text(layout, text, text_len);
|
||||
|
||||
/* Do the drawing */
|
||||
cairo_set_source_rgb(cr, pango_font_red, pango_font_green, pango_font_blue);
|
||||
@ -135,7 +139,7 @@ static void draw_text_pango(const char *text, size_t text_len,
|
||||
* Calculate the text width using Pango rendering.
|
||||
*
|
||||
*/
|
||||
static int predict_text_width_pango(const char *text, size_t text_len) {
|
||||
static int predict_text_width_pango(const char *text, size_t text_len, bool is_markup) {
|
||||
/* Create a dummy Pango layout */
|
||||
/* root_visual_type is cached in load_pango_font */
|
||||
cairo_surface_t *surface = cairo_xcb_surface_create(conn, root_screen->root, root_visual_type, 1, 1);
|
||||
@ -145,7 +149,12 @@ static int predict_text_width_pango(const char *text, size_t text_len) {
|
||||
/* Get the font width */
|
||||
gint width;
|
||||
pango_layout_set_font_description(layout, savedFont->specific.pango_desc);
|
||||
pango_layout_set_text(layout, text, text_len);
|
||||
|
||||
if (is_markup)
|
||||
pango_layout_set_markup(layout, text, text_len);
|
||||
else
|
||||
pango_layout_set_text(layout, text, text_len);
|
||||
|
||||
pango_cairo_update_layout(cr, layout);
|
||||
pango_layout_get_pixel_size(layout, &width, NULL);
|
||||
|
||||
@ -383,7 +392,7 @@ void draw_text(i3String *text, xcb_drawable_t drawable,
|
||||
case FONT_TYPE_PANGO:
|
||||
/* Render the text using Pango */
|
||||
draw_text_pango(i3string_as_utf8(text), i3string_get_num_bytes(text),
|
||||
drawable, x, y, max_width);
|
||||
drawable, x, y, max_width, i3string_is_markup(text));
|
||||
return;
|
||||
#endif
|
||||
default:
|
||||
@ -422,7 +431,7 @@ void draw_text_ascii(const char *text, xcb_drawable_t drawable,
|
||||
case FONT_TYPE_PANGO:
|
||||
/* Render the text using Pango */
|
||||
draw_text_pango(text, strlen(text),
|
||||
drawable, x, y, max_width);
|
||||
drawable, x, y, max_width, false);
|
||||
return;
|
||||
#endif
|
||||
default:
|
||||
@ -518,7 +527,8 @@ int predict_text_width(i3String *text) {
|
||||
#if PANGO_SUPPORT
|
||||
case FONT_TYPE_PANGO:
|
||||
/* Calculate extents using Pango */
|
||||
return predict_text_width_pango(i3string_as_utf8(text), i3string_get_num_bytes(text));
|
||||
return predict_text_width_pango(i3string_as_utf8(text), i3string_get_num_bytes(text),
|
||||
i3string_is_markup(text));
|
||||
#endif
|
||||
default:
|
||||
assert(false);
|
||||
|
@ -20,6 +20,7 @@ struct _i3String {
|
||||
xcb_char2b_t *ucs2;
|
||||
size_t num_glyphs;
|
||||
size_t num_bytes;
|
||||
bool is_markup;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -39,6 +40,19 @@ i3String *i3string_from_utf8(const char *from_utf8) {
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Build an i3String from an UTF-8 encoded string in Pango markup.
|
||||
*
|
||||
*/
|
||||
i3String *i3string_from_markup(const char *from_markup) {
|
||||
i3String *str = i3string_from_utf8(from_markup);
|
||||
|
||||
/* Set the markup flag */
|
||||
str->is_markup = true;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Build an i3String from an UTF-8 encoded string with fixed length.
|
||||
* To be used when no proper NUL-terminaison is available.
|
||||
@ -59,6 +73,20 @@ i3String *i3string_from_utf8_with_length(const char *from_utf8, size_t num_bytes
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Build an i3String from an UTF-8 encoded string in Pango markup with fixed
|
||||
* length.
|
||||
*
|
||||
*/
|
||||
i3String *i3string_from_markup_with_length(const char *from_markup, size_t num_bytes) {
|
||||
i3String *str = i3string_from_utf8_with_length(from_markup, num_bytes);
|
||||
|
||||
/* set the markup flag */
|
||||
str->is_markup = true;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Build an i3String from an UCS-2 encoded string.
|
||||
* Returns the newly-allocated i3String.
|
||||
@ -133,6 +161,13 @@ size_t i3string_get_num_bytes(i3String *str) {
|
||||
return str->num_bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
* Whether the given i3String is in Pango markup.
|
||||
*/
|
||||
bool i3string_is_markup(i3String *str) {
|
||||
return str->is_markup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the number of glyphs in an i3String.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user