]> git.sur5r.net Git - i3/i3/commitdiff
Added '%class' and '%instance' as placeholders for the title_format directive. 1864/head
authorIngo Bürk <ingo.buerk@tngtech.com>
Tue, 25 Aug 2015 17:22:05 +0000 (19:22 +0200)
committerIngo Bürk <ingo.buerk@tngtech.com>
Tue, 25 Aug 2015 17:22:05 +0000 (19:22 +0200)
relates to #1861

docs/userguide
src/x.c

index eea7141b67b184d8a6bb3d9ef45f6823ff5f6fec..0f260ead734584e412251d67ac99d6dc8aa0c7f5 100644 (file)
@@ -2115,6 +2115,12 @@ and the following placeholders which will be replaced:
 
 +%title+::
     The X11 window title (_NET_WM_NAME or WM_NAME as fallback).
++%class+:
+    The X11 window class (second part of WM_CLASS). This corresponds to the
+    +class+ criterion, see <<command_criteria>>.
++%instance+:
+    The X11 window instance (first part of WM_CLASS). This corresponds to the
+    +instance+ criterion, see <<command_criteria>>.
 
 Using the <<for_window>> directive, you can set the title format for any window
 based on <<command_criteria>>.
diff --git a/src/x.c b/src/x.c
index cdfc0f2f9964742055b43f8a6ca1c6df59fc0e35..16417ffcbf7869e09984a4cd1cb1fce381d9b528 100644 (file)
--- a/src/x.c
+++ b/src/x.c
@@ -302,21 +302,39 @@ void x_window_kill(xcb_window_t window, kill_window_t kill_window) {
     free(event);
 }
 
-static i3String *parse_title_format(char *format, i3String *_title) {
+static i3String *parse_title_format(struct Window *win) {
     /* 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);
+    char *format = win->title_format;
+    /* We initialize these lazily so we only escape them if really necessary. */
+    const char *escaped_title = NULL;
+    const char *escaped_class = NULL;
+    const char *escaped_instance = NULL;
 
     /* 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")) {
+            if (escaped_title == NULL)
+                escaped_title = i3string_as_utf8(is_markup ? i3string_escape_markup(win->name) : win->name);
+
             buffer_len = buffer_len - strlen("%title") + strlen(escaped_title);
             walk += strlen("%title") - 1;
+        } else if (STARTS_WITH(walk, "%class")) {
+            if (escaped_class == NULL)
+                escaped_class = is_markup ? g_markup_escape_text(win->class_class, -1) : win->class_class;
+
+            buffer_len = buffer_len - strlen("%class") + strlen(escaped_class);
+            walk += strlen("%class") - 1;
+        } else if (STARTS_WITH(walk, "%instance")) {
+            if (escaped_instance == NULL)
+                escaped_instance = is_markup ? g_markup_escape_text(win->class_instance, -1) : win->class_instance;
+
+            buffer_len = buffer_len - strlen("%instance") + strlen(escaped_instance);
+            walk += strlen("%instance") - 1;
         }
     }
 
@@ -332,6 +350,12 @@ static i3String *parse_title_format(char *format, i3String *_title) {
         if (STARTS_WITH(walk + 1, "title")) {
             outwalk += sprintf(outwalk, "%s", escaped_title);
             walk += strlen("title");
+        } else if (STARTS_WITH(walk + 1, "class")) {
+            outwalk += sprintf(outwalk, "%s", escaped_class);
+            walk += strlen("class");
+        } else if (STARTS_WITH(walk + 1, "instance")) {
+            outwalk += sprintf(outwalk, "%s", escaped_instance);
+            walk += strlen("instance");
         }
     }
     *outwalk = '\0';
@@ -588,7 +612,7 @@ void x_draw_decoration(Con *con) {
         I3STRING_FREE(mark);
     }
 
-    i3String *title = win->title_format == NULL ? win->name : parse_title_format(win->title_format, win->name);
+    i3String *title = win->title_format == NULL ? win->name : parse_title_format(win);
     draw_text(title,
               parent->pixmap, parent->pm_gc,
               con->deco_rect.x + logical_px(2) + indent_px, con->deco_rect.y + text_offset_y,