]> git.sur5r.net Git - i3/i3/commitdiff
Make horizontal edge-borders hidable too
authorAxel Wagner <mail@merovius.de>
Sun, 5 Aug 2012 19:41:36 +0000 (21:41 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Mon, 6 Aug 2012 01:03:00 +0000 (03:03 +0200)
docs/userguide
include/config.h
include/data.h
src/cfgparse.l
src/cfgparse.y
src/con.c
src/x.c

index 46a19e93e8ece826bf5973aadd8b0bd1afe91570..37e55d461e35ffe7fc7bf735be5661be096a0de6 100644 (file)
@@ -471,17 +471,17 @@ 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.
++hide_edge_borders+. This is useful if you are using scrollbars, or do not want
+to waste even two pixels in displayspace. Default is none.
 
 *Syntax*:
 ----------------------------
-hide_edge_borders <yes|no>
+hide_edge_borders <none|vertical|horizontal|both>
 ----------------------------
 
 *Example*:
 ----------------------
-hide_edge_borders yes
+hide_edge_borders vertical
 ----------------------
 
 === Arbitrary commands for specific windows (for_window)
index b6f356ad553a132c10d7e2394aadad8363ed274c..ebb24864cded0cb06548cfaebe11340ca87854be 100644 (file)
@@ -108,10 +108,11 @@ struct Config {
      * 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.
+    /** Remove 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;
+     * screen or do not want to waste a single pixel of displayspace.
+     * By default, this is disabled. */
+    adjacent_t 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
index acce59be197f581bdc0a387b2bcafc3d6bd6b087..a5ac943cead29eec8ea241e458c30e34395fa22b 100644 (file)
@@ -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. */
 typedef enum { ADJ_NONE = 0,
-               ADJ_LEFT_SCREEN_EDGE = 1,
-               ADJ_RIGHT_SCREEN_EDGE = 2} adjacent_t;
+               ADJ_LEFT_SCREEN_EDGE = (1 << 0),
+               ADJ_RIGHT_SCREEN_EDGE = (1 << 1),
+               ADJ_UPPER_SCREEN_EDGE = (1 << 2),
+               ADJ_LOWER_SCREEN_EDGE = (1 << 4)} adjacent_t;
 
 enum {
     BIND_NONE = 0,
index e2705b17e73de5aee4dfadb10cf30d94d5878a21..0411762407b6c0b7f62ca1482e36ac31464460ab 100644 (file)
@@ -201,6 +201,7 @@ normal                          { return TOK_NORMAL; }
 none                            { return TOK_NONE; }
 1pixel                          { return TOK_1PIXEL; }
 hide_edge_borders               { return TOK_HIDE_EDGE_BORDERS; }
+both                            { return TOK_BOTH; }
 focus_follows_mouse             { return TOKFOCUSFOLLOWSMOUSE; }
 force_focus_wrapping            { return TOK_FORCE_FOCUS_WRAPPING; }
 force_xinerama                  { return TOK_FORCE_XINERAMA; }
index a2f1b9f4cf2ad8248d733dcac511c4c0175ddabb..af7d77cf792cc31c9045d6060d2334b1de0e2989 100644 (file)
@@ -736,6 +736,7 @@ void parse_file(const char *f) {
 %token                  TOK_NONE                    "none"
 %token                  TOK_1PIXEL                  "1pixel"
 %token                  TOK_HIDE_EDGE_BORDERS       "hide_edge_borders"
+%token                  TOK_BOTH                    "both"
 %token                  TOKFOCUSFOLLOWSMOUSE        "focus_follows_mouse"
 %token                  TOK_FORCE_FOCUS_WRAPPING    "force_focus_wrapping"
 %token                  TOK_FORCE_XINERAMA          "force_xinerama"
@@ -800,6 +801,8 @@ void parse_file(const char *f) {
 %type   <number>        layout_mode
 %type   <number>        border_style
 %type   <number>        new_window
+%type   <number>        hide_edge_borders
+%type   <number>        edge_hiding_mode
 %type   <number>        new_float
 %type   <number>        colorpixel
 %type   <number>        bool
@@ -1477,13 +1480,21 @@ bool:
     ;
 
 hide_edge_borders:
-    TOK_HIDE_EDGE_BORDERS bool
+    TOK_HIDE_EDGE_BORDERS edge_hiding_mode
     {
         DLOG("hide edge borders = %d\n", $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:
     TOKFOCUSFOLLOWSMOUSE bool
     {
index 35ad540c0b510da9bf5de968b26d77387d4aa3b9..6f2a85b2d39be1f1bf918e2b7ccf127b9e7740b3 100644 (file)
--- a/src/con.c
+++ b/src/con.c
@@ -934,31 +934,41 @@ Con *con_descend_direction(Con *con, direction_t direction) {
  *
  */
 Rect con_border_style_rect(Con *con) {
-    adjacent_t adjacent_to = ADJ_NONE;
+    adjacent_t borders_to_hide = ADJ_NONE;
     Rect result;
-    if (config.hide_edge_borders)
-        adjacent_to = con_adjacent_borders(con);
+    borders_to_hide = con_adjacent_borders(con) & config.hide_edge_borders;
     switch (con_border_style(con)) {
     case BS_NORMAL:
         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.width += 2;
         }
-        if (adjacent_to & ADJ_RIGHT_SCREEN_EDGE) {
+        if (borders_to_hide & ADJ_RIGHT_SCREEN_EDGE) {
             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;
 
     case BS_1PIXEL:
         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.width += 1;
         }
-        if (adjacent_to & ADJ_RIGHT_SCREEN_EDGE) {
+        if (borders_to_hide & ADJ_RIGHT_SCREEN_EDGE) {
             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;
 
     case BS_NONE:
@@ -975,11 +985,15 @@ Rect con_border_style_rect(Con *con) {
  */
 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)
+    Con *workspace = con_get_workspace(con);
+    if (con->rect.x == workspace->rect.x)
         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;
+    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;
 }
 
diff --git a/src/x.c b/src/x.c
index f4d1416ff94329c4ed8c1a90b48fde0eae0990c9..cd85bcc6be7546fbfbf0a270a42fd21c2d3c80ce 100644 (file)
--- a/src/x.c
+++ b/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) {
     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
      *
      * It does not need to run for:
+     *  • direct children of outputs
      *  • floating containers (they don’t have a decoration)
      */
     if ((!leaf &&
          parent->layout != L_STACKED &&
          parent->layout != L_TABBED) ||
+        parent->type == CT_OUTPUT ||
         con->type == CT_FLOATING_CON)
         return;
 
@@ -399,6 +399,10 @@ void x_draw_decoration(Con *con) {
 
     /* 3: draw a rectangle in border color around the client */
     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);
 #if 0
         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
          * their background color to "shine through". */
         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_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_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);
+        if (!(borders_to_hide & ADJ_LOWER_SCREEN_EDGE)) {
+            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) {
+        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_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, &topline);
         }