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)
With the +for_window+ command, you can let i3 execute any command when it
*/
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 container’s border style. This is important
* because when inside a stack, the border style is always BS_NORMAL.
* It is not planned to add any different focus models. */
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.
* 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
* only this specific window or the whole X11 client */
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 {
BIND_NONE = 0,
BIND_SHIFT = XCB_MOD_MASK_SHIFT, /* (1 << 0) */
normal { return TOK_NORMAL; }
none { return TOK_NONE; }
1pixel { return TOK_1PIXEL; }
+hide_edge_borders { return TOK_HIDE_EDGE_BORDERS; }
focus_follows_mouse { return TOKFOCUSFOLLOWSMOUSE; }
force_focus_wrapping { return TOK_FORCE_FOCUS_WRAPPING; }
force_xinerama { return TOK_FORCE_XINERAMA; }
%token TOK_NORMAL "normal"
%token TOK_NONE "none"
%token TOK_1PIXEL "1pixel"
+%token TOK_HIDE_EDGE_BORDERS "hide_edge_borders"
%token TOKFOCUSFOLLOWSMOUSE "focus_follows_mouse"
%token TOK_FORCE_FOCUS_WRAPPING "force_focus_wrapping"
%token TOK_FORCE_XINERAMA "force_xinerama"
| workspace_layout
| new_window
| new_float
+ | hide_edge_borders
| focus_follows_mouse
| force_focus_wrapping
| force_xinerama
}
;
+hide_edge_borders:
+ TOK_HIDE_EDGE_BORDERS bool
+ {
+ DLOG("hide edge borders = %d\n", $2);
+ config.hide_edge_borders = $2;
+ }
+ ;
+
focus_follows_mouse:
TOKFOCUSFOLLOWSMOUSE bool
{
*
*/
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)) {
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:
- 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:
return (Rect){0, 0, 0, 0};
}
}
+/*
+ * 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 container’s border style. This is important
* because when inside a stack, the border style is always BS_NORMAL.
void x_draw_decoration(Con *con) {
Con *parent = con->parent;
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:
* • leaf containers
* • non-leaf containers which are in a stacked/tabbed container
* rectangle because some childs are not freely resizable and we want
* their background color to "shine through". */
xcb_change_gc(conn, con->pm_gc, XCB_GC_FOREGROUND, (uint32_t[]){ p->color->background });
- xcb_rectangle_t borders[] = {
- { 0, 0, br.x, r->height },
- { 0, r->height + br.height + br.y, r->width, r->height },
- { r->width + br.width + br.x, 0, r->width, r->height }
- };
- xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 3, borders);
+ if (!(adjacent_to & ADJ_LEFT_SCREEN_EDGE)) {
+ xcb_rectangle_t leftline = { 0, 0, br.x, r->height };
+ xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, &leftline);
+ }
+ if (!(adjacent_to & ADJ_RIGHT_SCREEN_EDGE)) {
+ 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 */
if (p->border_style == BS_1PIXEL) {
xcb_rectangle_t topline = { br.x, 0, con->rect.width + br.width + br.x, br.y };