i3 - improved tiling WM


Draw borders not wider than specified width

Patch status: needinfo

Patch by Mats

Long description:

Rectangles passed to function xcb_poly_fill_rectangle are of type
xcb_rectangle_t and defined as:

    struct xcb_rectangle_t {
        int16_t  x;
        int16_t  y;
        uint16_t width;
        uint16_t height;
    }

The rectangles for the right and lower border had a width and height,
respectively, greater than the specified border width.

To apply this patch, use:
curl http://cr.i3wm.org/patch/634/raw.patch | git am

b/src/x.c

25
@@ -412,7 +412,7 @@ void x_draw_decoration(Con *con) {
26
         /* We might hide some borders adjacent to the screen-edge */
27
         adjacent_t borders_to_hide = ADJ_NONE;
28
         borders_to_hide = con_adjacent_borders(con) & config.hide_edge_borders;
29
-
30
+        int border_width = con->current_border_width;
31
         Rect br = con_border_style_rect(con);
32
 #if 0
33
         DLOG("con->rect spans %d x %d\n", con->rect.width, con->rect.height);
34
@@ -424,24 +424,24 @@ void x_draw_decoration(Con *con) {
35
          * (left, bottom and right part). We don’t just fill the whole
36
          * rectangle because some childs are not freely resizable and we want
37
          * their background color to "shine through". */
38
-        xcb_change_gc(conn, con->pm_gc, XCB_GC_FOREGROUND, (uint32_t[]) {p->color->background});
39
-        if (!(borders_to_hide & ADJ_LEFT_SCREEN_EDGE)) {
40
-            xcb_rectangle_t leftline = {0, 0, br.x, r->height};
41
-            xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, &leftline);
42
-        }
43
-        if (!(borders_to_hide & ADJ_RIGHT_SCREEN_EDGE)) {
44
-            xcb_rectangle_t rightline = {r->width + br.width + br.x, 0, r->width, r->height};
45
-            xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, &rightline);
46
-        }
47
-        if (!(borders_to_hide & ADJ_LOWER_SCREEN_EDGE)) {
48
-            xcb_rectangle_t bottomline = {0, r->height + br.height + br.y, r->width, r->height};
49
-            xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, &bottomline);
50
-        }
51
+        xcb_rectangle_t border_rects[4];
52
+        uint32_t border_rects_len = 0;
53
+
54
+        if (!(borders_to_hide & ADJ_LEFT_SCREEN_EDGE))
55
+            border_rects[border_rects_len++] = (xcb_rectangle_t) {0, 0, border_width, r->height};
56
+
57
+        if (!(borders_to_hide & ADJ_RIGHT_SCREEN_EDGE))
58
+            border_rects[border_rects_len++] = (xcb_rectangle_t) {r->width - border_width, 0, border_width, r->height};
59
+
60
+        if (!(borders_to_hide & ADJ_LOWER_SCREEN_EDGE))
61
+            border_rects[border_rects_len++] = (xcb_rectangle_t) {0, r->height - border_width, r->width, border_width};
62
+
63
         /* 1pixel border needs an additional line at the top */
64
-        if (p->border_style == BS_PIXEL && !(borders_to_hide & ADJ_UPPER_SCREEN_EDGE)) {
65
-            xcb_rectangle_t topline = {br.x, 0, con->rect.width + br.width + br.x, br.y};
66
-            xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, &topline);
67
-        }
68
+        if (p->border_style == BS_PIXEL && !(borders_to_hide & ADJ_UPPER_SCREEN_EDGE))
69
+            border_rects[border_rects_len++] = (xcb_rectangle_t) {0, 0, r->width, border_width};
70
+
71
+        xcb_change_gc(conn, con->pm_gc, XCB_GC_FOREGROUND, (uint32_t[]) {p->color->background});
72
+        xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, border_rects_len, border_rects);
73
 
74
         /* Highlight the side of the border at which the next window will be
75
          * opened if we are rendering a single window within a split container
76
@@ -450,13 +450,16 @@ void x_draw_decoration(Con *con) {
77
         if (TAILQ_NEXT(con, nodes) == NULL &&
78
             TAILQ_PREV(con, nodes_head, nodes) == NULL &&
79
             con->parent->type != CT_FLOATING_CON) {
80
+            xcb_rectangle_t indicator_rects[1];
81
+            uint32_t indicator_rects_len = 0;
82
+
83
+            if (p->parent_layout == L_SPLITH && !(borders_to_hide & ADJ_RIGHT_SCREEN_EDGE))
84
+                indicator_rects[indicator_rects_len++] = (xcb_rectangle_t) {r->width - border_width, br.y, border_width, r->height + br.height};
85
+            else if (p->parent_layout == L_SPLITV && !(borders_to_hide & ADJ_LOWER_SCREEN_EDGE))
86
+                indicator_rects[indicator_rects_len++] = (xcb_rectangle_t) {br.x, r->height - border_width, r->width + br.width, border_width};
87
+
88
             xcb_change_gc(conn, con->pm_gc, XCB_GC_FOREGROUND, (uint32_t[]) {p->color->indicator});
89
-            if (p->parent_layout == L_SPLITH)
90
-                xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, (xcb_rectangle_t[]) {
91
-                                                                              {r->width + br.width + br.x, br.y, r->width, r->height + br.height}});
92
-            else if (p->parent_layout == L_SPLITV)
93
-                xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, 1, (xcb_rectangle_t[]) {
94
-                                                                              {br.x, r->height + br.height + br.y, r->width - (2 * br.x), r->height}});
95
+            xcb_poly_fill_rectangle(conn, con->pixmap, con->pm_gc, indicator_rects_len, indicator_rects);
96
         }
97
     }
98