diff --git a/config.c b/config.c index f9a5a96..06351a6 100644 --- a/config.c +++ b/config.c @@ -2,20 +2,11 @@ #include #include +#include "local.h" #include "config.h" #define FILE_NAME ".wmfsrc" -typedef struct { - char *name; - KeySym keysym; -} key_name_list_t; - -typedef struct { - char *name; - unsigned int button; -} mouse_button_list_t; - func_name_list_t func_list[] = { {"spawn", spawn}, {"killclient", killclient}, @@ -28,7 +19,8 @@ func_name_list_t func_list[] = { {"layoutswitch",layoutswitch}, {"tag", tag}, {"tagtransfert", tagtransfert}, - {"set_mwfact", set_mwfact} + {"set_mwfact", set_mwfact}, + {"tile_switch", tile_switch} }; key_name_list_t key_list[] = { @@ -44,7 +36,7 @@ key_name_list_t key_list[] = { {NULL, NoSymbol} }; -mouse_button_list_t mouse_button_list[] = { +name_to_uint_t mouse_button_list[] = { {"Button1", Button1}, {"Button2", Button2}, {"Button3", Button3}, @@ -52,6 +44,12 @@ mouse_button_list_t mouse_button_list[] = { {"Button5", Button5} }; +name_to_uint_t layout_list[] = { + {"tile", Tile}, + {"max", Max}, + {"free", Free} +}; + void* name_to_func(char *name) { int i; @@ -83,6 +81,16 @@ char_to_button(char *name) { return 0; } +unsigned int +layout_name_to_layout(char *name) { + int i; + if(name) + for(i=0; layout_list[i].name; ++i) + if(!strcmp(name, layout_list[i].name)) + return layout_list[i].button; + return 0; +} + void init_conf(void) { @@ -116,8 +124,15 @@ init_conf(void) { }; static cfg_opt_t tag_opts[] = { + CFG_STR("name", "", CFGF_NONE), + CFG_FLOAT("mwfact", 0.65, CFGF_NONE), + CFG_STR("layout", "tile", CFGF_NONE), + CFG_END() + }; - CFG_STR_LIST("tag", "{Tag}", CFGF_NONE), + static cfg_opt_t tags_opts[] = { + + CFG_SEC("tag", tag_opts, CFGF_MULTI), CFG_END() }; @@ -166,7 +181,7 @@ init_conf(void) { CFG_SEC("misc", misc_opts, CFGF_NONE), CFG_SEC("colors", colors_opts, CFGF_NONE), CFG_SEC("layout", layout_opts, CFGF_NONE), - CFG_SEC("tag", tag_opts, CFGF_NONE), + CFG_SEC("tags", tags_opts, CFGF_NONE), CFG_SEC("keys", keys_opts, CFGF_NONE), CFG_SEC("buttons", buttons_opts, CFGF_NONE), CFG_END() @@ -176,7 +191,7 @@ init_conf(void) { cfg_t *cfg_misc; cfg_t *cfg_colors; cfg_t *cfg_layout; - cfg_t *cfg_tag; + cfg_t *cfg_tags; cfg_t *cfg_keys; cfg_t *cfg_buttons; cfg_t *cfgtmp, *cfgtmp2, *cfgtmp3; @@ -201,7 +216,7 @@ init_conf(void) { cfg_misc = cfg_getsec(cfg, "misc"); cfg_colors = cfg_getsec(cfg, "colors"); cfg_layout = cfg_getsec(cfg, "layout"); - cfg_tag = cfg_getsec(cfg, "tag"); + cfg_tags = cfg_getsec(cfg, "tags"); cfg_keys = cfg_getsec(cfg, "keys"); cfg_buttons = cfg_getsec(cfg, "buttons"); @@ -226,9 +241,13 @@ init_conf(void) { conf.layouts.max = strdup(cfg_getstr(cfg_layout, "max")); /* tag */ - conf.ntag = cfg_size(cfg_tag, "tag"); - for(i=0; i < cfg_size(cfg_tag, "tag"); ++i) - conf.taglist[i] = strdup(cfg_getnstr(cfg_tag, "tag",i)); + conf.ntag = cfg_size(cfg_tags, "tag"); + for(i=0; i < cfg_size(cfg_tags, "tag"); ++i) { + cfgtmp = cfg_getnsec(cfg_tags, "tag", i); + conf.tag[i].name = strdup(cfg_getstr(cfgtmp, "name")); + conf.tag[i].mwfact = cfg_getfloat(cfgtmp, "mwfact"); + conf.tag[i].layout = layout_name_to_layout(cfg_getstr(cfgtmp, "layout")); + } /* keybind ('tention ça rigole plus) */ conf.nkeybind = cfg_size(cfg_keys, "key"); @@ -251,7 +270,8 @@ init_conf(void) { conf.nbutton = cfg_size(cfg_buttons, "button"); for(i = 0; i < conf.nbutton; ++i) { cfgtmp2 = cfg_getnsec(cfg_buttons, "button", i); - conf.buttonfont = strdup(cfg_getstr(cfg_buttons, "buttons_font")); + if(cfg_getstr(cfg_buttons, "buttons_font")) + conf.buttonfont = strdup(cfg_getstr(cfg_buttons, "buttons_font")); for(j = 0; j < cfg_size(cfgtmp2, "mouse"); ++j) { cfgtmp3 = cfg_getnsec(cfgtmp2, "mouse", j); conf.barbutton[i].func[j] = name_to_func(cfg_getstr(cfgtmp3, "func")); diff --git a/config.h.in b/config.h.in index 184083c..4847b8a 100644 --- a/config.h.in +++ b/config.h.in @@ -9,6 +9,21 @@ #define WMFS_COMPILE_FLAGS "@WMFS_COMPILE_FLAGS@" #define WMFS_LINKED_LIBS "@WMFS_LINKED_LIBS@" +typedef struct { + char *name; + void *func; +} func_name_list_t; + +typedef struct { + char *name; + KeySym keysym; +} key_name_list_t; + +typedef struct { + char *name; + unsigned int button; +} name_to_uint_t; + void init_conf(void); #endif /* CONFIG_H */ diff --git a/local.h b/local.h index 3d5a637..a96d911 100644 --- a/local.h +++ b/local.h @@ -62,11 +62,6 @@ typedef struct { char *cmd; } Key; -typedef struct { - char *name; - void *func; -} func_name_list_t; - typedef struct { char *text; Window win; @@ -79,6 +74,12 @@ typedef struct { unsigned int mouse[NBUTTON]; } BarButton; +typedef struct { + char *name; + float mwfact; + int layout; +} Tag; + typedef struct { /* bool and size */ char *font; @@ -99,13 +100,10 @@ typedef struct { char *tile; char *max; } layouts; - /* tag */ - int ntag; - char *taglist[MAXTAG]; - /* keybind */ - int nkeybind; - /* button */ + Tag tag[MAXTAG]; BarButton barbutton[64]; + int ntag; + int nkeybind; int nbutton; char *buttonfont; } Conf; @@ -159,6 +157,7 @@ void tag(char *cmd); void tagswitch(char *cmd); void tagtransfert(char *cmd); void tile(void); +void tile_switch(char *cmd); void togglemax(char *cmd); void unhide(Client *c); void unmanage(Client *c); @@ -192,6 +191,7 @@ int mw, mh; int fonth; int fonty; int barheight; +Client *master[MAXTAG]; /* Master client by tag */ Client *clients; /* First Client */ Client *sel; /* selected client */ int seltag; /* selected tag */ diff --git a/wmfs.c b/wmfs.c index 4944375..4c96767 100644 --- a/wmfs.c +++ b/wmfs.c @@ -53,7 +53,7 @@ buttonpress(XEvent *event) { if(ev->button == Button1) mouseaction(c, ev->x_root, ev->y_root, Move); /* type 0 for move */ else if(ev->button == Button2) - togglemax(NULL); + tile_switch(NULL); else if(ev->button == Button3) mouseaction(c, ev->x_root, ev->y_root, Resize); /* type 1 for resize */ } @@ -154,7 +154,9 @@ configurerequest(XEvent event) { if((c = getclient(event.xconfigurerequest.window))) { if(wc.y < mw && wc.x < mh) { c->free = True; - c->tile = c->max = False; + c->hint = True; + c->max = False; + XMoveWindow(dpy, c->tbar, wc.x, wc.y - conf.ttbarheight); XResizeWindow(dpy, c->tbar, wc.width, conf.ttbarheight); XMoveWindow(dpy, c->button, wc.x + wc.width - 10, BUTY(wc.y)); updatetitle(c); @@ -162,7 +164,6 @@ configurerequest(XEvent event) { c->x = wc.x; c->w = wc.width; c->h = wc.height; - updatelayout(); } } } @@ -355,7 +356,6 @@ 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') { @@ -450,9 +450,9 @@ init(void) { mh = DisplayHeight (dpy, screen); seltag = 1; init_conf(); - for(i=0;ix, c->y, c->w, c->h, 1); XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); mapclient(c); updatetitle(c); @@ -986,13 +987,16 @@ tagswitch(char *cmd) { void tagtransfert(char *cmd) { int n = atoi(cmd); + if(!sel) return; sel->tag = n; if(n != seltag) hide(sel); + if(n == seltag) unhide(sel); + updatelayout(); updateall(); } @@ -1003,51 +1007,78 @@ tile(void) { layout[seltag] = Tile; Client *c; int i; - unsigned int x, y, w, h, n, nh, mwf, bord; - unsigned int barto; + unsigned int y, h, wm, n; + unsigned int barto, mwf, bord; - barto = conf.ttbarheight + barheight; /* title bar heigt + bar height */ - bord = conf.borderheight * 2; /* border * 2 */ - mwf = mw*mwfact[seltag]; /* mwfact */ - n = clientpertag(seltag); - nh = clienthintpertag(seltag); - - x = mwf + conf.borderheight; + barto = conf.ttbarheight + barheight; + bord = conf.borderheight * 2; + mwf = mw*mwfact[seltag]; + n = clientpertag(seltag) - clienthintpertag(seltag); y = barto; - w = (mw - mwf - bord); + wm = (mh-bord) - conf.ttbarheight - barheight; - if((n-nh)-1) - h = ((mh - barheight) / ((n-nh) - 1)) - (conf.ttbarheight + bord); + if(n-1) + h = (mh - barheight) / (n - 1) - (conf.ttbarheight + bord); - /* tiling */ - for(i=0, c = clients; c; c = c->next, ++i) { + for(i = 0, c = clients; c; c = c->next, ++i) { if(!ishide(c)) { c->max = c->free = False; c->tile = True; c->ox = c->x; c->oy = c->y; c->ow = c->w; c->oh = c->h; - if((n-nh) == 1) - moveresize(c, 0, barto, (mw-bord), - ((mh-bord) - conf.ttbarheight - barheight), 0); - else if(i == 0) - moveresize(c, 0, barto, mwf - conf.borderheight, - ((mh-bord) - conf.ttbarheight - barheight), 0); - else { - moveresize(c, x, y, w, h, 0); - if(i < i + 1) - y = c->y + c->h + bord + conf.ttbarheight; + /* 1 clients, maximize it */ + if(n == 1) + moveresize(c, 0, barto, mw-bord, wm, 0); + /* 2 and more... , master client */ + else if(i == 0) { + moveresize(c, 0, barto, mwf-conf.borderheight, wm, 0); + master[seltag] = c; + } + /* other clients */ + else { + moveresize(c, (mwf+conf.borderheight), y, (mw-mwf-bord), h, 0); + if(i < i + 1) + y += h + bord + conf.ttbarheight; + } + /* when a client is out of screen */ + if(c->y > mh) { + moveresize(c, 0, barto, mwf - conf.borderheight, wm, 0); + master[seltag] = c; } - if(c->y > mh) - moveresize(c, 0, barto, mwf - conf.borderheight, - ((mh-bord) - conf.ttbarheight - barheight), 0); - updatetitle(c); } } - return; } +void +tile_switch(char *cmd) { + if(layout[seltag] != Tile) + return; + Client *tmp; + int sx, sy, sw, sh; + + if(sel == master[seltag] + || !master[seltag]) + return; + + sx = sel->x; + sy = sel->y; + sw = sel->w; + sh = sel->h; + + moveresize(sel, + master[seltag]->x, + master[seltag]->y, + master[seltag]->w, + master[seltag]->h, 0); + + moveresize(master[seltag], sx, sy, sw, sh, 0); + tmp = master[seltag]; + master[seltag] = sel; + focus(tmp); +} + void togglemax(char *cmd) { if(!sel && ishide(sel)) @@ -1116,10 +1147,9 @@ unmanage(Client *c) { void updateall(void) { Client *c; - for(c = clients; c; c = c->next) { + for(c = clients; c; c = c->next) if(!ishide(c)) - updatetitle(c); - } + updatetitle(c); } void @@ -1137,8 +1167,8 @@ updatebar(void) { for(i=0; i ", conf.taglist[i], (clientpertag(i+1)) ? p : ""); - taglen[i+1] = taglen[i] + fonty * ( strlen(conf.taglist[i]) + strlen(buf[i]) - strlen(conf.taglist[i]) ) + fonty-4; + sprintf(buf[i], "%s<%s> ", conf.tag[i].name, (clientpertag(i+1)) ? p : ""); + taglen[i+1] = taglen[i] + fonty * ( strlen(conf.tag[i].name) + strlen(buf[i]) - strlen(conf.tag[i].name) ) + fonty-4; /* Rectangle for the tag background */ XSetForeground(dpy, gc, (i+1 == seltag) ? conf.colors.tagselbg : conf.colors.bar); XFillRectangle(dpy, bar, gc, taglen[i] - 4, 0, (strlen(buf[i])*fonty), barheight); diff --git a/wmfsrc b/wmfsrc index b194551..8476862 100644 --- a/wmfsrc +++ b/wmfsrc @@ -26,9 +26,17 @@ layout max = "[Max]" } -tag +tags { - tag = { "1", "2", "3", "4", "5", "6", "7", "8", "9" } + tag { name = "one" mwfact = 0.65 layout = "tile"} + tag { name = "two" } + tag { name = "three" } + tag { name = "four" } + tag { name = "five" } + tag { name = "six" } + tag { name = "seven" } + tag { name = "eight" } + tag { name = "nine" } } buttons @@ -59,6 +67,7 @@ keys key { mod = {"Control"} key = "Down" func = "layoutswitch" cmd = "-" } key { mod = {"Alt", "Shift"} key = "l" func = "set_mwfact" cmd = "+0.025" } key { mod = {"Alt", "Shift"} key = "h" func = "set_mwfact" cmd = "-0.025" } + key { mod = {"Alt"} key = "d" func = "tile_switch" } # moving client keybind