]> git.sur5r.net Git - i3/i3/commitdiff
Add title_align config directive 3452/head
authorAestek <thib.gilles@gmail.com>
Sun, 22 Apr 2018 01:55:37 +0000 (03:55 +0200)
committerOrestis Floros <orestisf1993@gmail.com>
Fri, 12 Oct 2018 16:58:48 +0000 (19:58 +0300)
Controls the window titles alignment in title bars. Possible values are:
- left
- center
- right

Co-authored-by: Orestis Floros <orestisf1993@gmail.com>
- Made title_align a config directive instead of a command. Helps with
some tree_render() issues we had.
- Made title_max_width the same for all 3 cases.
- Modified title offset calculations and added explanations for each
case.
- Append title_padding to mark_width if a mark exists.

Fixes #1750

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 da5d98737197ca0fb9cd1416bf287068df69768c..401d5ff2ee25a07240facf9893fffafc3a21ed98 100644 (file)
@@ -585,6 +585,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 3eccca4cef604d3ebbd89ab4650ffb682d075700..a1e9cc8029418d3fa8af098d70fd9bd2f84c71aa 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 1f54db83afb923b024d426431be784b74a8eb6ab..ceffd30a446255277b8177bda386c4e312f52f13 100644 (file)
--- a/src/x.c
+++ b/src/x.c
@@ -602,6 +602,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("");
@@ -623,12 +625,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);
@@ -639,11 +646,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