diff --git a/src/event.c b/src/event.c index 62eea81..8794dbc 100644 --- a/src/event.c +++ b/src/event.c @@ -40,6 +40,7 @@ static void buttonpress(XEvent *e) { XButtonEvent *ev = &e->xbutton; + StatusMouse *sm; Client *c; int i, j, n; @@ -158,6 +159,14 @@ buttonpress(XEvent *e) } } + /* Status mouse bindings */ + SLIST_FOREACH(sm, &smhead, next) + if(sm->win == ev->window && ev->button == sm->button) + if(ev->x >= sm->area.x && ev->x <= sm->area.x + sm->area.width + && ev->y >= sm->area.y && ev->y <= sm->area.y + sm->area.height) + if(sm->func) + sm->func(sm->cmd); + return; } diff --git a/src/infobar.c b/src/infobar.c index 5f190b9..c89c9a9 100644 --- a/src/infobar.c +++ b/src/infobar.c @@ -368,22 +368,22 @@ infobar_set_position(int pos) switch(pos) { - case IB_Hide: - sgeo[selscreen].y = spgeo[selscreen].y + TBARH; - sgeo[selscreen].height = spgeo[selscreen].height - TBARH; - infobar[selscreen].geo.y = (-(infobar[selscreen].geo.height) << 1); - break; - case IB_Bottom: - sgeo[selscreen].y = spgeo[selscreen].y + TBARH; - sgeo[selscreen].height = spgeo[selscreen].height - INFOBARH - TBARH; - infobar[selscreen].geo.y = spgeo[selscreen].y + sgeo[selscreen].height + TBARH; - break; - default: - case IB_Top: - sgeo[selscreen].y = spgeo[selscreen].y + INFOBARH + TBARH; - sgeo[selscreen].height = spgeo[selscreen].height - INFOBARH - TBARH; - infobar[selscreen].geo.y = spgeo[selscreen].y; - break; + case IB_Hide: + sgeo[selscreen].y = spgeo[selscreen].y + TBARH; + sgeo[selscreen].height = spgeo[selscreen].height - TBARH; + infobar[selscreen].geo.y = (-(infobar[selscreen].geo.height) << 1); + break; + case IB_Bottom: + sgeo[selscreen].y = spgeo[selscreen].y + TBARH; + sgeo[selscreen].height = spgeo[selscreen].height - INFOBARH - TBARH; + infobar[selscreen].geo.y = spgeo[selscreen].y + sgeo[selscreen].height + TBARH; + break; + default: + case IB_Top: + sgeo[selscreen].y = spgeo[selscreen].y + INFOBARH + TBARH; + sgeo[selscreen].height = spgeo[selscreen].height - INFOBARH - TBARH; + infobar[selscreen].geo.y = spgeo[selscreen].y; + break; } tags[selscreen][seltag[selscreen]].barpos = pos; diff --git a/src/init.c b/src/init.c index 47f1707..70994a1 100644 --- a/src/init.c +++ b/src/init.c @@ -203,6 +203,7 @@ init(void) { /* Init lists heads */ SLIST_INIT(&bwhead); + SLIST_INIT(&smhead); SLIST_INIT(&clients); SLIST_INIT(&trayicons); diff --git a/src/mouse.c b/src/mouse.c index bd1a0e6..a644e32 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -332,21 +332,21 @@ mouse_resize(Client *c) void mouse_grabbuttons(Client *c, bool focused) { - size_t i; + size_t i = 0; uint but[] = {Button1, Button2, Button3, Button4, Button5}; XUngrabButton(dpy, AnyButton, AnyModifier, c->win); if(focused) - for(i = 0; i < LEN(but); ++i) + for(; i < LEN(but); ++i) { XGrabButton(dpy, but[i], conf.client.mod, c->win, False, - ButtonMask, GrabModeAsync,GrabModeSync, None, None); - XGrabButton(dpy, but[i], conf.client.mod|LockMask, c->win, False, - ButtonMask, GrabModeAsync,GrabModeSync, None, None); - XGrabButton(dpy, but[i], conf.client.mod|numlockmask, c->win, False, - ButtonMask, GrabModeAsync,GrabModeSync, None, None); - XGrabButton(dpy, but[i], conf.client.mod|LockMask|numlockmask, c->win, False, - ButtonMask, GrabModeAsync,GrabModeSync, None, None); + ButtonMask, GrabModeAsync, GrabModeSync, None, None); + XGrabButton(dpy, but[i], conf.client.mod | LockMask, c->win, False, + ButtonMask, GrabModeAsync, GrabModeSync, None, None); + XGrabButton(dpy, but[i], conf.client.mod | numlockmask, c->win, False, + ButtonMask, GrabModeAsync, GrabModeSync, None, None); + XGrabButton(dpy, but[i], conf.client.mod | LockMask | numlockmask, c->win, False, + ButtonMask, GrabModeAsync, GrabModeSync, None, None); } else XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, diff --git a/src/status.c b/src/status.c index 0589197..c6a6ce4 100644 --- a/src/status.c +++ b/src/status.c @@ -35,6 +35,42 @@ /* Systray width */ static int sw = 0; +/** Parse dynamic mouse binds in str and insert it in linked list + * --> (button;func;cmd)\[;;;;]\ add a mouse bind on the block object + *\param str String + *\param area Area of clicking + *\param win Window to click + *\return sm StatusMouse pointer + */ +static StatusMouse* +statustext_mouse(char *str, Geo area, Window win) +{ + StatusMouse *sm = NULL; + int i = 0, button = 1; + char cmd[256] = { 0 }; + char func[64] = { 0 }; + + if(!str) + return NULL; + + for(; i < strlen(str); ++i) + if(sscanf(&str[i], "(%d;%64[^;];%256[^)])", &button, func, cmd) == 3) + { + sm = zcalloc(sizeof(StatusMouse)); + sm->button = button; + sm->func = name_to_func((char*)func, func_list); + sm->cmd = xstrdup(cmd); + sm->area = area; + sm->win = win; + + SLIST_INSERT_HEAD(&smhead, sm, next); + + break; + } + + return sm; +} + /** Check rectangles blocks in str and draw it * --> \b[x;y;width;height;#color]\ *\param ib Infobar pointer @@ -44,14 +80,17 @@ static void statustext_rectangle(InfoBar *ib, char *str) { StatusRec r; - char as; - int i, j, k; + char as, mouse[512] = { 0 }; + int i, j, k, n; for(i = j = 0; i < (int)strlen(str); ++i, ++j) - if(sscanf(&str[i], "\\b[%d;%d;%d;%d;#%x]%c", &r.x, &r.y, &r.w, &r.h, &r.color, &as) == 6 - && as == '\\') + if((n = sscanf(&str[i], "%512[^\\]\\b[%d;%d;%d;%d;#%x]%c", + mouse, &r.g.x, &r.g.y, &r.g.width, &r.g.height, &r.color, &as)) == 7 + || n == 6 && as == '\\') { - draw_rectangle(ib->bar->dr, r.x - sw, r.y, r.w, r.h, r.color); + draw_rectangle(ib->bar->dr, r.g.x - sw, r.g.y, r.g.width, r.g.height, r.color); + + (StatusMouse*)statustext_mouse(mouse, r.g, ib->bar->win); for(++i, --j; str[i] != as || str[i - 1] != ']'; ++i); } @@ -203,6 +242,7 @@ void statustext_handle(int sc, char *str) { InfoBar *ib = &infobar[sc]; + StatusMouse *sm; char *lastst; int i; @@ -210,6 +250,15 @@ statustext_handle(int sc, char *str) if(!str) return; + /* Free linked list of mouse bind */ + while(!SLIST_EMPTY(&smhead)) + { + sm = SLIST_FIRST(&smhead); + SLIST_REMOVE_HEAD(&smhead, next); + free((void*)sm->cmd); + free(sm); + } + if(sc == conf.systray.screen) sw = systray_get_width(); diff --git a/src/structs.h b/src/structs.h index 08bc8a5..b428d6b 100644 --- a/src/structs.h +++ b/src/structs.h @@ -542,7 +542,7 @@ typedef struct /* status.c util struct */ typedef struct { - int x, y, w, h; + Geo g; uint color; } StatusRec; @@ -560,6 +560,16 @@ typedef struct char text[512]; } StatusText; +typedef struct StatusMouse +{ + Geo area; + Window win; + int button; + void (*func)(uicb_t); + uicb_t cmd; + SLIST_ENTRY(StatusMouse) next; +} StatusMouse; + typedef struct { int x, y, w, h; diff --git a/src/wmfs.h b/src/wmfs.h index 4e3efdc..9ca5d5e 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -322,7 +322,6 @@ char *char_to_str(const char c); pid_t spawn(const char *str, ...); void swap_ptr(void **x, void **y); void uicb_spawn(uicb_t); -char *clean_value(char *str); char* patht(char *path); int qsort_string_compare (const void * a, const void * b); @@ -500,6 +499,9 @@ int tray_width; /* BarWindow */ SLIST_HEAD(, BarWindow) bwhead; +/* Status */ +SLIST_HEAD(, StatusMouse) smhead; + #endif /* WMFS_H */