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");
|