Add variable width for block support.

This commit is contained in:
geommer 2016-04-24 07:45:44 +02:00
parent 8027cce1cc
commit 0d096c44f9
7 changed files with 196 additions and 27 deletions

View file

@ -1,6 +1,6 @@
VERSION = $(shell git describe)
CPPFLAGS += -DVERSION=\"$(VERSION)\" -D_POSIX_C_SOURCE=199309L -DYA_INTERNAL -DYA_DYN_COL \
-DYA_ENV_VARS -DYA_INTERNAL_EWMH -DYA_ICON -DYA_NOWIN_COL
-DYA_ENV_VARS -DYA_INTERNAL_EWMH -DYA_ICON -DYA_NOWIN_COL -DYA_MUTEX -DYA_VAR_WIDTH
CFLAGS += -std=c99 -Iinclude -pedantic -Wall -Os `pkg-config --cflags pango pangocairo libconfig gdk-pixbuf-2.0`
LDLIBS := -lxcb -lpthread -lxcb-randr -lxcb-ewmh `pkg-config --libs pango pangocairo libconfig gdk-pixbuf-2.0`
PROGRAM := yabar

View file

@ -190,6 +190,10 @@ Each block can have its command/script, background, foreground (i.e. font), unde
image-scale-width: 0.4; #float value
image-scale-height: 0.4; #float value
* Variable width: Use this optional feature in order to fit the block width into the current text width and subsequently save empty space inside the bar. Example:
variable-size: true;
### Dynamic colors for blocks
You can change block colors(background, foreground, underline and overline) within runtime. Along with pango markup format, you can fully control how a block looks throughout yabar's session.

View file

@ -316,6 +316,17 @@ image-scale-height: 0.4; #float value
.fi
.RE
.IP \(bu 2
Variable width: Use this optional feature in order to fit the block width into the current text width and subsequently save empty space inside the bar. Example:
.PP
.RS
.nf
variable-size: true;
.fi
.RE
.SS DYNAMIC COLORS FOR BLOCKS
.PP
You can change block colors(background, foreground, underline and overline) within runtime. Along with pango markup format, you can fully control how a block looks throughout yabar's session.

View file

@ -58,6 +58,10 @@ extern char *strdup(const char *s); //to suppress implicit decleration warning f
#define GET_BLUE(c) ((double)(((c)>>8) & 0xff)/255.0)
#define GET_MIN(A, B) ((A) < (B) ? (A) : (B))
#define GET_MAX(A, B) ((A) > (B) ? (A) : (B))
enum {
A_LEFT =0,
A_CENTER=1,
@ -90,16 +94,21 @@ enum {
BLKA_INHERIT = 1<<14,
BLKA_INTERN_X_EV = 1<<15,
BLKA_ICON = 1<<16,
BLKA_DIRTY_COL = 1<<17
BLKA_DIRTY_COL = 1<<17,
BLKA_VAR_WIDTH = 1<<18
};
enum {
BARA_INHERIT = 1<<0,
BARA_INHERIT_ALL = 1<<1,
BARA_DYN_COL = 1<<2
BARA_DYN_COL = 1<<2,
BARA_REDRAW = 1<<3
};
#define SHOULD_REDRAW(blk) (((blk)->attr & BLKA_VAR_WIDTH) && (!((blk)->bar->attr & BARA_REDRAW)) && ((blk)->curwidth != (blk)->width))
#ifdef YA_INTERNAL_EWMH
#define YA_INTERNAL_LEN 12
#else
@ -193,7 +202,12 @@ struct ya_block {
#ifdef YA_ICON
blk_img_t *img;
#endif //YA_ICON
//pthread_mutex_t mutex;
#ifdef YA_MUTEX
pthread_mutex_t mutex;
#endif //YA_MUTEX
int curwidth;
};
@ -249,7 +263,9 @@ struct ya_bar {
ya_monitor_t *mon;
//pthread_mutex_t mutex;
#ifdef YA_MUTEX
pthread_mutex_t mutex;
#endif //YA_MUTEX
#ifdef YA_NOWIN_COL
xcb_gcontext_t gc;
uint32_t bgcolor_none;
@ -308,4 +324,5 @@ void ya_handle_prop_notify(xcb_property_notify_event_t *ep);
cairo_surface_t * ya_draw_graphics(ya_block_t *blk);
void ya_redraw_bar(ya_bar_t *bar);
void ya_resetup_bar(ya_block_t *blk);
#endif /*YABAR_H*/

View file

@ -109,10 +109,15 @@ void ya_create_block(ya_block_t *blk) {
}
blk->bar->curblk[blk->align] = blk;
blk->pixmap = xcb_generate_id(ya.c);
int blk_width = 0;
if ((blk->attr & BLKA_VAR_WIDTH))
blk_width = blk->bar->mon->pos.width;
else
blk_width = blk->width;
xcb_create_pixmap(ya.c,
ya.depth,
blk->pixmap,
blk->bar->win, blk->width, blk->bar->height);
blk->bar->win, blk_width, blk->bar->height);
blk->gc = xcb_generate_id(ya.c);
xcb_create_gc(ya.c, blk->gc, blk->pixmap, XCB_GC_FOREGROUND, (const uint32_t[]){blk->bgcolor});
}
@ -215,15 +220,29 @@ void ya_draw_pango_text(struct ya_block *blk) {
#endif
pango_layout_set_alignment(layout, blk->justify);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
pango_layout_set_auto_dir(layout, false);
pango_layout_set_height(layout, blk->bar->height);
#ifdef YA_VAR_WIDTH
int ht;
pango_layout_get_pixel_size(layout, &blk->curwidth, &ht);
if(SHOULD_REDRAW(blk)) {
xcb_flush(ya.c);
g_object_unref(layout);
g_object_unref(context);
cairo_destroy(cr);
cairo_surface_destroy(surface);
ya_resetup_bar(blk);
return;
}
#else
int wd, ht;
pango_layout_get_pixel_size(layout, &wd, &ht);
#endif
pango_layout_set_width(layout, blk->width * PANGO_SCALE);
pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
pango_layout_set_auto_dir(layout, false);
int wd, ht;
pango_layout_set_height(layout, blk->bar->height);
pango_layout_get_pixel_size(layout, &wd, &ht);
int offset = (blk->bar->height - ht)/2;
cairo_move_to(cr, 0, offset);
pango_cairo_show_layout(cr, layout);
@ -448,7 +467,6 @@ void ya_redraw_bar(ya_bar_t *bar) {
for(int i=0; i<3; i++) {
if((blk = bar->curblk[i])) {
for(;blk;blk = blk->next_blk) {
//pthread_mutex_lock(&blk->mutex);
#ifdef YA_DYN_COL
if(!(blk->attr & BLKA_BGCOLOR)) {
if((!(blk->attr & BLKA_DIRTY_COL))) {
@ -467,9 +485,95 @@ void ya_redraw_bar(ya_bar_t *bar) {
}
#endif //YA_DYN_COL
ya_draw_pango_text(blk);
//pthread_mutex_unlock(&blk->mutex);
}
}
}
}
#endif //YA_NOWIN_COL
#ifdef YA_VAR_WIDTH
/*
*Calculate the max allowed width for the variable-sized block that does not minimize
*area from the neighboring alignment.
*/
void ya_set_width_resetup(ya_block_t *blk) {
int width_init = blk->curwidth;
int scrw = blk->bar->mon->pos.width;
int maxw = scrw;
int othw = 0;
switch(blk->align) {
case A_LEFT:
for(ya_block_t *cblk = blk->next_blk; cblk; cblk = cblk->next_blk) {
othw +=cblk->width + cblk->bar->slack;
}
if(blk->bar->curblk[1]) {
maxw = (scrw - blk->bar->occupied_width[1])/2 -othw;
if (blk->curwidth > maxw)
blk->curwidth = maxw;
}
else if (blk->bar->curblk[2]) {
maxw = scrw - blk->bar->occupied_width[2];
}
break;
case A_CENTER:
for(ya_block_t *cblk = blk->bar->curblk[1]; cblk; cblk = cblk->next_blk) {
if(cblk != blk)
othw +=cblk->width + cblk->bar->slack;
}
if(blk->bar->curblk[0] || blk->bar->curblk[2]) {
int maxsw = GET_MAX(blk->bar->occupied_width[0], blk->bar->occupied_width[2]);
maxw = scrw -2*maxsw -othw;
}
break;
case A_RIGHT:
for(ya_block_t *cblk = blk->prev_blk; cblk; cblk = cblk->prev_blk) {
othw +=cblk->width + cblk->bar->slack;
}
if(blk->bar->curblk[1]) {
maxw = (scrw - blk->bar->occupied_width[1])/2 - othw;
if (blk->curwidth > maxw)
blk->curwidth = maxw;
}
else if (blk->bar->curblk[0]) {
maxw = scrw - blk->bar->occupied_width[0] - othw;
}
break;
}
blk->curwidth = GET_MIN(width_init, maxw);
blk->bar->occupied_width[blk->align] = blk->curwidth + othw;
}
/*
*Calculate the correct shift of blocks and then redraw the bar.
*/
void ya_resetup_bar(ya_block_t *blk) {
pthread_mutex_lock(&blk->bar->mutex);
blk->bar->attr |= BARA_REDRAW;
ya_set_width_resetup(blk);
int delta = blk->curwidth - blk->width;
blk->width = blk->curwidth;
switch(blk->align) {
case A_LEFT:
for(ya_block_t *curblk = blk->next_blk;curblk; curblk = curblk->next_blk) {
curblk->shift += delta;
}
break;
case A_CENTER: {
ya_block_t *curblk = blk->bar->curblk[1];
curblk->shift -= delta/2;
for(curblk = curblk->next_blk;curblk;curblk=curblk->next_blk)
curblk->shift = curblk->prev_blk->shift+curblk->prev_blk->width;
}
break;
case A_RIGHT: {
for(ya_block_t *curblk = blk;curblk; curblk = curblk->prev_blk)
curblk->shift -= delta;
}
break;
}
ya_redraw_bar(blk->bar);
blk->bar->attr &= ~BARA_REDRAW;
pthread_mutex_unlock(&blk->bar->mutex);
}
#endif //YA_VAR_WIDTH

View file

@ -41,9 +41,13 @@ inline static void ya_exec_intern_ewmh_blk(ya_block_t *blk) {
switch(blk->internal->index) {
case YA_INT_TITLE: {
ya_get_cur_window_title(blk);
//pthread_mutex_lock(&blk->mutex);
#ifdef YA_MUTEX
pthread_mutex_lock(&blk->mutex);
#endif
ya_draw_pango_text(blk);
//pthread_mutex_unlock(&blk->mutex);
#ifdef YA_MUTEX
pthread_mutex_unlock(&blk->mutex);
#endif
break;
}
case YA_INT_WORKSPACE: {
@ -55,9 +59,14 @@ inline static void ya_exec_intern_ewmh_blk(ya_block_t *blk) {
else {
ya_copy_buf_from_index(blk, current_desktop);
}
//pthread_mutex_lock(&blk->mutex);
#ifdef YA_MUTEX
pthread_mutex_lock(&blk->mutex);
#endif
ya_draw_pango_text(blk);
//pthread_mutex_unlock(&blk->mutex);
#ifdef YA_MUTEX
pthread_mutex_unlock(&blk->mutex);
#endif
break;
}
}
@ -88,9 +97,14 @@ static void ya_exec_redir_once(ya_block_t *blk) {
#ifdef YA_DYN_COL
ya_buf_color_parse(blk);
#endif
//pthread_mutex_lock(&blk->mutex);
#ifdef YA_MUTEX
pthread_mutex_lock(&blk->mutex);
#endif
ya_draw_pango_text(blk);
//pthread_mutex_unlock(&blk->mutex);
#ifdef YA_MUTEX
pthread_mutex_unlock(&blk->mutex);
#endif
}
}
@ -123,9 +137,14 @@ static void ya_exec_redir_period(ya_block_t *blk) {
#ifdef YA_DYN_COL
ya_buf_color_parse(blk);
#endif
//pthread_mutex_lock(&blk->mutex);
#ifdef YA_MUTEX
pthread_mutex_lock(&blk->mutex);
#endif
ya_draw_pango_text(blk);
//pthread_mutex_unlock(&blk->mutex);
#ifdef YA_MUTEX
pthread_mutex_unlock(&blk->mutex);
#endif
}
sleep(blk->sleep);
}
@ -163,9 +182,14 @@ static void ya_exec_redir_persist(ya_block_t *blk) {
#ifdef YA_DYN_COL
ya_buf_color_parse(blk);
#endif
//pthread_mutex_lock(&blk->mutex);
#ifdef YA_MUTEX
pthread_mutex_lock(&blk->mutex);
#endif
ya_draw_pango_text(blk);
//pthread_mutex_unlock(&blk->mutex);
#ifdef YA_MUTEX
pthread_mutex_unlock(&blk->mutex);
#endif
}
}
}

View file

@ -344,7 +344,9 @@ static void ya_setup_bar(config_setting_t * set) {
bar->button_cmd[4] = strdup(retstr);
}
//pthread_mutex_init(&bar->mutex, NULL);
#ifdef YA_MUTEX
pthread_mutex_init(&bar->mutex, NULL);
#endif
ya_create_bar(bar);
if(bar->attr & BARA_INHERIT_ALL) {
ya_block_t * dstblk, *srcblk;
@ -645,6 +647,11 @@ skip_type:
}
retcnf = config_setting_lookup_bool(set, "variable-size", &retint);
if (retcnf == CONFIG_TRUE && retint) {
blk->attr |= BLKA_VAR_WIDTH;
}
if(blk->attr & BLKA_EXTERNAL) {
if(blk->attr & BLKA_MARKUP_PANGO)
blk->bufsize = BUFSIZE_EXT_PANGO;
@ -665,7 +672,9 @@ skip_type:
blk->strbuf = blk->buf;
#endif
//pthread_mutex_init(&blk->mutex, NULL);
#ifdef YA_MUTEX
pthread_mutex_init(&blk->mutex, NULL);
#endif
ya_create_block(blk);
}