Add title_align config directive

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
This commit is contained in:
Aestek 2018-04-22 03:55:37 +02:00 committed by Orestis Floros
parent dfe89cc4f1
commit 6d82753d53
No known key found for this signature in database
GPG Key ID: E9AD9F32E401E38F
7 changed files with 70 additions and 4 deletions

View File

@ -585,6 +585,16 @@ workspace_layout default|stacking|tabbed
workspace_layout 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 === Default border style for new windows
This option determines which border style new windows will have. The default is This option determines which border style new windows will have. The default is

View File

@ -56,6 +56,7 @@ CFGFUN(disable_randr15, const char *value);
CFGFUN(fake_outputs, const char *outputs); CFGFUN(fake_outputs, const char *outputs);
CFGFUN(force_display_urgency_hint, const long duration_ms); CFGFUN(force_display_urgency_hint, const long duration_ms);
CFGFUN(focus_on_window_activation, const char *mode); CFGFUN(focus_on_window_activation, const char *mode);
CFGFUN(title_align, const char *alignment);
CFGFUN(show_marks, const char *value); CFGFUN(show_marks, const char *value);
CFGFUN(hide_edge_borders, const char *borders); CFGFUN(hide_edge_borders, const char *borders);
CFGFUN(assign_output, const char *output); CFGFUN(assign_output, const char *output);

View File

@ -201,6 +201,13 @@ struct Config {
* decoration. Marks starting with a "_" will be ignored either way. */ * decoration. Marks starting with a "_" will be ignored either way. */
bool show_marks; bool show_marks;
/** Title alignment options. */
enum {
ALIGN_LEFT,
ALIGN_CENTER,
ALIGN_RIGHT
} title_align;
/** The default border style for new windows. */ /** The default border style for new windows. */
border_style_t default_border; border_style_t default_border;

View File

@ -45,6 +45,7 @@ state INITIAL:
'fake_outputs', 'fake-outputs' -> FAKE_OUTPUTS 'fake_outputs', 'fake-outputs' -> FAKE_OUTPUTS
'force_display_urgency_hint' -> FORCE_DISPLAY_URGENCY_HINT 'force_display_urgency_hint' -> FORCE_DISPLAY_URGENCY_HINT
'focus_on_window_activation' -> FOCUS_ON_WINDOW_ACTIVATION 'focus_on_window_activation' -> FOCUS_ON_WINDOW_ACTIVATION
'title_align' -> TITLE_ALIGN
'show_marks' -> SHOW_MARKS 'show_marks' -> SHOW_MARKS
'workspace' -> WORKSPACE 'workspace' -> WORKSPACE
'ipc_socket', 'ipc-socket' -> IPC_SOCKET 'ipc_socket', 'ipc-socket' -> IPC_SOCKET
@ -248,6 +249,11 @@ state FORCE_DISPLAY_URGENCY_HINT:
duration_ms = number duration_ms = number
-> FORCE_DISPLAY_URGENCY_HINT_MS -> FORCE_DISPLAY_URGENCY_HINT_MS
# title_align [left|center|right]
state TITLE_ALIGN:
alignment = 'left', 'center', 'right'
-> call cfg_title_align($alignment)
# show_marks # show_marks
state SHOW_MARKS: state SHOW_MARKS:
value = word value = word

View 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); 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) { CFGFUN(show_marks, const char *value) {
config.show_marks = eval_boolstr(value); config.show_marks = eval_boolstr(value);
} }

37
src/x.c
View File

@ -602,6 +602,8 @@ void x_draw_decoration(Con *con) {
goto after_title; goto after_title;
} }
const int title_padding = logical_px(2);
const int deco_width = (int)con->deco_rect.width;
int mark_width = 0; int mark_width = 0;
if (config.show_marks && !TAILQ_EMPTY(&(con->marks_head))) { if (config.show_marks && !TAILQ_EMPTY(&(con->marks_head))) {
char *formatted_mark = sstrdup(""); char *formatted_mark = sstrdup("");
@ -623,12 +625,17 @@ void x_draw_decoration(Con *con) {
i3String *mark = i3string_from_utf8(formatted_mark); i3String *mark = i3string_from_utf8(formatted_mark);
mark_width = predict_text_width(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), draw_util_text(mark, &(parent->frame_buffer),
p->color->text, p->color->background, 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); con->deco_rect.y + text_offset_y, mark_width);
I3STRING_FREE(mark); I3STRING_FREE(mark);
mark_width += title_padding;
} }
FREE(formatted_mark); FREE(formatted_mark);
@ -639,11 +646,33 @@ void x_draw_decoration(Con *con) {
goto copy_pixmaps; 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), draw_util_text(title, &(parent->frame_buffer),
p->color->text, p->color->background, 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.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) { if (con->title_format != NULL) {
I3STRING_FREE(title); I3STRING_FREE(title);

View File

@ -497,6 +497,7 @@ my $expected_all_tokens = "ERROR: CONFIG: Expected one of these tokens: <end>, '
fake-outputs fake-outputs
force_display_urgency_hint force_display_urgency_hint
focus_on_window_activation focus_on_window_activation
title_align
show_marks show_marks
workspace workspace
ipc_socket ipc_socket