Make horizontal edge-borders hidable too
This commit is contained in:
parent
1b2d222449
commit
57effd65b2
|
@ -471,17 +471,17 @@ new_window 1pixel
|
||||||
=== Hiding vertical borders
|
=== Hiding vertical borders
|
||||||
|
|
||||||
You can hide vertical borders adjacent to the screen edges using
|
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
|
+hide_edge_borders+. This is useful if you are using scrollbars, or do not want
|
||||||
disabled by default.
|
to waste even two pixels in displayspace. Default is none.
|
||||||
|
|
||||||
*Syntax*:
|
*Syntax*:
|
||||||
----------------------------
|
----------------------------
|
||||||
hide_edge_borders <yes|no>
|
hide_edge_borders <none|vertical|horizontal|both>
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
*Example*:
|
*Example*:
|
||||||
----------------------
|
----------------------
|
||||||
hide_edge_borders yes
|
hide_edge_borders vertical
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
=== Arbitrary commands for specific windows (for_window)
|
=== Arbitrary commands for specific windows (for_window)
|
||||||
|
|
|
@ -108,10 +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.
|
/** Remove borders if they are adjacent to the screen edge.
|
||||||
* This is useful if you are reaching scrollbar on the edge of the
|
* This is useful if you are reaching scrollbar on the edge of the
|
||||||
* screen. By default, this is disabled. */
|
* screen or do not want to waste a single pixel of displayspace.
|
||||||
bool hide_edge_borders;
|
* By default, this is disabled. */
|
||||||
|
adjacent_t 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
|
||||||
|
|
|
@ -62,8 +62,10 @@ typedef enum { DONT_KILL_WINDOW = 0, KILL_WINDOW = 1, KILL_CLIENT = 2 } kill_win
|
||||||
|
|
||||||
/** describes if the window is adjacent to the output (physical screen) edges. */
|
/** describes if the window is adjacent to the output (physical screen) edges. */
|
||||||
typedef enum { ADJ_NONE = 0,
|
typedef enum { ADJ_NONE = 0,
|
||||||
ADJ_LEFT_SCREEN_EDGE = 1,
|
ADJ_LEFT_SCREEN_EDGE = (1 << 0),
|
||||||
ADJ_RIGHT_SCREEN_EDGE = 2} adjacent_t;
|
ADJ_RIGHT_SCREEN_EDGE = (1 << 1),
|
||||||
|
ADJ_UPPER_SCREEN_EDGE = (1 << 2),
|
||||||
|
ADJ_LOWER_SCREEN_EDGE = (1 << 4)} adjacent_t;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
BIND_NONE = 0,
|
BIND_NONE = 0,
|
||||||
|
|
|
@ -201,6 +201,7 @@ 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; }
|
hide_edge_borders { return TOK_HIDE_EDGE_BORDERS; }
|
||||||
|
both { return TOK_BOTH; }
|
||||||
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; }
|
||||||
|
|
|
@ -736,6 +736,7 @@ void parse_file(const char *f) {
|
||||||
%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 TOK_HIDE_EDGE_BORDERS "hide_edge_borders"
|
||||||
|
%token TOK_BOTH "both"
|
||||||
%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"
|
||||||
|
@ -800,6 +801,8 @@ void parse_file(const char *f) {
|
||||||
%type <number> layout_mode
|
%type <number> layout_mode
|
||||||
%type <number> border_style
|
%type <number> border_style
|
||||||
%type <number> new_window
|
%type <number> new_window
|
||||||
|
%type <number> hide_edge_borders
|
||||||
|
%type <number> edge_hiding_mode
|
||||||
%type <number> new_float
|
%type <number> new_float
|
||||||
%type <number> colorpixel
|
%type <number> colorpixel
|
||||||
%type <number> bool
|
%type <number> bool
|
||||||
|
@ -1477,13 +1480,21 @@ bool:
|
||||||
;
|
;
|
||||||
|
|
||||||
hide_edge_borders:
|
hide_edge_borders:
|
||||||
TOK_HIDE_EDGE_BORDERS bool
|
TOK_HIDE_EDGE_BORDERS edge_hiding_mode
|
||||||
{
|
{
|
||||||
DLOG("hide edge borders = %d\n", $2);
|
DLOG("hide edge borders = %d\n", $2);
|
||||||
config.hide_edge_borders = $2;
|
config.hide_edge_borders = $2;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
edge_hiding_mode:
|
||||||
|
TOK_NONE { $$ = ADJ_NONE; }
|
||||||
|
| TOK_VERT { $$ = ADJ_LEFT_SCREEN_EDGE | ADJ_RIGHT_SCREEN_EDGE; }
|
||||||
|
| TOK_HORIZ { $$ = ADJ_UPPER_SCREEN_EDGE | ADJ_LOWER_SCREEN_EDGE; }
|
||||||
|
| TOK_BOTH { $$ = ADJ_LEFT_SCREEN_EDGE | ADJ_RIGHT_SCREEN_EDGE | ADJ_UPPER_SCREEN_EDGE | ADJ_LOWER_SCREEN_EDGE; }
|
||||||
|
| bool { $$ = ($1 ? ADJ_LEFT_SCREEN_EDGE | ADJ_RIGHT_SCREEN_EDGE : ADJ_NONE); }
|
||||||
|
;
|
||||||
|
|
||||||
focus_follows_mouse:
|
focus_follows_mouse:
|
||||||
TOKFOCUSFOLLOWSMOUSE bool
|
TOKFOCUSFOLLOWSMOUSE bool
|
||||||
{
|
{
|
||||||
|
|
34
src/con.c
34
src/con.c
|
@ -934,31 +934,41 @@ 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;
|
adjacent_t borders_to_hide = ADJ_NONE;
|
||||||
Rect result;
|
Rect result;
|
||||||
if (config.hide_edge_borders)
|
borders_to_hide = con_adjacent_borders(con) & 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:
|
||||||
result = (Rect){2, 0, -(2 * 2), -2};
|
result = (Rect){2, 0, -(2 * 2), -2};
|
||||||
if (adjacent_to & ADJ_LEFT_SCREEN_EDGE) {
|
if (borders_to_hide & ADJ_LEFT_SCREEN_EDGE) {
|
||||||
result.x -= 2;
|
result.x -= 2;
|
||||||
result.width += 2;
|
result.width += 2;
|
||||||
}
|
}
|
||||||
if (adjacent_to & ADJ_RIGHT_SCREEN_EDGE) {
|
if (borders_to_hide & ADJ_RIGHT_SCREEN_EDGE) {
|
||||||
result.width += 2;
|
result.width += 2;
|
||||||
}
|
}
|
||||||
|
/* With normal borders we never hide the upper border */
|
||||||
|
if (borders_to_hide & ADJ_LOWER_SCREEN_EDGE) {
|
||||||
|
result.height += 2;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
case BS_1PIXEL:
|
case BS_1PIXEL:
|
||||||
result = (Rect){1, 1, -2, -2};
|
result = (Rect){1, 1, -2, -2};
|
||||||
if (adjacent_to & ADJ_LEFT_SCREEN_EDGE) {
|
if (borders_to_hide & ADJ_LEFT_SCREEN_EDGE) {
|
||||||
result.x -= 1;
|
result.x -= 1;
|
||||||
result.width += 1;
|
result.width += 1;
|
||||||
}
|
}
|
||||||
if (adjacent_to & ADJ_RIGHT_SCREEN_EDGE) {
|
if (borders_to_hide & ADJ_RIGHT_SCREEN_EDGE) {
|
||||||
result.width += 1;
|
result.width += 1;
|
||||||
}
|
}
|
||||||
|
if (borders_to_hide & ADJ_UPPER_SCREEN_EDGE) {
|
||||||
|
result.y -= 1;
|
||||||
|
result.height += 1;
|
||||||
|
}
|
||||||
|
if (borders_to_hide & ADJ_LOWER_SCREEN_EDGE) {
|
||||||
|
result.height += 1;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
case BS_NONE:
|
case BS_NONE:
|
||||||
|
@ -975,11 +985,15 @@ Rect con_border_style_rect(Con *con) {
|
||||||
*/
|
*/
|
||||||
adjacent_t con_adjacent_borders(Con *con) {
|
adjacent_t con_adjacent_borders(Con *con) {
|
||||||
adjacent_t result = ADJ_NONE;
|
adjacent_t result = ADJ_NONE;
|
||||||
Con *output = con_get_output(con);
|
Con *workspace = con_get_workspace(con);
|
||||||
if (con->rect.x == output->rect.x)
|
if (con->rect.x == workspace->rect.x)
|
||||||
result |= ADJ_LEFT_SCREEN_EDGE;
|
result |= ADJ_LEFT_SCREEN_EDGE;
|
||||||
if (con->rect.x + con->rect.width == output->rect.x + output->rect.width)
|
if (con->rect.x + con->rect.width == workspace->rect.x + workspace->rect.width)
|
||||||
result |= ADJ_RIGHT_SCREEN_EDGE;
|
result |= ADJ_RIGHT_SCREEN_EDGE;
|
||||||
|
if (con->rect.y == workspace->rect.y)
|
||||||
|
result |= ADJ_UPPER_SCREEN_EDGE;
|
||||||
|
if (con->rect.y + con->rect.height == workspace->rect.y + workspace->rect.height)
|
||||||
|
result |= ADJ_LOWER_SCREEN_EDGE;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
22
src/x.c
22
src/x.c
|
@ -299,19 +299,19 @@ 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
|
||||||
*
|
*
|
||||||
* It does not need to run for:
|
* It does not need to run for:
|
||||||
|
* • direct children of outputs
|
||||||
* • floating containers (they don’t have a decoration)
|
* • floating containers (they don’t have a decoration)
|
||||||
*/
|
*/
|
||||||
if ((!leaf &&
|
if ((!leaf &&
|
||||||
parent->layout != L_STACKED &&
|
parent->layout != L_STACKED &&
|
||||||
parent->layout != L_TABBED) ||
|
parent->layout != L_TABBED) ||
|
||||||
|
parent->type == CT_OUTPUT ||
|
||||||
con->type == CT_FLOATING_CON)
|
con->type == CT_FLOATING_CON)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -399,6 +399,10 @@ void x_draw_decoration(Con *con) {
|
||||||
|
|
||||||
/* 3: draw a rectangle in border color around the client */
|
/* 3: draw a rectangle in border color around the client */
|
||||||
if (p->border_style != BS_NONE && p->con_is_leaf) {
|
if (p->border_style != BS_NONE && p->con_is_leaf) {
|
||||||
|
/* We might hide some borders adjacent to the screen-edge */
|
||||||
|
adjacent_t borders_to_hide = ADJ_NONE;
|
||||||
|
borders_to_hide = con_adjacent_borders(con) & config.hide_edge_borders;
|
||||||
|
|
||||||
Rect br = con_border_style_rect(con);
|
Rect br = con_border_style_rect(con);
|
||||||
#if 0
|
#if 0
|
||||||
DLOG("con->rect spans %d x %d\n", con->rect.width, con->rect.height);
|
DLOG("con->rect spans %d x %d\n", con->rect.width, con->rect.height);
|
||||||
|
@ -411,18 +415,20 @@ 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 });
|
||||||
if (!(adjacent_to & ADJ_LEFT_SCREEN_EDGE)) {
|
if (!(borders_to_hide & ADJ_LEFT_SCREEN_EDGE)) {
|
||||||
xcb_rectangle_t leftline = { 0, 0, br.x, r->height };
|
xcb_rectangle_t leftline = { 0, 0, br.x, r->height };
|
||||||
xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, &leftline);
|
xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, &leftline);
|
||||||
}
|
}
|
||||||
if (!(adjacent_to & ADJ_RIGHT_SCREEN_EDGE)) {
|
if (!(borders_to_hide & ADJ_RIGHT_SCREEN_EDGE)) {
|
||||||
xcb_rectangle_t rightline = { r->width + br.width + br.x, 0, r->width, r->height };
|
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_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 };
|
if (!(borders_to_hide & ADJ_LOWER_SCREEN_EDGE)) {
|
||||||
xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, &bottomline);
|
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 && !(borders_to_hide & ADJ_UPPER_SCREEN_EDGE)) {
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue