A more sane? implementation for variable width feature

This commit is contained in:
geommer 2016-05-02 14:02:54 +02:00
parent 4b06c264d5
commit e5c77b711d
4 changed files with 235 additions and 66 deletions

View file

@ -62,6 +62,12 @@ extern char *strdup(const char *s); //to suppress implicit decleration warning f
#define GET_MAX(A, B) ((A) > (B) ? (A) : (B))
#define DRAW_TEXT(blk) if((blk->attr & BLKA_VAR_WIDTH)) \
ya_draw_text_var_width(blk);\
else \
ya_draw_pango_text(blk);
enum {
A_LEFT =0,
A_CENTER=1,
@ -304,6 +310,8 @@ struct yabar_gen_info {
xcb_ewmh_connection_t *ewmh;
xcb_window_t curwin; //current window
xcb_window_t lstwin; //last window
uint32_t curws;
uint32_t lstws;
ya_ewmh_blk *ewmh_blk;
#endif //YA_INTERNAL_EWMH
};
@ -336,4 +344,9 @@ 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);
void ya_draw_text_var_width(ya_block_t * blk);
void ya_get_text_max_width(ya_block_t *blk);
void ya_draw_bar_var(ya_block_t *blk);
void ya_inherit_bar_bgcol(ya_block_t *blk);
void ya_draw_bar_curwin(ya_bar_t *bar);
#endif /*YABAR_H*/

View file

@ -128,6 +128,7 @@ void ya_create_block(ya_block_t *blk) {
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});
//ya_inherit_bar_bgcol(blk);
}
/*
@ -173,6 +174,7 @@ void ya_create_bar(ya_bar_t * bar) {
bar->gc = xcb_generate_id(ya.c);
xcb_create_gc(ya.c, bar->gc, bar->win, XCB_GC_FOREGROUND, (const uint32_t[]){bar->bgcolor});
#endif //YA_NOWIN_COL
ya_draw_bar_curwin(bar);
ya_setup_ewmh(bar);
}
@ -197,6 +199,8 @@ xcb_visualtype_t * ya_get_visualtype() {
* Here is how the text buffer of a block is rendered on the screen
*/
void ya_draw_pango_text(struct ya_block *blk) {
if((blk->bar->attr & BARA_REDRAW))
ya_inherit_bar_bgcol(blk);
//First override the block area with its background color in order to not draw the new text above the old one.
xcb_poly_fill_rectangle(ya.c, blk->pixmap, blk->gc, 1, (const xcb_rectangle_t[]) { {0,0,blk->width, blk->bar->height} });
cairo_surface_t *surface = cairo_xcb_surface_create(ya.c, blk->pixmap, ya.visualtype, blk->width, blk->bar->height);
@ -244,25 +248,17 @@ void ya_draw_pango_text(struct ya_block *blk) {
pango_layout_set_auto_dir(layout, false);
pango_layout_set_height(layout, blk->bar->height);
#ifdef YA_VAR_WIDTH
int ht;
//Get the width that text can be drawn comfortably and put it in curwidth member.
pango_layout_get_pixel_size(layout, &blk->curwidth, &ht);
if(SHOULD_REDRAW(blk)) {
//Now if the bar should be redrawn due to a modified text width, we free pango and cairo memory and then do
//a total redraw for the bar.
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
//#endif
pango_layout_set_width(layout, blk->width * PANGO_SCALE);
pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
@ -496,9 +492,37 @@ cairo_surface_t * ya_draw_graphics(ya_block_t *blk) {
* Redraw the entire bar
*/
#ifdef YA_NOWIN_COL
void ya_redraw_bar(ya_bar_t *bar) {
inline void ya_inherit_bar_bgcol(ya_block_t *blk) {
//if (ya.curwin == ya.lstwin)
// return;
uint32_t col = 0x0;
//If there is no current window, set color to bgcolor_none
//Otherwise set it to the normal bar background color
if(ya.curwin == XCB_NONE)
col = blk->bar->bgcolor_none;
else
col = blk->bar->bgcolor;
#ifdef YA_DYN_COL
if(!(blk->attr & BLKA_BGCOLOR)) {
if((!(blk->attr & BLKA_DIRTY_COL))) {
blk->bgcolor = col;
blk->bgcolor_old = col;
xcb_change_gc(ya.c, blk->gc, XCB_GC_FOREGROUND, (const uint32_t[]){col});
}
else {
blk->bgcolor_old = col;
}
}
#else
if(!(blk->attr & BLKA_BGCOLOR)) {
blk->bgcolor = col;
xcb_change_gc(ya.c, blk->gc, XCB_GC_FOREGROUND, (const uint32_t[]){col});
}
#endif //YA_DYN_COL
}
inline void ya_draw_bar_curwin(ya_bar_t *bar) {
uint32_t col = 0x0;
ya_block_t *blk;
//If there is no current window, set color to bgcolor_none
//Otherwise set it to the normal bar background color
if(ya.curwin == XCB_NONE)
@ -506,34 +530,27 @@ void ya_redraw_bar(ya_bar_t *bar) {
else
col = bar->bgcolor;
xcb_change_gc(ya.c, bar->gc, XCB_GC_FOREGROUND, (const uint32_t[]){col});
xcb_poly_fill_rectangle(ya.c, bar->win, bar->gc, 1, (const xcb_rectangle_t[]) { {0,0,bar->width, bar->height} });
xcb_flush(ya.c);
for(int i=0; i<3; i++) {
if((blk = bar->curblk[i])) {
for(;blk;blk = blk->next_blk) {
//For blocks that have no background color, inherit the background color
//for the bar.
#ifdef YA_DYN_COL
if(!(blk->attr & BLKA_BGCOLOR)) {
if((!(blk->attr & BLKA_DIRTY_COL))) {
blk->bgcolor = col;
blk->bgcolor_old = col;
xcb_change_gc(ya.c, blk->gc, XCB_GC_FOREGROUND, (const uint32_t[]){col});
}
else {
blk->bgcolor_old = col;
}
}
#else
if(!(blk->attr & BLKA_BGCOLOR)) {
blk->bgcolor = col;
xcb_change_gc(ya.c, blk->gc, XCB_GC_FOREGROUND, (const uint32_t[]){col});
}
#endif //YA_DYN_COL
ya_draw_pango_text(blk);
xcb_poly_fill_rectangle(ya.c, bar->win,
bar->gc, 1,
(const xcb_rectangle_t[]) { {0,0,bar->width, bar->height} });
}
void ya_redraw_bar(ya_bar_t *bar) {
bar->attr |= BARA_REDRAW;
ya_draw_bar_curwin(bar);
for(int i=0; i<3;i++) {
for(ya_block_t *blk = bar->curblk[i]; blk; blk = blk->next_blk) {
if((blk->attr & BLKA_VAR_WIDTH) && (i!=A_RIGHT)) {
ya_draw_text_var_width(blk);
break;
}
else
ya_draw_pango_text(blk);
}
}
bar->attr &= ~BARA_REDRAW;
}
#endif //YA_NOWIN_COL
@ -581,20 +598,8 @@ void ya_set_width_resetup(ya_block_t *blk) {
}
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) {
//Lock the bar!
//occupied_width member will be modified after calculating the maximum
//allowed size of block width using ya_set_width_resetup()
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) {
@ -614,8 +619,126 @@ void ya_resetup_bar(ya_block_t *blk) {
}
break;
}
blk->width = blk->curwidth;
}
/*
*Calculate the correct shift of blocks and then redraw the bar.
*/
void ya_resetup_bar(ya_block_t *blk) {
//Lock the bar!
//occupied_width member will be modified after calculating the maximum
//allowed size of block width using ya_set_width_resetup()
#ifdef YA_MUTEX
pthread_mutex_lock(&blk->bar->mutex);
#endif
ya_set_width_resetup(blk);
ya_redraw_bar(blk->bar);
blk->bar->attr &= ~BARA_REDRAW;
#ifdef YA_MUTEX
pthread_mutex_unlock(&blk->bar->mutex);
#endif
}
void ya_draw_text_var_width(ya_block_t * blk) {
ya_get_text_max_width(blk);
if (blk->curwidth == blk->width) {
ya_draw_pango_text(blk);
return;
}
ya_draw_bar_var(blk);
ya_set_width_resetup(blk);
switch(blk->align) {
case A_LEFT:
for(ya_block_t *curblk = blk; curblk; curblk = curblk->next_blk) {
ya_draw_pango_text(curblk);
}
break;
case A_CENTER:
for(ya_block_t *curblk = blk->bar->curblk[A_CENTER]; curblk; curblk = curblk->next_blk) {
ya_draw_pango_text(curblk);
}
break;
case A_RIGHT:
for(ya_block_t *curblk = blk; curblk; curblk = curblk->prev_blk) {
ya_draw_pango_text(curblk);
}
break;
}
}
void ya_draw_bar_var(ya_block_t *blk) {
int start =0, end=0;
int scrw = blk->bar->mon->pos.width;
switch(blk->align) {
case A_LEFT:
start = blk->shift;
if(blk->bar->curblk[1]) {
end = (scrw - blk->bar->occupied_width[1])/2;
}
else if (blk->bar->curblk[2]) {
end = scrw - blk->bar->occupied_width[2];
}
else {
end = scrw;
}
break;
case A_CENTER:
start = (scrw - blk->bar->occupied_width[1])/2;
end = (scrw + blk->bar->occupied_width[1])/2;
break;
case A_RIGHT:
if(blk->bar->curblk[1]) {
start = (scrw + blk->bar->occupied_width[1])/2;
}
else if (blk->bar->curblk[0]) {
start = blk->bar->occupied_width[0];
}
else
start = 0;
end = blk->shift + blk->width;
break;
}
xcb_poly_fill_rectangle(ya.c, blk->bar->win,
blk->bar->gc, 1,
(const xcb_rectangle_t[]) { {start,0, end-start, blk->bar->height} });
}
void ya_get_text_max_width(ya_block_t *blk) {
cairo_surface_t *surface = cairo_xcb_surface_create(ya.c,
blk->pixmap, ya.visualtype,
blk->width, blk->bar->height);
cairo_t *cr = cairo_create(surface);
PangoContext *context = pango_cairo_create_context(cr);
PangoLayout *layout = pango_layout_new(context);
pango_layout_set_font_description(layout, blk->bar->desc);
#ifdef YA_DYN_COL
//Start drawing text at strbuf member, where !Y COLORS Y! config ends
if (!(blk->attr & BLKA_MARKUP_PANGO))
pango_layout_set_text(layout, blk->strbuf, strlen(blk->strbuf));
else
pango_layout_set_markup(layout, blk->strbuf, strlen(blk->strbuf));
#else
if (!(blk->attr & BLKA_MARKUP_PANGO))
pango_layout_set_text(layout, blk->buf, strlen(blk->buf));
else
pango_layout_set_markup(layout, blk->buf, strlen(blk->buf));
#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);
int ht;
//Get the width that text can be drawn comfortably and put it in curwidth member.
pango_layout_get_pixel_size(layout, &blk->curwidth, &ht);
cairo_surface_flush(surface);
xcb_flush(ya.c);
g_object_unref(layout);
g_object_unref(context);
cairo_destroy(cr);
cairo_surface_destroy(surface);
}
#endif //YA_VAR_WIDTH

View file

@ -51,26 +51,34 @@ inline static void ya_exec_intern_ewmh_blk(ya_block_t *blk) {
#ifdef YA_MUTEX
pthread_mutex_lock(&blk->mutex);
#endif
#ifdef YA_VAR_WIDTH
DRAW_TEXT(blk);
#else
ya_draw_pango_text(blk);
#endif //YA_VAR_WIDTH
#ifdef YA_MUTEX
pthread_mutex_unlock(&blk->mutex);
#endif
break;
}
case YA_INT_WORKSPACE: {
uint32_t current_desktop;
xcb_get_property_cookie_t ck = xcb_ewmh_get_current_desktop(ya.ewmh, 0);
xcb_ewmh_get_current_desktop_reply(ya.ewmh, ck, &current_desktop, NULL);
//uint32_t current_desktop;
//xcb_get_property_cookie_t ck = xcb_ewmh_get_current_desktop(ya.ewmh, 0);
//xcb_ewmh_get_current_desktop_reply(ya.ewmh, ck, &current_desktop, NULL);
if(blk->internal->option[0]==NULL)
sprintf(blk->buf, "%u", current_desktop+1);
sprintf(blk->buf, "%u", ya.curws+1);
else {
ya_copy_buf_from_index(blk, current_desktop);
ya_copy_buf_from_index(blk, ya.curws);
}
#ifdef YA_MUTEX
pthread_mutex_lock(&blk->mutex);
#endif
#ifdef YA_VAR_WIDTH
DRAW_TEXT(blk);
#else
ya_draw_pango_text(blk);
#endif //YA_VAR_WIDTH
#ifdef YA_MUTEX
pthread_mutex_unlock(&blk->mutex);
#endif
@ -108,7 +116,11 @@ static void ya_exec_redir_once(ya_block_t *blk) {
#ifdef YA_MUTEX
pthread_mutex_lock(&blk->mutex);
#endif
#ifdef YA_VAR_WIDTH
DRAW_TEXT(blk);
#else
ya_draw_pango_text(blk);
#endif //YA_VAR_WIDTH
#ifdef YA_MUTEX
pthread_mutex_unlock(&blk->mutex);
#endif
@ -151,7 +163,11 @@ static void ya_exec_redir_period(ya_block_t *blk) {
#ifdef YA_MUTEX
pthread_mutex_lock(&blk->mutex);
#endif
#ifdef YA_VAR_WIDTH
DRAW_TEXT(blk);
#else
ya_draw_pango_text(blk);
#endif //YA_VAR_WIDTH
#ifdef YA_MUTEX
pthread_mutex_unlock(&blk->mutex);
#endif
@ -196,7 +212,11 @@ static void ya_exec_redir_persist(ya_block_t *blk) {
#ifdef YA_MUTEX
pthread_mutex_lock(&blk->mutex);
#endif
#ifdef YA_VAR_WIDTH
DRAW_TEXT(blk);
#else
ya_draw_pango_text(blk);
#endif //YA_VAR_WIDTH
#ifdef YA_MUTEX
pthread_mutex_unlock(&blk->mutex);
#endif
@ -385,10 +405,13 @@ void ya_init() {
ya.lstwin = XCB_NONE;
uint32_t evm = XCB_EVENT_MASK_PROPERTY_CHANGE;
xcb_get_property_cookie_t prop_ck = xcb_ewmh_get_active_window(ya.ewmh, 0);
xcb_ewmh_get_active_window_reply(ya.ewmh, prop_ck, &ya.curwin, NULL);
xcb_change_window_attributes(ya.c, ya.curwin, XCB_CW_EVENT_MASK, &evm);
xcb_change_window_attributes(ya.c, ya.scr->root, XCB_CW_EVENT_MASK, &evm);
xcb_get_property_cookie_t prop_ck = xcb_ewmh_get_active_window(ya.ewmh, 0);
xcb_ewmh_get_active_window_reply(ya.ewmh, prop_ck, &ya.curwin, NULL);
xcb_get_property_cookie_t ws_ck = xcb_ewmh_get_current_desktop(ya.ewmh, 0);
xcb_ewmh_get_current_desktop_reply(ya.ewmh, ws_ck, &ya.curws, NULL);
fprintf(stderr, "WINNN = %x DESK= %x\n", ya.curwin, ya.curws);
#endif //YA_INTERNAL_EWMH
ya_config_parse();
@ -398,15 +421,16 @@ void ya_init() {
* After yabar initialization, we create a thread for each block.
*/
void ya_execute() {
ya_bar_t *curbar;
ya_block_t *curblk;
curbar = ya.curbar;
ya_bar_t *curbar = ya.curbar;
ya_block_t *curblk = NULL;
#ifdef YA_INTERNAL_EWMH
if(ya.ewmh_blk) {
for(;ya.ewmh_blk->prev_ewblk; ya.ewmh_blk = ya.ewmh_blk->prev_ewblk);
//ya_ewmh_blk *ewmh_blk = ya.ewmh_blk;
//for(;ewmh_blk; ewmh_blk = ewmh_blk->next_ewblk)
// ya_exec_intern_ewmh_blk(ewmh_blk->blk);
ya_ewmh_blk *ewmh_blk = ya.ewmh_blk;
for(;ewmh_blk; ewmh_blk = ewmh_blk->next_ewblk) {
fprintf(stderr, "H %s\n", ewmh_blk->blk->name);
ya_exec_intern_ewmh_blk(ewmh_blk->blk);
}
}
#endif //YA_INTERNAL_EWMH
for(; curbar->prev_bar; curbar = curbar->prev_bar);
@ -471,8 +495,12 @@ void ya_handle_prop_notify(xcb_property_notify_event_t *ep) {
uint32_t pr_ev_val = XCB_EVENT_MASK_PROPERTY_CHANGE;
ya_ewmh_blk *ewblk;
if(ep->atom == ya.ewmh->_NET_ACTIVE_WINDOW) {
xcb_get_property_cookie_t prop_ck = xcb_ewmh_get_active_window(ya.ewmh, 0);
xcb_ewmh_get_active_window_reply(ya.ewmh, prop_ck, &ya.curwin, NULL);
xcb_get_property_cookie_t win_ck = xcb_ewmh_get_active_window(ya.ewmh, 0);
xcb_ewmh_get_active_window_reply(ya.ewmh, win_ck, &ya.curwin, NULL);
xcb_get_property_cookie_t ws_ck = xcb_ewmh_get_current_desktop(ya.ewmh, 0);
xcb_ewmh_get_current_desktop_reply(ya.ewmh, ws_ck, &ya.curws, NULL);
if (ya.curwin != ya.lstwin) {
xcb_change_window_attributes(ya.c, ya.lstwin, XCB_CW_EVENT_MASK, &no_ev_val);
xcb_change_window_attributes(ya.c, ya.curwin, XCB_CW_EVENT_MASK, &pr_ev_val);
@ -503,5 +531,6 @@ void ya_handle_prop_notify(xcb_property_notify_event_t *ep) {
ya_exec_intern_ewmh_blk(ewblk->blk);
}
ya.lstwin = ya.curwin;
ya.lstws = ya.curws;
}
#endif //YA_INTERNAL_EWMH

View file

@ -87,6 +87,7 @@ static void ya_copy_blk_members(ya_block_t *dstb, ya_block_t *srcb) {
dstb->internal->option[i] = srcb->internal->option[i];
dstb->internal->index = srcb->internal->index;
}
#ifdef YA_ICON
if((srcb->attr & BLKA_ICON)) {
dstb->img = calloc(1, sizeof(blk_img_t));
strncpy(dstb->img->path, srcb->img->path, CFILELEN);
@ -95,6 +96,7 @@ static void ya_copy_blk_members(ya_block_t *dstb, ya_block_t *srcb) {
dstb->img->scale_w = srcb->img->scale_w;
dstb->img->scale_h = srcb->img->scale_h;
}
#endif //YA_ICON
}
static int ya_inherit_bar(ya_bar_t *dstb, const char *srcname, bool inherit_all, ya_bar_t **inherit_bar) {
@ -372,6 +374,8 @@ inline static void ya_setup_ewmh_intern_blk(ya_block_t *blk) {
case YA_INT_TITLE:
blk->attr |= BLKA_INTERN_X_EV;
break;
default:
return;
}
cur = calloc(1, sizeof(ya_ewmh_blk));
cur->blk = blk;