]> git.sur5r.net Git - i3/i3/blobdiff - src/x.c
Parse the title_format and display the customized window title if a format was set.
[i3/i3] / src / x.c
diff --git a/src/x.c b/src/x.c
index 2dcffe6b15929ae8d25d6a656ae1017d8d122a20..ef6c734162c0431bc6dad0ee7bb56d17e9c78788 100644 (file)
--- a/src/x.c
+++ b/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