Re-implement bar borders (by Angelo Haller)

This re-introduces borders around the workspace buttons in i3bar.
No additional pixels will be consumed (you will not lose any space for your
windows).
This commit is contained in:
Michael Stapelberg 2012-01-20 21:36:50 +00:00
parent 57bf93ebaf
commit 31b7ec29fd
10 changed files with 107 additions and 51 deletions

View File

@ -998,19 +998,19 @@ background::
statusline:: statusline::
Text color to be used for the statusline. Text color to be used for the statusline.
focused_workspace:: focused_workspace::
Text color/background color for a workspace button when the workspace Border, background and text color for a workspace button when the workspace
has focus. has focus.
active_workspace:: active_workspace::
Text color/background color for a workspace button when the workspace Border, background and text color for a workspace button when the workspace
is active (visible) on some output, but the focus is on another one. is active (visible) on some output, but the focus is on another one.
You can only tell this apart from the focused workspace when you are You can only tell this apart from the focused workspace when you are
using multiple monitors. using multiple monitors.
inactive_workspace:: inactive_workspace::
Text color/background color for a workspace button when the workspace Border, background and text color for a workspace button when the workspace
does not have focus and is not active (visible) on any output. This does not have focus and is not active (visible) on any output. This
will be the case for most workspaces. will be the case for most workspaces.
urgent_workspace:: urgent_workspace::
Text color/background color for workspaces which contain at least one Border, background and text color for a workspace button when the workspace
window with the urgency hint set. window with the urgency hint set.
*Syntax*: *Syntax*:
@ -1019,21 +1019,21 @@ colors {
background <color> background <color>
statusline <color> statusline <color>
colorclass <foreground> <background> colorclass <border> <background> <text>
} }
---------------------------------------- ----------------------------------------
*Example*: *Example (default colors)*:
-------------------------------------- --------------------------------------
bar { bar {
colors { colors {
background #000000 background #000000
statusline #ffffff statusline #ffffff
focused_workspace #ffffff #285577 focused_workspace #4c7899 #285577 #ffffff
active_workspace #ffffff #333333 active_workspace #333333 #5f676a #ffffff
inactive_workspace #888888 #222222 inactive_workspace #333333 #222222 #888888
urgent_workspace #ffffff #900000 urgent_workspace #2f343a #900000 #ffffff
} }
} }
-------------------------------------- --------------------------------------

View File

@ -30,12 +30,16 @@ struct xcb_color_strings_t {
char *bar_bg; char *bar_bg;
char *active_ws_fg; char *active_ws_fg;
char *active_ws_bg; char *active_ws_bg;
char *active_ws_border;
char *inactive_ws_fg; char *inactive_ws_fg;
char *inactive_ws_bg; char *inactive_ws_bg;
char *inactive_ws_border;
char *focus_ws_bg; char *focus_ws_bg;
char *focus_ws_fg; char *focus_ws_fg;
char *focus_ws_border;
char *urgent_ws_bg; char *urgent_ws_bg;
char *urgent_ws_fg; char *urgent_ws_fg;
char *urgent_ws_border;
}; };
typedef struct xcb_colors_t xcb_colors_t; typedef struct xcb_colors_t xcb_colors_t;

View File

@ -161,14 +161,18 @@ static int config_string_cb(void *params_, const unsigned char *val, unsigned in
COLOR(statusline, bar_fg); COLOR(statusline, bar_fg);
COLOR(background, bar_bg); COLOR(background, bar_bg);
COLOR(focused_workspace_border, focus_ws_border);
COLOR(focused_workspace_background, focus_ws_bg);
COLOR(focused_workspace_text, focus_ws_fg); COLOR(focused_workspace_text, focus_ws_fg);
COLOR(focused_workspace_bg, focus_ws_bg); COLOR(active_workspace_border, active_ws_border);
COLOR(active_workspace_background, active_ws_bg);
COLOR(active_workspace_text, active_ws_fg); COLOR(active_workspace_text, active_ws_fg);
COLOR(active_workspace_bg, active_ws_bg); COLOR(inactive_workspace_border, inactive_ws_border);
COLOR(inactive_workspace_background, inactive_ws_bg);
COLOR(inactive_workspace_text, inactive_ws_fg); COLOR(inactive_workspace_text, inactive_ws_fg);
COLOR(inactive_workspace_bg, inactive_ws_bg); COLOR(urgent_workspace_border, urgent_ws_border);
COLOR(urgent_workspace_background, urgent_ws_bg);
COLOR(urgent_workspace_text, urgent_ws_fg); COLOR(urgent_workspace_text, urgent_ws_fg);
COLOR(urgent_workspace_bg, urgent_ws_bg);
printf("got unexpected string %.*s for cur_key = %s\n", len, val, cur_key); printf("got unexpected string %.*s for cur_key = %s\n", len, val, cur_key);
@ -258,12 +262,16 @@ void free_colors(struct xcb_color_strings_t *colors) {
FREE_COLOR(bar_bg); FREE_COLOR(bar_bg);
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(inactive_ws_fg); FREE_COLOR(inactive_ws_fg);
FREE_COLOR(inactive_ws_bg); FREE_COLOR(inactive_ws_bg);
FREE_COLOR(inactive_ws_border);
FREE_COLOR(urgent_ws_fg); FREE_COLOR(urgent_ws_fg);
FREE_COLOR(urgent_ws_bg); FREE_COLOR(urgent_ws_bg);
FREE_COLOR(urgent_ws_border);
FREE_COLOR(focus_ws_fg); FREE_COLOR(focus_ws_fg);
FREE_COLOR(focus_ws_bg); FREE_COLOR(focus_ws_bg);
FREE_COLOR(focus_ws_border);
#undef FREE_COLOR #undef FREE_COLOR
} }

View File

@ -79,12 +79,16 @@ struct xcb_colors_t {
uint32_t bar_bg; uint32_t bar_bg;
uint32_t active_ws_fg; uint32_t active_ws_fg;
uint32_t active_ws_bg; uint32_t active_ws_bg;
uint32_t active_ws_border;
uint32_t inactive_ws_fg; uint32_t inactive_ws_fg;
uint32_t inactive_ws_bg; uint32_t inactive_ws_bg;
uint32_t inactive_ws_border;
uint32_t urgent_ws_bg; uint32_t urgent_ws_bg;
uint32_t urgent_ws_fg; uint32_t urgent_ws_fg;
uint32_t urgent_ws_border;
uint32_t focus_ws_bg; uint32_t focus_ws_bg;
uint32_t focus_ws_fg; uint32_t focus_ws_fg;
uint32_t focus_ws_border;
}; };
struct xcb_colors_t colors; struct xcb_colors_t colors;
@ -205,12 +209,16 @@ void init_colors(const struct xcb_color_strings_t *new_colors) {
PARSE_COLOR(bar_bg, "#000000"); PARSE_COLOR(bar_bg, "#000000");
PARSE_COLOR(active_ws_fg, "#FFFFFF"); PARSE_COLOR(active_ws_fg, "#FFFFFF");
PARSE_COLOR(active_ws_bg, "#333333"); PARSE_COLOR(active_ws_bg, "#333333");
PARSE_COLOR(active_ws_border, "#333333");
PARSE_COLOR(inactive_ws_fg, "#888888"); PARSE_COLOR(inactive_ws_fg, "#888888");
PARSE_COLOR(inactive_ws_bg, "#222222"); PARSE_COLOR(inactive_ws_bg, "#222222");
PARSE_COLOR(inactive_ws_border, "#333333");
PARSE_COLOR(urgent_ws_fg, "#FFFFFF"); PARSE_COLOR(urgent_ws_fg, "#FFFFFF");
PARSE_COLOR(urgent_ws_bg, "#900000"); PARSE_COLOR(urgent_ws_bg, "#900000");
PARSE_COLOR(urgent_ws_border, "#2f343a");
PARSE_COLOR(focus_ws_fg, "#FFFFFF"); PARSE_COLOR(focus_ws_fg, "#FFFFFF");
PARSE_COLOR(focus_ws_bg, "#285577"); PARSE_COLOR(focus_ws_bg, "#285577");
PARSE_COLOR(focus_ws_border, "#4c7899");
#undef PARSE_COLOR #undef PARSE_COLOR
} }
@ -1367,29 +1375,44 @@ void draw_bars() {
DLOG("Drawing Button for WS %s at x = %d\n", ws_walk->name, i); DLOG("Drawing Button for WS %s at x = %d\n", ws_walk->name, i);
uint32_t fg_color = colors.inactive_ws_fg; uint32_t fg_color = colors.inactive_ws_fg;
uint32_t bg_color = colors.inactive_ws_bg; uint32_t bg_color = colors.inactive_ws_bg;
uint32_t border_color = colors.inactive_ws_border;
if (ws_walk->visible) { if (ws_walk->visible) {
if (!ws_walk->focused) { if (!ws_walk->focused) {
fg_color = colors.active_ws_fg; fg_color = colors.active_ws_fg;
bg_color = colors.active_ws_bg; bg_color = colors.active_ws_bg;
border_color = colors.active_ws_border;
} else { } else {
fg_color = colors.focus_ws_fg; fg_color = colors.focus_ws_fg;
bg_color = colors.focus_ws_bg; bg_color = colors.focus_ws_bg;
border_color = colors.focus_ws_border;
} }
} }
if (ws_walk->urgent) { if (ws_walk->urgent) {
DLOG("WS %s is urgent!\n", ws_walk->name); DLOG("WS %s is urgent!\n", ws_walk->name);
fg_color = colors.urgent_ws_fg; fg_color = colors.urgent_ws_fg;
bg_color = colors.urgent_ws_bg; bg_color = colors.urgent_ws_bg;
border_color = colors.urgent_ws_border;
/* The urgent-hint should get noticed, so we unhide the bars shortly */ /* The urgent-hint should get noticed, so we unhide the bars shortly */
unhide_bars(); unhide_bars();
} }
uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND; uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
uint32_t vals_border[] = { border_color, border_color };
xcb_change_gc(xcb_connection,
outputs_walk->bargc,
mask,
vals_border);
xcb_rectangle_t rect_border = { i + 1, 0, ws_walk->name_width + 10, font.height + 4 };
xcb_poly_fill_rectangle(xcb_connection,
outputs_walk->buffer,
outputs_walk->bargc,
1,
&rect_border);
uint32_t vals[] = { bg_color, bg_color }; uint32_t vals[] = { bg_color, bg_color };
xcb_change_gc(xcb_connection, xcb_change_gc(xcb_connection,
outputs_walk->bargc, outputs_walk->bargc,
mask, mask,
vals); vals);
xcb_rectangle_t rect = { i + 1, 1, ws_walk->name_width + 8, font.height + 4 }; xcb_rectangle_t rect = { i + 2, 1, ws_walk->name_width + 8, font.height + 2 };
xcb_poly_fill_rectangle(xcb_connection, xcb_poly_fill_rectangle(xcb_connection,
outputs_walk->buffer, outputs_walk->buffer,
outputs_walk->bargc, outputs_walk->bargc,
@ -1397,8 +1420,8 @@ void draw_bars() {
&rect); &rect);
set_font_colors(outputs_walk->bargc, fg_color, bg_color); set_font_colors(outputs_walk->bargc, fg_color, bg_color);
draw_text((char*)ws_walk->ucs2_name, ws_walk->name_glyphs, true, draw_text((char*)ws_walk->ucs2_name, ws_walk->name_glyphs, true,
outputs_walk->buffer, outputs_walk->bargc, i + 5, 2, ws_walk->name_width); outputs_walk->buffer, outputs_walk->bargc, i + 6, 2, ws_walk->name_width);
i += 10 + ws_walk->name_width; i += 12 + ws_walk->name_width;
} }
i = 0; i = 0;

View File

@ -2,7 +2,7 @@
* vim:ts=4:sw=4:expandtab * vim:ts=4:sw=4:expandtab
* *
* i3 - an improved dynamic tiling window manager * i3 - an improved dynamic tiling window manager
* © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE) * © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE)
* *
* include/config.h: Contains all structs/variables for the configurable * include/config.h: Contains all structs/variables for the configurable
* part of i3 as well as functions handling the configuration file (calling * part of i3 as well as functions handling the configuration file (calling
@ -237,17 +237,21 @@ struct Barconfig {
char *background; char *background;
char *statusline; char *statusline;
char *focused_workspace_text; char *focused_workspace_border;
char *focused_workspace_bg; char *focused_workspace_bg;
char *focused_workspace_text;
char *active_workspace_text; char *active_workspace_border;
char *active_workspace_bg; char *active_workspace_bg;
char *active_workspace_text;
char *inactive_workspace_text; char *inactive_workspace_border;
char *inactive_workspace_bg; char *inactive_workspace_bg;
char *inactive_workspace_text;
char *urgent_workspace_text; char *urgent_workspace_border;
char *urgent_workspace_bg; char *urgent_workspace_bg;
char *urgent_workspace_text;
} colors; } colors;
TAILQ_ENTRY(Barconfig) configs; TAILQ_ENTRY(Barconfig) configs;

View File

@ -37,7 +37,8 @@ int yycolumn = 1;
yy_push_state(EAT_WHITESPACE); \ yy_push_state(EAT_WHITESPACE); \
} while (0) } while (0)
#define BAR_DOUBLE_COLOR do { \ #define BAR_TRIPLE_COLOR do { \
yy_push_state(BAR_COLOR); \
yy_push_state(BAR_COLOR); \ yy_push_state(BAR_COLOR); \
yy_push_state(BAR_COLOR); \ yy_push_state(BAR_COLOR); \
} while (0) } while (0)
@ -122,10 +123,10 @@ EOL (\r?\n)
<BAR_COLORS>^[ \t]*#[^\n]* { return TOKCOMMENT; } <BAR_COLORS>^[ \t]*#[^\n]* { return TOKCOMMENT; }
<BAR_COLORS>background { yy_push_state(BAR_COLOR); return TOK_BAR_COLOR_BACKGROUND; } <BAR_COLORS>background { yy_push_state(BAR_COLOR); return TOK_BAR_COLOR_BACKGROUND; }
<BAR_COLORS>statusline { yy_push_state(BAR_COLOR); return TOK_BAR_COLOR_STATUSLINE; } <BAR_COLORS>statusline { yy_push_state(BAR_COLOR); return TOK_BAR_COLOR_STATUSLINE; }
<BAR_COLORS>focused_workspace { BAR_DOUBLE_COLOR; return TOK_BAR_COLOR_FOCUSED_WORKSPACE; } <BAR_COLORS>focused_workspace { BAR_TRIPLE_COLOR; return TOK_BAR_COLOR_FOCUSED_WORKSPACE; }
<BAR_COLORS>active_workspace { BAR_DOUBLE_COLOR; return TOK_BAR_COLOR_ACTIVE_WORKSPACE; } <BAR_COLORS>active_workspace { BAR_TRIPLE_COLOR; return TOK_BAR_COLOR_ACTIVE_WORKSPACE; }
<BAR_COLORS>inactive_workspace { BAR_DOUBLE_COLOR; return TOK_BAR_COLOR_INACTIVE_WORKSPACE; } <BAR_COLORS>inactive_workspace { BAR_TRIPLE_COLOR; return TOK_BAR_COLOR_INACTIVE_WORKSPACE; }
<BAR_COLORS>urgent_workspace { BAR_DOUBLE_COLOR; return TOK_BAR_COLOR_URGENT_WORKSPACE; } <BAR_COLORS>urgent_workspace { BAR_TRIPLE_COLOR; return TOK_BAR_COLOR_URGENT_WORKSPACE; }
<BAR_COLOR>#[0-9a-fA-F]+ { yy_pop_state(); yylval.string = sstrdup(yytext); return HEXCOLOR; } <BAR_COLOR>#[0-9a-fA-F]+ { yy_pop_state(); yylval.string = sstrdup(yytext); return HEXCOLOR; }
<BAR,BAR_COLORS,BAR_MODE,BAR_MODIFIER,BAR_POSITION>[a-zA-Z]+ { yylval.string = sstrdup(yytext); return WORD; } <BAR,BAR_COLORS,BAR_MODE,BAR_MODIFIER,BAR_POSITION>[a-zA-Z]+ { yylval.string = sstrdup(yytext); return WORD; }

View File

@ -1208,38 +1208,42 @@ bar_color_statusline:
; ;
bar_color_focused_workspace: bar_color_focused_workspace:
TOK_BAR_COLOR_FOCUSED_WORKSPACE HEXCOLOR HEXCOLOR TOK_BAR_COLOR_FOCUSED_WORKSPACE HEXCOLOR HEXCOLOR HEXCOLOR
{ {
DLOG("focused_ws = %s and %s\n", $2, $3); DLOG("focused_ws = %s, %s and %s\n", $2, $3, $4);
current_bar.colors.focused_workspace_text = $2; current_bar.colors.focused_workspace_border = $2;
current_bar.colors.focused_workspace_bg = $3; current_bar.colors.focused_workspace_bg = $3;
current_bar.colors.focused_workspace_text = $4;
} }
; ;
bar_color_active_workspace: bar_color_active_workspace:
TOK_BAR_COLOR_ACTIVE_WORKSPACE HEXCOLOR HEXCOLOR TOK_BAR_COLOR_ACTIVE_WORKSPACE HEXCOLOR HEXCOLOR HEXCOLOR
{ {
DLOG("active_ws = %s and %s\n", $2, $3); DLOG("active_ws = %s, %s and %s\n", $2, $3, $4);
current_bar.colors.active_workspace_text = $2; current_bar.colors.active_workspace_border = $2;
current_bar.colors.active_workspace_bg = $3; current_bar.colors.active_workspace_bg = $3;
current_bar.colors.active_workspace_text = $4;
} }
; ;
bar_color_inactive_workspace: bar_color_inactive_workspace:
TOK_BAR_COLOR_INACTIVE_WORKSPACE HEXCOLOR HEXCOLOR TOK_BAR_COLOR_INACTIVE_WORKSPACE HEXCOLOR HEXCOLOR HEXCOLOR
{ {
DLOG("inactive_ws = %s and %s\n", $2, $3); DLOG("inactive_ws = %s, %s and %s\n", $2, $3, $4);
current_bar.colors.inactive_workspace_text = $2; current_bar.colors.inactive_workspace_border = $2;
current_bar.colors.inactive_workspace_bg = $3; current_bar.colors.inactive_workspace_bg = $3;
current_bar.colors.inactive_workspace_text = $4;
} }
; ;
bar_color_urgent_workspace: bar_color_urgent_workspace:
TOK_BAR_COLOR_URGENT_WORKSPACE HEXCOLOR HEXCOLOR TOK_BAR_COLOR_URGENT_WORKSPACE HEXCOLOR HEXCOLOR HEXCOLOR
{ {
DLOG("urgent_ws = %s and %s\n", $2, $3); DLOG("urgent_ws = %s, %s and %s\n", $2, $3, $4);
current_bar.colors.urgent_workspace_text = $2; current_bar.colors.urgent_workspace_border = $2;
current_bar.colors.urgent_workspace_bg = $3; current_bar.colors.urgent_workspace_bg = $3;
current_bar.colors.urgent_workspace_text = $4;
} }
; ;

View File

@ -311,14 +311,18 @@ 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.focused_workspace_text); FREE(barconfig->colors.focused_workspace_border);
FREE(barconfig->colors.focused_workspace_bg); FREE(barconfig->colors.focused_workspace_bg);
FREE(barconfig->colors.active_workspace_text); FREE(barconfig->colors.focused_workspace_text);
FREE(barconfig->colors.active_workspace_border);
FREE(barconfig->colors.active_workspace_bg); FREE(barconfig->colors.active_workspace_bg);
FREE(barconfig->colors.inactive_workspace_text); FREE(barconfig->colors.active_workspace_text);
FREE(barconfig->colors.inactive_workspace_border);
FREE(barconfig->colors.inactive_workspace_bg); FREE(barconfig->colors.inactive_workspace_bg);
FREE(barconfig->colors.urgent_workspace_text); FREE(barconfig->colors.inactive_workspace_text);
FREE(barconfig->colors.urgent_workspace_border);
FREE(barconfig->colors.urgent_workspace_bg); FREE(barconfig->colors.urgent_workspace_bg);
FREE(barconfig->colors.urgent_workspace_text);
TAILQ_REMOVE(&barconfigs, barconfig, configs); TAILQ_REMOVE(&barconfigs, barconfig, configs);
FREE(barconfig); FREE(barconfig);
} }

View File

@ -646,14 +646,18 @@ IPC_HANDLER(get_bar_config) {
y(map_open); y(map_open);
YSTR_IF_SET(background); YSTR_IF_SET(background);
YSTR_IF_SET(statusline); YSTR_IF_SET(statusline);
YSTR_IF_SET(focused_workspace_text); YSTR_IF_SET(focused_workspace_border);
YSTR_IF_SET(focused_workspace_bg); YSTR_IF_SET(focused_workspace_bg);
YSTR_IF_SET(active_workspace_text); YSTR_IF_SET(focused_workspace_text);
YSTR_IF_SET(active_workspace_border);
YSTR_IF_SET(active_workspace_bg); YSTR_IF_SET(active_workspace_bg);
YSTR_IF_SET(inactive_workspace_text); YSTR_IF_SET(active_workspace_text);
YSTR_IF_SET(inactive_workspace_border);
YSTR_IF_SET(inactive_workspace_bg); YSTR_IF_SET(inactive_workspace_bg);
YSTR_IF_SET(urgent_workspace_text); YSTR_IF_SET(inactive_workspace_text);
YSTR_IF_SET(urgent_workspace_border);
YSTR_IF_SET(urgent_workspace_bg); YSTR_IF_SET(urgent_workspace_bg);
YSTR_IF_SET(urgent_workspace_text);
y(map_close); y(map_close);
#undef YSTR_IF_SET #undef YSTR_IF_SET

View File

@ -92,10 +92,10 @@ bar {
background #ff0000 background #ff0000
statusline #00ff00 statusline #00ff00
focused_workspace #ffffff #285577 focused_workspace #4c7899 #285577 #ffffff
active_workspace #888888 #222222 active_workspace #333333 #222222 #888888
inactive_workspace #888888 #222222 inactive_workspace #333333 #222222 #888888
urgent_workspace #ffffff #900000 urgent_workspace #2f343a #900000 #ffffff
} }
} }
EOT EOT
@ -122,12 +122,16 @@ is_deeply($bar_config->{colors},
{ {
background => '#ff0000', background => '#ff0000',
statusline => '#00ff00', statusline => '#00ff00',
focused_workspace_border => '#4c7899',
focused_workspace_text => '#ffffff', focused_workspace_text => '#ffffff',
focused_workspace_bg => '#285577', focused_workspace_bg => '#285577',
active_workspace_border => '#333333',
active_workspace_text => '#888888', active_workspace_text => '#888888',
active_workspace_bg => '#222222', active_workspace_bg => '#222222',
inactive_workspace_border => '#333333',
inactive_workspace_text => '#888888', inactive_workspace_text => '#888888',
inactive_workspace_bg => '#222222', inactive_workspace_bg => '#222222',
urgent_workspace_border => '#2f343a',
urgent_workspace_text => '#ffffff', urgent_workspace_text => '#ffffff',
urgent_workspace_bg => '#900000', urgent_workspace_bg => '#900000',
}, 'colors ok'); }, 'colors ok');