Merge pull request #2030 from DavidMikeSimon/focus-bar-color
Optionally change i3bar color on focused output, implements #2020
This commit is contained in:
commit
3295e05089
8
docs/ipc
8
docs/ipc
|
@ -520,6 +520,14 @@ statusline::
|
||||||
Text color to be used for the statusline.
|
Text color to be used for the statusline.
|
||||||
separator::
|
separator::
|
||||||
Text color to be used for the separator.
|
Text color to be used for the separator.
|
||||||
|
focused_background::
|
||||||
|
Background color of the bar on the currently focused monitor output.
|
||||||
|
focused_statusline::
|
||||||
|
Text color to be used for the statusline on the currently focused
|
||||||
|
monitor output.
|
||||||
|
focused_separator::
|
||||||
|
Text color to be used for the separator on the currently focused
|
||||||
|
monitor output.
|
||||||
focused_workspace_text/focused_workspace_bg/focused_workspace_border::
|
focused_workspace_text/focused_workspace_bg/focused_workspace_border::
|
||||||
Text/background/border color for a workspace button when the workspace
|
Text/background/border color for a workspace button when the workspace
|
||||||
has focus.
|
has focus.
|
||||||
|
|
|
@ -1529,6 +1529,15 @@ statusline::
|
||||||
Text color to be used for the statusline.
|
Text color to be used for the statusline.
|
||||||
separator::
|
separator::
|
||||||
Text color to be used for the separator.
|
Text color to be used for the separator.
|
||||||
|
focused_background::
|
||||||
|
Background color of the bar on the currently focused monitor output. If
|
||||||
|
not used, the color will be taken from +background+.
|
||||||
|
focused_statusline::
|
||||||
|
Text color to be used for the statusline on the currently focused
|
||||||
|
monitor output. If not used, the color will be taken from +statusline+.
|
||||||
|
focused_separator::
|
||||||
|
Text color to be used for the separator on the currently focused
|
||||||
|
monitor output. If not used, the color will be taken from +separator+.
|
||||||
focused_workspace::
|
focused_workspace::
|
||||||
Border, background and text color for a workspace button when the workspace
|
Border, background and text color for a workspace button when the workspace
|
||||||
has focus.
|
has focus.
|
||||||
|
|
|
@ -38,6 +38,12 @@ void init_outputs(void);
|
||||||
*/
|
*/
|
||||||
i3_output* get_output_by_name(char* name);
|
i3_output* get_output_by_name(char* name);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns true if the output has the currently focused workspace
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool output_has_focus(i3_output* output);
|
||||||
|
|
||||||
struct i3_output {
|
struct i3_output {
|
||||||
char* name; /* Name of the output */
|
char* name; /* Name of the output */
|
||||||
bool active; /* If the output is active */
|
bool active; /* If the output is active */
|
||||||
|
|
|
@ -34,6 +34,9 @@ struct xcb_color_strings_t {
|
||||||
char *bar_fg;
|
char *bar_fg;
|
||||||
char *bar_bg;
|
char *bar_bg;
|
||||||
char *sep_fg;
|
char *sep_fg;
|
||||||
|
char *focus_bar_fg;
|
||||||
|
char *focus_bar_bg;
|
||||||
|
char *focus_sep_fg;
|
||||||
char *active_ws_fg;
|
char *active_ws_fg;
|
||||||
char *active_ws_bg;
|
char *active_ws_bg;
|
||||||
char *active_ws_border;
|
char *active_ws_border;
|
||||||
|
|
|
@ -214,6 +214,9 @@ static int config_string_cb(void *params_, const unsigned char *val, size_t _len
|
||||||
COLOR(statusline, bar_fg);
|
COLOR(statusline, bar_fg);
|
||||||
COLOR(background, bar_bg);
|
COLOR(background, bar_bg);
|
||||||
COLOR(separator, sep_fg);
|
COLOR(separator, sep_fg);
|
||||||
|
COLOR(focused_statusline, focus_bar_fg);
|
||||||
|
COLOR(focused_background, focus_bar_bg);
|
||||||
|
COLOR(focused_separator, focus_sep_fg);
|
||||||
COLOR(focused_workspace_border, focus_ws_border);
|
COLOR(focused_workspace_border, focus_ws_border);
|
||||||
COLOR(focused_workspace_bg, focus_ws_bg);
|
COLOR(focused_workspace_bg, focus_ws_bg);
|
||||||
COLOR(focused_workspace_text, focus_ws_fg);
|
COLOR(focused_workspace_text, focus_ws_fg);
|
||||||
|
@ -343,6 +346,9 @@ void free_colors(struct xcb_color_strings_t *colors) {
|
||||||
FREE_COLOR(bar_fg);
|
FREE_COLOR(bar_fg);
|
||||||
FREE_COLOR(bar_bg);
|
FREE_COLOR(bar_bg);
|
||||||
FREE_COLOR(sep_fg);
|
FREE_COLOR(sep_fg);
|
||||||
|
FREE_COLOR(focus_bar_fg);
|
||||||
|
FREE_COLOR(focus_bar_bg);
|
||||||
|
FREE_COLOR(focus_sep_fg);
|
||||||
FREE_COLOR(active_ws_fg);
|
FREE_COLOR(active_ws_fg);
|
||||||
FREE_COLOR(active_ws_bg);
|
FREE_COLOR(active_ws_bg);
|
||||||
FREE_COLOR(active_ws_border);
|
FREE_COLOR(active_ws_border);
|
||||||
|
|
|
@ -302,3 +302,17 @@ i3_output *get_output_by_name(char *name) {
|
||||||
|
|
||||||
return walk;
|
return walk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns true if the output has the currently focused workspace
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool output_has_focus(i3_output *output) {
|
||||||
|
i3_ws *ws_walk;
|
||||||
|
TAILQ_FOREACH(ws_walk, output->workspaces, tailq) {
|
||||||
|
if (ws_walk->focused) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -91,6 +91,9 @@ struct xcb_colors_t {
|
||||||
color_t bar_fg;
|
color_t bar_fg;
|
||||||
color_t bar_bg;
|
color_t bar_bg;
|
||||||
color_t sep_fg;
|
color_t sep_fg;
|
||||||
|
color_t focus_bar_fg;
|
||||||
|
color_t focus_bar_bg;
|
||||||
|
color_t focus_sep_fg;
|
||||||
color_t active_ws_fg;
|
color_t active_ws_fg;
|
||||||
color_t active_ws_bg;
|
color_t active_ws_bg;
|
||||||
color_t active_ws_border;
|
color_t active_ws_border;
|
||||||
|
@ -160,7 +163,10 @@ int get_tray_width(struct tc_head *trayclients) {
|
||||||
* Draws a separator for the given block if necessary.
|
* Draws a separator for the given block if necessary.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void draw_separator(i3_output *output, uint32_t x, struct status_block *block) {
|
static void draw_separator(i3_output *output, uint32_t x, struct status_block *block, bool use_focus_colors) {
|
||||||
|
color_t sep_fg = (use_focus_colors ? colors.focus_sep_fg : colors.sep_fg);
|
||||||
|
color_t bar_bg = (use_focus_colors ? colors.focus_bar_bg : colors.bar_bg);
|
||||||
|
|
||||||
uint32_t sep_offset = get_sep_offset(block);
|
uint32_t sep_offset = get_sep_offset(block);
|
||||||
if (TAILQ_NEXT(block, blocks) == NULL || sep_offset == 0)
|
if (TAILQ_NEXT(block, blocks) == NULL || sep_offset == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -168,7 +174,7 @@ static void draw_separator(i3_output *output, uint32_t x, struct status_block *b
|
||||||
uint32_t center_x = x - sep_offset;
|
uint32_t center_x = x - sep_offset;
|
||||||
if (config.separator_symbol == NULL) {
|
if (config.separator_symbol == NULL) {
|
||||||
/* Draw a classic one pixel, vertical separator. */
|
/* Draw a classic one pixel, vertical separator. */
|
||||||
draw_util_rectangle(&output->statusline_buffer, colors.sep_fg,
|
draw_util_rectangle(&output->statusline_buffer, sep_fg,
|
||||||
center_x,
|
center_x,
|
||||||
logical_px(sep_voff_px),
|
logical_px(sep_voff_px),
|
||||||
logical_px(1),
|
logical_px(1),
|
||||||
|
@ -176,7 +182,7 @@ static void draw_separator(i3_output *output, uint32_t x, struct status_block *b
|
||||||
} else {
|
} else {
|
||||||
/* Draw a custom separator. */
|
/* Draw a custom separator. */
|
||||||
uint32_t separator_x = MAX(x - block->sep_block_width, center_x - separator_symbol_width / 2);
|
uint32_t separator_x = MAX(x - block->sep_block_width, center_x - separator_symbol_width / 2);
|
||||||
draw_util_text(config.separator_symbol, &output->statusline_buffer, colors.sep_fg, colors.bar_bg,
|
draw_util_text(config.separator_symbol, &output->statusline_buffer, sep_fg, bar_bg,
|
||||||
separator_x, logical_px(ws_voff_px), x - separator_x);
|
separator_x, logical_px(ws_voff_px), x - separator_x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,10 +239,11 @@ uint32_t predict_statusline_length(bool use_short_text) {
|
||||||
/*
|
/*
|
||||||
* Redraws the statusline to the output's statusline_buffer
|
* Redraws the statusline to the output's statusline_buffer
|
||||||
*/
|
*/
|
||||||
void draw_statusline(i3_output *output, uint32_t clip_left, bool use_short_text) {
|
void draw_statusline(i3_output *output, uint32_t clip_left, bool use_focus_colors, bool use_short_text) {
|
||||||
struct status_block *block;
|
struct status_block *block;
|
||||||
|
|
||||||
draw_util_clear_surface(&output->statusline_buffer, colors.bar_bg);
|
color_t bar_color = (use_focus_colors ? colors.focus_bar_bg : colors.bar_bg);
|
||||||
|
draw_util_clear_surface(&output->statusline_buffer, bar_color);
|
||||||
|
|
||||||
/* Use unsigned integer wraparound to clip off the left side.
|
/* Use unsigned integer wraparound to clip off the left side.
|
||||||
* For example, if clip_left is 75, then x will start at the very large
|
* For example, if clip_left is 75, then x will start at the very large
|
||||||
|
@ -263,17 +270,19 @@ void draw_statusline(i3_output *output, uint32_t clip_left, bool use_short_text)
|
||||||
fg_color = colors.urgent_ws_fg;
|
fg_color = colors.urgent_ws_fg;
|
||||||
} else if (block->color) {
|
} else if (block->color) {
|
||||||
fg_color = draw_util_hex_to_color(block->color);
|
fg_color = draw_util_hex_to_color(block->color);
|
||||||
|
} else if (use_focus_colors) {
|
||||||
|
fg_color = colors.focus_bar_fg;
|
||||||
} else {
|
} else {
|
||||||
fg_color = colors.bar_fg;
|
fg_color = colors.bar_fg;
|
||||||
}
|
}
|
||||||
|
|
||||||
color_t bg_color = colors.bar_bg;
|
color_t bg_color = bar_color;
|
||||||
|
|
||||||
int border_width = (block->border) ? logical_px(1) : 0;
|
int border_width = (block->border) ? logical_px(1) : 0;
|
||||||
int full_render_width = render->width + render->x_offset + render->x_append;
|
int full_render_width = render->width + render->x_offset + render->x_append;
|
||||||
if (block->border || block->background || block->urgent) {
|
if (block->border || block->background || block->urgent) {
|
||||||
/* Let's determine the colors first. */
|
/* Let's determine the colors first. */
|
||||||
color_t border_color = colors.bar_bg;
|
color_t border_color = bar_color;
|
||||||
if (block->urgent) {
|
if (block->urgent) {
|
||||||
border_color = colors.urgent_ws_border;
|
border_color = colors.urgent_ws_border;
|
||||||
bg_color = colors.urgent_ws_bg;
|
bg_color = colors.urgent_ws_bg;
|
||||||
|
@ -306,7 +315,7 @@ void draw_statusline(i3_output *output, uint32_t clip_left, bool use_short_text)
|
||||||
/* If this is not the last block, draw a separator. */
|
/* If this is not the last block, draw a separator. */
|
||||||
if (TAILQ_NEXT(block, blocks) != NULL) {
|
if (TAILQ_NEXT(block, blocks) != NULL) {
|
||||||
x += block->sep_block_width;
|
x += block->sep_block_width;
|
||||||
draw_separator(output, x, block);
|
draw_separator(output, x, block, use_focus_colors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,6 +421,12 @@ void init_colors(const struct xcb_color_strings_t *new_colors) {
|
||||||
PARSE_COLOR_FALLBACK(binding_mode_fg, urgent_ws_fg);
|
PARSE_COLOR_FALLBACK(binding_mode_fg, urgent_ws_fg);
|
||||||
PARSE_COLOR_FALLBACK(binding_mode_bg, urgent_ws_bg);
|
PARSE_COLOR_FALLBACK(binding_mode_bg, urgent_ws_bg);
|
||||||
PARSE_COLOR_FALLBACK(binding_mode_border, urgent_ws_border);
|
PARSE_COLOR_FALLBACK(binding_mode_border, urgent_ws_border);
|
||||||
|
|
||||||
|
/* Similarly, for unspecified focused bar colors, we fall back to the
|
||||||
|
* regular bar colors. */
|
||||||
|
PARSE_COLOR_FALLBACK(focus_bar_fg, bar_fg);
|
||||||
|
PARSE_COLOR_FALLBACK(focus_bar_bg, bar_bg);
|
||||||
|
PARSE_COLOR_FALLBACK(focus_sep_fg, sep_fg);
|
||||||
#undef PARSE_COLOR_FALLBACK
|
#undef PARSE_COLOR_FALLBACK
|
||||||
|
|
||||||
init_tray_colors();
|
init_tray_colors();
|
||||||
|
@ -1826,8 +1841,11 @@ void draw_bars(bool unhide) {
|
||||||
reconfig_windows(false);
|
reconfig_windows(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool use_focus_colors = output_has_focus(outputs_walk);
|
||||||
|
|
||||||
/* First things first: clear the backbuffer */
|
/* First things first: clear the backbuffer */
|
||||||
draw_util_clear_surface(&(outputs_walk->buffer), colors.bar_bg);
|
draw_util_clear_surface(&(outputs_walk->buffer),
|
||||||
|
(use_focus_colors ? colors.focus_bar_bg : colors.bar_bg));
|
||||||
|
|
||||||
if (!config.disable_ws) {
|
if (!config.disable_ws) {
|
||||||
i3_ws *ws_walk;
|
i3_ws *ws_walk;
|
||||||
|
@ -1928,7 +1946,7 @@ void draw_bars(bool unhide) {
|
||||||
int16_t visible_statusline_width = MIN(statusline_width, max_statusline_width);
|
int16_t visible_statusline_width = MIN(statusline_width, max_statusline_width);
|
||||||
int x_dest = outputs_walk->rect.w - tray_width - logical_px(sb_hoff_px) - visible_statusline_width;
|
int x_dest = outputs_walk->rect.w - tray_width - logical_px(sb_hoff_px) - visible_statusline_width;
|
||||||
|
|
||||||
draw_statusline(outputs_walk, clip_left, use_short_text);
|
draw_statusline(outputs_walk, clip_left, use_focus_colors, use_short_text);
|
||||||
draw_util_copy_surface(&outputs_walk->statusline_buffer, &outputs_walk->buffer, 0, 0,
|
draw_util_copy_surface(&outputs_walk->statusline_buffer, &outputs_walk->buffer, 0, 0,
|
||||||
x_dest, 0, visible_statusline_width, (int16_t)bar_height);
|
x_dest, 0, visible_statusline_width, (int16_t)bar_height);
|
||||||
|
|
||||||
|
|
|
@ -323,6 +323,10 @@ struct Barconfig {
|
||||||
char *statusline;
|
char *statusline;
|
||||||
char *separator;
|
char *separator;
|
||||||
|
|
||||||
|
char *focused_background;
|
||||||
|
char *focused_statusline;
|
||||||
|
char *focused_separator;
|
||||||
|
|
||||||
char *focused_workspace_border;
|
char *focused_workspace_border;
|
||||||
char *focused_workspace_bg;
|
char *focused_workspace_bg;
|
||||||
char *focused_workspace_text;
|
char *focused_workspace_text;
|
||||||
|
|
|
@ -520,7 +520,7 @@ state BAR_COLORS:
|
||||||
end ->
|
end ->
|
||||||
'#' -> BAR_COLORS_IGNORE_LINE
|
'#' -> BAR_COLORS_IGNORE_LINE
|
||||||
'set' -> BAR_COLORS_IGNORE_LINE
|
'set' -> BAR_COLORS_IGNORE_LINE
|
||||||
colorclass = 'background', 'statusline', 'separator'
|
colorclass = 'background', 'statusline', 'separator', 'focused_background', 'focused_statusline', 'focused_separator'
|
||||||
-> BAR_COLORS_SINGLE
|
-> BAR_COLORS_SINGLE
|
||||||
colorclass = 'focused_workspace', 'active_workspace', 'inactive_workspace', 'urgent_workspace', 'binding_mode'
|
colorclass = 'focused_workspace', 'active_workspace', 'inactive_workspace', 'urgent_workspace', 'binding_mode'
|
||||||
-> BAR_COLORS_BORDER
|
-> BAR_COLORS_BORDER
|
||||||
|
|
|
@ -118,6 +118,10 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
|
||||||
FREE(barconfig->font);
|
FREE(barconfig->font);
|
||||||
FREE(barconfig->colors.background);
|
FREE(barconfig->colors.background);
|
||||||
FREE(barconfig->colors.statusline);
|
FREE(barconfig->colors.statusline);
|
||||||
|
FREE(barconfig->colors.separator);
|
||||||
|
FREE(barconfig->colors.focused_background);
|
||||||
|
FREE(barconfig->colors.focused_statusline);
|
||||||
|
FREE(barconfig->colors.focused_separator);
|
||||||
FREE(barconfig->colors.focused_workspace_border);
|
FREE(barconfig->colors.focused_workspace_border);
|
||||||
FREE(barconfig->colors.focused_workspace_bg);
|
FREE(barconfig->colors.focused_workspace_bg);
|
||||||
FREE(barconfig->colors.focused_workspace_text);
|
FREE(barconfig->colors.focused_workspace_text);
|
||||||
|
|
|
@ -533,8 +533,14 @@ CFGFUN(bar_color_single, const char *colorclass, const char *color) {
|
||||||
current_bar.colors.background = sstrdup(color);
|
current_bar.colors.background = sstrdup(color);
|
||||||
else if (strcmp(colorclass, "separator") == 0)
|
else if (strcmp(colorclass, "separator") == 0)
|
||||||
current_bar.colors.separator = sstrdup(color);
|
current_bar.colors.separator = sstrdup(color);
|
||||||
else
|
else if (strcmp(colorclass, "statusline") == 0)
|
||||||
current_bar.colors.statusline = sstrdup(color);
|
current_bar.colors.statusline = sstrdup(color);
|
||||||
|
else if (strcmp(colorclass, "focused_background") == 0)
|
||||||
|
current_bar.colors.focused_background = sstrdup(color);
|
||||||
|
else if (strcmp(colorclass, "focused_separator") == 0)
|
||||||
|
current_bar.colors.focused_separator = sstrdup(color);
|
||||||
|
else
|
||||||
|
current_bar.colors.focused_statusline = sstrdup(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFGFUN(bar_status_command, const char *command) {
|
CFGFUN(bar_status_command, const char *command) {
|
||||||
|
|
|
@ -663,6 +663,9 @@ static void dump_bar_config(yajl_gen gen, Barconfig *config) {
|
||||||
YSTR_IF_SET(background);
|
YSTR_IF_SET(background);
|
||||||
YSTR_IF_SET(statusline);
|
YSTR_IF_SET(statusline);
|
||||||
YSTR_IF_SET(separator);
|
YSTR_IF_SET(separator);
|
||||||
|
YSTR_IF_SET(focused_background);
|
||||||
|
YSTR_IF_SET(focused_statusline);
|
||||||
|
YSTR_IF_SET(focused_separator);
|
||||||
YSTR_IF_SET(focused_workspace_border);
|
YSTR_IF_SET(focused_workspace_border);
|
||||||
YSTR_IF_SET(focused_workspace_bg);
|
YSTR_IF_SET(focused_workspace_bg);
|
||||||
YSTR_IF_SET(focused_workspace_text);
|
YSTR_IF_SET(focused_workspace_text);
|
||||||
|
|
|
@ -109,6 +109,9 @@ bar {
|
||||||
colors {
|
colors {
|
||||||
background #ff0000
|
background #ff0000
|
||||||
statusline #00ff00
|
statusline #00ff00
|
||||||
|
focused_background #cc0000
|
||||||
|
focused_statusline #cccc00
|
||||||
|
focused_separator #0000cc
|
||||||
|
|
||||||
focused_workspace #4c7899 #285577 #ffffff
|
focused_workspace #4c7899 #285577 #ffffff
|
||||||
active_workspace #333333 #222222 #888888
|
active_workspace #333333 #222222 #888888
|
||||||
|
@ -143,6 +146,9 @@ is_deeply($bar_config->{colors},
|
||||||
{
|
{
|
||||||
background => '#ff0000',
|
background => '#ff0000',
|
||||||
statusline => '#00ff00',
|
statusline => '#00ff00',
|
||||||
|
focused_background => '#cc0000',
|
||||||
|
focused_statusline=> '#cccc00',
|
||||||
|
focused_separator => '#0000cc',
|
||||||
focused_workspace_border => '#4c7899',
|
focused_workspace_border => '#4c7899',
|
||||||
focused_workspace_text => '#ffffff',
|
focused_workspace_text => '#ffffff',
|
||||||
focused_workspace_bg => '#285577',
|
focused_workspace_bg => '#285577',
|
||||||
|
|
Loading…
Reference in New Issue