Status: Add dynamic mouse bind: (1;spawn;xterm)\b[;;;;]\ = clickable rectangle

This commit is contained in:
Martin Duquesnoy 2011-07-30 17:40:39 +02:00
parent bbf11ac274
commit 1934aa713d
7 changed files with 103 additions and 32 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -203,6 +203,7 @@ init(void)
{
/* Init lists heads */
SLIST_INIT(&bwhead);
SLIST_INIT(&smhead);
SLIST_INIT(&clients);
SLIST_INIT(&trayicons);

View File

@ -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,

View File

@ -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)\<block>[;;;;]\ 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();

View File

@ -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;

View File

@ -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 */