[ALL] Add some features and fix some stuff

This commit is contained in:
Martin Duquesnoy 2008-08-15 03:39:17 +02:00
parent 9bea4c382e
commit 4c23f7c6b8
4 changed files with 242 additions and 152 deletions

View File

@ -15,9 +15,9 @@ func_name_list_t func_list[] = {
{"spawn", spawn},
{"killclient", killclient},
{"togglemax", togglemax},
{"tile", tile},
{"wswitch", wswitch},
{"tagswitch", tagswitch},
{"togglemax", togglemax},
{"keymovex", keymovex},
{"keymovey", keymovey},
{"keyresize", keyresize},
@ -88,7 +88,9 @@ init_conf(void) {
static cfg_opt_t layout_opts[] = {
CFG_STR_LIST("layout_symbol", "{Symbol}", CFGF_NONE),
CFG_STR_LIST("free","[Free]", CFGF_NONE),
CFG_STR_LIST("tile","[Tile]", CFGF_NONE),
CFG_STR_LIST("max","[Max]", CFGF_NONE),
CFG_END()
};
@ -171,8 +173,9 @@ init_conf(void) {
conf.colors.tagselbg = cfg_getint(cfg_colors, "tag_sel_bg");
/* layout */
for(i=0; i < 3; ++i)
conf.symlayout[i] = strdup(cfg_getnstr(cfg_layout, "layout_symbol",i));
conf.layouts.free = strdup(cfg_getstr(cfg_layout,"free"));
conf.layouts.tile = strdup(cfg_getstr(cfg_layout,"tile"));
conf.layouts.max = strdup(cfg_getstr(cfg_layout,"max"));
/* tag */
conf.ntag = cfg_size(cfg_tag, "tag");
@ -181,22 +184,21 @@ init_conf(void) {
/* keybind ('tention ça rigole plus) */
conf.nkeybind = cfg_size(cfg_keys, "key");
for(j = 0; j < cfg_size(cfg_keys, "key"); ++j) {
cfgtmp = cfg_getnsec(cfg_keys, "key", j);
for(j = 0; j < cfg_size(cfg_keys, "key"); ++j) {
cfgtmp = cfg_getnsec(cfg_keys, "key", j);
for(l = 0; l < cfg_size(cfgtmp, "mod"); ++l)
keys[j].mod |= char_to_modkey(cfg_getnstr(cfgtmp, "mod", l));
for(l = 0; l < cfg_size(cfgtmp, "mod"); ++l)
keys[j].mod |= char_to_modkey(cfg_getnstr(cfgtmp, "mod", l));
keys[j].keysym = XStringToKeysym(cfg_getstr(cfgtmp, "key"));
keys[j].func = name_to_func (cfg_getstr(cfgtmp, "func"));
if(!keys[j].func) {
printf("WMFS Configuration: Unknow Function %s",cfg_getstr(cfgtmp,"func"));
return;
}
keys[j].cmd = strdup(strdup(cfg_getstr(cfgtmp, "cmd")));
keys[j].keysym = XStringToKeysym(cfg_getstr(cfgtmp, "key"));
keys[j].func = name_to_func (cfg_getstr(cfgtmp, "func"));
if(!keys[j].func) {
printf("WMFS Configuration: Unknow Function %s",cfg_getstr(cfgtmp,"func"));
return;
}
cfg_free(cfg);
keys[j].cmd = strdup(strdup(cfg_getstr(cfgtmp, "cmd")));
}
cfg_free(cfg);
}

16
local.h
View File

@ -50,7 +50,7 @@ struct Client {
Window win; /* window */
Window tbar; /* Titlebar? */
Window button; /* Close Button */
Bool max, tile; /* client info */
Bool max, tile, hint; /* client info */
Client *next; /* next client */
Client *prev; /* previous client */
};
@ -84,8 +84,11 @@ typedef struct {
int tagselfg;
int tagselbg;
} colors;
/* layout */
char *symlayout[3];
struct {
char *free;
char *tile;
char *max;
} layouts;
/* tag */
int ntag;
char *taglist[MAXTAG];
@ -100,7 +103,10 @@ enum { Free=0, Tile, Max};
/* wmfs.c */
void attach(Client *c);
void buttonpress(XEvent *event);
int clienthintpertag(int tag);
int clientpertag(int tag);
void configurerequest(XEvent event);
void detach(Client *c);
void *emallocz(unsigned int size);
int errorhandler(Display *d, XErrorEvent *event);
@ -109,6 +115,7 @@ void freelayout(void);
Client* getbutton(Window w);
Client* getclient(Window w);
Client* getnext(Client *c);
char* getlayoutsym(int l);
Client* gettbar(Window w);
void getevent(void);
void grabbuttons(Client *c, Bool focused);
@ -124,6 +131,7 @@ void killclient(char *cmd);
void layoutswitch(char *cmd);
void mapclient(Client *c);
void manage(Window w, XWindowAttributes *wa);
void maxlayout(void);
void mouseaction(Client *c, int x, int y, int type);
void moveresize(Client *c, int x, int y, int w, int h, bool r);
void raiseclient(Client *c);
@ -134,7 +142,7 @@ void spawn(char *cmd);
void tag(char *cmd);
void tagswitch(char *cmd);
void tagtransfert(char *cmd);
void tile(char *cmd);
void tile(void);
void togglemax(char *cmd);
void unhide(Client *c);
void unmanage(Client *c);

333
wmfs.c
View File

@ -39,6 +39,92 @@ attach(Client *c) {
return;
}
void
buttonpress(XEvent *event) {
Client *c;
int i;
char s[6];
XButtonPressedEvent *ev = &event->xbutton;
/* Window and Tbar */
/* move, resize and toggle max */
if((c = gettbar(ev->window))
|| (c = getclient(ev->window))) {
raiseclient(c);
if(ev->button == Button1)
mouseaction(c, ev->x_root, ev->y_root, Move); /* type 0 for move */
else if(ev->button == Button2)
togglemax(NULL);
else if(ev->button == Button3)
mouseaction(c, ev->x_root, ev->y_root, Resize); /* type 1 for resize */
}
/* Button */
/* for kill and togglemax the sel client */
else if((c = getbutton(ev->window))) {
if(ev->button == Button1)
killclient(NULL);
else if(ev->button == Button3)
togglemax(NULL);
}
/* Bar */
/* for tag click */
else if(ev->window == bar) {
for(i = 0; i < conf.ntag + 1; ++i) {
if(ev->x > taglen[i-1]
&& ev->x < taglen[i]) {
if(ev->button == Button1) {
ITOA(s, i);
if(ev->state & ALT) {
tagtransfert(s);
updateall();
}
tag(s);
updateall();
}
}
}
/* tag switch with scroll */
if(ev->x < taglen[conf.ntag]) {
if(ev->button == Button4)
tagswitch("+1");
else if(ev->button == Button5)
tagswitch("-1");
}
/* layout switch */
if(ev->x >= taglen[conf.ntag]
&& ev->x < taglen[conf.ntag] + (strlen((getlayoutsym(layout[seltag])))*6)) {
if(ev->button == Button1
|| ev->button == Button4) {
layoutswitch("+");
}
else if(ev->button == Button3
|| ev->button == Button5) {
layoutswitch("-");
}
}
}
/* Root */
/* tag switch */
else if(ev->window == root) {
if(ev->button == Button4)
tagswitch("+1");
else if(ev->button == Button5)
tagswitch("-1");
}
}
int
clienthintpertag(int tag) {
Client *c;
int i = 0;
for(c = clients; c; c = c->next) {
if(c->tag == tag && c->hint)
++i;
}
return i;
}
int
clientpertag(int tag) {
Client *c;
@ -50,6 +136,34 @@ clientpertag(int tag) {
return i;
}
void
configurerequest(XEvent event) {
Client *c;
XWindowChanges wc;
if(layout[seltag] != Free)
return;
wc.x = event.xconfigurerequest.x;
wc.y = event.xconfigurerequest.y;
wc.width = event.xconfigurerequest.width;
wc.height = event.xconfigurerequest.height;
wc.border_width = event.xconfigurerequest.border_width;
wc.sibling = event.xconfigurerequest.above;
wc.stack_mode = event.xconfigurerequest.detail;
XConfigureWindow(dpy, event.xconfigurerequest.window,
event.xconfigurerequest.value_mask, &wc);
if((c = getclient(event.xconfigurerequest.window))) {
if(wc.y < mw && wc.x < mh) {
XResizeWindow(dpy, c->tbar, wc.width, conf.ttbarheight);
XMoveWindow(dpy, c->button, wc.x + wc.width - 10, BUTY(wc.y));
updatetitle(c);
c->y = wc.y;
c->x = wc.x;
c->w = wc.width;
c->h = wc.height;
}
}
}
void
detach(Client *c) {
if(c->prev) c->prev->next = c->next;
@ -108,7 +222,7 @@ freelayout(void) {
for(c = clients; c; c = c->next){
if(!ishide(c)) {
if(c->max) {
moveresize(c, c->ox, c->oy, c->ow, c->oh, 0);
moveresize(c, c->ox, c->oy, c->ow, c->oh, 1);
}
c->max = False;
}
@ -137,6 +251,17 @@ getnext(Client *c) {
return c;
}
char*
getlayoutsym(int l) {
char *t;
switch(layout[seltag]) {
case Free: t = conf.layouts.free; break;
case Tile: t = conf.layouts.tile; break;
case Max: t = conf.layouts.max; break;
}
return t;
}
Client*
gettbar(Window w) {
Client *c;
@ -148,10 +273,7 @@ void
getevent(void) {
XEvent event;
XWindowAttributes at;
XWindowChanges wc;
Client *c;
int i;
char s[6];
struct timeval tv;
if(QLength(dpy) > 0) {
@ -161,7 +283,7 @@ getevent(void) {
FD_ZERO(&fd);
FD_SET(ConnectionNumber(dpy), &fd);
event.type = LASTEvent;
tv.tv_sec = 1;
tv.tv_sec = 2;
tv.tv_usec = 0;
if(select(FD_SETSIZE, &fd, NULL, NULL, &tv) > 0) {
XNextEvent(dpy, &event);
@ -204,42 +326,16 @@ getevent(void) {
}
}
break;
case ConfigureRequest:
/* configure size and window position required (only if the layout is Free)*/
if(layout[seltag] != Free)
return;
wc.x = event.xconfigurerequest.x;
wc.y = event.xconfigurerequest.y;
wc.width = event.xconfigurerequest.width;
wc.height = event.xconfigurerequest.height;
wc.border_width = event.xconfigurerequest.border_width;
wc.sibling = event.xconfigurerequest.above;
wc.stack_mode = event.xconfigurerequest.detail;
XConfigureWindow(dpy, event.xconfigurerequest.window,
event.xconfigurerequest.value_mask, &wc);
if((c = getclient(event.xconfigurerequest.window))) {
if(wc.y < mw && wc.x < mh) {
XResizeWindow(dpy, c->tbar, wc.width, conf.ttbarheight);
XMoveWindow(dpy, c->button, wc.x + wc.width - 10, BUTY(wc.y));
updatetitle(c);
c->y = wc.y;
c->x = wc.x;
c->w = wc.width;
c->h = wc.height;
}
}
break;
case ConfigureRequest: configurerequest(event); break;
case UnmapNotify:
if((c = getclient(event.xunmap.window))) {
if((c = getclient(event.xunmap.window)))
unmanage(c);
}
break;
case DestroyNotify:
if((c = getclient(event.xdestroywindow.window))) {
if((c = getclient(event.xdestroywindow.window)))
unmanage(c);
}
break;
case FocusIn:
@ -248,57 +344,7 @@ getevent(void) {
break;
case KeyPress: keypress(&event); break;
case ButtonPress:
/* Window and Tbar */
if((c = gettbar(event.xbutton.window))
|| (c = getclient(event.xbutton.window))) {
raiseclient(c);
if(event.xbutton.button == Button1)
mouseaction(c, event.xbutton.x_root, event.xbutton.y_root, Move); /* type 0 for move */
else if(event.xbutton.button == Button2)
tile(NULL);
else if(event.xbutton.button == Button3)
mouseaction(c, event.xbutton.x_root, event.xbutton.y_root, Resize); /* type 1 for resize */
}
/* Button */
else if((c = getbutton(event.xbutton.window))) {
if(event.xbutton.button == Button1) {
killclient(NULL);
} else if(event.xbutton.button == Button3)
togglemax(NULL);
}
/* Bar */
else if(event.xbutton.window == bar) {
for(i = 0; i < conf.ntag + 1; ++i) {
if(event.xbutton.x > taglen[i-1]
&& event.xbutton.x < taglen[i]) {
if(event.xbutton.button == Button1) {
ITOA(s, i);
if(event.xbutton.state & ALT) {
tagtransfert(s);
updateall();
}
tag(s);
updateall();
}
}
}
if(event.xbutton.x >= taglen[conf.ntag]
&& event.xbutton.x < taglen[conf.ntag] + strlen(conf.symlayout[layout[seltag]])+30) {
if(event.xbutton.button == Button1) {
layoutswitch(NULL);
}
}
}
/* Root */
else if(event.xbutton.window == root) {
if(event.xbutton.button == Button4)
tagswitch("+1");
else if(event.xbutton.button == Button5)
tagswitch("-1");
}
break;
case ButtonPress: buttonpress(&event); break;
}
return;
}
@ -354,7 +400,7 @@ hide(Client *c) {
XMoveWindow(dpy, c->win, c->x, c->y+mh*2);
XMoveWindow(dpy, c->tbar, c->x, c->y+mh*2);
XMoveWindow(dpy, c->button, c->x, c->y+mh*2);
}
}
}
void
@ -372,8 +418,8 @@ init(void) {
seltag = 1;
init_conf();
for(i=0;i<MAXTAG;++i) {
mwfact[i] = 0.5;
layout[i] = Tile;
mwfact[i] = 0.65;
layout[i] = Max;
}
/* INIT FONT */
@ -446,7 +492,9 @@ ishide(Client *c) {
void
keymovex(char *cmd) {
if(sel && cmd && !ishide(sel) && !sel->max && layout[seltag] != Tile) {
if(sel && cmd && !ishide(sel) && !sel->max) {
if(layout[seltag] == Tile && !sel->hint)
return;
int tmp;
tmp = sel->x + atoi(cmd);
moveresize(sel,tmp, sel->y, sel->w, sel->h, 1);
@ -456,7 +504,9 @@ keymovex(char *cmd) {
void
keymovey(char *cmd) {
if(sel && cmd && !ishide(sel) && !sel->max && layout[seltag] != Tile) {
if(sel && cmd && !ishide(sel) && !sel->max) {
if(layout[seltag] == Tile && !sel->hint)
return;
int tmp;
tmp = sel->y + atoi(cmd);
moveresize(sel, sel->x, tmp, sel->w, sel->h, 1);
@ -521,11 +571,18 @@ killclient(char *cmd) {
void
layoutswitch(char *cmd) {
if(sel) {
if(cmd[0] == '+') {
switch(layout[seltag]) {
case Free: tile(NULL); break;
case Tile: togglemax(NULL); break;
case Max: freelayout(); break;
case Free: tile(); break;
case Tile: maxlayout(); break;
case Max: freelayout(); break;
}
}
else if(cmd[0] == '-') {
switch(layout[seltag]) {
case Free: maxlayout(); break;
case Tile: freelayout(); break;
case Max: tile(); break;
}
}
return;
@ -590,7 +647,7 @@ manage(Window w, XWindowAttributes *wa) {
grabbuttons(c, False);
setsizehints(c);
attach(c);
moveresize(c, c->x, c->y, c->w, c->h, 0);
moveresize(c, c->x, c->y, c->w, c->h, 1);
XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
mapclient(c);
updatetitle(c);
@ -600,6 +657,30 @@ manage(Window w, XWindowAttributes *wa) {
return;
}
void
maxlayout(void) {
layout[seltag] = Max;
if(sel && !ishide(sel) && !sel->hint) {
Client *c;
for(c = clients; c; c = c->next) {
if(!ishide(c)) {
c->ox = c->x;
c->oy = c->y;
c->ow = c->w;
c->oh = c->h;
moveresize(sel, 0,
conf.ttbarheight + barheight,
(mw-(conf.borderheight * 2)),
(mh-(conf.borderheight * 2)- conf.ttbarheight - barheight),1);
c->max = True;
raiseclient(sel);
}
}
}
return;
}
/* If the type is 0, this function will move, else,
this will resize */
@ -608,7 +689,7 @@ mouseaction(Client *c, int x, int y, int type) {
int ocx, ocy;
XEvent ev;
if(c->max || layout[seltag] == Tile)
if(c->max || (layout[seltag] == Tile && !c->hint))
return;
ocx = c->x;
@ -633,7 +714,7 @@ mouseaction(Client *c, int x, int y, int type) {
if(type) /* Resize */
moveresize(c, c->x, c->y,
((ev.xmotion.x - ocx <= 0) ? 1 : ev.xmotion.x - ocx),
((ev.xmotion.y - ocy <= 0) ? 1 : ev.xmotion.y - ocy),0);
((ev.xmotion.y - ocy <= 0) ? 1 : ev.xmotion.y - ocy),1);
else /* Move */
moveresize(c,
(ocx + (ev.xmotion.x - x)),
@ -641,7 +722,7 @@ mouseaction(Client *c, int x, int y, int type) {
c->w, c->h,0);
if(conf.clientbarblock) {
if(c->y < barheight + conf.ttbarheight - 5) {
moveresize(c, c->x, barheight+conf.ttbarheight, c->w, c->h, 0);
moveresize(c, c->x, barheight+conf.ttbarheight, c->w, c->h, 1);
XUngrabPointer(dpy, CurrentTime);
return;
}
@ -657,10 +738,10 @@ moveresize(Client *c, int x, int y, int w, int h, bool r) {
if(c) {
/* Resize hints {{{ */
if(r) {
if(c->minw > 0 && w < c->minw) w = c->minw;
if(c->minh > 0 && h < c->minh) h = c->minh;
if(c->maxw > 0 && w > c->maxw) w = c->maxw;
if(c->maxh > 0 && h > c->maxh) h = c->maxh;
if(c->minw > 0 && w < c->minw){ w = c->minw; c->hint = 1; };
if(c->minh > 0 && h < c->minh){ h = c->minh; c->hint = 1; };
if(c->maxw > 0 && w > c->maxw){ w = c->maxw; c->hint = 1; };
if(c->maxh > 0 && h > c->maxh){ h = c->maxh; c->hint = 1; };
if(w <= 0 || h <= 0) return;
}
/* }}} */
@ -828,11 +909,12 @@ tagtransfert(char *cmd) {
}
void
tile(char *cmd) {
tile(void) {
layout[seltag] = Tile;
if(sel) {
Client *c;
int i;
unsigned int n, h, w, bord;
unsigned int n, nh, h, w, bord;
unsigned int barto;
float mwf;
@ -840,23 +922,22 @@ tile(char *cmd) {
bord = conf.borderheight * 2;
mwf = mw*mwfact[seltag];
n = clientpertag(seltag);
nh = clienthintpertag(seltag);
w = mw - mwf - bord;
if(n > 1)
h = (mh- barheight) / (n - 1);
else
h = mh - barheight;
for(i=0, c = clients; c; c = c->next, ++i) {
if((n-nh) > 1) h = (mh - barheight) / ((n-nh) - 1);
else h = mh - barheight;
for(i = 0, c = clients; c && !c->hint; c = c->next, ++i) {
if(!ishide(c)) {
if(n == 1)
if((n-nh) == 1)
moveresize(c, 0, barto, mw-bord, mh-(bord+barto), 0);
else if(i == 0)
moveresize(c, 0, barto, mwf-bord, mh-(bord+barto), 0);
else
moveresize(c, mwf, (i-1)* h + barto, w, h - (conf.ttbarheight + bord), 0);
layout[seltag] = Tile;
moveresize(c, mwf, (i-1)*h + barto, w, h - (conf.ttbarheight + bord), 0);
}
}
}
@ -865,7 +946,7 @@ tile(char *cmd) {
void
togglemax(char *cmd) {
if(sel && !ishide(sel)) {
if(sel && !ishide(sel) && !sel->hint) {
if(!sel->max) {
sel->ox = sel->x;
sel->oy = sel->y;
@ -874,20 +955,16 @@ togglemax(char *cmd) {
moveresize(sel, 0,
conf.ttbarheight + barheight,
(mw-(conf.borderheight * 2)),
(mh-(conf.borderheight * 2)- conf.ttbarheight - barheight),1);
sel->max = True;
layout[seltag] = Max;
} else if(sel->max) {
moveresize(sel, sel->ox, sel->oy, sel->ow, sel->oh,0);
sel->max = False;
layout[seltag] = Free;
(mh-(conf.borderheight * 2)- conf.ttbarheight - barheight), 0);
raiseclient(sel);
sel->max = True;
} else if(sel->max) {
moveresize(sel, sel->ox, sel->oy, sel->ow, sel->oh, 1);
sel->max = False;
}
raiseclient(sel);
}
return;
}
void
unhide(Client *c) {
if(c) {
@ -900,7 +977,7 @@ unhide(Client *c) {
if(conf.clientbarblock)
if(c->y+conf.ttbarheight <= barheight)
moveresize(c, c->x, barheight + conf.ttbarheight, c->w, c->h,1);
}
}
}
void
@ -932,7 +1009,7 @@ updateall(void) {
void
updatebar(void) {
int i,j;
int i,j;
char buf[conf.ntag][100];
tm = localtime(&lt);
lt = time(NULL);
@ -962,8 +1039,8 @@ updatebar(void) {
XSetForeground(dpy, gc, conf.colors.tagselfg);
XDrawString(dpy, bar, gc, taglen[conf.ntag],
fonth-1,
conf.symlayout[layout[seltag]],
strlen(conf.symlayout[layout[seltag]]));
getlayoutsym(layout[seltag]),
strlen(getlayoutsym(layout[seltag])));
/* Draw date */
sprintf(status, "%02d:%02d WMFS", tm->tm_hour, tm->tm_min);
@ -978,7 +1055,7 @@ updatebar(void) {
void
updatelayout(void) {
if(layout[seltag] == Tile)
tile(NULL);
tile();
if(layout[seltag] == Max)
togglemax(NULL);
if(layout[seltag] == Free)

9
wmfsrc
View File

@ -23,7 +23,9 @@ colors
layout
{
layout_symbol = { "[Free]", "[Tile]", "[Max]" }
free = "[Free]"
tile = "[Tile]"
max = "[Max]"
}
tag
@ -37,12 +39,13 @@ keys
key { mod = {"Control"} key = "Return" func = "spawn" cmd = "urxvt" }
key { mod = {"Alt"} key = "q" func = "killclient" cmd = NULL }
key { mod = {"Control"} key = "t" func = "togglemax" cmd = NULL }
key { mod = {"Control"} key = "o" func = "tile" cmd = NULL }
key { mod = {"Control"} key = "m" func = "togglemax" cmd = NULL }
key { mod = {"Alt"} key = "Tab" func = "wswitch" cmd = "+" }
key { mod = {"Alt","Shift"} key = "Tab" func = "wswitch" cmd = "-" }
key { mod = {"Control"} key = "Right" func = "tagswitch" cmd = "+1" }
key { mod = {"Control"} key = "Left" func = "tagswitch" cmd = "-1" }
key { mod = {"Control"} key = "l" func = "layoutswitch" cmd = "+" }
key { mod = {"Control", "Shift"} key = "l" func = "layoutswitch" cmd = "-" }
# moving client keybind