diff --git a/src/barwin.c b/src/barwin.c index c573b3e..00d3683 100644 --- a/src/barwin.c +++ b/src/barwin.c @@ -51,6 +51,7 @@ barwin_new(Window parent, int x, int y, int w, int h, Color fg, Color bg, bool e b->fg = fg; SLIST_INIT(&b->mousebinds); + SLIST_INIT(&b->statusmousebinds); /* Attach */ SLIST_INSERT_HEAD(&W->h.barwin, b, next); diff --git a/src/client.c b/src/client.c index b079db6..669e091 100644 --- a/src/client.c +++ b/src/client.c @@ -346,10 +346,17 @@ client_grabbuttons(struct client *c, bool focused) #define _REMAINDER() \ if((rm = ((x + f) - (c->rgeo.w - c->border))) > 0) \ f -= rm; + +#define _STATUSLINE(C, b) \ + sctx = (b ? &c->theme->client_s_sl : &c->theme->client_n_sl); \ + sctx->barwin = C->titlebar; \ + status_copy_mousebind(sctx); \ + status_render(sctx); void client_frame_update(struct client *c, struct colpair *cp) { struct client *cc; + struct status_ctx *sctx; int y, f, xt, rm, w, n = 1; if(c->flags & CLIENT_TABBED) @@ -384,6 +391,9 @@ client_frame_update(struct client *c, struct colpair *cp) barwin_move(c->titlebar, 0, 0); barwin_resize(c->titlebar, f, c->tbarw); barwin_refresh_color(c->titlebar); + + _STATUSLINE(c, (cp == &c->scol)); + draw_text(c->titlebar->dr, c->theme, xt, y, cp->fg, c->title); barwin_refresh(c->titlebar); } @@ -407,6 +417,8 @@ client_frame_update(struct client *c, struct colpair *cp) barwin_resize(c->titlebar, f, c->tbarw); barwin_refresh_color(c->titlebar); + + _STATUSLINE(c, true); draw_rect(c->titlebar->dr, &g, c->scol.bg); draw_text(c->titlebar->dr, c->theme, xt, y, cp->fg, c->title); barwin_refresh(c->titlebar); @@ -423,6 +435,8 @@ client_frame_update(struct client *c, struct colpair *cp) barwin_resize(cc->titlebar, f, c->tbarw - 2); barwin_refresh_color(cc->titlebar); + + _STATUSLINE(cc, false); draw_rect(cc->titlebar->dr, &g, c->scol.bg); draw_text(cc->titlebar->dr, c->theme, xt, y - 1, c->ncol.fg, cc->title); barwin_refresh(cc->titlebar); diff --git a/src/config.c b/src/config.c index 7b7b26a..ead1ffb 100644 --- a/src/config.c +++ b/src/config.c @@ -32,6 +32,7 @@ config_mouse_section(struct mbhead *mousebinds, struct conf_sec **sec) m->cmd = xstrdup(p); m->use_area = false; + m->flags = 0; SLIST_INSERT_HEAD(mousebinds, m, next); SLIST_INSERT_HEAD(&W->h.mousebind, m, globnext); @@ -103,6 +104,15 @@ config_theme(void) t->client_titlebar_width = fetch_opt_first(ks[i], "12", "client_titlebar_width").num; t->client_border_width = fetch_opt_first(ks[i], "1", "client_border_width").num; + /* status line */ + t->client_n_sl = status_new_ctx(NULL, t); + t->client_s_sl = status_new_ctx(NULL, t); + + if((t->client_n_sl.status = xstrdup(fetch_opt_first(ks[i], "", "client_normal_statusline").str))) + status_parse(&t->client_n_sl); + if((t->client_s_sl.status = xstrdup(fetch_opt_first(ks[i], "", "client_sel_statusline").str))) + status_parse(&t->client_s_sl); + SLIST_INSERT_TAIL(&W->h.theme, t, next, p); p = t; diff --git a/src/event.c b/src/event.c index fb37bfb..e20cd85 100644 --- a/src/event.c +++ b/src/event.c @@ -13,6 +13,11 @@ #define EVDPY(e) (e)->xany.display +#define MOUSE_CHECK_BIND(m) \ + if(m->button == ev->button) \ + if(!m->use_area || (m->use_area && INAREA(ev->x, ev->y, m->area))) \ + if(m->func) \ + m->func(m->cmd); static void event_buttonpress(XEvent *e) { @@ -28,10 +33,10 @@ event_buttonpress(XEvent *e) W->last_clicked_barwin = b; SLIST_FOREACH(m, &b->mousebinds, next) - if(m->button == ev->button) - if(!m->use_area || (m->use_area && INAREA(ev->x, ev->y, m->area))) - if(m->func) - m->func(m->cmd); + MOUSE_CHECK_BIND(m); + + SLIST_FOREACH(m, &b->statusmousebinds, next) + MOUSE_CHECK_BIND(m); break; } diff --git a/src/infobar.c b/src/infobar.c index 4c2d4a1..5ec95c6 100644 --- a/src/infobar.c +++ b/src/infobar.c @@ -117,7 +117,6 @@ infobar_elem_tag_update(struct element *e) /* Manage status line */ e->statusctx->barwin = b; - status_flush_mousebind(e->statusctx); status_copy_mousebind(e->statusctx); status_render(e->statusctx); diff --git a/src/status.c b/src/status.c index 0452566..8e94031 100644 --- a/src/status.c +++ b/src/status.c @@ -50,14 +50,14 @@ status_free_ctx(struct status_ctx *ctx) free(ctx->status); if(ctx->barwin) - status_flush_mousebind(ctx); + SLIST_INIT(&ctx->barwin->statusmousebinds); status_flush_list(ctx); } /* Parse mousebind sequence next normal sequence: \[](button;func;cmd) */ static char* -status_parse_mouse(struct status_seq *sq, struct status_ctx *ctx, char *str) +status_parse_mouse(struct status_seq *sq, char *str) { struct mousebind *m; char *end, *arg[3] = { NULL }; @@ -76,9 +76,6 @@ status_parse_mouse(struct status_seq *sq, struct status_ctx *ctx, char *str) m->cmd = (i > 1 ? xstrdup(arg[2]) : NULL); m->flags |= MOUSEBIND_STATUS; - if(ctx->barwin) - SLIST_INSERT_HEAD(&ctx->barwin->mousebinds, m, next); - SLIST_INSERT_HEAD(&sq->mousebinds, m, snext); return end + 1; @@ -163,7 +160,7 @@ status_parse(struct status_ctx *ctx) * Parse it while there is a mousebind sequence. */ dstr = ++end; - while((*(dstr = status_parse_mouse(sq, ctx, dstr)) == '(')); + while((*(dstr = status_parse_mouse(sq, dstr)) == '(')); prev = sq; } @@ -283,27 +280,27 @@ void status_flush_list(struct status_ctx *ctx) { struct status_seq *sq; + struct mousebind *m; /* Flush previous linked list of status sequences */ while(!SLIST_EMPTY(&ctx->statushead)) { sq = SLIST_FIRST(&ctx->statushead); SLIST_REMOVE_HEAD(&ctx->statushead, next); + + while(!SLIST_EMPTY(&sq->mousebinds)) + { + m = SLIST_FIRST(&sq->mousebinds); + SLIST_REMOVE_HEAD(&sq->mousebinds, snext); + free((void*)m->cmd); + free(m); + } + free(sq->str); free(sq); } } -void -status_flush_mousebind(struct status_ctx *ctx) -{ - struct mousebind *m; - - SLIST_FOREACH(m, &ctx->barwin->mousebinds, next) - if(m->flags & MOUSEBIND_STATUS) - SLIST_REMOVE(&ctx->barwin->mousebinds, m, mousebind, next); -} - void status_copy_mousebind(struct status_ctx *ctx) { @@ -313,10 +310,13 @@ status_copy_mousebind(struct status_ctx *ctx) if(!ctx->barwin) return; + /* Flush barwin head of status mousebinds */ + SLIST_INIT(&ctx->barwin->statusmousebinds); + SLIST_FOREACH(sq, &ctx->statushead, next) { SLIST_FOREACH(m, &sq->mousebinds, snext) - SLIST_INSERT_HEAD(&ctx->barwin->mousebinds, m, next); + SLIST_INSERT_HEAD(&ctx->barwin->statusmousebinds, m, next); } } @@ -328,9 +328,9 @@ status_manage(struct status_ctx *ctx) return; status_flush_list(ctx); - status_flush_mousebind(ctx); status_parse(ctx); status_render(ctx); + status_copy_mousebind(ctx); } /* Syntax: " " */ diff --git a/src/wmfs.c b/src/wmfs.c index edf0bfe..03fe5b9 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -442,6 +442,8 @@ wmfs_quit(void) status_free_ctx(&t->tags_n_sl); status_free_ctx(&t->tags_s_sl); status_free_ctx(&t->tags_o_sl); + status_free_ctx(&t->client_n_sl); + status_free_ctx(&t->client_s_sl); free(r->class); free(r->instance); free(r->role); diff --git a/src/wmfs.h b/src/wmfs.h index 6ff9808..08f6911 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -92,6 +92,7 @@ struct barwin Color fg, bg; void *ptr; /* Special cases */ SLIST_HEAD(mbhead, mousebind) mousebinds; + SLIST_HEAD(, mousebind) statusmousebinds; SLIST_ENTRY(barwin) next; /* global barwin */ SLIST_ENTRY(barwin) enext; /* element barwin */ }; @@ -253,6 +254,7 @@ struct theme /* client / frame */ struct colpair client_n, client_s; + struct status_ctx client_n_sl, client_s_sl; Color frame_bg; int client_titlebar_width; int client_border_width; diff --git a/wmfsrc b/wmfsrc index 224a2a1..a014a39 100644 --- a/wmfsrc +++ b/wmfsrc @@ -38,8 +38,12 @@ # Frame / Client client_normal_fg = "#AABBAA" client_normal_bg = "#223322" + client_normal_statusline = "\s[left;#ff0000; x](1;client_close)" + client_sel_fg = "#223322" client_sel_bg = "#AABBAA" + client_sel_statusline = "\s[left;#ff0000; x](1;client_close)" + frame_bg = "#555555" client_titlebar_width = 12 client_border_width = 1