[ALL] Add Bar Button support with config etc.., test of stdin getting and other stuff

This commit is contained in:
Martin Duquesnoy 2008-09-02 22:38:25 +02:00
parent db92169d34
commit a10bb1ffa6
5 changed files with 386 additions and 227 deletions

1
TODO
View File

@ -3,5 +3,6 @@
· Add XPM support · Add XPM support
· Add colors gradation for bar and titlebar maybe · Add colors gradation for bar and titlebar maybe
· Better tile layout · Better tile layout
· Multi-Head support
· Fix all the bug \o/ · Fix all the bug \o/
· XCB ? · XCB ?

View File

@ -114,6 +114,22 @@ init_conf(void) {
CFG_END() CFG_END()
}; };
static cfg_opt_t button_opts[] = {
CFG_STR("text", "", CFGF_NONE),
CFG_STR("func", "", CFGF_NONE),
CFG_STR("cmd", NULL, CFGF_NONE),
CFG_INT("fg_color", 0x000000, CFGF_NONE),
CFG_INT("bg_color", 0xFFFFFF, CFGF_NONE),
CFG_END()
};
static cfg_opt_t buttons_opts[] = {
CFG_SEC("button", button_opts, CFGF_MULTI),
CFG_END()
};
static cfg_opt_t opts[] = { static cfg_opt_t opts[] = {
CFG_SEC("misc", misc_opts, CFGF_NONE), CFG_SEC("misc", misc_opts, CFGF_NONE),
@ -121,15 +137,18 @@ init_conf(void) {
CFG_SEC("layout", layout_opts, CFGF_NONE), CFG_SEC("layout", layout_opts, CFGF_NONE),
CFG_SEC("tag", tag_opts, CFGF_NONE), CFG_SEC("tag", tag_opts, CFGF_NONE),
CFG_SEC("keys", keys_opts, CFGF_NONE), CFG_SEC("keys", keys_opts, CFGF_NONE),
CFG_SEC("buttons", buttons_opts, CFGF_NONE),
CFG_END() CFG_END()
}; };
cfg_t *cfg; cfg_t *cfg;
cfg_t *cfg_misc; cfg_t *cfg_misc;
cfg_t *cfg_colors; cfg_t *cfg_colors;
cfg_t *cfg_layout; cfg_t *cfg_layout;
cfg_t *cfg_tag; cfg_t *cfg_tag;
cfg_t *cfg_keys; cfg_t *cfg_keys;
cfg_t *cfgtmp; cfg_t *cfg_buttons;
cfg_t *cfgtmp, *cfgtmp2;
char final_path[100]; char final_path[100];
int ret, i, j, l; int ret, i, j, l;
@ -153,6 +172,7 @@ init_conf(void) {
cfg_layout = cfg_getsec(cfg, "layout"); cfg_layout = cfg_getsec(cfg, "layout");
cfg_tag = cfg_getsec(cfg, "tag"); cfg_tag = cfg_getsec(cfg, "tag");
cfg_keys = cfg_getsec(cfg, "keys"); cfg_keys = cfg_getsec(cfg, "keys");
cfg_buttons = cfg_getsec(cfg, "buttons");
/* misc */ /* misc */
conf.font = strdup(cfg_getstr(cfg_misc, "font")); conf.font = strdup(cfg_getstr(cfg_misc, "font"));
@ -179,7 +199,7 @@ init_conf(void) {
/* tag */ /* tag */
conf.ntag = cfg_size(cfg_tag, "tag"); conf.ntag = cfg_size(cfg_tag, "tag");
for(i=0; i < cfg_size(cfg_tag, "tag"); ++i) for(i=0; i < cfg_size(cfg_tag, "tag"); ++i)
conf.taglist[i] = strdup(cfg_getnstr(cfg_tag,"tag",i)); conf.taglist[i] = strdup(cfg_getnstr(cfg_tag, "tag",i));
/* keybind ('tention ça rigole plus) */ /* keybind ('tention ça rigole plus) */
conf.nkeybind = cfg_size(cfg_keys, "key"); conf.nkeybind = cfg_size(cfg_keys, "key");
@ -190,13 +210,24 @@ init_conf(void) {
keys[j].mod |= char_to_modkey(cfg_getnstr(cfgtmp, "mod", l)); keys[j].mod |= char_to_modkey(cfg_getnstr(cfgtmp, "mod", l));
keys[j].keysym = XStringToKeysym(cfg_getstr(cfgtmp, "key")); keys[j].keysym = XStringToKeysym(cfg_getstr(cfgtmp, "key"));
keys[j].func = name_to_func (cfg_getstr(cfgtmp, "func")); keys[j].func = name_to_func(cfg_getstr(cfgtmp, "func"));
if(!keys[j].func) { if(!keys[j].func) {
printf("WMFS Configuration: Unknow Function %s",cfg_getstr(cfgtmp,"func")); printf("WMFS Configuration: Unknow Function %s",cfg_getstr(cfgtmp,"func"));
return; return;
} }
keys[j].cmd = strdup(strdup(cfg_getstr(cfgtmp, "cmd"))); keys[j].cmd = strdup(strdup(cfg_getstr(cfgtmp, "cmd")));
} }
/* button */
conf.nbutton = cfg_size(cfg_buttons, "button");
for(i = 0; i < conf.nbutton; ++i) {
cfgtmp2 = cfg_getnsec(cfg_buttons, "button", i);
conf.barbutton[i].text = strdup(cfg_getstr(cfgtmp2, "text"));
conf.barbutton[i].func = name_to_func(cfg_getstr(cfgtmp2, "func"));
conf.barbutton[i].cmd = strdup(cfg_getstr(cfgtmp2, "cmd"));
conf.barbutton[i].fg_color = cfg_getint(cfgtmp2, "fg_color");
conf.barbutton[i].bg_color = cfg_getint(cfgtmp2, "bg_color");
}
cfg_free(cfg); cfg_free(cfg);
} }

29
local.h
View File

@ -8,6 +8,7 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#include <errno.h>
#include <time.h> #include <time.h>
#include <getopt.h> #include <getopt.h>
#include <confuse.h> #include <confuse.h>
@ -19,7 +20,6 @@
#include <X11/keysym.h> #include <X11/keysym.h>
#include <X11/cursorfont.h> #include <X11/cursorfont.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include "config.h" #include "config.h"
/* DEFINE TYPES */ /* DEFINE TYPES */
@ -33,6 +33,7 @@
#define SHIFT ShiftMask #define SHIFT ShiftMask
#define LEN(x) (sizeof x / sizeof x[0]) #define LEN(x) (sizeof x / sizeof x[0])
#define ITOA(p,n) sprintf(p,"%i",n) #define ITOA(p,n) sprintf(p,"%i",n)
#define debug(p) printf("debug: %d\n", p)
#define Move 0 #define Move 0
#define Resize 1 #define Resize 1
#define MAXTAG 36 #define MAXTAG 36
@ -50,7 +51,8 @@ struct Client {
Window win; /* window */ Window win; /* window */
Window tbar; /* Titlebar? */ Window tbar; /* Titlebar? */
Window button; /* Close Button */ Window button; /* Close Button */
Bool max, tile, hint; /* client info */ Bool max, tile, free; /* Client Info */
Bool hint, hide; /* Client Info² */
Client *next; /* next client */ Client *next; /* next client */
Client *prev; /* previous client */ Client *prev; /* previous client */
}; };
@ -67,6 +69,15 @@ typedef struct {
void *func; void *func;
} func_name_list_t; } func_name_list_t;
typedef struct {
char *text;
Window win;
void (*func)(char *cmd);
char *cmd;
int fg_color;
int bg_color;
} BarButton;
typedef struct { typedef struct {
/* bool and size */ /* bool and size */
char *font; char *font;
@ -94,6 +105,8 @@ typedef struct {
char *taglist[MAXTAG]; char *taglist[MAXTAG];
/* keybind */ /* keybind */
int nkeybind; int nkeybind;
BarButton barbutton[64];
int nbutton;
} Conf; } Conf;
enum { CurNormal, CurResize, CurMove, CurInput, CurLast }; enum { CurNormal, CurResize, CurMove, CurInput, CurLast };
@ -118,6 +131,7 @@ Client* getnext(Client *c);
char* getlayoutsym(int l); char* getlayoutsym(int l);
Client* gettbar(Window w); Client* gettbar(Window w);
void getevent(void); void getevent(void);
void getstdin(void);
void grabbuttons(Client *c, Bool focused); void grabbuttons(Client *c, Bool focused);
void grabkeys(void); void grabkeys(void);
void hide(Client *c); void hide(Client *c);
@ -147,6 +161,7 @@ void togglemax(char *cmd);
void unhide(Client *c); void unhide(Client *c);
void unmanage(Client *c); void unmanage(Client *c);
void updatebar(void); void updatebar(void);
void updatebutton(void);
void updatelayout(void); void updatelayout(void);
void unmapclient(Client *c); void unmapclient(Client *c);
void updateall(void); void updateall(void);
@ -173,11 +188,19 @@ Atom net_atom[NetLast];
Cursor cursor[CurLast]; Cursor cursor[CurLast];
int mw, mh; int mw, mh;
int fonth; int fonth;
int fonty;
int barheight; int barheight;
Client *clients; /* First Client */ Client *clients; /* First Client */
Client *sel[MAXTAG]; /* selected client */ Client *sel; /* selected client */
int seltag; /* selected tag */ int seltag; /* selected tag */
Client *selbytag[MAXTAG];
char status[16]; char status[16];
float mwfact[MAXTAG]; float mwfact[MAXTAG];
int layout[MAXTAG]; int layout[MAXTAG];
char bartext[256];
char *ptrb, bufbt[sizeof bartext];
int readp;
Bool readin;
unsigned int offset, len;
#endif /* LOCAL_H */ #endif /* LOCAL_H */

395
wmfs.c
View File

@ -27,7 +27,6 @@
#include "local.h" #include "local.h"
unsigned int numlockmask = 0; unsigned int numlockmask = 0;
int taglen[MAXTAG] = {3}; int taglen[MAXTAG] = {3};
void void
@ -72,15 +71,11 @@ buttonpress(XEvent *event) {
for(i = 0; i < conf.ntag + 1; ++i) { for(i = 0; i < conf.ntag + 1; ++i) {
if(ev->x > taglen[i-1] if(ev->x > taglen[i-1]
&& ev->x < taglen[i]) { && ev->x < taglen[i]) {
if(ev->button == Button1) {
ITOA(s, i); ITOA(s, i);
if(ev->state & ALT) { if(ev->button == Button1)
tagtransfert(s);
updateall();
}
tag(s); tag(s);
updateall(); else if(ev->button == Button3)
} tagtransfert(s);
} }
} }
/* tag switch with scroll */ /* tag switch with scroll */
@ -92,7 +87,8 @@ buttonpress(XEvent *event) {
} }
/* layout switch */ /* layout switch */
if(ev->x >= taglen[conf.ntag] if(ev->x >= taglen[conf.ntag]
&& ev->x < taglen[conf.ntag] + (strlen((getlayoutsym(layout[seltag])))*6)) { && ev->x < taglen[conf.ntag] +
(strlen((getlayoutsym(layout[seltag])))*fonty+3)) {
if(ev->button == Button1 if(ev->button == Button1
|| ev->button == Button4) { || ev->button == Button4) {
layoutswitch("+"); layoutswitch("+");
@ -112,6 +108,13 @@ buttonpress(XEvent *event) {
tagswitch("-1"); tagswitch("-1");
} }
/* Bar Button */
for(i=0; i<conf.nbutton ; ++i) {
if(ev->window == conf.barbutton[i].win
&& ev->button == Button1) {
conf.barbutton[i].func(conf.barbutton[i].cmd);
}
}
} }
int int
@ -195,19 +198,21 @@ errorhandler(Display *d, XErrorEvent *event) {
void void
focus(Client *c) { focus(Client *c) {
if(sel[seltag] && sel[seltag] != c) { if(sel && sel != c) {
grabbuttons(sel[seltag], False); grabbuttons(sel, False);
setborder(sel[seltag]->win, conf.colors.bordernormal); setborder(sel->win, conf.colors.bordernormal);
setborder(sel[seltag]->tbar, conf.colors.bordernormal); setborder(sel->tbar, conf.colors.bordernormal);
} }
if(c) grabbuttons(c, True); if(c)
grabbuttons(c, True);
sel[seltag] = c; sel = c;
selbytag[seltag] = c;
if(c) { if(c) {
setborder(c->win, conf.colors.borderfocus); setborder(c->win, conf.colors.borderfocus);
setborder(sel[seltag]->tbar, conf.colors.borderfocus); setborder(sel->tbar, conf.colors.borderfocus);
if(conf.raisefocus) if(conf.raisefocus)
raiseclient(c); raiseclient(c);
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
@ -218,16 +223,15 @@ focus(Client *c) {
void void
freelayout(void) { freelayout(void) {
layout[seltag] = Free;
Client *c; Client *c;
for(c = clients; c; c = c->next){ for(c = clients; c; c = c->next){
if(!ishide(c)) { if(!ishide(c)) {
if(c->max) { if(c->max)
moveresize(c, c->ox, c->oy, c->ow, c->oh, 1); moveresize(c, c->ox, c->oy, c->ow, c->oh, 1);
}
c->max = False; c->max = False;
} }
} }
layout[seltag] = Free;
return; return;
} }
@ -271,24 +275,22 @@ gettbar(Window w) {
void void
getevent(void) { getevent(void) {
XEvent event;
XWindowAttributes at; XWindowAttributes at;
Client *c; Client *c;
struct timeval tv; struct timeval tv;
if(QLength(dpy) > 0) { if(QLength(dpy) > 0)
XNextEvent(dpy, &event); XNextEvent(dpy, &event);
} else { else {
XFlush(dpy); XFlush(dpy);
FD_ZERO(&fd); FD_ZERO(&fd);
FD_SET(ConnectionNumber(dpy), &fd); FD_SET(ConnectionNumber(dpy), &fd);
event.type = LASTEvent; event.type = LASTEvent;
tv.tv_sec = 2; tv.tv_sec = 1;
tv.tv_usec = 0; tv.tv_usec = 0;
if(select(FD_SETSIZE, &fd, NULL, NULL, &tv) > 0) { if(select(FD_SETSIZE, &fd, NULL, NULL, &tv) > 0)
XNextEvent(dpy, &event); XNextEvent(dpy, &event);
} }
}
switch (event.type) { switch (event.type) {
case EnterNotify: case EnterNotify:
@ -307,10 +309,7 @@ getevent(void) {
manage(event.xmaprequest.window, &at); manage(event.xmaprequest.window, &at);
break; break;
case MappingNotify: case MappingNotify: if(event.xmapping.request == MappingKeyboard) grabkeys(); break;
if(event.xmapping.request == MappingKeyboard)
grabkeys();
break;
case PropertyNotify: case PropertyNotify:
if(event.xproperty.state == PropertyDelete) if(event.xproperty.state == PropertyDelete)
@ -326,10 +325,12 @@ getevent(void) {
} }
} }
break; break;
case ConfigureRequest: configurerequest(event); break; case ConfigureRequest: configurerequest(event); break;
case UnmapNotify: case UnmapNotify:
if((c = getclient(event.xunmap.window))) if((c = getclient(event.xunmap.window)))
if(!c->hide)
unmanage(c); unmanage(c);
break; break;
@ -339,8 +340,8 @@ getevent(void) {
break; break;
case FocusIn: case FocusIn:
if(sel[seltag] && event.xfocus.window != sel[seltag]->win) if(sel && event.xfocus.window != sel->win)
XSetInputFocus(dpy, sel[seltag]->win, RevertToPointerRoot, CurrentTime); XSetInputFocus(dpy, sel->win, RevertToPointerRoot, CurrentTime);
break; break;
case KeyPress: keypress(&event); break; case KeyPress: keypress(&event); break;
@ -349,8 +350,30 @@ getevent(void) {
return; return;
} }
/* Not finish, testing */
void
getstdin(void) {
if(isatty(STDIN_FILENO))
return;
debug(354);
readp = read(STDIN_FILENO, bufbt + offset, len - offset);
for(ptrb = bufbt + offset; readp > 0; ptrb++, readp--, offset++)
if(*ptrb == '\n' || *ptrb == '\0') {
*ptrb = '\0';
strncpy(bartext, bufbt, len);
ptrb += readp - 1;
for(readp = 0; *(ptrb - readp) && *(ptrb - readp) != '\n'; readp++);
offset = readp;
if(readp)
memmove(bufbt, ptrb - readp + 1, readp);
break;
}
return;
}
void void
grabbuttons(Client *c, Bool focused) { grabbuttons(Client *c, Bool focused) {
int i;
XUngrabButton(dpy, AnyButton, AnyModifier, c->win); XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
XUngrabButton(dpy, AnyButton, AnyModifier, c->tbar); XUngrabButton(dpy, AnyButton, AnyModifier, c->tbar);
XUngrabButton(dpy, AnyButton, AnyModifier, c->button); XUngrabButton(dpy, AnyButton, AnyModifier, c->button);
@ -367,14 +390,15 @@ grabbuttons(Client *c, Bool focused) {
XGrabButton(dpy, Button1, AnyModifier, c->tbar, 0, ButtonMask,GrabModeAsync, GrabModeSync, None, None); XGrabButton(dpy, Button1, AnyModifier, c->tbar, 0, ButtonMask,GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button2, AnyModifier, c->tbar, 0, ButtonMask,GrabModeAsync, GrabModeSync, None, None); XGrabButton(dpy, Button2, AnyModifier, c->tbar, 0, ButtonMask,GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button3, AnyModifier, c->tbar, 0, ButtonMask,GrabModeAsync, GrabModeSync, None, None); XGrabButton(dpy, Button3, AnyModifier, c->tbar, 0, ButtonMask,GrabModeAsync, GrabModeSync, None, None);
/* Button */ /* Titlebar Button */
XGrabButton(dpy, Button1, AnyModifier, c->button, 0, ButtonMask,GrabModeAsync, GrabModeSync, None, None); XGrabButton(dpy, Button1, AnyModifier, c->button, 0, ButtonMask,GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button3, AnyModifier, c->button, 0, ButtonMask,GrabModeAsync, GrabModeSync, None, None); XGrabButton(dpy, Button3, AnyModifier, c->button, 0, ButtonMask,GrabModeAsync, GrabModeSync, None, None);
/* Bar Button */
for(i=0; i< conf.nbutton; ++i)
XGrabButton(dpy, Button1, AnyModifier, conf.barbutton[i].win, 0, ButtonMask,GrabModeAsync, GrabModeSync, None, None);
} else { } else {
XGrabButton(dpy, AnyButton, AnyModifier, c->win, 0, ButtonMask, GrabModeAsync, GrabModeSync, None, None); XGrabButton(dpy, AnyButton, AnyModifier, c->win, 0, ButtonMask, GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, AnyButton, AnyModifier, c->tbar, 0, ButtonMask, GrabModeAsync, GrabModeSync, None, None); XGrabButton(dpy, AnyButton, AnyModifier, c->tbar, 0, ButtonMask, GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, AnyButton, AnyModifier, c->button, 0, ButtonMask, GrabModeAsync, GrabModeSync, None, None); XGrabButton(dpy, AnyButton, AnyModifier, c->button, 0, ButtonMask, GrabModeAsync, GrabModeSync, None, None);
} }
} }
@ -396,11 +420,19 @@ grabkeys(void) {
void void
hide(Client *c) { hide(Client *c) {
if(c) { if(!c || c->hide) return;
long data[] = { IconicState, None };
/* unmapclient(c); */
/* Just hide for now... */
XMoveWindow(dpy, c->win, c->x, c->y+mh*2); XMoveWindow(dpy, c->win, c->x, c->y+mh*2);
XMoveWindow(dpy, c->tbar, 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); XMoveWindow(dpy, c->button, c->x, c->y+mh*2);
}
XChangeProperty(dpy, c->win, XInternAtom(dpy, "WM_STATE", False),
XInternAtom(dpy, "WM_STATE", False), 32,
PropModeReplace, (unsigned char *) data, 2);
c->hide = True;
} }
void void
@ -430,8 +462,9 @@ init(void) {
} }
XSetFont(dpy, gc, font->fid); XSetFont(dpy, gc, font->fid);
fonth = font->ascent + font->descent; fonth = (font->ascent + font->descent) - 1;
barheight = fonth + 3; barheight = fonth + 3;
fonty = (font->ascent + font->descent) / 2;
/* INIT CURSOR */ /* INIT CURSOR */
cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
@ -441,7 +474,7 @@ init(void) {
/* INIT MODIFIER */ /* INIT MODIFIER */
modmap = XGetModifierMapping(dpy); modmap = XGetModifierMapping(dpy);
for(i = 0; i < 8; i++) for(i = 0; i < 8; i++)
for(j = 0; j < modmap->max_keypermod; j++) { for(j = 0; j < modmap->max_keypermod; ++j) {
if(modmap->modifiermap[i * modmap->max_keypermod + j] if(modmap->modifiermap[i * modmap->max_keypermod + j]
== XKeysymToKeycode(dpy, XK_Num_Lock)) == XKeysymToKeycode(dpy, XK_Num_Lock))
numlockmask = (1 << i); numlockmask = (1 << i);
@ -473,10 +506,17 @@ init(void) {
CWOverrideRedirect | CWBackPixmap | CWEventMask, &at); CWOverrideRedirect | CWBackPixmap | CWEventMask, &at);
XSetWindowBackground(dpy, bar, conf.colors.bar); XSetWindowBackground(dpy, bar, conf.colors.bar);
XMapRaised(dpy, bar); XMapRaised(dpy, bar);
strncpy(bartext, "WMFS-devel", strlen("WMFS-devel"));
updatebar();
updatebutton();
/* INIT STUFF */ /* INIT STUFF */
XSetErrorHandler(errorhandler); XSetErrorHandler(errorhandler);
grabkeys(); grabkeys();
readin = True;
offset = 0;
len = sizeof bartext - 1;
bufbt[len] = bartext[len] = '\0';
return; return;
} }
@ -492,24 +532,24 @@ ishide(Client *c) {
void void
keymovex(char *cmd) { keymovex(char *cmd) {
if(sel[seltag] && cmd && !ishide(sel[seltag]) && !sel[seltag]->max) { if(sel && cmd && !ishide(sel) && !sel->max) {
if(layout[seltag] == Tile && !sel[seltag]->hint) if(layout[seltag] == Tile && !sel->hint)
return; return;
int tmp; int tmp;
tmp = sel[seltag]->x + atoi(cmd); tmp = sel->x + atoi(cmd);
moveresize(sel[seltag], tmp, sel[seltag]->y, sel[seltag]->w, sel[seltag]->h, 1); moveresize(sel, tmp, sel->y, sel->w, sel->h, 1);
} }
return; return;
} }
void void
keymovey(char *cmd) { keymovey(char *cmd) {
if(sel[seltag] && cmd && !ishide(sel[seltag]) && !sel[seltag]->max) { if(sel && cmd && !ishide(sel) && !sel->max) {
if(layout[seltag] == Tile && !sel[seltag]->hint) if(layout[seltag] == Tile && !sel->hint)
return; return;
int tmp; int tmp;
tmp = sel[seltag]->y + atoi(cmd); tmp = sel->y + atoi(cmd);
moveresize(sel[seltag], sel[seltag]->x, tmp, sel[seltag]->w, sel[seltag]->h, 1); moveresize(sel, sel->x, tmp, sel->w, sel->h, 1);
} }
return; return;
} }
@ -535,38 +575,34 @@ keypress(XEvent *e) {
void void
keyresize(char *cmd) { keyresize(char *cmd) {
if(sel[seltag] if(sel && !ishide(sel) && !sel->max && layout[seltag] != Tile) {
&& !ishide(sel[seltag]) int temph = 0, tempw = 0, modh = 0, modw = 0, tmp = 0;
&& !sel[seltag]->max
&& layout[seltag] != Tile)
{
unsigned int temph, tempw, modh, modw, tmp;
switch(cmd[1]) { switch(cmd[1]) {
case 'h': tmp = (cmd[0] == '+') ? 5 : -5; modh = tmp; break; case 'h': tmp = (cmd[0] == '+') ? 5 : -5; modh = tmp; break;
case 'w': tmp = (cmd[0] == '+') ? 5 : -5; modw = tmp; break; case 'w': tmp = (cmd[0] == '+') ? 5 : -5; modw = tmp; break;
} }
temph = sel[seltag]->h + modh; temph = sel->h + modh;
tempw = sel[seltag]->w + modw; tempw = sel->w + modw;
temph = (temph < 10) ? 10 : temph; temph = (temph < 10) ? 10 : temph;
tempw = (tempw < 10) ? 10 : tempw; tempw = (tempw < 10) ? 10 : tempw;
moveresize(sel[seltag], sel[seltag]->x, sel[seltag]->y, tempw, temph, 1); moveresize(sel, sel->x, sel->y, tempw, temph, 1);
} }
return; return;
} }
void void
killclient(char *cmd) { killclient(char *cmd) {
if(sel[seltag] && !ishide(sel[seltag])) { if(sel && !ishide(sel)) {
XEvent ev; XEvent ev;
ev.type = ClientMessage; ev.type = ClientMessage;
ev.xclient.window = sel[seltag]->win; ev.xclient.window = sel->win;
ev.xclient.message_type = wm_atom[WMProtocols]; ev.xclient.message_type = wm_atom[WMProtocols];
ev.xclient.format = 32; ev.xclient.format = 32;
ev.xclient.data.l[0] = wm_atom[WMDelete]; ev.xclient.data.l[0] = wm_atom[WMDelete];
ev.xclient.data.l[1] = CurrentTime; ev.xclient.data.l[1] = CurrentTime;
XSendEvent(dpy, sel[seltag]->win, False, NoEventMask, &ev); XSendEvent(dpy, sel->win, False, NoEventMask, &ev);
} }
updatelayout(); updatelayout();
return; return;
@ -593,11 +629,12 @@ layoutswitch(char *cmd) {
void void
mapclient(Client *c) { mapclient(Client *c) {
if(c) { if(!c)
return;
XMapWindow(dpy, c->win); XMapWindow(dpy, c->win);
XMapWindow(dpy, c->tbar); XMapWindow(dpy, c->tbar);
XMapWindow(dpy, c->button); XMapWindow(dpy, c->button);
} XMapSubwindows(dpy, c->win);
return; return;
} }
@ -663,21 +700,22 @@ manage(Window w, XWindowAttributes *wa) {
void void
maxlayout(void) { maxlayout(void) {
layout[seltag] = Max; layout[seltag] = Max;
if(sel[seltag] && !ishide(sel[seltag]) && !sel[seltag]->hint) { if(!sel || ishide(sel) || sel->hint)
return;
printf("PWOUTE\n");
Client *c; Client *c;
for(c = clients; c; c = c->next) { for(c = clients; c; c = c->next) {
if(!ishide(c)) { if(!ishide(c) && !c->free) {
c->ox = c->x; c->ox = c->x;
c->oy = c->y; c->oy = c->y;
c->ow = c->w; c->ow = c->w;
c->oh = c->h; c->oh = c->h;
moveresize(sel[seltag], 0, moveresize(c, 0,
conf.ttbarheight + barheight, conf.ttbarheight + barheight,
(mw-(conf.borderheight * 2)), (mw-(conf.borderheight * 2)),
(mh-(conf.borderheight * 2)- conf.ttbarheight - barheight), 1); (mh-(conf.borderheight * 2)- conf.ttbarheight - barheight), 1);
raiseclient(sel);
c->max = True; c->max = True;
raiseclient(sel[seltag]);
}
} }
} }
return; return;
@ -745,7 +783,8 @@ moveresize(Client *c, int x, int y, int w, int h, bool r) {
if(c->minh > 0 && h < c->minh){ h = c->minh; 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->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(c->maxh > 0 && h > c->maxh){ h = c->maxh; c->hint = 1; };
if(w <= 0 || h <= 0) return; if(w <= 0 || h <= 0)
return;
} }
/* }}} */ /* }}} */
@ -759,7 +798,8 @@ moveresize(Client *c, int x, int y, int w, int h, bool r) {
if(conf.clientbarblock) { if(conf.clientbarblock) {
if((y-conf.ttbarheight) <= barheight) if((y-conf.ttbarheight) <= barheight)
y = barheight+conf.ttbarheight; y = barheight+conf.ttbarheight;
} else updatebar(); } else
updatebar();
XMoveResizeWindow(dpy, c->win, x, y, w ,h); XMoveResizeWindow(dpy, c->win, x, y, w ,h);
XMoveResizeWindow(dpy, c->tbar, x, y - conf.ttbarheight, w, conf.ttbarheight); XMoveResizeWindow(dpy, c->tbar, x, y - conf.ttbarheight, w, conf.ttbarheight);
@ -863,17 +903,22 @@ tag(char *cmd) {
if(tmp > conf.ntag || tmp < 1 || tmp == seltag) if(tmp > conf.ntag || tmp < 1 || tmp == seltag)
return; return;
for(c = clients; c; c = c->next) { for(c = clients; c; c = c->next) {
if(c->win && c->tbar && c->button) {
if(!ishide(c)) if(!ishide(c))
hide(c); hide(c);
if(c->tag == tmp) if(c->tag == tmp)
unhide(c); unhide(c);
} }
}
seltag = tmp; seltag = tmp;
if(sel[tmp])
focus(sel[tmp]); if(selbytag[seltag])
updatelayout(); focus(selbytag[seltag]);
updateall();
return; return;
} }
@ -887,36 +932,40 @@ tagswitch(char *cmd) {
if(seltag + tmp > conf.ntag || seltag + tmp < 1) if(seltag + tmp > conf.ntag || seltag + tmp < 1)
return; return;
seltag += tmp;
for(c = clients; c; c = c->next) { for(c = clients; c; c = c->next) {
if(c->tag == seltag - tmp)
hide(c);
if(c->tag == seltag) if(c->tag == seltag)
hide(c);
if(c && c->tag == seltag + tmp)
unhide(c); unhide(c);
} }
if(sel[seltag])
focus(sel[seltag]); seltag += tmp;
updatelayout();
if(selbytag[seltag])
focus(selbytag[seltag]);
return; return;
} }
void void
tagtransfert(char *cmd) { tagtransfert(char *cmd) {
int n = atoi(cmd); int n = atoi(cmd);
if(!sel[seltag]) if(!sel)
return; return;
sel[seltag]->tag = n; sel->tag = n;
if(n != seltag) if(n != seltag)
hide(sel[seltag]); hide(sel);
if(n == seltag) if(n == seltag)
unhide(sel[seltag]); unhide(sel);
updatelayout(); updateall();
} }
/* Testing for now */
void void
tile(void) { tile(void) {
layout[seltag] = Tile; layout[seltag] = Tile;
if(sel[seltag]) { if(!sel)
return;
Client *c; Client *c;
int i; int i;
unsigned int n, nh, h, w, bord; unsigned int n, nh, h, w, bord;
@ -925,7 +974,6 @@ tile(void) {
barto = conf.ttbarheight + barheight; barto = conf.ttbarheight + barheight;
bord = conf.borderheight * 2; bord = conf.borderheight * 2;
mwf = mw*mwfact[seltag]; mwf = mw*mwfact[seltag];
n = clientpertag(seltag); n = clientpertag(seltag);
nh = clienthintpertag(seltag); nh = clienthintpertag(seltag);
@ -934,16 +982,18 @@ tile(void) {
if((n-nh) > 1) h = (mh - barheight) / ((n-nh) - 1); if((n-nh) > 1) h = (mh - barheight) / ((n-nh) - 1);
else h = mh - barheight; else h = mh - barheight;
moveresize(sel, 0, barto,
((n > 1) ? mwf-bord : mw-bord),
((mh-bord) - conf.ttbarheight - barheight), 0);
for(i = 0, c = clients; c && !c->hint; c = c->next, ++i) { for(i = 0, c = clients; c && !c->hint; c = c->next, ++i) {
if(!ishide(c)) { if(!ishide(c) && c != sel) {/*
if((n-nh) == 1) if((n-nh) == 1)
moveresize(c, 0, barto, mw-bord, mh-(bord+barto), 0); moveresize(c, 0, barto, mw-bord, mh-(bord+barto), 0);
else if(i == 0) else if(i == 0)
moveresize(c, 0, barto, mwf-bord, mh-(bord+barto), 0); moveresize(c, 0, barto, mwf-bord, mh-(bord+barto), 0);
else else */
moveresize(c, mwf, (i-1)*h + barto, w, h - (conf.ttbarheight + bord), 0); moveresize(c, mwf, (i-1)*h + barto, w, h - (conf.ttbarheight + bord), 0);
}
} }
} }
return; return;
@ -951,55 +1001,67 @@ tile(void) {
void void
togglemax(char *cmd) { togglemax(char *cmd) {
if(sel[seltag] && !ishide(sel[seltag]) && !sel[seltag]->hint) { if(sel && !ishide(sel) && !sel->hint) {
if(!sel[seltag]->max) { if(!sel->max) {
sel[seltag]->ox = sel[seltag]->x; sel->ox = sel->x;
sel[seltag]->oy = sel[seltag]->y; sel->oy = sel->y;
sel[seltag]->ow = sel[seltag]->w; sel->ow = sel->w;
sel[seltag]->oh = sel[seltag]->h; sel->oh = sel->h;
moveresize(sel[seltag], 0, moveresize(sel, 0,
conf.ttbarheight + barheight, conf.ttbarheight + barheight,
(mw-(conf.borderheight * 2)), (mw-(conf.borderheight * 2)),
(mh-(conf.borderheight * 2)- conf.ttbarheight - barheight), 0); (mh-(conf.borderheight * 2)- conf.ttbarheight - barheight), 0);
raiseclient(sel[seltag]); raiseclient(sel);
sel[seltag]->max = True; sel->max = True;
} else if(sel[seltag]->max) { } else if(sel->max) {
moveresize(sel[seltag], sel[seltag]->ox, sel[seltag]->oy, sel[seltag]->ow, sel[seltag]->oh, 1); moveresize(sel,
sel[seltag]->max = False; sel->ox,
sel->oy,
sel->ow,
sel->oh, 1);
sel->max = False;
sel->free = True;
} }
} }
return; return;
} }
void void
unhide(Client *c) { unhide(Client *c) {
if(c) { if(!c || !c->hide)
return;
long data[] = { NormalState, None };
/* mapclient(c); */
XMoveWindow(dpy,c->win,c->x,c->y); XMoveWindow(dpy,c->win,c->x,c->y);
XMoveWindow(dpy,c->tbar,c->x, XMoveWindow(dpy,c->tbar,c->x, (c->y - conf.ttbarheight));
(c->y - conf.ttbarheight)); XMoveWindow(dpy,c->button, (c->x + c->w -10), (c->y - 9));
XMoveWindow(dpy,c->button, XChangeProperty(dpy, c->win, XInternAtom(dpy, "WM_STATE", False),
(c->x + c->w -10), XInternAtom(dpy, "WM_STATE", False), 32,
(c->y - 9)); PropModeReplace, (unsigned char *) data, 2);
if(conf.clientbarblock) c->hide = False;
if(c->y+conf.ttbarheight <= barheight)
moveresize(c, c->x, barheight + conf.ttbarheight, c->w, c->h,1);
}
} }
void void
unmanage(Client *c) { unmanage(Client *c) {
XSetErrorHandler(errorhandler); XSetErrorHandler(errorhandler);
if(sel[seltag] == c) int i;
sel[seltag] = c->next; c->hide = True;
else
sel[seltag] = NULL; sel = (sel == c) ? c->next : NULL;
for(i = 0; i < conf.ntag; ++i)
selbytag[i] = (selbytag[i] == c) ? c->next : NULL;
XUnmapWindow(dpy, c->tbar); XUnmapWindow(dpy, c->tbar);
XDestroyWindow(dpy, c->tbar); XDestroyWindow(dpy, c->tbar);
XUnmapWindow(dpy, c->button); XUnmapWindow(dpy, c->button);
XDestroyWindow(dpy, c->button); XDestroyWindow(dpy, c->button);
detach(c); detach(c);
free(c); free(c);
XSync(dpy, False);
updatelayout(); updatelayout();
updateall();
XSync(dpy, False);
return; return;
} }
@ -1014,67 +1076,102 @@ updateall(void) {
void void
updatebar(void) { updatebar(void) {
int i,j; int i ,j, x;
char buf[conf.ntag][100]; char buf[conf.ntag][100];
char p[3];
tm = localtime(&lt); tm = localtime(&lt);
lt = time(NULL); lt = time(NULL);
if(!conf.clientbarblock) if(!conf.clientbarblock)
XRaiseWindow(dpy, bar); XRaiseWindow(dpy, bar);
else
XClearWindow(dpy, bar); XClearWindow(dpy, bar);
XSetForeground(dpy, gc, conf.colors.text); XSetForeground(dpy, gc, conf.colors.text);
for(i=0;i< conf.ntag;++i) { for(i=0; i<conf.ntag; ++i) {
/* Make the tag string */ ITOA(p, clientpertag(i+1));
if(clientpertag(i+1)) sprintf(buf[i], "%s<%s> ", conf.taglist[i], (clientpertag(i+1)) ? p : "");
sprintf(buf[i], "%s(%d) ", conf.taglist[i], clientpertag(i+1)); taglen[i+1] = taglen[i] + fonty * ( strlen(conf.taglist[i]) + strlen(buf[i]) - strlen(conf.taglist[i]) ) + fonty-4;
else
sprintf(buf[i], "%s() ", conf.taglist[i]);
taglen[i+1] = taglen[i] + 6*(strlen(conf.taglist[i]) + ((clientpertag(i+1) >= 10) ? 5 : 4));
/* Rectangle for the tag background */ /* Rectangle for the tag background */
if(i+1 == seltag) XSetForeground(dpy, gc, conf.colors.tagselbg); XSetForeground(dpy, gc, (i+1 == seltag) ? conf.colors.tagselbg : conf.colors.bar);
else XSetForeground(dpy, gc, 0x090909); XFillRectangle(dpy, bar, gc, taglen[i] - 4, 0, (strlen(buf[i])*fonty), barheight);
XFillRectangle(dpy, bar, gc, taglen[i]-4, 0, strlen(buf[i])*6, barheight);
/* Draw tag */ /* Draw tag */
if(i+1 == seltag) XSetForeground(dpy, gc, conf.colors.tagselfg); XSetForeground(dpy, gc, (i+1 == seltag) ? conf.colors.tagselfg : conf.colors.text);
else XSetForeground(dpy, gc, conf.colors.text); XDrawString(dpy, bar, gc, taglen[i], fonth, buf[i], strlen(buf[i]));
XDrawString(dpy, bar, gc, taglen[i], fonth-1, buf[i], strlen(buf[i])); }
j = taglen[conf.ntag] + ((strlen(getlayoutsym(layout[seltag]))*fonty) + 10);
for(i=0; i<conf.nbutton; ++i) {
x = (!i) ? j : j + strlen(conf.barbutton[i-1].text)*fonty + 10;
if(conf.barbutton[i].win)
XMoveWindow(dpy, conf.barbutton[i].win, x, 0);
} }
/* Draw layout symbol */ /* Draw layout symbol */
XSetForeground(dpy, gc, conf.colors.tagselfg); XSetForeground(dpy, gc, conf.colors.tagselfg);
XDrawString(dpy, bar, gc, taglen[conf.ntag], XDrawString(dpy, bar, gc, taglen[conf.ntag] + 4,
fonth-1, fonth-1,
getlayoutsym(layout[seltag]), getlayoutsym(layout[seltag]),
strlen(getlayoutsym(layout[seltag]))); strlen(getlayoutsym(layout[seltag])));
/* Draw date */ /* Draw stdin */
sprintf(status, "%02d:%02d WMFS", tm->tm_hour, tm->tm_min); j = strlen(bartext);
j = strlen(status);
XSetForeground(dpy, gc, conf.colors.text); XSetForeground(dpy, gc, conf.colors.text);
XDrawString(dpy, bar, gc, mw- j*6, fonth -1 , status, j); XDrawString(dpy, bar, gc, mw - j * fonty, fonth-1 , bartext ,j);
XDrawLine(dpy, bar, gc, mw-j*6-5, 0 , mw-j*6-5, barheight); XDrawLine(dpy, bar, gc, mw- j * fonty-5 , 0 , mw - j * fonty-5, barheight);
XSync(dpy, False); XSync(dpy, False);
return; return;
} }
void
updatebutton(void) {
int i, j, p, x;
XSetWindowAttributes at;
at.override_redirect = 1;
at.background_pixmap = ParentRelative;
at.event_mask = ButtonPressMask | ExposureMask;
j = taglen[conf.ntag] + ((strlen(getlayoutsym(layout[seltag]))*fonty) + 10);
for(i = 0; i < conf.nbutton; ++i) {
p = strlen(conf.barbutton[i].text);
x = (!i) ? j : j + strlen(conf.barbutton[i-1].text)*fonty + 10;
conf.barbutton[i].win = XCreateWindow(dpy, root, x, 0, p*fonty+4, barheight,
0, DefaultDepth(dpy, screen),
CopyFromParent, DefaultVisual(dpy, screen),
CWOverrideRedirect | CWBackPixmap | CWEventMask, &at);
XSetWindowBackground(dpy, conf.barbutton[i].win, conf.barbutton[i].bg_color);
XMapRaised(dpy, conf.barbutton[i].win);
XSetForeground(dpy, gc, conf.barbutton[i].fg_color);
XDrawString(dpy, conf.barbutton[i].win, gc, 2, fonth, conf.barbutton[i].text, p);
}
return;
}
void void
updatelayout(void) { updatelayout(void) {
if(layout[seltag] == Tile) switch(layout[seltag]) {
tile(); case Tile: tile(); break;
if(layout[seltag] == Max) case Max: maxlayout(); break;
togglemax(NULL); case Free: freelayout(); break;
if(layout[seltag] == Free) }
freelayout();
return; return;
} }
void void
unmapclient(Client *c) { unmapclient(Client *c) {
if(c) { if(!c)
return;
XUnmapWindow(dpy, c->win); XUnmapWindow(dpy, c->win);
XUnmapWindow(dpy, c->tbar); XUnmapWindow(dpy, c->tbar);
XUnmapWindow(dpy, c->button); XUnmapWindow(dpy, c->button);
} XUnmapSubwindows(dpy, c->win);
return; return;
} }
@ -1091,10 +1188,11 @@ updatetitle(Client *c) {
void void
wswitch(char *cmd) { wswitch(char *cmd) {
if(sel[seltag] && !ishide(sel[seltag])) { if(!sel || ishide(sel))
return;
Client *c; Client *c;
if(cmd[0] == '+') { if(cmd[0] == '+') {
for(c = sel[seltag]->next; c && ishide(c); c = c->next); for(c = sel->next; c && ishide(c); c = c->next);
if(!c) if(!c)
for(c = clients; c && ishide(c); c = c->next); for(c = clients; c && ishide(c); c = c->next);
if(c) { if(c) {
@ -1102,7 +1200,7 @@ wswitch(char *cmd) {
raiseclient(c); raiseclient(c);
} }
} else if(cmd[0] == '-') { } else if(cmd[0] == '-') {
for(c = sel[seltag]->prev; c && ishide(c); c = c->prev); for(c = sel->prev; c && ishide(c); c = c->prev);
if(!c) { if(!c) {
for(c = clients; c && c->next; c = c->next); for(c = clients; c && c->next; c = c->next);
for(; c && ishide(c); c = c->prev); for(; c && ishide(c); c = c->prev);
@ -1112,7 +1210,7 @@ wswitch(char *cmd) {
raiseclient(c); raiseclient(c);
} }
} }
} updateall();
return; return;
} }
@ -1159,10 +1257,11 @@ main(int argc,char **argv) {
init(); init();
scan(); scan();
for(;;) { for(;;) {
getevent(); /* Not finish */
/* getstdin(); */
updatebar(); updatebar();
getevent();
} }
XCloseDisplay(dpy); XCloseDisplay(dpy);

11
wmfsrc
View File

@ -33,9 +33,14 @@ tag
tag = { "1", "2", "3", "4", "5", "6", "7", "8", "9" } tag = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }
} }
buttons
{
button { text = "Terminal" func = "spawn" cmd = "urxvt" fg_color = 0xFFFFFF bg_color = 0x3E3E3E }
}
keys keys
{ {
#general keybind # general keybind
key { mod = {"Control"} key = "Return" func = "spawn" cmd = "urxvt" } key { mod = {"Control"} key = "Return" func = "spawn" cmd = "urxvt" }
key { mod = {"Alt"} key = "q" func = "killclient" cmd = NULL } key { mod = {"Alt"} key = "q" func = "killclient" cmd = NULL }
@ -44,8 +49,8 @@ keys
key { mod = {"Alt","Shift"} 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 = "Right" func = "tagswitch" cmd = "+1" }
key { mod = {"Control"} key = "Left" func = "tagswitch" cmd = "-1" } key { mod = {"Control"} key = "Left" func = "tagswitch" cmd = "-1" }
key { mod = {"Control"} key = "l" func = "layoutswitch" cmd = "+" } key { mod = {"Control"} key = "Up" func = "layoutswitch" cmd = "+" }
key { mod = {"Control", "Shift"} key = "l" func = "layoutswitch" cmd = "-" } key { mod = {"Control"} key = "Down" func = "layoutswitch" cmd = "-" }
# moving client keybind # moving client keybind