create hide_edge_borders option

This commit is contained in:
Iakov Davydov 2012-07-22 13:57:07 +04:00 committed by Michael Stapelberg
parent 48f1e383ca
commit f27735f620
8 changed files with 92 additions and 8 deletions

View File

@ -468,6 +468,22 @@ new_window <normal|1pixel|none>
new_window 1pixel new_window 1pixel
--------------------- ---------------------
=== Hiding vertical borders
You can hide vertical borders adjacent to the screen edges using
+hide_edge_borders+. This is useful if you are using scrollbars. This option is
disabled by default.
*Syntax*:
----------------------------
hide_edge_borders <yes|no>
----------------------------
*Example*:
----------------------
hide_edge_borders yes
----------------------
=== Arbitrary commands for specific windows (for_window) === Arbitrary commands for specific windows (for_window)
With the +for_window+ command, you can let i3 execute any command when it With the +for_window+ command, you can let i3 execute any command when it

View File

@ -221,6 +221,12 @@ Con *con_descend_direction(Con *con, direction_t direction);
*/ */
Rect con_border_style_rect(Con *con); Rect con_border_style_rect(Con *con);
/**
* Returns adjacent borders of the window. We need this if hide_edge_borders is
* enabled.
*/
adjacent_t con_adjacent_borders(Con *con);
/** /**
* Use this function to get a containers border style. This is important * Use this function to get a containers border style. This is important
* because when inside a stack, the border style is always BS_NORMAL. * because when inside a stack, the border style is always BS_NORMAL.

View File

@ -108,6 +108,11 @@ struct Config {
* It is not planned to add any different focus models. */ * It is not planned to add any different focus models. */
bool disable_focus_follows_mouse; bool disable_focus_follows_mouse;
/** Remove vertical borders if they are adjacent to the screen edge.
* This is useful if you are reaching scrollbar on the edge of the
* screen. By default, this is disabled. */
bool hide_edge_borders;
/** By default, a workspace bar is drawn at the bottom of the screen. /** By default, a workspace bar is drawn at the bottom of the screen.
* If you want to have a more fancy bar, it is recommended to replace * If you want to have a more fancy bar, it is recommended to replace
* the whole bar by dzen2, for example using the i3-wsbar script which * the whole bar by dzen2, for example using the i3-wsbar script which

View File

@ -60,6 +60,11 @@ typedef enum { BS_NORMAL = 0, BS_NONE = 1, BS_1PIXEL = 2 } border_style_t;
* only this specific window or the whole X11 client */ * only this specific window or the whole X11 client */
typedef enum { DONT_KILL_WINDOW = 0, KILL_WINDOW = 1, KILL_CLIENT = 2 } kill_window_t; typedef enum { DONT_KILL_WINDOW = 0, KILL_WINDOW = 1, KILL_CLIENT = 2 } kill_window_t;
/** describes if the window is adjacent to the output (physical screen) edges. */
typedef enum { ADJ_NONE = 0,
ADJ_LEFT_SCREEN_EDGE = 1,
ADJ_RIGHT_SCREEN_EDGE = 2} adjacent_t;
enum { enum {
BIND_NONE = 0, BIND_NONE = 0,
BIND_SHIFT = XCB_MOD_MASK_SHIFT, /* (1 << 0) */ BIND_SHIFT = XCB_MOD_MASK_SHIFT, /* (1 << 0) */

View File

@ -200,6 +200,7 @@ new_float { return TOKNEWFLOAT; }
normal { return TOK_NORMAL; } normal { return TOK_NORMAL; }
none { return TOK_NONE; } none { return TOK_NONE; }
1pixel { return TOK_1PIXEL; } 1pixel { return TOK_1PIXEL; }
hide_edge_borders { return TOK_HIDE_EDGE_BORDERS; }
focus_follows_mouse { return TOKFOCUSFOLLOWSMOUSE; } focus_follows_mouse { return TOKFOCUSFOLLOWSMOUSE; }
force_focus_wrapping { return TOK_FORCE_FOCUS_WRAPPING; } force_focus_wrapping { return TOK_FORCE_FOCUS_WRAPPING; }
force_xinerama { return TOK_FORCE_XINERAMA; } force_xinerama { return TOK_FORCE_XINERAMA; }

View File

@ -735,6 +735,7 @@ void parse_file(const char *f) {
%token TOK_NORMAL "normal" %token TOK_NORMAL "normal"
%token TOK_NONE "none" %token TOK_NONE "none"
%token TOK_1PIXEL "1pixel" %token TOK_1PIXEL "1pixel"
%token TOK_HIDE_EDGE_BORDERS "hide_edge_borders"
%token TOKFOCUSFOLLOWSMOUSE "focus_follows_mouse" %token TOKFOCUSFOLLOWSMOUSE "focus_follows_mouse"
%token TOK_FORCE_FOCUS_WRAPPING "force_focus_wrapping" %token TOK_FORCE_FOCUS_WRAPPING "force_focus_wrapping"
%token TOK_FORCE_XINERAMA "force_xinerama" %token TOK_FORCE_XINERAMA "force_xinerama"
@ -833,6 +834,7 @@ line:
| workspace_layout | workspace_layout
| new_window | new_window
| new_float | new_float
| hide_edge_borders
| focus_follows_mouse | focus_follows_mouse
| force_focus_wrapping | force_focus_wrapping
| force_xinerama | force_xinerama
@ -1474,6 +1476,14 @@ bool:
} }
; ;
hide_edge_borders:
TOK_HIDE_EDGE_BORDERS bool
{
DLOG("hide edge borders = %d\n", $2);
config.hide_edge_borders = $2;
}
;
focus_follows_mouse: focus_follows_mouse:
TOKFOCUSFOLLOWSMOUSE bool TOKFOCUSFOLLOWSMOUSE bool
{ {

View File

@ -934,12 +934,32 @@ Con *con_descend_direction(Con *con, direction_t direction) {
* *
*/ */
Rect con_border_style_rect(Con *con) { Rect con_border_style_rect(Con *con) {
adjacent_t adjacent_to = ADJ_NONE;
Rect result;
if (config.hide_edge_borders)
adjacent_to = con_adjacent_borders(con);
switch (con_border_style(con)) { switch (con_border_style(con)) {
case BS_NORMAL: case BS_NORMAL:
return (Rect){2, 0, -(2 * 2), -2}; result = (Rect){2, 0, -(2 * 2), -2};
if (adjacent_to & ADJ_LEFT_SCREEN_EDGE) {
result.x -= 2;
result.width += 2;
}
if (adjacent_to & ADJ_RIGHT_SCREEN_EDGE) {
result.width += 2;
}
return result;
case BS_1PIXEL: case BS_1PIXEL:
return (Rect){1, 1, -2, -2}; result = (Rect){1, 1, -2, -2};
if (adjacent_to & ADJ_LEFT_SCREEN_EDGE) {
result.x -= 1;
result.width += 1;
}
if (adjacent_to & ADJ_RIGHT_SCREEN_EDGE) {
result.width += 1;
}
return result;
case BS_NONE: case BS_NONE:
return (Rect){0, 0, 0, 0}; return (Rect){0, 0, 0, 0};
@ -949,6 +969,20 @@ Rect con_border_style_rect(Con *con) {
} }
} }
/*
* Returns adjacent borders of the window. We need this if hide_edge_borders is
* enabled.
*/
adjacent_t con_adjacent_borders(Con *con) {
adjacent_t result = ADJ_NONE;
Con *output = con_get_output(con);
if (con->rect.x == output->rect.x)
result |= ADJ_LEFT_SCREEN_EDGE;
if (con->rect.x + con->rect.width == output->rect.x + output->rect.width)
result |= ADJ_RIGHT_SCREEN_EDGE;
return result;
}
/* /*
* Use this function to get a containers border style. This is important * Use this function to get a containers border style. This is important
* because when inside a stack, the border style is always BS_NORMAL. * because when inside a stack, the border style is always BS_NORMAL.

19
src/x.c
View File

@ -299,6 +299,9 @@ void x_window_kill(xcb_window_t window, kill_window_t kill_window) {
void x_draw_decoration(Con *con) { void x_draw_decoration(Con *con) {
Con *parent = con->parent; Con *parent = con->parent;
bool leaf = con_is_leaf(con); bool leaf = con_is_leaf(con);
adjacent_t adjacent_to = ADJ_NONE;
if (config.hide_edge_borders)
adjacent_to = con_adjacent_borders(con);
/* This code needs to run for: /* This code needs to run for:
* leaf containers * leaf containers
* non-leaf containers which are in a stacked/tabbed container * non-leaf containers which are in a stacked/tabbed container
@ -408,12 +411,16 @@ void x_draw_decoration(Con *con) {
* rectangle because some childs are not freely resizable and we want * rectangle because some childs are not freely resizable and we want
* their background color to "shine through". */ * their background color to "shine through". */
xcb_change_gc(conn, con->pm_gc, XCB_GC_FOREGROUND, (uint32_t[]){ p->color->background }); xcb_change_gc(conn, con->pm_gc, XCB_GC_FOREGROUND, (uint32_t[]){ p->color->background });
xcb_rectangle_t borders[] = { if (!(adjacent_to & ADJ_LEFT_SCREEN_EDGE)) {
{ 0, 0, br.x, r->height }, xcb_rectangle_t leftline = { 0, 0, br.x, r->height };
{ 0, r->height + br.height + br.y, r->width, r->height }, xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, &leftline);
{ r->width + br.width + br.x, 0, r->width, r->height } }
}; if (!(adjacent_to & ADJ_RIGHT_SCREEN_EDGE)) {
xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 3, borders); xcb_rectangle_t rightline = { r->width + br.width + br.x, 0, r->width, r->height };
xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, &rightline);
}
xcb_rectangle_t bottomline = { 0, r->height + br.height + br.y, r->width, r->height };
xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, &bottomline);
/* 1pixel border needs an additional line at the top */ /* 1pixel border needs an additional line at the top */
if (p->border_style == BS_1PIXEL) { if (p->border_style == BS_1PIXEL) {
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 };