]> git.sur5r.net Git - i3/i3/commitdiff
Merge pull request #3452 from orestisf1993/title_align
authorIngo Bürk <admin@airblader.de>
Tue, 23 Oct 2018 14:41:54 +0000 (16:41 +0200)
committerGitHub <noreply@github.com>
Tue, 23 Oct 2018 14:41:54 +0000 (16:41 +0200)
Add title_align config directive

docs/userguide
include/config_directives.h
include/configuration.h
parser-specs/config.spec
src/config_directives.c
src/x.c
testcases/t/201-config-parser.t

index 4bfcdb6b980e5a2009bdc6f61541054c6a7b00e1..91060ab2cc6df006f4c23a80665976d0c503041b 100644 (file)
@@ -587,6 +587,16 @@ workspace_layout default|stacking|tabbed
 workspace_layout tabbed
 ---------------------
 
+=== Window title alignment
+
+This option determines the window title's text alignment.
+Default is +left+
+
+*Syntax*:
+---------------------------------------------
+title_align left|center|right
+---------------------------------------------
+
 === Default border style for new windows
 
 This option determines which border style new windows will have. The default is
index 4a20a1f5a6ce9d4c9c31454337b5d8258a95f284..72b59ea2b9171e2d0487bd3827e73732b241cffa 100644 (file)
@@ -56,6 +56,7 @@ CFGFUN(disable_randr15, const char *value);
 CFGFUN(fake_outputs, const char *outputs);
 CFGFUN(force_display_urgency_hint, const long duration_ms);
 CFGFUN(focus_on_window_activation, const char *mode);
+CFGFUN(title_align, const char *alignment);
 CFGFUN(show_marks, const char *value);
 CFGFUN(hide_edge_borders, const char *borders);
 CFGFUN(assign_output, const char *output);
index d99d9fff663cd5bc965abd0049f4f24ec2ffd250..6f55ac2a57f7fe7ef280ca956267b46c63b82db9 100644 (file)
@@ -201,6 +201,13 @@ struct Config {
      * decoration. Marks starting with a "_" will be ignored either way. */
     bool show_marks;
 
+    /** Title alignment options. */
+    enum {
+        ALIGN_LEFT,
+        ALIGN_CENTER,
+        ALIGN_RIGHT
+    } title_align;
+
     /** The default border style for new windows. */
     border_style_t default_border;
 
index 5cdb7c32dd981518dbcb8325286ce80fd7529a7b..43181c59e1bb96f52563e5063e719daa9a7848fe 100644 (file)
@@ -45,6 +45,7 @@ state INITIAL:
   'fake_outputs', 'fake-outputs'           -> FAKE_OUTPUTS
   'force_display_urgency_hint'             -> FORCE_DISPLAY_URGENCY_HINT
   'focus_on_window_activation'             -> FOCUS_ON_WINDOW_ACTIVATION
+  'title_align'                            -> TITLE_ALIGN
   'show_marks'                             -> SHOW_MARKS
   'workspace'                              -> WORKSPACE
   'ipc_socket', 'ipc-socket'               -> IPC_SOCKET
@@ -248,6 +249,11 @@ state FORCE_DISPLAY_URGENCY_HINT:
   duration_ms = number
       -> FORCE_DISPLAY_URGENCY_HINT_MS
 
+# title_align [left|center|right]
+state TITLE_ALIGN:
+  alignment = 'left', 'center', 'right'
+      -> call cfg_title_align($alignment)
+
 # show_marks
 state SHOW_MARKS:
   value = word
index 5c85197f6e0194cf702bff727ef8c45ba4d67c1a..0b01d54a4acaf4ffa4a1fa0a6b3ff26ccf1109fc 100644 (file)
@@ -318,6 +318,18 @@ CFGFUN(focus_on_window_activation, const char *mode) {
     DLOG("Set new focus_on_window_activation mode = %i.\n", config.focus_on_window_activation);
 }
 
+CFGFUN(title_align, const char *alignment) {
+    if (strcmp(alignment, "left") == 0) {
+        config.title_align = ALIGN_LEFT;
+    } else if (strcmp(alignment, "center") == 0) {
+        config.title_align = ALIGN_CENTER;
+    } else if (strcmp(alignment, "right") == 0) {
+        config.title_align = ALIGN_RIGHT;
+    } else {
+        assert(false);
+    }
+}
+
 CFGFUN(show_marks, const char *value) {
     config.show_marks = eval_boolstr(value);
 }
diff --git a/src/x.c b/src/x.c
index 6a0170a5699be528dd17b67b05cf13396400edc5..0fc6e714e5ab27f28c1ae929ed6849ceb4adbb50 100644 (file)
--- a/src/x.c
+++ b/src/x.c
@@ -600,6 +600,8 @@ void x_draw_decoration(Con *con) {
         goto after_title;
     }
 
+    const int title_padding = logical_px(2);
+    const int deco_width = (int)con->deco_rect.width;
     int mark_width = 0;
     if (config.show_marks && !TAILQ_EMPTY(&(con->marks_head))) {
         char *formatted_mark = sstrdup("");
@@ -621,12 +623,17 @@ void x_draw_decoration(Con *con) {
             i3String *mark = i3string_from_utf8(formatted_mark);
             mark_width = predict_text_width(mark);
 
+            int mark_offset_x = (config.title_align == ALIGN_RIGHT)
+                                    ? title_padding
+                                    : deco_width - mark_width - title_padding;
+
             draw_util_text(mark, &(parent->frame_buffer),
                            p->color->text, p->color->background,
-                           con->deco_rect.x + con->deco_rect.width - mark_width - logical_px(2),
+                           con->deco_rect.x + mark_offset_x,
                            con->deco_rect.y + text_offset_y, mark_width);
-
             I3STRING_FREE(mark);
+
+            mark_width += title_padding;
         }
 
         FREE(formatted_mark);
@@ -637,11 +644,33 @@ void x_draw_decoration(Con *con) {
         goto copy_pixmaps;
     }
 
+    int title_offset_x;
+    switch (config.title_align) {
+        case ALIGN_LEFT:
+            /* (pad)[text    ](pad)[mark + its pad) */
+            title_offset_x = title_padding;
+            break;
+        case ALIGN_CENTER:
+            /* (pad)[  text  ](pad)[mark + its pad)
+             * To center the text inside its allocated space, the surface
+             * between the brackets, we use the formula
+             * (surface_width - predict_text_width) / 2
+             * where surface_width = deco_width - 2 * pad - mark_width
+             * so, offset = pad + (surface_width - predict_text_width) / 2 =
+             * = … = (deco_width - mark_width - predict_text_width) / 2 */
+            title_offset_x = max(title_padding, (deco_width - mark_width - predict_text_width(title)) / 2);
+            break;
+        case ALIGN_RIGHT:
+            /* [mark + its pad](pad)[    text](pad) */
+            title_offset_x = max(title_padding + mark_width, deco_width - title_padding - predict_text_width(title));
+            break;
+    }
+
     draw_util_text(title, &(parent->frame_buffer),
                    p->color->text, p->color->background,
-                   con->deco_rect.x + logical_px(2),
+                   con->deco_rect.x + title_offset_x,
                    con->deco_rect.y + text_offset_y,
-                   con->deco_rect.width - mark_width - 2 * logical_px(2));
+                   deco_width - mark_width - 2 * title_padding);
 
     if (con->title_format != NULL) {
         I3STRING_FREE(title);
index a58f33c1339db17bcc631132e7e36a84e630d8a6..c6ce22eb9582eeaa35e1402c72d3ad3fb5c76377 100644 (file)
@@ -497,6 +497,7 @@ my $expected_all_tokens = "ERROR: CONFIG: Expected one of these tokens: <end>, '
         fake-outputs
         force_display_urgency_hint
         focus_on_window_activation
+        title_align
         show_marks
         workspace
         ipc_socket