Add transparency support. Reworked EWMH stuff, fixes #20.
This commit is contained in:
parent
216162c7eb
commit
d87fc1f0c8
|
@ -1,10 +1,11 @@
|
||||||
b(ar) a(in't) r(ecursive)
|
b(ar) a(in't) r(ecursive)
|
||||||
=========================
|
=========================
|
||||||
2012 (C) The Lemon Man
|
2012-2013 (C) The Lemon Man
|
||||||
|
|
||||||
A lightweight bar based on XCB (yay). Provides foreground/background color
|
A lightweight bar based on XCB (yay). Provides foreground/background color
|
||||||
switching along with text alignment (screw you dzen!), full utf8 support
|
switching along with text alignment (screw you dzen!), full utf8 support
|
||||||
and reduced memory footprint. Nothing less and nothing more.
|
and reduced memory footprint. It also supports transparency when using a
|
||||||
|
compositor such as compton. Nothing less and nothing more.
|
||||||
|
|
||||||
Options
|
Options
|
||||||
-------
|
-------
|
||||||
|
@ -13,6 +14,7 @@ bar accepts a couple of command line switches.
|
||||||
```
|
```
|
||||||
-h Show the help and bail out.
|
-h Show the help and bail out.
|
||||||
-p Make the bar permanent.
|
-p Make the bar permanent.
|
||||||
|
-f Force docking (use this if your WM isn't EWMH compliant)
|
||||||
-b Show the bar at the bottom of the screen.
|
-b Show the bar at the bottom of the screen.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
131
bar.c
131
bar.c
|
@ -44,6 +44,7 @@ static xcb_gcontext_t clear_gc;
|
||||||
static xcb_gcontext_t underl_gc;
|
static xcb_gcontext_t underl_gc;
|
||||||
static int bar_width;
|
static int bar_width;
|
||||||
static int bar_bottom = BAR_BOTTOM;
|
static int bar_bottom = BAR_BOTTOM;
|
||||||
|
static int force_docking = 0;
|
||||||
static fontset_item_t fontset[FONT_MAX];
|
static fontset_item_t fontset[FONT_MAX];
|
||||||
static fontset_item_t *sel_font = NULL;
|
static fontset_item_t *sel_font = NULL;
|
||||||
|
|
||||||
|
@ -240,72 +241,67 @@ font_load (const char **font_list)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
enum {
|
||||||
set_ewmh_atoms (xcb_window_t root)
|
NET_WM_WINDOW_TYPE,
|
||||||
|
NET_WM_WINDOW_TYPE_DOCK,
|
||||||
|
NET_WM_DESKTOP,
|
||||||
|
NET_WM_STRUT_PARTIAL,
|
||||||
|
NET_WM_STRUT,
|
||||||
|
NET_WM_STATE,
|
||||||
|
NET_WM_WINDOW_OPACITY,
|
||||||
|
NET_WM_STATE_STICKY,
|
||||||
|
NET_WM_STATE_ABOVE,
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
set_ewmh_atoms ()
|
||||||
{
|
{
|
||||||
xcb_intern_atom_cookie_t cookies[5];
|
const char *atom_names[] = {
|
||||||
xcb_intern_atom_reply_t *reply;
|
"_NET_WM_WINDOW_TYPE",
|
||||||
xcb_get_property_reply_t *reply1;
|
"_NET_WM_WINDOW_TYPE_DOCK",
|
||||||
xcb_atom_t atoms[5];
|
"_NET_WM_DESKTOP",
|
||||||
int compliance_lvl;
|
"_NET_WM_STRUT_PARTIAL",
|
||||||
uint32_t v[12] = {0};
|
"_NET_WM_STRUT",
|
||||||
|
"_NET_WM_STATE",
|
||||||
|
"_NET_WM_WINDOW_OPACITY",
|
||||||
|
/* Leave those at the end since are batch-set */
|
||||||
|
"_NET_WM_STATE_STICKY",
|
||||||
|
"_NET_WM_STATE_ABOVE",
|
||||||
|
};
|
||||||
|
const int atoms = sizeof(atom_names)/sizeof(char *);
|
||||||
|
xcb_intern_atom_cookie_t atom_cookie[atoms];
|
||||||
|
xcb_atom_t atom_list[atoms];
|
||||||
|
xcb_intern_atom_reply_t *atom_reply;
|
||||||
|
int strut[12] = {0};
|
||||||
|
|
||||||
cookies[0] = xcb_intern_atom (c, 0, strlen ("_NET_WM_WINDOW_TYPE") , "_NET_WM_WINDOW_TYPE");
|
/* As suggested fetch all the cookies first (yum!) and then retrieve the
|
||||||
cookies[1] = xcb_intern_atom (c, 0, strlen ("_NET_WM_WINDOW_TYPE_DOCK"), "_NET_WM_WINDOW_TYPE_DOCK");
|
* atoms to exploit the async'ness */
|
||||||
cookies[2] = xcb_intern_atom (c, 0, strlen ("_NET_WM_DESKTOP") , "_NET_WM_DESKTOP");
|
for (int i = 0; i < atoms; i++)
|
||||||
cookies[3] = xcb_intern_atom (c, 0, strlen ("_NET_WM_STRUT_PARTIAL") , "_NET_WM_STRUT_PARTIAL");
|
atom_cookie[i] = xcb_intern_atom(c, 0, strlen(atom_names[i]), atom_names[i]);
|
||||||
cookies[4] = xcb_intern_atom (c, 0, strlen ("_NET_SUPPORTED") , "_NET_SUPPORTED");
|
|
||||||
|
|
||||||
reply = xcb_intern_atom_reply (c, cookies[0], NULL);
|
for (int i = 0; i < atoms; i++) {
|
||||||
atoms[0] = reply->atom; free (reply);
|
atom_reply = xcb_intern_atom_reply(c, atom_cookie[i], NULL);
|
||||||
reply = xcb_intern_atom_reply (c, cookies[1], NULL);
|
if (!atom_reply)
|
||||||
atoms[1] = reply->atom; free (reply);
|
return;
|
||||||
reply = xcb_intern_atom_reply (c, cookies[2], NULL);
|
atom_list[i] = atom_reply->atom;
|
||||||
atoms[2] = reply->atom; free (reply);
|
free(atom_reply);
|
||||||
reply = xcb_intern_atom_reply (c, cookies[3], NULL);
|
|
||||||
atoms[3] = reply->atom; free (reply);
|
|
||||||
reply = xcb_intern_atom_reply (c, cookies[4], NULL);
|
|
||||||
atoms[4] = reply->atom; free (reply);
|
|
||||||
|
|
||||||
compliance_lvl = 0;
|
|
||||||
|
|
||||||
reply1 = xcb_get_property_reply (c, xcb_get_property (c, 0, root, atoms[4], XCB_ATOM_ATOM, 0, -1), NULL);
|
|
||||||
if (!reply)
|
|
||||||
return compliance_lvl;
|
|
||||||
|
|
||||||
for (xcb_atom_t *a = xcb_get_property_value (reply1);
|
|
||||||
a && a != xcb_get_property_value_end (reply1).data;
|
|
||||||
a++)
|
|
||||||
{
|
|
||||||
/* Set the _NET_WM_WINDOW_TYPE_DOCK state */
|
|
||||||
if (*a == atoms[0]) {
|
|
||||||
xcb_change_property (c, XCB_PROP_MODE_REPLACE, win, atoms[0], XCB_ATOM_ATOM, 32, 1, &atoms[1]);
|
|
||||||
compliance_lvl++;
|
|
||||||
}
|
|
||||||
/* Show on every desktop */
|
|
||||||
if (*a == atoms[2]) {
|
|
||||||
xcb_change_property (c, XCB_PROP_MODE_REPLACE, win, atoms[2], XCB_ATOM_CARDINAL, 32, 1,
|
|
||||||
(const uint32_t []){ 0xffffffff } );
|
|
||||||
compliance_lvl++;
|
|
||||||
}
|
|
||||||
/* Tell the WM that this space is for the bar */
|
|
||||||
if (*a == atoms[3]) {
|
|
||||||
if (bar_bottom) {
|
|
||||||
v[3] = BAR_HEIGHT;
|
|
||||||
v[11] = bar_width;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
v[2] = BAR_HEIGHT;
|
|
||||||
v[8] = bar_width;
|
|
||||||
}
|
|
||||||
xcb_change_property (c, XCB_PROP_MODE_REPLACE, win, atoms[3], XCB_ATOM_CARDINAL, 32, 12, v);
|
|
||||||
compliance_lvl++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
free (reply1);
|
|
||||||
|
|
||||||
/* If the wm supports at least 2 NET atoms then mark as compliant */
|
/* Prepare the strut array */
|
||||||
return (compliance_lvl > 1);
|
if (bar_bottom) {
|
||||||
|
strut[3] = BAR_HEIGHT;
|
||||||
|
strut[11] = bar_width;
|
||||||
|
} else {
|
||||||
|
strut[2] = BAR_HEIGHT;
|
||||||
|
strut[9] = bar_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_change_property (c, XCB_PROP_MODE_REPLACE, win, atom_list[NET_WM_WINDOW_OPACITY], XCB_ATOM_CARDINAL, 32, 1, (const uint32_t []){ (uint32_t)(BAR_OPACITY * 0xffffffff) } );
|
||||||
|
xcb_change_property (c, XCB_PROP_MODE_REPLACE, win, 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, win, atom_list[NET_WM_STATE], XCB_ATOM_ATOM, 32, 2, &atom_list[NET_WM_STATE_STICKY]);
|
||||||
|
xcb_change_property (c, XCB_PROP_MODE_REPLACE, win, atom_list[NET_WM_DESKTOP], XCB_ATOM_CARDINAL, 32, 1, (const uint32_t []){ -1 } );
|
||||||
|
xcb_change_property (c, XCB_PROP_MODE_REPLACE, win, atom_list[NET_WM_STRUT_PARTIAL], XCB_ATOM_CARDINAL, 32, 12, strut);
|
||||||
|
xcb_change_property (c, XCB_PROP_MODE_REPLACE, win, atom_list[NET_WM_STRUT], XCB_ATOM_CARDINAL, 32, 4, strut);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -340,11 +336,10 @@ init (void)
|
||||||
BAR_HEIGHT, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, scr->root_visual,
|
BAR_HEIGHT, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, scr->root_visual,
|
||||||
XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, (const uint32_t []){ palette[10], XCB_EVENT_MASK_EXPOSURE });
|
XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, (const uint32_t []){ palette[10], XCB_EVENT_MASK_EXPOSURE });
|
||||||
|
|
||||||
/* Set EWMH hints */
|
/* For WM that support EWMH atoms */
|
||||||
int ewmh_docking = set_ewmh_atoms (root);
|
set_ewmh_atoms();
|
||||||
|
|
||||||
/* Quirk for wm not supporting the EWMH docking method */
|
xcb_change_window_attributes (c, win, XCB_CW_OVERRIDE_REDIRECT, (const uint32_t []){ force_docking });
|
||||||
xcb_change_window_attributes (c, win, XCB_CW_OVERRIDE_REDIRECT, (const uint32_t []){ !ewmh_docking });
|
|
||||||
|
|
||||||
/* Create a temporary canvas */
|
/* Create a temporary canvas */
|
||||||
canvas = xcb_generate_id (c);
|
canvas = xcb_generate_id (c);
|
||||||
|
@ -362,8 +357,6 @@ init (void)
|
||||||
|
|
||||||
/* Make the bar visible */
|
/* Make the bar visible */
|
||||||
xcb_map_window (c, win);
|
xcb_map_window (c, win);
|
||||||
/* Send a configure event. Needed to make bar work with Openbox */
|
|
||||||
xcb_configure_window (c, win, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, (const uint32_t []){ BAR_OFFSET, y });
|
|
||||||
|
|
||||||
xcb_flush (c);
|
xcb_flush (c);
|
||||||
}
|
}
|
||||||
|
@ -412,16 +405,18 @@ main (int argc, char **argv)
|
||||||
int permanent = 0;
|
int permanent = 0;
|
||||||
|
|
||||||
char ch;
|
char ch;
|
||||||
while ((ch = getopt (argc, argv, "phb")) != -1) {
|
while ((ch = getopt (argc, argv, "phbf")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'h':
|
case 'h':
|
||||||
printf ("usage: %s [-p | -h] [-b]\n"
|
printf ("usage: %s [-p | -h] [-b]\n"
|
||||||
"\t-h Show this help\n"
|
"\t-h Show this help\n"
|
||||||
"\t-b Put bar at the bottom of the screen\n"
|
"\t-b Put bar at the bottom of the screen\n"
|
||||||
|
"\t-f Force docking (use this if your WM isn't EWMH compliant)\n"
|
||||||
"\t-p Don't close after the data ends\n", argv[0]);
|
"\t-p Don't close after the data ends\n", argv[0]);
|
||||||
exit (0);
|
exit (0);
|
||||||
case 'p': permanent = 1; break;
|
case 'p': permanent = 1; break;
|
||||||
case 'b': bar_bottom = 1; break;
|
case 'b': bar_bottom = 1; break;
|
||||||
|
case 'f': force_docking = 1; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#define BAR_FONT "-*-terminus-medium-r-normal-*-12-*-*-*-c-*-*-1","fixed"
|
#define BAR_FONT "-*-terminus-medium-r-normal-*-12-*-*-*-c-*-*-1","fixed"
|
||||||
/* Some fonts don't set the right width for some chars, pheex it */
|
/* Some fonts don't set the right width for some chars, pheex it */
|
||||||
#define BAR_FONT_FALLBACK_WIDTH 6
|
#define BAR_FONT_FALLBACK_WIDTH 6
|
||||||
|
/* Define the opacity of the bar (requires a compositor such as compton) */
|
||||||
|
#define BAR_OPACITY 1.0 /* 0 is invisible, 1 is opaque */
|
||||||
/* Color palette */
|
/* Color palette */
|
||||||
#define BACKGROUND 0x232c31
|
#define BACKGROUND 0x232c31
|
||||||
#define COLOR0 0x2d3c46
|
#define COLOR0 0x2d3c46
|
||||||
|
|
Loading…
Reference in New Issue
Block a user