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:
parent
dfe89cc4f1
commit
6d82753d53
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
37
src/x.c
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue