i3 - improved tiling WM


Separator color via config; separator width and on/off via ipc

Patch status: merged

Patch by Artem Shinkarov

Long description:

This patch adds the following features:
1) Configure a color of the separator via config.  It is done like
   bar {
      colors {
         separator #000000
      }
   }
2) A block can have an integer entry "separator_block_width" which
   sets the width of the gap which would follow after the current block.

3) A block can have a boolean entry "separator" and if it is set
   to false, then the drawing of the separating line would be disabled.

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

b/docs/i3bar-protocol

37
@@ -154,6 +154,14 @@ urgent::
38
 	A boolean which specifies whether the current value is urgent. Examples
39
 	are battery charge values below 1 percent or no more available disk
40
 	space (for non-root users). The presentation of urgency is up to i3bar.
41
+separator::
42
+	The boolean value false disables drawing of a separating line after the
43
+	block.  If the field is not present then the separator will be still
44
+	drawn.  Keep in mind that absence of a separator is only responsible for
45
+	the line itself, the gap between the items would be still present.
46
+separator_block_width::
47
+	The integer value that sets the width of the gap between items in pixels.
48
+	In the middle of the gap, a separating line is going to be drawn.
49
 
50
 If you want to put in your own entries into a block, prefix the key with an
51
 underscore (_). i3bar will ignore all keys it doesn’t understand, and prefixing

b/docs/ipc

56
@@ -507,6 +507,8 @@ background::
57
 	Background color of the bar.
58
 statusline::
59
 	Text color to be used for the statusline.
60
+separator::
61
+	Text color to be used for the separator.
62
 focused_workspace_text/focused_workspace_bg::
63
 	Text color/background color for a workspace button when the workspace
64
 	has focus.

b/docs/userguide

69
@@ -1158,6 +1158,8 @@ background::
70
 	Background color of the bar.
71
 statusline::
72
 	Text color to be used for the statusline.
73
+separator::	
74
+	Text color to be used for the separator.
75
 focused_workspace::
76
 	Border, background and text color for a workspace button when the workspace
77
 	has focus.
78
@@ -1179,6 +1181,7 @@ urgent_workspace::
79
 colors {
80
     background <color>
81
     statusline <color>
82
+    separator <color>
83
 
84
     colorclass <border> <background> <text>
85
 }
86
@@ -1190,6 +1193,7 @@ bar {
87
     colors {
88
         background #000000
89
         statusline #ffffff
90
+        separator #666666
91
 
92
         focused_workspace  #4c7899 #285577 #ffffff
93
         active_workspace   #333333 #5f676a #ffffff

b/i3bar/include/common.h

98
@@ -43,6 +43,10 @@ struct status_block {
99
     blockalign_t align;
100
 
101
     bool urgent;
102
+    bool no_separator;
103
+
104
+    /* The amount of pixels necessary to render a separater after the block. */
105
+    uint32_t sep_block_width;
106
 
107
     /* The amount of pixels necessary to render this block. These variables are
108
      * only temporarily used in refresh_statusline(). */

b/i3bar/include/xcb.h

113
@@ -28,6 +28,7 @@
114
 struct xcb_color_strings_t {
115
     char *bar_fg;
116
     char *bar_bg;
117
+    char *sep_fg;
118
     char *active_ws_fg;
119
     char *active_ws_bg;
120
     char *active_ws_border;

b/i3bar/src/child.c

125
@@ -98,6 +98,10 @@ static int stdin_start_array(void *context) {
126
 static int stdin_start_map(void *context) {
127
     parser_ctx *ctx = context;
128
     memset(&(ctx->block), '\0', sizeof(struct status_block));
129
+
130
+    /* Default width of the separator block. */
131
+    ctx->block.sep_block_width = 9;
132
+
133
     return 1;
134
 }
135
 
136
@@ -117,6 +121,9 @@ static int stdin_boolean(void *context, int val) {
137
     if (strcasecmp(ctx->last_map_key, "urgent") == 0) {
138
         ctx->block.urgent = val;
139
     }
140
+    if (strcasecmp(ctx->last_map_key, "separator") == 0) {
141
+        ctx->block.no_separator = !val;
142
+    }
143
     return 1;
144
 }
145
 
146
@@ -153,6 +160,9 @@ static int stdin_integer(void *context, long val) {
147
     if (strcasecmp(ctx->last_map_key, "min_width") == 0) {
148
         ctx->block.min_width = (uint32_t)val;
149
     }
150
+    if (strcasecmp(ctx->last_map_key, "separator_block_width") == 0) {
151
+        ctx->block.sep_block_width = (uint32_t)val;
152
+    }
153
     return 1;
154
 }
155
 

b/i3bar/src/config.c

160
@@ -161,6 +161,7 @@ static int config_string_cb(void *params_, const unsigned char *val, unsigned in
161
 
162
     COLOR(statusline, bar_fg);
163
     COLOR(background, bar_bg);
164
+    COLOR(separator, sep_fg);
165
     COLOR(focused_workspace_border, focus_ws_border);
166
     COLOR(focused_workspace_bg, focus_ws_bg);
167
     COLOR(focused_workspace_text, focus_ws_fg);
168
@@ -260,6 +261,7 @@ void free_colors(struct xcb_color_strings_t *colors) {
169
     } while (0)
170
     FREE_COLOR(bar_fg);
171
     FREE_COLOR(bar_bg);
172
+    FREE_COLOR(sep_fg);
173
     FREE_COLOR(active_ws_fg);
174
     FREE_COLOR(active_ws_bg);
175
     FREE_COLOR(active_ws_border);

b/i3bar/src/xcb.c

180
@@ -84,6 +84,7 @@ static mode binding;
181
 struct xcb_colors_t {
182
     uint32_t bar_fg;
183
     uint32_t bar_bg;
184
+    uint32_t sep_fg;
185
     uint32_t active_ws_fg;
186
     uint32_t active_ws_bg;
187
     uint32_t active_ws_border;
188
@@ -149,7 +150,8 @@ void refresh_statusline(void) {
189
 
190
         /* If this is not the last block, add some pixels for a separator. */
191
         if (TAILQ_NEXT(block, blocks) != NULL)
192
-            block->width += 9;
193
+            block->width += block->sep_block_width;
194
+
195
         statusline_width += block->width + block->x_offset + block->x_append;
196
     }
197
 
198
@@ -174,12 +176,14 @@ void refresh_statusline(void) {
199
         draw_text(block->full_text, statusline_pm, statusline_ctx, x + block->x_offset, 1, block->width);
200
         x += block->width + block->x_offset + block->x_append;
201
 
202
-        if (TAILQ_NEXT(block, blocks) != NULL) {
203
+        if (TAILQ_NEXT(block, blocks) != NULL && !block->no_separator && block->sep_block_width > 0) {
204
             /* This is not the last block, draw a separator. */
205
-            set_font_colors(statusline_ctx, get_colorpixel("#666666"), colors.bar_bg);
206
+            uint32_t sep_offset = block->sep_block_width/2 + block->sep_block_width % 2;
207
+            set_font_colors(statusline_ctx, colors.sep_fg, colors.bar_bg);
208
             xcb_poly_line(xcb_connection, XCB_COORD_MODE_ORIGIN, statusline_pm,
209
                           statusline_ctx, 2,
210
-                          (xcb_point_t[]){ { x - 5, 2 }, { x - 5, font.height - 2 } });
211
+                          (xcb_point_t[]){ { x - sep_offset, 2 },
212
+                                           { x - sep_offset, font.height - 2 } });
213
         }
214
     }
215
 }
216
@@ -259,6 +263,7 @@ void init_colors(const struct xcb_color_strings_t *new_colors) {
217
     } while  (0)
218
     PARSE_COLOR(bar_fg, "#FFFFFF");
219
     PARSE_COLOR(bar_bg, "#000000");
220
+    PARSE_COLOR(sep_fg, "#666666");
221
     PARSE_COLOR(active_ws_fg, "#FFFFFF");
222
     PARSE_COLOR(active_ws_bg, "#333333");
223
     PARSE_COLOR(active_ws_border, "#333333");

b/include/config.h

228
@@ -267,6 +267,7 @@ struct Barconfig {
229
     struct bar_colors {
230
         char *background;
231
         char *statusline;
232
+        char *separator;
233
 
234
         char *focused_workspace_border;
235
         char *focused_workspace_bg;

b/parser-specs/config.spec

240
@@ -419,7 +419,7 @@ state BAR_COLORS:
241
   end ->
242
   '#' -> BAR_COLORS_IGNORE_LINE
243
   'set' -> BAR_COLORS_IGNORE_LINE
244
-  colorclass = 'background', 'statusline'
245
+  colorclass = 'background', 'statusline', 'separator'
246
       -> BAR_COLORS_SINGLE
247
   colorclass = 'focused_workspace', 'active_workspace', 'inactive_workspace', 'urgent_workspace'
248
       -> BAR_COLORS_BORDER

b/src/config_directives.c

253
@@ -526,7 +526,10 @@ CFGFUN(bar_tray_output, const char *output) {
254
 CFGFUN(bar_color_single, const char *colorclass, const char *color) {
255
     if (strcmp(colorclass, "background") == 0)
256
         current_bar.colors.background = sstrdup(color);
257
-    else current_bar.colors.statusline = sstrdup(color);
258
+    else if (strcmp(colorclass, "separator") == 0)
259
+        current_bar.colors.separator = sstrdup(color);
260
+    else
261
+        current_bar.colors.statusline = sstrdup(color);
262
 }
263
 
264
 CFGFUN(bar_status_command, const char *command) {

b/src/ipc.c

269
@@ -677,6 +677,7 @@ IPC_HANDLER(get_bar_config) {
270
         y(map_open);
271
         YSTR_IF_SET(background);
272
         YSTR_IF_SET(statusline);
273
+        YSTR_IF_SET(separator);
274
         YSTR_IF_SET(focused_workspace_border);
275
         YSTR_IF_SET(focused_workspace_bg);
276
         YSTR_IF_SET(focused_workspace_text);