Add configuration options for tray icon size and minimum panel size
Patch status: needinfo
Patch by Jaroslav Smid
To apply this patch, use:
curl http://cr.i3wm.org/patch/399/raw.patch | git am
b/i3bar/include/config.h
21 |
@@ -23,6 +23,8 @@ typedef enum { M_DOCK = 0, M_HIDE = 1, M_INVISIBLE = 2 } bar_display_mode_t; |
22 |
typedef struct config_t { |
23 |
int modifier; |
24 |
position_t position; |
25 |
+ int min_height; |
26 |
+ int tray_icon_size; |
27 |
int verbose; |
28 |
struct xcb_color_strings_t colors; |
29 |
bool disable_binding_mode_indicator; |
b/i3bar/src/config.c
34 |
@@ -210,10 +210,42 @@ static int config_boolean_cb(void *params_, int val) { |
35 |
return 0; |
36 |
} |
37 |
|
38 |
+/* Parse an integer value */ |
39 |
+#if YAJL_MAJOR >= 2 |
40 |
+static int config_integer_cb(void *params_, long long val) { |
41 |
+#else |
42 |
+static int config_integer_cb(void *params_, long val) { |
43 |
+#endif |
44 |
+ /* Minimum panel height, allowed values <0, INT16_MAX> */ |
45 |
+ if (!strcmp(cur_key, "min_height")) { |
46 |
+ if (val < 0) |
47 |
+ config.min_height = 0; |
48 |
+ else if (val > INT16_MAX) |
49 |
+ config.min_height = INT16_MAX; |
50 |
+ else |
51 |
+ config.min_height = (int)val; |
52 |
+ return 1; |
53 |
+ } |
54 |
+ |
55 |
+ /* Tray icon size, allowed values <0, INT16_MAX> */ |
56 |
+ if (!strcmp(cur_key, "tray_icon_size")) { |
57 |
+ if (val < 0) |
58 |
+ config.tray_icon_size = 0; |
59 |
+ else if (val > INT16_MAX) |
60 |
+ config.tray_icon_size = INT16_MAX; |
61 |
+ else |
62 |
+ config.tray_icon_size = (int)val; |
63 |
+ return 1; |
64 |
+ } |
65 |
+ |
66 |
+ return 0; |
67 |
+} |
68 |
+ |
69 |
/* A datastructure to pass all these callbacks to yajl */ |
70 |
static yajl_callbacks outputs_callbacks = { |
71 |
.yajl_null = config_null_cb, |
72 |
.yajl_boolean = config_boolean_cb, |
73 |
+ .yajl_integer = config_integer_cb, |
74 |
.yajl_string = config_string_cb, |
75 |
.yajl_map_key = config_map_key_cb, |
76 |
}; |
b/i3bar/src/xcb.c
81 |
@@ -59,9 +59,12 @@ xcb_connection_t *conn; |
82 |
/* The font we'll use */ |
83 |
static i3Font font; |
84 |
|
85 |
-/* Overall height of the bar (based on font size) */ |
86 |
+/* Overall height of the bar */ |
87 |
int bar_height; |
88 |
|
89 |
+/* Pixel size of a tray icon */ |
90 |
+int tray_icon_size; |
91 |
+ |
92 |
/* These are only relevant for XKB, which we only need for grabbing modifiers */ |
93 |
Display *xkb_dpy; |
94 |
int xkb_event_base; |
95 |
@@ -372,7 +375,7 @@ void handle_button(xcb_button_press_event_t *event) { |
96 |
TAILQ_FOREACH_REVERSE(trayclient, walk->trayclients, tc_head, tailq) { |
97 |
if (!trayclient->mapped) |
98 |
continue; |
99 |
- tray_width += (font.height + 2); |
100 |
+ tray_width += (tray_icon_size + 2); |
101 |
} |
102 |
|
103 |
int block_x = 0, last_block_x; |
104 |
@@ -452,8 +455,8 @@ static void configure_trayclients(void) { |
105 |
clients++; |
106 |
|
107 |
DLOG("Configuring tray window %08x to x=%d\n", |
108 |
- trayclient->win, output->rect.w - (clients * (font.height + 2))); |
109 |
- uint32_t x = output->rect.w - (clients * (font.height + 2)); |
110 |
+ trayclient->win, output->rect.w - (clients * (tray_icon_size + 2))); |
111 |
+ uint32_t x = output->rect.w - (clients * (tray_icon_size + 2)); |
112 |
xcb_configure_window(xcb_connection, |
113 |
trayclient->win, |
114 |
XCB_CONFIG_WINDOW_X, |
115 |
@@ -563,16 +566,16 @@ static void handle_client_message(xcb_client_message_event_t* event) { |
116 |
xcb_reparent_window(xcb_connection, |
117 |
client, |
118 |
output->bar, |
119 |
- output->rect.w - font.height - 2, |
120 |
- 2); |
121 |
+ output->rect.w - tray_icon_size - 2, |
122 |
+ (bar_height - tray_icon_size)/2); |
123 |
/* We reconfigure the window to use a reasonable size. The systray |
124 |
* specification explicitly says: |
125 |
* Tray icons may be assigned any size by the system tray, and |
126 |
* should do their best to cope with any size effectively |
127 |
*/ |
128 |
mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; |
129 |
- values[0] = font.height; |
130 |
- values[1] = font.height; |
131 |
+ values[0] = tray_icon_size; |
132 |
+ values[1] = tray_icon_size; |
133 |
xcb_configure_window(xcb_connection, |
134 |
client, |
135 |
mask, |
136 |
@@ -802,10 +805,10 @@ static void handle_configure_request(xcb_configure_request_event_t *event) { |
137 |
continue; |
138 |
|
139 |
xcb_rectangle_t rect; |
140 |
- rect.x = output->rect.w - (clients * (font.height + 2)); |
141 |
- rect.y = 2; |
142 |
- rect.width = font.height; |
143 |
- rect.height = font.height; |
144 |
+ rect.x = output->rect.w - (clients * (tray_icon_size + 2)); |
145 |
+ rect.y = (bar_height - tray_icon_size)/2; |
146 |
+ rect.width = tray_icon_size; |
147 |
+ rect.height = tray_icon_size; |
148 |
|
149 |
DLOG("This is a tray window. x = %d\n", rect.x); |
150 |
fake_configure_notify(xcb_connection, rect, event->window, 0); |
151 |
@@ -1107,7 +1110,19 @@ void init_xcb_late(char *fontname) { |
152 |
font = load_font(fontname, true); |
153 |
set_font(&font); |
154 |
DLOG("Calculated Font-height: %d\n", font.height); |
155 |
- bar_height = font.height + 6; |
156 |
+ |
157 |
+ bar_height = MAX(font.height + 6, |
158 |
+ config.min_height); |
159 |
+ |
160 |
+ if (config.tray_icon_size != 0) { |
161 |
+ /* Tray icon size is set. Increase bar's height if it won't fit */ |
162 |
+ tray_icon_size = config.tray_icon_size; |
163 |
+ bar_height = MAX(tray_icon_size, bar_height); |
164 |
+ } |
165 |
+ else { |
166 |
+ /* Tray icon size is not set. Use the same as font's height */ |
167 |
+ tray_icon_size = font.height; |
168 |
+ } |
169 |
|
170 |
xcb_flush(xcb_connection); |
171 |
|
172 |
@@ -1705,10 +1720,8 @@ void draw_bars(bool unhide) { |
173 |
TAILQ_FOREACH(trayclient, outputs_walk->trayclients, tailq) { |
174 |
if (!trayclient->mapped) |
175 |
continue; |
176 |
- /* We assume the tray icons are quadratic (we use the font |
177 |
- * *height* as *width* of the icons) because we configured them |
178 |
- * like this. */ |
179 |
- traypx += font.height + 2; |
180 |
+ /* We assume the tray icons are quadratic */ |
181 |
+ traypx += tray_icon_size + 2; |
182 |
} |
183 |
/* Add 2px of padding if there are any tray icons */ |
184 |
if (traypx > 0) |
185 |
@@ -1717,9 +1730,12 @@ void draw_bars(bool unhide) { |
186 |
statusline_pm, |
187 |
outputs_walk->buffer, |
188 |
outputs_walk->bargc, |
189 |
- MAX(0, (int16_t)(statusline_width - outputs_walk->rect.w + 4)), 0, |
190 |
- MAX(0, (int16_t)(outputs_walk->rect.w - statusline_width - traypx - 4)), 3, |
191 |
- MIN(outputs_walk->rect.w - traypx - 4, (int)statusline_width), font.height + 2); |
192 |
+ MAX(0, (int16_t)(statusline_width - outputs_walk->rect.w + 4)), |
193 |
+ 0, |
194 |
+ MAX(0, (int16_t)(outputs_walk->rect.w - statusline_width - traypx - 4)), |
195 |
+ (bar_height - font.height - 2)/2, |
196 |
+ MIN(outputs_walk->rect.w - traypx - 4, (int)statusline_width), |
197 |
+ font.height + 2); |
198 |
} |
199 |
|
200 |
if (!config.disable_ws) { |
201 |
@@ -1754,7 +1770,7 @@ void draw_bars(bool unhide) { |
202 |
outputs_walk->bargc, |
203 |
mask, |
204 |
vals_border); |
205 |
- xcb_rectangle_t rect_border = { i, 1, ws_walk->name_width + 10, font.height + 4 }; |
206 |
+ xcb_rectangle_t rect_border = { i, 1, ws_walk->name_width + 10, bar_height - 2 }; |
207 |
xcb_poly_fill_rectangle(xcb_connection, |
208 |
outputs_walk->buffer, |
209 |
outputs_walk->bargc, |
210 |
@@ -1765,7 +1781,7 @@ void draw_bars(bool unhide) { |
211 |
outputs_walk->bargc, |
212 |
mask, |
213 |
vals); |
214 |
- xcb_rectangle_t rect = { i + 1, 2, ws_walk->name_width + 8, font.height + 2 }; |
215 |
+ xcb_rectangle_t rect = { i + 1, 2, ws_walk->name_width + 8, bar_height - 4 }; |
216 |
xcb_poly_fill_rectangle(xcb_connection, |
217 |
outputs_walk->buffer, |
218 |
outputs_walk->bargc, |
219 |
@@ -1773,7 +1789,7 @@ void draw_bars(bool unhide) { |
220 |
&rect); |
221 |
set_font_colors(outputs_walk->bargc, fg_color, bg_color); |
222 |
draw_text(ws_walk->name, outputs_walk->buffer, outputs_walk->bargc, |
223 |
- i + 5, 3, ws_walk->name_width); |
224 |
+ i + 5, (bar_height - font.height)/2, ws_walk->name_width); |
225 |
i += 10 + ws_walk->name_width + 1; |
226 |
|
227 |
} |
b/include/config.h
232 |
@@ -224,6 +224,12 @@ struct Barconfig { |
233 |
* disables the tray (it’s enabled by default). */ |
234 |
char *tray_output; |
235 |
|
236 |
+ /** Minimum height of the panel in pixels */ |
237 |
+ int min_height; |
238 |
+ |
239 |
+ /** Size of tray icons in pixels */ |
240 |
+ int tray_icon_size; |
241 |
+ |
242 |
/** Path to the i3 IPC socket. This option is discouraged since programs |
243 |
* can find out the path by looking for the I3_SOCKET_PATH property on the |
244 |
* root window! */ |
b/include/config_directives.h
249 |
@@ -77,6 +77,8 @@ CFGFUN(bar_i3bar_command, const char *i3bar_command); |
250 |
CFGFUN(bar_color, const char *colorclass, const char *border, const char *background, const char *text); |
251 |
CFGFUN(bar_socket_path, const char *socket_path); |
252 |
CFGFUN(bar_tray_output, const char *output); |
253 |
+CFGFUN(bar_tray_icon_size, const long size); |
254 |
+CFGFUN(bar_min_height, const long size); |
255 |
CFGFUN(bar_color_single, const char *colorclass, const char *color); |
256 |
CFGFUN(bar_status_command, const char *command); |
257 |
CFGFUN(bar_binding_mode_indicator, const char *value); |
b/parser-specs/config.spec
262 |
@@ -355,6 +355,8 @@ state BAR: |
263 |
'position' -> BAR_POSITION |
264 |
'output' -> BAR_OUTPUT |
265 |
'tray_output' -> BAR_TRAY_OUTPUT |
266 |
+ 'tray_icon_size' -> BAR_TRAY_ICON_SIZE |
267 |
+ 'min_height' -> BAR_MIN_HEIGHT |
268 |
'font' -> BAR_FONT |
269 |
'binding_mode_indicator' -> BAR_BINDING_MODE_INDICATOR |
270 |
'workspace_buttons' -> BAR_WORKSPACE_BUTTONS |
271 |
@@ -408,6 +410,14 @@ state BAR_TRAY_OUTPUT: |
272 |
output = string |
273 |
-> call cfg_bar_tray_output($output); BAR |
274 |
|
275 |
+state BAR_TRAY_ICON_SIZE: |
276 |
+ tray_icon_size = number |
277 |
+ -> call cfg_bar_tray_icon_size(&tray_icon_size); BAR |
278 |
+ |
279 |
+state BAR_MIN_HEIGHT: |
280 |
+ min_height = number |
281 |
+ -> call cfg_bar_min_height(&min_height); BAR |
282 |
+ |
283 |
state BAR_FONT: |
284 |
font = string |
285 |
-> call cfg_bar_font($font); BAR |
b/src/config_directives.c
290 |
@@ -495,6 +495,14 @@ CFGFUN(bar_tray_output, const char *output) { |
291 |
current_bar.tray_output = sstrdup(output); |
292 |
} |
293 |
|
294 |
+CFGFUN(bar_tray_icon_size, const long size) { |
295 |
+ current_bar.tray_icon_size = size; |
296 |
+} |
297 |
+ |
298 |
+CFGFUN(bar_min_height, const long size) { |
299 |
+ current_bar.min_height = size; |
300 |
+} |
301 |
+ |
302 |
CFGFUN(bar_color_single, const char *colorclass, const char *color) { |
303 |
if (strcmp(colorclass, "background") == 0) |
304 |
current_bar.colors.background = sstrdup(color); |
b/src/ipc.c
309 |
@@ -736,6 +736,12 @@ IPC_HANDLER(get_bar_config) { |
310 |
break; |
311 |
} |
312 |
|
313 |
+ ystr("tray_icon_size"); |
314 |
+ y(integer, config->tray_icon_size); |
315 |
+ |
316 |
+ ystr("min_height"); |
317 |
+ y(integer, config->min_height); |
318 |
+ |
319 |
ystr("position"); |
320 |
if (config->position == P_BOTTOM) |
321 |
ystr("bottom"); |