Use 32bit visuals when available

This commit is contained in:
LemonBoy 2014-02-24 12:35:56 +00:00
parent e9086e83b9
commit 4d5f9b60e3
2 changed files with 70 additions and 44 deletions

View File

@ -4,7 +4,7 @@ bar - bar ain't recursive
=head1 SYNOPSIS =head1 SYNOPSIS
I<bar> [-h | -g I<width>B<x>I<height>B<+>I<x> | -b | -d | -f I<font> | -a I<alpha>| -p | -u I<pixel> | -B I<color> | -F I<color>] I<bar> [-h | -g I<width>B<x>I<height>B<+>I<x> | -b | -d | -f I<font> | -p | -u I<pixel> | -B I<color> | -F I<color>]
=head1 DESCRIPTION =head1 DESCRIPTION
@ -48,7 +48,7 @@ Sets the underline width in pixels. The default is 1.
=item B<-B> I<color> =item B<-B> I<color>
Set the background color of the bar. I<color> might be either in hex format (#rrggbb) or in the symbolic name format (eg. white, brightred, darkgray). Set the background color of the bar. I<color> might be either in hex format (#aarrggbb) or in the symbolic name format (eg. white, brightred, darkgray). If no compositor such as compton or xcompmgr is running the alpha channel is silently ignored.
=item B<-F> I<color> =item B<-F> I<color>

110
bar.c
View File

@ -57,10 +57,11 @@ static xcb_connection_t *c;
static xcb_screen_t *scr; static xcb_screen_t *scr;
static xcb_drawable_t canvas; static xcb_drawable_t canvas;
static xcb_gcontext_t gc[GC_MAX]; static xcb_gcontext_t gc[GC_MAX];
static xcb_visualid_t visual;
static xcb_colormap_t colormap;
static monitor_t *monhead, *montail; static monitor_t *monhead, *montail;
static font_t *main_font, *alt_font; static font_t *main_font, *alt_font;
static uint32_t attrs = 0; static uint32_t attrs = 0;
static float ba = 1.0f; /* bar alpha */
static bool dock = false; static bool dock = false;
static bool topbar = true; static bool topbar = true;
static int bw = -1, bh = -1, bx = 0; static int bw = -1, bh = -1, bx = 0;
@ -140,16 +141,22 @@ parse_color (const char *str, char **end, const uint32_t def)
return def; return def;
} }
/* Hex rapresentation */ /* Hex representation */
if (str[0] == '#') if (str[0] == '#') {
return strtoul(str + 1, end, 16); errno = 0;
uint32_t tmp = strtoul(str + 1, end, 16);
/* Some error checking it's good */
if (errno)
return def;
return tmp;
}
/* Actual color name, resolve it */ /* Actual color name, resolve it */
str_len = 0; str_len = 0;
while (isalpha(str[str_len])) while (isalpha(str[str_len]))
str_len++; str_len++;
nc_reply = xcb_alloc_named_color_reply(c, xcb_alloc_named_color(c, scr->default_colormap, str_len, str), NULL); nc_reply = xcb_alloc_named_color_reply(c, xcb_alloc_named_color(c, colormap, str_len, str), NULL);
if (!nc_reply) if (!nc_reply)
fprintf(stderr, "Could not alloc color \"%.*s\"\n", str_len, str); fprintf(stderr, "Could not alloc color \"%.*s\"\n", str_len, str);
@ -327,7 +334,6 @@ enum {
NET_WM_STRUT_PARTIAL, NET_WM_STRUT_PARTIAL,
NET_WM_STRUT, NET_WM_STRUT,
NET_WM_STATE, NET_WM_STATE,
NET_WM_WINDOW_OPACITY,
NET_WM_STATE_STICKY, NET_WM_STATE_STICKY,
NET_WM_STATE_ABOVE, NET_WM_STATE_ABOVE,
}; };
@ -342,7 +348,6 @@ set_ewmh_atoms (void)
"_NET_WM_STRUT_PARTIAL", "_NET_WM_STRUT_PARTIAL",
"_NET_WM_STRUT", "_NET_WM_STRUT",
"_NET_WM_STATE", "_NET_WM_STATE",
"_NET_WM_WINDOW_OPACITY",
/* Leave those at the end since are batch-set */ /* Leave those at the end since are batch-set */
"_NET_WM_STATE_STICKY", "_NET_WM_STATE_STICKY",
"_NET_WM_STATE_ABOVE", "_NET_WM_STATE_ABOVE",
@ -378,7 +383,6 @@ set_ewmh_atoms (void)
strut[11] = mon->x + mon->width; strut[11] = mon->x + mon->width;
} }
xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, atom_list[NET_WM_WINDOW_OPACITY], XCB_ATOM_CARDINAL, 32, 1, (const uint32_t []){ (uint32_t)(ba * 0xffffffff) } );
xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, atom_list[NET_WM_WINDOW_TYPE], XCB_ATOM_ATOM, 32, 1, &atom_list[NET_WM_WINDOW_TYPE_DOCK]); xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, atom_list[NET_WM_WINDOW_TYPE], XCB_ATOM_ATOM, 32, 1, &atom_list[NET_WM_WINDOW_TYPE_DOCK]);
xcb_change_property(c, XCB_PROP_MODE_APPEND, mon->window, atom_list[NET_WM_STATE], XCB_ATOM_ATOM, 32, 2, &atom_list[NET_WM_STATE_STICKY]); xcb_change_property(c, XCB_PROP_MODE_APPEND, mon->window, atom_list[NET_WM_STATE], XCB_ATOM_ATOM, 32, 2, &atom_list[NET_WM_STATE_STICKY]);
xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, atom_list[NET_WM_DESKTOP], XCB_ATOM_CARDINAL, 32, 1, (const uint32_t []){ -1 } ); xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, atom_list[NET_WM_DESKTOP], XCB_ATOM_CARDINAL, 32, 1, (const uint32_t []){ -1 } );
@ -405,17 +409,15 @@ monitor_new (int x, int y, int width, int height)
int win_y = (topbar ? 0 : height - bh) + y; int win_y = (topbar ? 0 : height - bh) + y;
ret->window = xcb_generate_id(c); ret->window = xcb_generate_id(c);
xcb_create_window(c, XCB_COPY_FROM_PARENT, ret->window, scr->root, int depth = (visual == scr->root_visual) ? XCB_COPY_FROM_PARENT : 32;
xcb_create_window(c, depth, ret->window, scr->root,
x, win_y, width, bh, 0, x, win_y, width, bh, 0,
XCB_WINDOW_CLASS_INPUT_OUTPUT, scr->root_visual, XCB_WINDOW_CLASS_INPUT_OUTPUT, visual,
XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP,
(const uint32_t []){ bgc, dock, XCB_EVENT_MASK_EXPOSURE }); (const uint32_t []){ bgc, bgc, dock, XCB_EVENT_MASK_EXPOSURE, colormap });
ret->pixmap = xcb_generate_id(c); ret->pixmap = xcb_generate_id(c);
xcb_create_pixmap(c, scr->root_depth, ret->pixmap, scr->root, width, bh); xcb_create_pixmap(c, depth, ret->pixmap, ret->window, width, bh);
/* Clear the bar */
fill_rect(ret->pixmap, gc[GC_CLEAR], 0, 0, width, bh);
return ret; return ret;
} }
@ -603,6 +605,27 @@ get_xinerama_monitors (void)
monitor_create_chain(rects, screens); monitor_create_chain(rects, screens);
} }
xcb_visualid_t
get_visual (void)
{
xcb_depth_iterator_t iter;
iter = xcb_screen_allowed_depths_iterator(scr);
/* Try to find a RGBA visual */
while (iter.rem) {
xcb_visualtype_t *vis = xcb_depth_visuals(iter.data);
if (iter.data->depth == 32)
return vis->visual_id;
xcb_depth_next(&iter);
}
/* Fallback to the default one */
return scr->root_visual;
}
void void
xconn (void) xconn (void)
{ {
@ -615,6 +638,12 @@ xconn (void)
/* Grab infos from the first screen */ /* Grab infos from the first screen */
scr = xcb_setup_roots_iterator(xcb_get_setup(c)).data; scr = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
/* Try to get a RGBA visual and build the colormap for that */
visual = get_visual();
colormap = xcb_generate_id(c);
xcb_create_colormap(c, XCB_COLORMAP_ALLOC_NONE, colormap, scr->root, visual);
} }
void void
@ -640,18 +669,6 @@ init (void)
if (bh < 0 || bh > scr->height_in_pixels) if (bh < 0 || bh > scr->height_in_pixels)
bh = main_font->height + bu + 2; bh = main_font->height + bu + 2;
ugc = fgc;
/* Create the gc for drawing */
gc[GC_DRAW] = xcb_generate_id(c);
xcb_create_gc(c, gc[GC_DRAW], scr->root, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND, (const uint32_t []){ fgc, bgc });
gc[GC_CLEAR] = xcb_generate_id(c);
xcb_create_gc(c, gc[GC_CLEAR], scr->root, XCB_GC_FOREGROUND, (const uint32_t []){ bgc });
gc[GC_ATTR] = xcb_generate_id(c);
xcb_create_gc(c, gc[GC_ATTR], scr->root, XCB_GC_FOREGROUND, (const uint32_t []){ ugc });
/* Generate a list of screens */ /* Generate a list of screens */
const xcb_query_extension_reply_t *qe_reply; const xcb_query_extension_reply_t *qe_reply;
@ -688,9 +705,21 @@ init (void)
/* For WM that support EWMH atoms */ /* For WM that support EWMH atoms */
set_ewmh_atoms(); set_ewmh_atoms();
/* Make the bar visible */ /* Create the gc for drawing */
for (monitor_t *mon = monhead; mon; mon = mon->next) gc[GC_DRAW] = xcb_generate_id(c);
xcb_create_gc(c, gc[GC_DRAW], monhead->pixmap, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND, (const uint32_t []){ fgc, bgc });
gc[GC_CLEAR] = xcb_generate_id(c);
xcb_create_gc(c, gc[GC_CLEAR], monhead->pixmap, XCB_GC_FOREGROUND, (const uint32_t []){ bgc });
gc[GC_ATTR] = xcb_generate_id(c);
xcb_create_gc(c, gc[GC_ATTR], monhead->pixmap, XCB_GC_FOREGROUND, (const uint32_t []){ ugc });
/* Make the bar visible and clear the pixmap */
for (monitor_t *mon = monhead; mon; mon = mon->next) {
fill_rect(mon->pixmap, gc[GC_CLEAR], 0, 0, mon->width, bh);
xcb_map_window(c, mon->window); xcb_map_window(c, mon->window);
}
xcb_flush(c); xcb_flush(c);
} }
@ -716,6 +745,8 @@ cleanup (void)
monhead = next; monhead = next;
} }
xcb_free_colormap(c, colormap);
if (gc[GC_DRAW]) if (gc[GC_DRAW])
xcb_free_gc(c, gc[GC_DRAW]); xcb_free_gc(c, gc[GC_DRAW]);
if (gc[GC_CLEAR]) if (gc[GC_CLEAR])
@ -824,8 +855,10 @@ main (int argc, char **argv)
xconn(); xconn();
/* B/W combo */ /* B/W combo */
dbgc = bgc = scr->black_pixel; dbgc = bgc = parse_color("black", NULL, scr->black_pixel);
dfgc = fgc = scr->white_pixel; dfgc = fgc = parse_color("white", NULL, scr->white_pixel);
ugc = fgc;
char ch; char ch;
while ((ch = getopt(argc, argv, "hg:bdf:a:pu:B:F:")) != -1) { while ((ch = getopt(argc, argv, "hg:bdf:a:pu:B:F:")) != -1) {
@ -837,13 +870,11 @@ main (int argc, char **argv)
"\t-b Put bar at the bottom of the screen\n" "\t-b Put bar at the bottom of the screen\n"
"\t-d Force docking (use this if your WM isn't EWMH compliant)\n" "\t-d Force docking (use this if your WM isn't EWMH compliant)\n"
"\t-f Bar font list, comma separated\n" "\t-f Bar font list, comma separated\n"
"\t-a Set the bar alpha ranging from 0.0 to 1.0 (requires a compositor)\n"
"\t-p Don't close after the data ends\n" "\t-p Don't close after the data ends\n"
"\t-u Set the underline/overline height in pixels\n" "\t-u Set the underline/overline height in pixels\n"
"\t-B Set background color in #RRGGBB\n" "\t-B Set background color in #AARRGGBB\n"
"\t-F Set foreground color in #RRGGBB\n", argv[0]); "\t-F Set foreground color in #AARRGGBB\n", argv[0]);
exit (EXIT_SUCCESS); exit (EXIT_SUCCESS);
case 'a': ba = strtof(optarg, NULL); break;
case 'g': (void)parse_geometry_string(optarg, geom_v); break; case 'g': (void)parse_geometry_string(optarg, geom_v); break;
case 'p': permanent = true; break; case 'p': permanent = true; break;
case 'b': topbar = false; break; case 'b': topbar = false; break;
@ -860,17 +891,12 @@ main (int argc, char **argv)
bh = geom_v[1]; bh = geom_v[1];
bx = geom_v[2]; bx = geom_v[2];
/* Sanitize the arguments */ /* Check the geometry */
if (bx >= scr->width_in_pixels || bx + bw > scr->width_in_pixels) { if (bx >= scr->width_in_pixels || bx + bw > scr->width_in_pixels) {
fprintf(stderr, "The geometry specified doesn't fit the screen!\n"); fprintf(stderr, "The geometry specified doesn't fit the screen!\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (ba > 1.0f)
ba = 1.0f;
if (ba < 0.0f)
ba = 0.0f;
/* Do the heavy lifting */ /* Do the heavy lifting */
init(); init();
/* Get the fd to Xserver */ /* Get the fd to Xserver */