Infobar: Add Infobar element: see elements_order in [bar]

This commit is contained in:
Martin Duquesnoy 2011-08-04 18:43:51 +02:00
parent 02cd7d91e9
commit 13d8a0acc8
6 changed files with 261 additions and 133 deletions

View File

@ -217,10 +217,11 @@ conf_bar_section(void)
conf.bars.height = fetch_opt_first(bar, "-1", "height").num;
conf.colors.bar = getcolor((barbg = fetch_opt_first(bar, "#000000", "bg").str));
conf.colors.text = fetch_opt_first(bar, "#ffffff", "fg").str;
conf.colors.bar_light_shade = fetch_opt_first(bar, "0.25", "light_shade").fnum;
conf.colors.bar_dark_shade = fetch_opt_first(bar, "-0.25", "dark_shade").fnum;
conf.bars.element_order = fetch_opt_first(bar, "tls", "elements_order").str;
mouse = fetch_section(bar, "mouse");
if ((conf.bars.nmouse = fetch_section_count(mouse)) > 0)
@ -442,9 +443,6 @@ conf_layout_section(void)
if((tmp = fetch_opt_first(layouts, "menu", "system").str) && !strcmp(tmp, "menu"))
conf.layout_system = True;
if((tmp = fetch_opt_first(layouts, "right", "placement").str) && !strcmp(tmp, "left"))
conf.layout_placement = True;
layout = fetch_section(layouts, "layout");
conf.nlayout = fetch_section_count(layout);

View File

@ -115,26 +115,29 @@ buttonpress(XEvent *e)
do_mousebind(selscreen, ev->button, conf.selbar.nmouse, conf.selbar.mouse);
/* Tags */
for(i = 1; i < conf.ntag[selscreen] + 1; ++i)
if(ev->window == ib->tags[i]->win)
{
do_mousebind(selscreen, ev->button, tags[selscreen][i].nmouse, tags[selscreen][i].mouse);
if(ib->tags_board)
{
for(i = 1; i < conf.ntag[selscreen] + 1; ++i)
if(ev->window == ib->tags[i]->win)
{
do_mousebind(selscreen, ev->button, tags[selscreen][i].nmouse, tags[selscreen][i].mouse);
/* Mouse button action on tag */
if(ev->button == conf.mouse_tag_action[TagSel])
tag_set(i);
else if(ev->button == conf.mouse_tag_action[TagTransfert])
tag_transfert(sel, i);
else if(ev->button == conf.mouse_tag_action[TagAdd])
tag_additional(selscreen, seltag[selscreen], i);
else if(ev->button == conf.mouse_tag_action[TagNext])
tag_set(seltag[selscreen] + 1);
else if(ev->button == conf.mouse_tag_action[TagPrev])
tag_set(seltag[selscreen] - 1);
}
/* Mouse button action on tag */
if(ev->button == conf.mouse_tag_action[TagSel])
tag_set(i);
else if(ev->button == conf.mouse_tag_action[TagTransfert])
tag_transfert(sel, i);
else if(ev->button == conf.mouse_tag_action[TagAdd])
tag_additional(selscreen, seltag[selscreen], i);
else if(ev->button == conf.mouse_tag_action[TagNext])
tag_set(seltag[selscreen] + 1);
else if(ev->button == conf.mouse_tag_action[TagPrev])
tag_set(seltag[selscreen] - 1);
}
}
/* Layout button */
if(ev->window == ib->layout_button->win && conf.nlayout > 1)
if(ib->layout_button && ev->window == ib->layout_button->win && conf.nlayout > 1)
{
if(conf.layout_system && (ev->button == Button1 || ev->button == Button3)) /* True -> menu */
{

View File

@ -34,101 +34,184 @@
#define SPLIT_IND_S (3 + conf.border.layout)
/** Init InfoBar elements
*/
static void
infobar_init_element(InfoBar *i)
{
int j = 0, k, n = 0;
InfobarElem *e, *prev = NULL;
Geo pg = { -PAD, 0, 0, 0 };
STAILQ_INIT(&i->elemhead);
for(; n < (int)strlen(i->elemorder); ++n)
{
e = zcalloc(sizeof(InfobarElem));
/* Previous element geo */
if(prev)
pg = prev->geo;
e->geo.x = pg.x + pg.width + PAD;
e->geo.y = 0;
e->geo.height = i->geo.height;
switch(i->elemorder[n])
{
/* Tags element */
case 't':
e->type = ElemTag;
e->geo.width = PAD; /* Will change */
if(!i->tags_board)
{
i->tags_board = barwin_create(i->bar->win,
e->geo.x,
e->geo.y,
e->geo.width,
e->geo.height,
conf.colors.bar, conf.colors.text,
False, False, False);
/* Create tags window */
for(k = 1; k < conf.ntag[i->screen] + 1; ++k)
{
i->tags[k] = barwin_create(i->tags_board->win,
j, 0,
textw(tags[i->screen][k].name) + PAD,
i->geo.height,
conf.colors.bar, conf.colors.text,
False, False, conf.border.tag);
j += textw(tags[i->screen][k].name) + PAD;
barwin_map_subwin(i->tags[k]);
}
}
barwin_resize(i->tags_board, (e->geo.width = j), i->geo.height);
barwin_map(i->tags_board);
barwin_map_subwin(i->tags_board);
break;
/* Layout button element */
case 'l':
e->type = ElemLayout;
e->geo.width = (conf.layout_button_width > 0
? (uint)conf.layout_button_width
: textw(tags[i->screen][seltag[i->screen]].layout.symbol) + PAD);
if(!i->layout_button)
i->layout_button = barwin_create(i->bar->win,
e->geo.x,
e->geo.y,
e->geo.width,
e->geo.height,
conf.colors.layout_bg, conf.colors.layout_fg,
False, False, conf.border.layout);
barwin_map(i->layout_button);
if(conf.border.layout)
barwin_map_subwin(i->layout_button);
break;
/* Selbar element */
case 's':
e->type = ElemSelbar;
i->selbar_geo = e->geo;
break;
}
STAILQ_INSERT_TAIL(&i->elemhead, e, next);
prev = e;
e = NULL;
}
return;
}
/** Init the InfoBar
*/
void
infobar_init(void)
{
InfoBar *ib;
int s, sc, i, j = 0;
s = screen_count();
InfoBar *i;
int s = screen_count(), sc = 0;
if(!infobar)
infobar = xcalloc(s, sizeof(InfoBar));
for(sc = 0; sc < s; ++sc)
for(; sc < s; ++sc)
{
j = 0;
ib = &infobar[sc];
ib->geo.height = INFOBARH;
ib->screen = sc;
i = &infobar[sc];
i->geo.height = INFOBARH;
i->screen = sc;
i->elemorder = conf.bars.element_order;
switch(tags[sc][seltag[sc]].barpos)
{
case IB_Hide:
sgeo[sc].y = spgeo[sc].y + TBARH;
sgeo[sc].height += INFOBARH;
ib->geo.y = (-(ib->geo.height) << 2);
break;
case IB_Bottom:
sgeo[sc].y = TBARH;
ib->geo.y = spgeo[sc].y + sgeo[sc].height + TBARH;
break;
default:
case IB_Top:
sgeo[sc].y = spgeo[sc].y + INFOBARH + TBARH;
ib->geo.y = spgeo[sc].y;
break;
case IB_Hide:
sgeo[sc].y = spgeo[sc].y + TBARH;
sgeo[sc].height += INFOBARH;
i->geo.y = (-(i->geo.height) << 2);
break;
case IB_Bottom:
sgeo[sc].y = TBARH;
i->geo.y = spgeo[sc].y + sgeo[sc].height + TBARH;
break;
default:
case IB_Top:
sgeo[sc].y = spgeo[sc].y + INFOBARH + TBARH;
i->geo.y = spgeo[sc].y;
break;
}
/* Create infobar barwindow */
ib->bar = barwin_create(ROOT, sgeo[sc].x - BORDH, ib->geo.y,
sgeo[sc].width, ib->geo.height,
conf.colors.bar, conf.colors.text, False, False, conf.border.bar);
i->bar = barwin_create(ROOT,
sgeo[sc].x - BORDH,
i->geo.y,
sgeo[sc].width,
i->geo.height,
conf.colors.bar, conf.colors.text,
False, False, conf.border.bar);
ib->tags_board = barwin_create(ib->bar->win,
((conf.layout_placement) ? textw(tags[sc][seltag[sc]].layout.symbol) + PAD * 1.5: 0), 0,
textw(tags[sc][0].name) + PAD, /* Base size, will change */
ib->geo.height,
conf.colors.bar, conf.colors.text, False, False, False);
barwin_map(i->bar);
barwin_map_subwin(i->bar);
barwin_refresh_color(i->bar);
barwin_refresh(i->bar);
/* Create tags window */
for(i = 1; i < conf.ntag[sc] + 1; ++i)
{
ib->tags[i] = barwin_create(ib->tags_board->win, j, 0,
textw(tags[sc][i].name) + PAD,
ib->geo.height,
conf.colors.bar, conf.colors.text, False, False, conf.border.tag);
j += textw(tags[sc][i].name) + PAD;
barwin_resize(ib->tags_board, j, ib->geo.height);
barwin_map_subwin(ib->tags[i]);
}
/* Create layout switch barwindow */
ib->layout_button = barwin_create(ib->bar->win,
((conf.layout_placement) ? 0 : (j + (PAD >> 1))), 0,
((conf.layout_button_width > 0) ? (uint)conf.layout_button_width : (textw(tags[sc][seltag[sc]].layout.symbol) + PAD)),
ib->geo.height,
conf.colors.layout_bg, conf.colors.layout_fg,
False, False, conf.border.layout);
/* Selbar */
if(conf.bars.selbar)
{
ib->selbar_geo.y = 0;
ib->selbar_geo.height = ib->geo.height;
}
/* Map/Refresh all */
barwin_map(ib->bar);
barwin_map_subwin(ib->bar);
barwin_map(ib->tags_board);
barwin_map_subwin(ib->tags_board);
if(conf.border.layout)
barwin_map_subwin(ib->layout_button);
barwin_refresh_color(ib->bar);
barwin_refresh(ib->bar);
/* Init elements */
infobar_init_element(i);
/* Default statustext is set here */
ib->statustext = xstrdup("wmfs"WMFS_VERSION);
i->statustext = xstrdup("wmfs"WMFS_VERSION);
infobar_draw(ib);
infobar_draw(i);
}
return;
}
static void
infobar_arrange_element(InfoBar *i)
{
Geo pg = { -PAD, 0, 0, 0 };
InfobarElem *e, *pe = NULL;
STAILQ_FOREACH(e, &i->elemhead, next)
{
if(pe)
pg = pe->geo;
e->geo.x = pg.x + pg.width + PAD;
e->geo.y = 0;
if(e->type != ElemSelbar)
barwin_move((e->type == ElemTag ? i->tags_board : i->layout_button), e->geo.x, e->geo.y);
pe = e;
}
return;
@ -140,28 +223,34 @@ infobar_init(void)
void
infobar_draw_layout(InfoBar *i)
{
int w, sc = i->screen;
InfobarElem *e;
int s = i->screen;
if(!conf.layout_placement)
barwin_move(i->layout_button, i->tags_board->geo.width + (PAD >> 1), 0);
/* Check if there is element in string element list */
if(!strchr(i->elemorder, 'l'))
return;
w = (conf.layout_button_width >= 1)
STAILQ_FOREACH(e, &i->elemhead, next)
if(e->type == ElemLayout)
break;
e->geo.width = (conf.layout_button_width >= 1)
? conf.layout_button_width
: (int)(textw(tags[sc][seltag[sc]].layout.symbol) + PAD);
: (int)(textw(tags[s][seltag[s]].layout.symbol) + PAD);
barwin_resize(i->layout_button, w, i->geo.height);
barwin_resize(i->layout_button, e->geo.width, e->geo.height);
barwin_refresh_color(i->layout_button);
/* Split mode indicator; little rectangle at bottom-right */
if(tags[sc][seltag[sc]].flags & SplitFlag)
if(tags[s][seltag[s]].flags & SplitFlag)
draw_rectangle(i->layout_button->dr,
w - SPLIT_IND_S,
i->geo.height - SPLIT_IND_S,
e->geo.width - SPLIT_IND_S,
e->geo.height - SPLIT_IND_S,
SPLIT_IND_S, SPLIT_IND_S,
getcolor(i->layout_button->fg));
if(tags[sc][seltag[sc]].layout.symbol)
barwin_draw_text(i->layout_button, (PAD >> 1), FHINFOBAR, tags[sc][seltag[sc]].layout.symbol);
if(tags[s][seltag[s]].layout.symbol)
barwin_draw_text(i->layout_button, (PAD >> 1), FHINFOBAR, tags[s][seltag[s]].layout.symbol);
return;
}
@ -179,6 +268,8 @@ _infobar_draw(InfoBar *i)
barwin_refresh(i->bar);
infobar_arrange_element(i);
return;
}
@ -202,6 +293,7 @@ infobar_draw(InfoBar *i)
void
infobar_draw_selbar(InfoBar *i)
{
InfobarElem *e;
char *str = NULL;
int sc = i->screen;
bool f = False;
@ -209,9 +301,16 @@ infobar_draw_selbar(InfoBar *i)
if(!conf.bars.selbar)
return;
if(!strchr(i->elemorder, 's'))
return;
if(!sel || (sel && sel->screen != sc))
return;
STAILQ_FOREACH(e, &i->elemhead, next)
if(e->type == ElemSelbar)
break;
str = sel->title;
/* Truncate string if too long */
@ -227,17 +326,19 @@ infobar_draw_selbar(InfoBar *i)
f = True;
}
i->selbar_geo.x = (conf.layout_placement
? i->tags_board->geo.x + i->tags_board->geo.width + (PAD >> 1)
: i->layout_button->geo.x + i->layout_button->geo.width + (PAD >> 1));
XSetForeground(dpy, gc, conf.selbar.bg);
XFillRectangle(dpy, i->bar->dr, gc, i->selbar_geo.x, 0, (i->selbar_geo.width = textw(str) + PAD), i->geo.height);
draw_text(i->bar->dr, i->selbar_geo.x, FHINFOBAR - 1, conf.selbar.fg, str);
XFillRectangle(dpy, i->bar->dr, gc,
e->geo.x,
e->geo.y,
(e->geo.width = textw(str) + PAD),
e->geo.height);
draw_text(i->bar->dr, e->geo.x, FHINFOBAR, conf.selbar.fg, str);
if(f)
free(str);
i->selbar_geo = e->geo;
return;
}
@ -247,21 +348,23 @@ infobar_draw_selbar(InfoBar *i)
void
infobar_draw_taglist(InfoBar *i)
{
int j, x, sc = i->screen;
Client *c = SLIST_FIRST(&clients);
InfobarElem *e;
Client *c;
int j = 1, x = 0, sc = i->screen;
uint occupied = 0;
if(conf.layout_placement)
barwin_move(i->tags_board,
((conf.layout_button_width > 0)
? (uint)conf.layout_button_width
: (textw(tags[sc][seltag[sc]].layout.symbol) + PAD)) + (PAD >> 1), 0);
if(!strchr(i->elemorder, 't'))
return;
STAILQ_FOREACH(e, &i->elemhead, next)
if(e->type == ElemTag)
break;
SLIST_FOREACH(c, &clients, next)
if(c->screen == sc)
occupied |= TagFlag(c->tag);
for(j = 1, x = 0; j < conf.ntag[sc] + 1; ++j)
for(; j < conf.ntag[sc] + 1; ++j)
{
/* Autohide tag feature */
if(conf.tagautohide)
@ -274,7 +377,7 @@ infobar_draw_taglist(InfoBar *i)
barwin_map(i->tags[j]);
barwin_move(i->tags[j], x, 0);
barwin_resize(i->tags_board, (x += i->tags[j]->geo.width), i->geo.height);
barwin_resize(i->tags_board, (e->geo.width = (x += i->tags[j]->geo.width)), e->geo.height);
}
if(tags[sc][j].flags & TagUrgentFlag)
@ -343,6 +446,7 @@ infobar_update_taglist(InfoBar *i)
void
infobar_destroy(void)
{
InfobarElem *e;
int sc, i;
for(sc = 0; sc < screen_count(); ++sc)
@ -360,6 +464,15 @@ infobar_destroy(void)
barwin_delete(infobar[sc].tags_board);
barwin_delete_subwin(infobar[sc].bar);
barwin_delete(infobar[sc].bar);
/* Free elements */
while(!STAILQ_EMPTY(&infobar[sc].elemhead))
{
e = STAILQ_FIRST(&infobar[sc].elemhead);
STAILQ_REMOVE_HEAD(&infobar[sc].elemhead, next);
free(e);
}
}
return;

View File

@ -189,16 +189,17 @@ launcher_execute(Launcher *launcher)
char buf[512] = { 0 };
char tmpbuf[512] = { 0 };
char *complete;
int i, pos = 0, histpos = 0, x, w;
int i, pos = 0, histpos = 0, w, x = 0;
int tabhits = 0;
KeySym ks;
XEvent ev;
InfobarElem *e;
screen_get_sel();
x = (conf.layout_placement)
? (infobar[selscreen].tags_board->geo.x + infobar[selscreen].tags_board->geo.width)
: (infobar[selscreen].layout_button->geo.x + infobar[selscreen].layout_button->geo.width);
STAILQ_FOREACH(e, &infobar[selscreen].elemhead, next)
if(x < (e->geo.x + e->geo.width))
x = e->geo.x + e->geo.width + PAD;
XGrabKeyboard(dpy, ROOT, True, GrabModeAsync, GrabModeAsync, CurrentTime);

View File

@ -112,10 +112,10 @@ enum { TagSel, TagTransfert, TagAdd, TagNext, TagPrev, TagActionLast };
/* Menu align */
enum { MA_Center = 0, MA_Left = 1, MA_Right = 2 };
/* Infobar position */
/* Infobar position / elements */
enum { IB_Hide = 0, IB_Bottom = 1, IB_Top = 2 };
typedef enum { Right = 0, Left, Top, Bottom, Center, PositionLast } Position;
typedef enum { ElemTag, ElemLayout, ElemSelbar } IbElemType;
/* Ewmh hints list */
enum
@ -267,12 +267,22 @@ typedef struct
uicb_t cmd;
} MouseBinding;
/* InfoBar elements */
typedef struct InfobarElem
{
IbElemType type;
Geo geo;
STAILQ_ENTRY(InfobarElem) next;
} InfobarElem;
/* InfoBar Struct */
typedef struct
{
BarWindow *bar;
BarWindow *layout_button;
BarWindow *tags_board, *tags[MAXTAG];
BarWindow *layout_button;
BarWindow *bar;
STAILQ_HEAD(, InfobarElem) elemhead;
char *elemorder;
Geo geo, selbar_geo;
int screen, position;
char *statustext;
@ -441,6 +451,7 @@ typedef struct
MouseBinding *mouse;
int nmouse;
bool selbar;
char *element_order;
} bars;
struct
{
@ -516,7 +527,6 @@ typedef struct
bool client_auto_center;
bool client_tile_raise;
bool layout_system; /* Switch: False, Menu: True. */
bool layout_placement; /* Right (normal): False, Left: True. */
bool keep_layout_geo;
bool cfactor_enable_split;
char *tag_expose_name;

9
wmfsrc
View File

@ -29,6 +29,12 @@
light_shade = 0.10
dark_shade = -0.10
# Order of infobar elements:
# t = Tag list
# l = Layout button
# s = Selbar
elements_order = "tls"
[systray]
# Enable/disable systray
active = true
@ -65,9 +71,6 @@
# Value menu or switch.
system = "menu"
# Value left or right.
placement = "right"
# Keep layout geo for free layout
keep_layout_geo = false