Parse the title_format and display the customized window title if a format was set.
The format string set with "title_format" can contain the placeholder "%title" which will be replaced with the actual window title. By not overwriting window->name itself, we make sure that assignment matching still works as expected. fixes #1723
This commit is contained in:
44
src/x.c
44
src/x.c
@ -302,6 +302,45 @@ void x_window_kill(xcb_window_t window, kill_window_t kill_window) {
|
||||
free(event);
|
||||
}
|
||||
|
||||
static i3String *parse_title_format(char *format, i3String *_title) {
|
||||
/* We need to ensure that we only escape the window title if pango
|
||||
* is used by the current font. */
|
||||
const bool is_markup = font_is_pango();
|
||||
|
||||
i3String *title = is_markup ? i3string_escape_markup(_title) : _title;
|
||||
const char *escaped_title = i3string_as_utf8(title);
|
||||
|
||||
/* We have to first iterate over the string to see how much buffer space
|
||||
* we need to allocate. */
|
||||
int buffer_len = strlen(format) + 1;
|
||||
for (char *walk = format; *walk != '\0'; walk++) {
|
||||
if (STARTS_WITH(walk, "%title")) {
|
||||
buffer_len = buffer_len - strlen("%title") + strlen(escaped_title);
|
||||
walk += strlen("%title") - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we can parse the format string. */
|
||||
char buffer[buffer_len];
|
||||
char *outwalk = buffer;
|
||||
for (char *walk = format; *walk != '\0'; walk++) {
|
||||
if (*walk != '%') {
|
||||
*(outwalk++) = *walk;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (STARTS_WITH(walk + 1, "title")) {
|
||||
outwalk += sprintf(outwalk, "%s", escaped_title);
|
||||
walk += strlen("title");
|
||||
}
|
||||
}
|
||||
*outwalk = '\0';
|
||||
|
||||
i3String *formatted = i3string_from_utf8(buffer);
|
||||
i3string_set_markup(formatted, is_markup);
|
||||
return formatted;
|
||||
}
|
||||
|
||||
/*
|
||||
* Draws the decoration of the given container onto its parent.
|
||||
*
|
||||
@ -549,10 +588,13 @@ void x_draw_decoration(Con *con) {
|
||||
I3STRING_FREE(mark);
|
||||
}
|
||||
|
||||
draw_text(win->name,
|
||||
i3String *title = win->title_format == NULL ? win->name : parse_title_format(win->title_format, win->name);
|
||||
draw_text(title,
|
||||
parent->pixmap, parent->pm_gc,
|
||||
con->deco_rect.x + logical_px(2) + indent_px, con->deco_rect.y + text_offset_y,
|
||||
con->deco_rect.width - logical_px(2) - indent_px - mark_width - logical_px(2));
|
||||
if (win->title_format != NULL)
|
||||
I3STRING_FREE(title);
|
||||
|
||||
after_title:
|
||||
/* Since we don’t clip the text at all, it might in some cases be painted
|
||||
|
Reference in New Issue
Block a user