dwm

dynamic window manager
git clone git://git.suckless.org/dwm
Log | Files | Refs | README | LICENSE

commit d4b7a9a3735deeab639f28b5bb2f568e0dc49616
parent 4d67199a4bb68e5377d2fece62a83fde66c92861
Author: Anselm R.Garbe <arg@10ksloc.org>
Date:   Mon, 14 Aug 2006 10:18:24 +0200

implemented restack behavior (floats are on top in tiled mode)

Diffstat:
Mclient.c | 26++++++++------------------
Mdwm.1 | 4++--
Mdwm.h | 3++-
Mevent.c | 9++++++---
Mtag.c | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Mutil.c | 9+++++++++
6 files changed, 81 insertions(+), 34 deletions(-)

diff --git a/client.c b/client.c @@ -59,8 +59,6 @@ focus(Client *c) drawtitle(old); drawtitle(c); XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); - XSync(dpy, False); - while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); } void @@ -77,8 +75,8 @@ focusnext(Arg *arg) if(!(c = getnext(sel->next))) c = getnext(clients); if(c) { - higher(c); focus(c); + restack(); } } @@ -98,8 +96,8 @@ focusprev(Arg *arg) c = getprev(c); } if(c) { - higher(c); focus(c); + restack(); } } @@ -181,13 +179,6 @@ gravitate(Client *c, Bool invert) } void -higher(Client *c) -{ - XRaiseWindow(dpy, c->win); - XRaiseWindow(dpy, c->title); -} - -void killclient(Arg *arg) { if(!sel) @@ -271,13 +262,12 @@ manage(Window w, XWindowAttributes *wa) || (c->maxw && c->minw && c->maxw == c->minw && c->maxh == c->minh); settitle(c); - arrange(NULL); - /* mapping the window now prevents flicker */ - XMapRaised(dpy, c->win); - XMapRaised(dpy, c->title); + XMapWindow(dpy, c->win); + XMapWindow(dpy, c->title); if(isvisible(c)) focus(c); + arrange(NULL); } void @@ -410,7 +400,7 @@ togglemax(Arg *arg) sel->w = sw - 2; sel->h = sh - 2 - bh; - higher(sel); + restack(); resize(sel, arrange == dofloat, TopLeft); sel->x = ox; @@ -446,9 +436,9 @@ unmanage(Client *c) XSync(dpy, False); XSetErrorHandler(xerror); XUngrabServer(dpy); - arrange(NULL); if(sel) focus(sel); + arrange(NULL); } void @@ -474,6 +464,6 @@ zoom(Arg *arg) clients->prev = sel; sel->next = clients; clients = sel; - arrange(NULL); focus(sel); + arrange(NULL); } diff --git a/dwm.1 b/dwm.1 @@ -36,11 +36,11 @@ prints version information to standard output, then exits. .B Standard input is read and displayed in the status text area. .TP -.B Button[1,3] +.B Button[1,2] click on a tag label focuses that .B tag. .TP -.B Button2 +.B Button3 click on a tag label toggles that .B tag. .SS Keyboard commands diff --git a/dwm.h b/dwm.h @@ -89,7 +89,6 @@ extern void focusprev(Arg *arg); extern Client *getclient(Window w); extern Client *getctitle(Window w); extern void gravitate(Client *c, Bool invert); -extern void higher(Client *c); extern void killclient(Arg *arg); extern void manage(Window w, XWindowAttributes *wa); extern void resize(Client *c, Bool sizehints, Corner sticky); @@ -125,6 +124,7 @@ extern Bool isvisible(Client *c); extern Client *getnext(Client *c); extern Client *getprev(Client *c); extern void replacetag(Arg *arg); +extern void restack(); extern void settags(Client *c); extern void togglemode(Arg *arg); extern void view(Arg *arg); @@ -133,4 +133,5 @@ extern void toggleview(Arg *arg); /* util.c */ extern void *emallocz(unsigned int size); extern void eprint(const char *errstr, ...); +extern void *erealloc(void *ptr, unsigned int size); extern void spawn(Arg *arg); diff --git a/event.c b/event.c @@ -118,21 +118,24 @@ buttonpress(XEvent *e) } } else if((c = getclient(ev->window))) { - higher(c); focus(c); switch(ev->button) { default: break; case Button1: - if(!c->ismax && (arrange == dofloat || c->isfloat)) + if(!c->ismax && (arrange == dofloat || c->isfloat)) { + restack(c); movemouse(c); + } break; case Button2: zoom(NULL); break; case Button3: - if(!c->ismax && (arrange == dofloat || c->isfloat)) + if(!c->ismax && (arrange == dofloat || c->isfloat)) { + restack(c); resizemouse(c); + } break; } } diff --git a/tag.c b/tag.c @@ -58,18 +58,17 @@ dofloat(Arg *arg) ban(c); } if((sel = getnext(clients))) { - higher(sel); focus(sel); + restack(); } else XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - drawall(); } void dotile(Arg *arg) { - int n, i, w, h; + int h, i, n, w; Client *c; w = sw - mw; @@ -86,7 +85,6 @@ dotile(Arg *arg) c->ismax = False; if(isvisible(c)) { if(c->isfloat) { - higher(c); resize(c, True, TopLeft); continue; } @@ -123,13 +121,11 @@ dotile(Arg *arg) else ban(c); } - if((sel = getnext(clients))) { - higher(sel); + if((sel = getnext(clients))) focus(sel); - } else XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - drawall(); + restack(); } Client * @@ -200,6 +196,56 @@ replacetag(Arg *arg) } void +restack() +{ + static unsigned int nwins = 0; + static Window *wins = NULL; + unsigned int f, fi, m, mi, n; + Client *c; + XEvent ev; + + for(f = 0, m = 0, c = clients; c; c = c->next) + if(isvisible(c)) { + if(c->isfloat || arrange == dofloat) + f++; + else + m++; + } + + n = 2 * (f + m); + if(nwins < n) { + nwins = n; + wins = erealloc(wins, nwins * sizeof(Window)); + } + + fi = 0; + mi = 2 * f; + if(sel->isfloat || arrange == dofloat) { + wins[fi++] = sel->title; + wins[fi++] = sel->win; + } + else { + wins[mi++] = sel->title; + wins[mi++] = sel->win; + } + for(c = clients; c; c = c->next) + if(isvisible(c) && c != sel) { + if(c->isfloat || arrange == dofloat) { + wins[fi++] = c->title; + wins[fi++] = c->win; + } + else { + wins[mi++] = c->title; + wins[mi++] = c->win; + } + } + XRestackWindows(dpy, wins, n); + drawall(); + XSync(dpy, False); + while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); +} + +void settags(Client *c) { char classinst[256]; @@ -248,7 +294,6 @@ view(Arg *arg) seltag[i] = False; seltag[arg->i] = True; arrange(NULL); - drawall(); } void @@ -261,5 +306,4 @@ toggleview(Arg *arg) if(i == ntags) seltag[arg->i] = True; /* cannot toggle last view */ arrange(NULL); - drawall(); } diff --git a/util.c b/util.c @@ -40,6 +40,15 @@ eprint(const char *errstr, ...) exit(EXIT_FAILURE); } +void * +erealloc(void *ptr, unsigned int size) +{ + void *res = realloc(ptr, size); + if(!res) + bad_malloc(size); + return res; +} + void spawn(Arg *arg) {