From 48af067dfe56545ccf0f462db4f62bb12ac16004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20B=C3=BCrk?= Date: Sat, 22 Jun 2019 17:23:21 +0200 Subject: [PATCH] feat: support transparency (RGBA) in i3bar (#3727) We introduce a --transparency flag for i3bar in order to enable a mode which supports the use of RGBA colors. An important constraint here is that tray icons will always have a fully transparent background. fixes #3723 --- docs/userguide | 20 ++++++++++++++++++++ i3bar/include/configuration.h | 1 + i3bar/src/main.c | 19 ++++++++++++------- i3bar/src/xcb.c | 16 +++++++++++++++- 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/docs/userguide b/docs/userguide index 875e886f..0fda7e80 100644 --- a/docs/userguide +++ b/docs/userguide @@ -1744,6 +1744,26 @@ bar { } -------------------------------------- +=== Transparency + +i3bar can support transparency by passing the +--transparency+ flag in the +configuration: + +*Syntax*: +-------------------------------------- +bar { + i3bar_command i3bar --transparency +} +-------------------------------------- + +In the i3bar color configuration and i3bar status block color attribute you can +then use colors in the RGBA format, i.e. the last two (hexadecimal) digits +specify the opacity. For example, +#00000000+ will be completely transparent, +while +#000000FF+ will be a fully opaque black (the same as +#000000+). + +Please note that due to the way the tray specification works, enabling this +flag will cause all tray icons to have a transparent background. + [[list_of_commands]] == List of commands diff --git a/i3bar/include/configuration.h b/i3bar/include/configuration.h index b86da2e0..3d875e5d 100644 --- a/i3bar/include/configuration.h +++ b/i3bar/include/configuration.h @@ -48,6 +48,7 @@ typedef struct config_t { position_t position; bool verbose; + bool transparency; struct xcb_color_strings_t colors; bool disable_binding_mode_indicator; bool disable_ws; diff --git a/i3bar/src/main.c b/i3bar/src/main.c index a818dd97..26ea0eeb 100644 --- a/i3bar/src/main.c +++ b/i3bar/src/main.c @@ -56,13 +56,14 @@ static char *expand_path(char *path) { } static void print_usage(char *elf_name) { - printf("Usage: %s -b bar_id [-s sock_path] [-h] [-v]\n", elf_name); + printf("Usage: %s -b bar_id [-s sock_path] [-t] [-h] [-v]\n", elf_name); printf("\n"); - printf("-b, --bar_id \tBar ID for which to get the configuration\n"); - printf("-s, --socket \tConnect to i3 via \n"); - printf("-h, --help Display this help message and exit\n"); - printf("-v, --version Display version number and exit\n"); - printf("-V, --verbose Enable verbose mode\n"); + printf("-b, --bar_id \tBar ID for which to get the configuration\n"); + printf("-s, --socket \tConnect to i3 via \n"); + printf("-t, --transparency Enable transparency (RGBA colors)\n"); + printf("-h, --help Display this help message and exit\n"); + printf("-v, --version Display version number and exit\n"); + printf("-V, --verbose Enable verbose mode\n"); printf("\n"); printf(" PLEASE NOTE that i3bar will be automatically started by i3\n" " as soon as there is a 'bar' configuration block in your\n" @@ -105,12 +106,13 @@ int main(int argc, char **argv) { static struct option long_opt[] = { {"socket", required_argument, 0, 's'}, {"bar_id", required_argument, 0, 'b'}, + {"transparency", no_argument, 0, 't'}, {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'v'}, {"verbose", no_argument, 0, 'V'}, {NULL, 0, 0, 0}}; - while ((opt = getopt_long(argc, argv, "b:s:hvV", long_opt, &option_index)) != -1) { + while ((opt = getopt_long(argc, argv, "b:s:thvV", long_opt, &option_index)) != -1) { switch (opt) { case 's': socket_path = expand_path(optarg); @@ -122,6 +124,9 @@ int main(int argc, char **argv) { case 'b': config.bar_id = sstrdup(optarg); break; + case 't': + config.transparency = true; + break; case 'V': config.verbose = true; break; diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index ccfd5135..33e13c1b 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -1197,7 +1197,21 @@ char *init_xcb_early(void) { depth = root_screen->root_depth; colormap = root_screen->default_colormap; - visual_type = get_visualtype(root_screen); + visual_type = config.transparency ? xcb_aux_find_visual_by_attrs(root_screen, -1, 32) : NULL; + if (visual_type != NULL) { + depth = xcb_aux_get_depth_of_visual(root_screen, visual_type->visual_id); + colormap = xcb_generate_id(xcb_connection); + xcb_void_cookie_t cm_cookie = xcb_create_colormap_checked(xcb_connection, + XCB_COLORMAP_ALLOC_NONE, + colormap, + xcb_root, + visual_type->visual_id); + if (xcb_request_failed(cm_cookie, "Could not allocate colormap")) { + exit(EXIT_FAILURE); + } + } else { + visual_type = get_visualtype(root_screen); + } xcb_cursor_context_t *cursor_ctx; if (xcb_cursor_context_new(conn, root_screen, &cursor_ctx) == 0) {