Implement highlighting right/bottom borders of splitted windows

Fixes #299
This commit is contained in:
Michael Stapelberg 2012-01-22 11:22:15 +00:00
parent 318d4fdeef
commit f9bc434e2a
6 changed files with 63 additions and 21 deletions

View File

@ -591,7 +591,7 @@ You can change all colors which i3 uses to draw the window decorations.
*Syntax*: *Syntax*:
-------------------------------------------- --------------------------------------------
colorclass border background text colorclass border background text indicator
-------------------------------------------- --------------------------------------------
Where colorclass can be one of: Where colorclass can be one of:
@ -624,18 +624,24 @@ area of the terminal and the i3 border.
Colors are in HTML hex format (#rrggbb), see the following example: Colors are in HTML hex format (#rrggbb), see the following example:
*Examples (default colors)*: *Examples (default colors)*:
----------------------------------------------- ---------------------------------------------------------
# class border backgr. text # class border backgr. text indicator
client.focused #4c7899 #285577 #ffffff client.focused #4c7899 #285577 #ffffff #2e9ef4
client.focused_inactive #333333 #5f676a #ffffff client.focused_inactive #333333 #5f676a #ffffff #484e50
client.unfocused #333333 #222222 #888888 client.unfocused #333333 #222222 #888888 #292d2e
client.urgent #2f343a #900000 #ffffff client.urgent #2f343a #900000 #ffffff #900000
----------------------------------------------- ---------------------------------------------------------
Note that for the window decorations, the color around the child window is the Note that for the window decorations, the color around the child window is the
background color, and the border color is only the two thin lines at the top of background color, and the border color is only the two thin lines at the top of
the window. the window.
The indicator color is used for indicating where a new window will be opened.
For horizontal split containers, the right border will be painted in indicator
color, for vertical split containers, the bottom border. This only applies to
single windows within a split container, which are otherwise indistinguishable
from single windows outside of a split container.
=== Interprocess communication === Interprocess communication
i3 uses unix sockets to provide an IPC interface. This allows third-party i3 uses unix sockets to provide an IPC interface. This allows third-party

View File

@ -54,6 +54,7 @@ struct Colortriple {
uint32_t border; uint32_t border;
uint32_t background; uint32_t background;
uint32_t text; uint32_t text;
uint32_t indicator;
}; };
/** /**

View File

@ -160,6 +160,12 @@ EOL (\r?\n)
<OUTPUT_COND>[a-zA-Z0-9_-]+ { yy_pop_state(); yylval.string = sstrdup(yytext); return OUTPUT; } <OUTPUT_COND>[a-zA-Z0-9_-]+ { yy_pop_state(); yylval.string = sstrdup(yytext); return OUTPUT; }
^[ \t]*#[^\n]* { return TOKCOMMENT; } ^[ \t]*#[^\n]* { return TOKCOMMENT; }
<COLOR_COND>#[0-9a-fA-F]+ { yy_pop_state(); yylval.string = sstrdup(yytext); return HEXCOLOR; } <COLOR_COND>#[0-9a-fA-F]+ { yy_pop_state(); yylval.string = sstrdup(yytext); return HEXCOLOR; }
<COLOR_COND>{EOL} {
yy_pop_state();
FREE(context->line_copy);
context->line_number++;
yy_push_state(BUFFER_LINE);
}
<ASSIGN_TARGET_COND>[ \t]*→[ \t]* { BEGIN(WANT_STRING); } <ASSIGN_TARGET_COND>[ \t]*→[ \t]* { BEGIN(WANT_STRING); }
<ASSIGN_TARGET_COND>[ \t]+ { BEGIN(WANT_STRING); } <ASSIGN_TARGET_COND>[ \t]+ { BEGIN(WANT_STRING); }
<EXEC>--no-startup-id { printf("no startup id\n"); yy_pop_state(); return TOK_NO_STARTUP_ID; } <EXEC>--no-startup-id { printf("no startup id\n"); yy_pop_state(); return TOK_NO_STARTUP_ID; }
@ -220,10 +226,10 @@ rows { /* yylval.number = STACK_LIMIT_ROWS; */return
exec { WS_STRING; yy_push_state(EXEC); yy_push_state(EAT_WHITESPACE); return TOKEXEC; } exec { WS_STRING; yy_push_state(EXEC); yy_push_state(EAT_WHITESPACE); return TOKEXEC; }
exec_always { WS_STRING; yy_push_state(EXEC); yy_push_state(EAT_WHITESPACE); return TOKEXEC_ALWAYS; } exec_always { WS_STRING; yy_push_state(EXEC); yy_push_state(EAT_WHITESPACE); return TOKEXEC_ALWAYS; }
client.background { yy_push_state(COLOR_COND); yylval.single_color = &config.client.background; return TOKSINGLECOLOR; } client.background { yy_push_state(COLOR_COND); yylval.single_color = &config.client.background; return TOKSINGLECOLOR; }
client.focused { yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yylval.color = &config.client.focused; return TOKCOLOR; } client.focused { yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yylval.color = &config.client.focused; return TOKCOLOR; }
client.focused_inactive { yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yylval.color = &config.client.focused_inactive; return TOKCOLOR; } client.focused_inactive { yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yylval.color = &config.client.focused_inactive; return TOKCOLOR; }
client.unfocused { yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yylval.color = &config.client.unfocused; return TOKCOLOR; } client.unfocused { yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yylval.color = &config.client.unfocused; return TOKCOLOR; }
client.urgent { yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yylval.color = &config.client.urgent; return TOKCOLOR; } client.urgent { yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yylval.color = &config.client.urgent; return TOKCOLOR; }
bar.focused { yy_push_state(COLOR_COND); yylval.color = &config.bar.focused; return TOKCOLOR; } bar.focused { yy_push_state(COLOR_COND); yylval.color = &config.bar.focused; return TOKCOLOR; }
bar.unfocused { yy_push_state(COLOR_COND); yylval.color = &config.bar.unfocused; return TOKCOLOR; } bar.unfocused { yy_push_state(COLOR_COND); yylval.color = &config.bar.unfocused; return TOKCOLOR; }
bar.urgent { yy_push_state(COLOR_COND); yylval.color = &config.bar.urgent; return TOKCOLOR; } bar.urgent { yy_push_state(COLOR_COND); yylval.color = &config.bar.urgent; return TOKCOLOR; }

View File

@ -1649,6 +1649,15 @@ color:
dest->background = $3; dest->background = $3;
dest->text = $4; dest->text = $4;
} }
| TOKCOLOR colorpixel colorpixel colorpixel colorpixel
{
struct Colortriple *dest = $1;
dest->border = $2;
dest->background = $3;
dest->text = $4;
dest->indicator = $5;
}
; ;
colorpixel: colorpixel:

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)
* *
* config.c: Configuration file (calling the parser (src/cfgparse.y) with the * config.c: Configuration file (calling the parser (src/cfgparse.y) with the
* correct path, switching key bindings mode). * correct path, switching key bindings mode).
@ -361,21 +361,24 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
memset(&config, 0, sizeof(config)); memset(&config, 0, sizeof(config));
/* Initialize default colors */ /* Initialize default colors */
#define INIT_COLOR(x, cborder, cbackground, ctext) \ #define INIT_COLOR(x, cborder, cbackground, ctext, cindicator) \
do { \ do { \
x.border = get_colorpixel(cborder); \ x.border = get_colorpixel(cborder); \
x.background = get_colorpixel(cbackground); \ x.background = get_colorpixel(cbackground); \
x.text = get_colorpixel(ctext); \ x.text = get_colorpixel(ctext); \
x.indicator = get_colorpixel(cindicator); \
} while (0) } while (0)
config.client.background = get_colorpixel("#000000"); config.client.background = get_colorpixel("#000000");
INIT_COLOR(config.client.focused, "#4c7899", "#285577", "#ffffff"); INIT_COLOR(config.client.focused, "#4c7899", "#285577", "#ffffff", "#2e9ef4");
INIT_COLOR(config.client.focused_inactive, "#333333", "#5f676a", "#ffffff"); INIT_COLOR(config.client.focused_inactive, "#333333", "#5f676a", "#ffffff", "#484e50");
INIT_COLOR(config.client.unfocused, "#333333", "#222222", "#888888"); INIT_COLOR(config.client.unfocused, "#333333", "#222222", "#888888", "#292d2e");
INIT_COLOR(config.client.urgent, "#2f343a", "#900000", "#ffffff"); INIT_COLOR(config.client.urgent, "#2f343a", "#900000", "#ffffff", "#900000");
INIT_COLOR(config.bar.focused, "#4c7899", "#285577", "#ffffff");
INIT_COLOR(config.bar.unfocused, "#333333", "#222222", "#888888"); /* the last argument (indicator color) is ignored for bar colors */
INIT_COLOR(config.bar.urgent, "#2f343a", "#900000", "#ffffff"); INIT_COLOR(config.bar.focused, "#4c7899", "#285577", "#ffffff", "#000000");
INIT_COLOR(config.bar.unfocused, "#333333", "#222222", "#888888", "#000000");
INIT_COLOR(config.bar.urgent, "#2f343a", "#900000", "#ffffff", "#000000");
config.default_border = BS_NORMAL; config.default_border = BS_NORMAL;
config.default_floating_border = BS_NORMAL; config.default_floating_border = BS_NORMAL;

17
src/x.c
View File

@ -382,6 +382,23 @@ void x_draw_decoration(Con *con) {
xcb_rectangle_t topline = { br.x, 0, con->rect.width + br.width + br.x, br.y }; xcb_rectangle_t topline = { br.x, 0, con->rect.width + br.width + br.x, br.y };
xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, &topline); xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, &topline);
} }
/* Highlight the side of the border at which the next window will be
* opened if we are rendering a single window within a split container
* (which is undistinguishable from a single window outside a split
* container otherwise. */
if (TAILQ_NEXT(con, nodes) == NULL &&
TAILQ_PREV(con, nodes_head, nodes) == NULL &&
con->parent->type != CT_FLOATING_CON) {
xcb_change_gc(conn, con->pm_gc, XCB_GC_FOREGROUND, (uint32_t[]){ p->color->indicator });
if (con_orientation(con->parent) == HORIZ)
xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, (xcb_rectangle_t[]){
{ r->width + br.width + br.x, 0, r->width, r->height + br.height } });
else
xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, (xcb_rectangle_t[]){
{ br.x, r->height + br.height + br.y, r->width - (2 * br.x), r->height } });
}
} }
/* if this is a borderless/1pixel window, we dont need to render the /* if this is a borderless/1pixel window, we dont need to render the