aboutsummaryrefslogtreecommitdiff
path: root/.repos/dwm/dwm.c
diff options
context:
space:
mode:
Diffstat (limited to '.repos/dwm/dwm.c')
-rw-r--r--.repos/dwm/dwm.c532
1 files changed, 155 insertions, 377 deletions
diff --git a/.repos/dwm/dwm.c b/.repos/dwm/dwm.c
index eb92650..8e327ec 100644
--- a/.repos/dwm/dwm.c
+++ b/.repos/dwm/dwm.c
@@ -35,14 +35,11 @@
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xproto.h>
-#include <X11/Xresource.h>
#include <X11/Xutil.h>
#ifdef XINERAMA
#include <X11/extensions/Xinerama.h>
#endif /* XINERAMA */
#include <X11/Xft/Xft.h>
-#include <X11/Xlib-xcb.h>
-#include <xcb/res.h>
#include "drw.h"
#include "util.h"
@@ -50,24 +47,18 @@
/* macros */
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
-#define GETINC(X) ((X) - 2000)
-#define INC(X) ((X) + 2000)
#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
* MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
-#define ISINC(X) ((X) > 1000 && (X) < 3000)
-#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]) || C->issticky)
-#define PREVSEL 3000
+#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
#define LENGTH(X) (sizeof X / sizeof X[0])
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
-#define MOD(N,M) ((N)%(M) < 0 ? (N)%(M) + (M) : (N)%(M))
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
-#define NUMTAGS (LENGTH(tags) + LENGTH(scratchpads))
-#define TAGMASK ((1 << NUMTAGS) - 1)
-#define SPTAG(i) ((1 << LENGTH(tags)) << (i))
-#define SPTAGMASK (((1 << LENGTH(scratchpads))-1) << LENGTH(tags))
+#define NUMTAGS (LENGTH(tags) + LENGTH(scratchpads))
+#define TAGMASK ((1 << NUMTAGS) - 1)
+#define SPTAG(i) ((1 << LENGTH(tags)) << (i))
+#define SPTAGMASK (((1 << LENGTH(scratchpads))-1) << LENGTH(tags))
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
-#define TRUNC(X,A,B) (MAX((A), MIN((X), (B))))
/* enums */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
@@ -104,11 +95,9 @@ struct Client {
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
int bw, oldbw;
unsigned int tags;
- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow, issticky;
- pid_t pid;
+ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
Client *next;
Client *snext;
- Client *swallowing;
Monitor *mon;
Window win;
};
@@ -125,6 +114,7 @@ typedef struct {
void (*arrange)(Monitor *);
} Layout;
+typedef struct Pertag Pertag;
struct Monitor {
char ltsymbol[16];
float mfact;
@@ -133,10 +123,6 @@ struct Monitor {
int by; /* bar geometry */
int mx, my, mw, mh; /* screen size */
int wx, wy, ww, wh; /* window area */
- int gappih; /* horizontal gap between windows */
- int gappiv; /* vertical gap between windows */
- int gappoh; /* horizontal outer gaps */
- int gappov; /* vertical outer gaps */
unsigned int seltags;
unsigned int sellt;
unsigned int tagset[2];
@@ -148,6 +134,7 @@ struct Monitor {
Monitor *next;
Window barwin;
const Layout *lt[2];
+ Pertag *pertag;
};
typedef struct {
@@ -156,8 +143,6 @@ typedef struct {
const char *title;
unsigned int tags;
int isfloating;
- int isterminal;
- int noswallow;
int monitor;
} Rule;
@@ -176,7 +161,6 @@ static void clientmessage(XEvent *e);
static void configure(Client *c);
static void configurenotify(XEvent *e);
static void configurerequest(XEvent *e);
-static void copyvalidchars(char *text, char *rawtext);
static Monitor *createmon(void);
static void destroynotify(XEvent *e);
static void detach(Client *c);
@@ -208,7 +192,6 @@ static void movemouse(const Arg *arg);
static Client *nexttiled(Client *c);
static void pop(Client *);
static void propertynotify(XEvent *e);
-static void pushstack(const Arg *arg);
static void quit(const Arg *arg);
static Monitor *recttomon(int x, int y, int w, int h);
static void resize(Client *c, int x, int y, int w, int h, int interact);
@@ -228,17 +211,13 @@ static void setup(void);
static void seturgent(Client *c, int urg);
static void showhide(Client *c);
static void sigchld(int unused);
-static void sighup(int unused);
-static void sigterm(int unused);
static void spawn(const Arg *arg);
-static int stackpos(const Arg *arg);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
+static void tile(Monitor *);
static void togglebar(const Arg *arg);
static void togglefloating(const Arg *arg);
static void togglescratch(const Arg *arg);
-static void togglesticky(const Arg *arg);
-static void togglefullscr(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unfocus(Client *c, int setfocus);
@@ -262,17 +241,9 @@ static int xerrordummy(Display *dpy, XErrorEvent *ee);
static int xerrorstart(Display *dpy, XErrorEvent *ee);
static void zoom(const Arg *arg);
-static pid_t getparentprocess(pid_t p);
-static int isdescprocess(pid_t p, pid_t c);
-static Client *swallowingclient(Window w);
-static Client *termforwin(const Client *c);
-static pid_t winpid(Window w);
-
-
/* variables */
static const char broken[] = "broken";
static char stext[256];
-static char rawstext[256];
static int screen;
static int sw, sh; /* X display screen geometry width, height */
static int bh, blw = 0; /* bar geometry */
@@ -296,7 +267,6 @@ static void (*handler[LASTEvent]) (XEvent *) = {
[UnmapNotify] = unmapnotify
};
static Atom wmatom[WMLast], netatom[NetLast];
-static int restart = 0;
static int running = 1;
static Cur *cursor[CurLast];
static Clr **scheme;
@@ -305,11 +275,18 @@ static Drw *drw;
static Monitor *mons, *selmon;
static Window root, wmcheckwin;
-static xcb_connection_t *xcon;
-
/* configuration, allows nested code to access above variables */
#include "config.h"
+struct Pertag {
+ unsigned int curtag, prevtag; /* current and previous tag */
+ int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
+ float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
+ unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */
+ const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */
+ int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */
+};
+
/* compile-time check if all tags fit into an unsigned int bit array. */
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
@@ -336,9 +313,7 @@ applyrules(Client *c)
&& (!r->class || strstr(class, r->class))
&& (!r->instance || strstr(instance, r->instance)))
{
- c->isterminal = r->isterminal;
c->isfloating = r->isfloating;
- c->noswallow = r->noswallow;
c->tags |= r->tags;
if ((r->tags & SPTAGMASK) && r->isfloating) {
c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
@@ -460,55 +435,9 @@ attachstack(Client *c)
}
void
-swallow(Client *p, Client *c)
-{
- if (c->noswallow || c->isterminal)
- return;
- if (!swallowfloating && c->isfloating)
- return;
-
- detach(c);
- detachstack(c);
-
- setclientstate(c, WithdrawnState);
- XUnmapWindow(dpy, p->win);
-
- p->swallowing = c;
- c->mon = p->mon;
-
- Window w = p->win;
- p->win = c->win;
- c->win = w;
- updatetitle(p);
- XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h);
- arrange(p->mon);
- configure(p);
- updateclientlist();
-}
-
-void
-unswallow(Client *c)
-{
- c->win = c->swallowing->win;
-
- free(c->swallowing);
- c->swallowing = NULL;
-
- /* unfullscreen the client */
- setfullscreen(c, 0);
- updatetitle(c);
- arrange(c->mon);
- XMapWindow(dpy, c->win);
- XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
- setclientstate(c, NormalState);
- focus(NULL);
- arrange(c->mon);
-}
-
-void
buttonpress(XEvent *e)
{
- unsigned int i, x, click, occ = 0;
+ unsigned int i, x, click;
Arg arg = {0};
Client *c;
Monitor *m;
@@ -523,37 +452,17 @@ buttonpress(XEvent *e)
}
if (ev->window == selmon->barwin) {
i = x = 0;
- for (c = m->clients; c; c = c->next)
- occ |= c->tags == 255 ? 0 : c->tags;
- do {
- /* do not reserve space for vacant tags */
- if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
- continue;
+ do
x += TEXTW(tags[i]);
- } while (ev->x >= x && ++i < LENGTH(tags));
+ while (ev->x >= x && ++i < LENGTH(tags));
if (i < LENGTH(tags)) {
click = ClkTagBar;
arg.ui = 1 << i;
} else if (ev->x < x + blw)
click = ClkLtSymbol;
- else if (ev->x > (x = selmon->ww - TEXTW(stext) + lrpad)) {
+ else if (ev->x > selmon->ww - (int)TEXTW(stext))
click = ClkStatusText;
-
- char *text = rawstext;
- int i = -1;
- char ch;
- while (text[++i]) {
- if ((unsigned char)text[i] < ' ') {
- ch = text[i];
- text[i] = '\0';
- x += TEXTW(text) - lrpad;
- text[i] = ch;
- text += i+1;
- i = -1;
- if (x >= ev->x) break;
- }
- }
- } else
+ else
click = ClkWinTitle;
} else if ((c = wintoclient(ev->window))) {
focus(c);
@@ -739,23 +648,11 @@ configurerequest(XEvent *e)
XSync(dpy, False);
}
-void
-copyvalidchars(char *text, char *rawtext)
-{
- int i = -1, j = 0;
-
- while(rawtext[++i]) {
- if ((unsigned char)rawtext[i] >= ' ') {
- text[j++] = rawtext[i];
- }
- }
- text[j] = '\0';
-}
-
Monitor *
createmon(void)
{
Monitor *m;
+ unsigned int i;
m = ecalloc(1, sizeof(Monitor));
m->tagset[0] = m->tagset[1] = 1;
@@ -763,13 +660,23 @@ createmon(void)
m->nmaster = nmaster;
m->showbar = showbar;
m->topbar = topbar;
- m->gappih = gappih;
- m->gappiv = gappiv;
- m->gappoh = gappoh;
- m->gappov = gappov;
m->lt[0] = &layouts[0];
m->lt[1] = &layouts[1 % LENGTH(layouts)];
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+ m->pertag = ecalloc(1, sizeof(Pertag));
+ m->pertag->curtag = m->pertag->prevtag = 1;
+
+ for (i = 0; i <= LENGTH(tags); i++) {
+ m->pertag->nmasters[i] = m->nmaster;
+ m->pertag->mfacts[i] = m->mfact;
+
+ m->pertag->ltidxs[i][0] = m->lt[0];
+ m->pertag->ltidxs[i][1] = m->lt[1];
+ m->pertag->sellts[i] = m->sellt;
+
+ m->pertag->showbars[i] = m->showbar;
+ }
+
return m;
}
@@ -781,9 +688,6 @@ destroynotify(XEvent *e)
if ((c = wintoclient(ev->window)))
unmanage(c, 1);
-
- else if ((c = swallowingclient(ev->window)))
- unmanage(c->swallowing, 1);
}
void
@@ -841,19 +745,19 @@ drawbar(Monitor *m)
}
for (c = m->clients; c; c = c->next) {
- occ |= c->tags == 255 ? 0 : c->tags;
+ occ |= c->tags;
if (c->isurgent)
urg |= c->tags;
}
x = 0;
for (i = 0; i < LENGTH(tags); i++) {
- /* do not draw vacant tags */
- if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
- continue;
-
w = TEXTW(tags[i]);
drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
+ if (occ & 1 << i)
+ drw_rect(drw, x + boxs, boxs, boxw, boxw,
+ m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
+ urg & 1 << i);
x += w;
}
w = blw = TEXTW(m->ltsymbol);
@@ -964,16 +868,27 @@ focusmon(const Arg *arg)
void
focusstack(const Arg *arg)
{
- int i = stackpos(arg);
- Client *c, *p;
+ Client *c = NULL, *i;
- if (i < 0 || !selmon->sel || selmon->sel->isfullscreen)
+ if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen))
return;
-
- for(p = NULL, c = selmon->clients; c && (i || !ISVISIBLE(c));
- i -= ISVISIBLE(c) ? 1 : 0, p = c, c = c->next);
- focus(c ? c : p);
- restack(selmon);
+ if (arg->i > 0) {
+ for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
+ if (!c)
+ for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next);
+ } else {
+ for (i = selmon->clients; i != selmon->sel; i = i->next)
+ if (ISVISIBLE(i))
+ c = i;
+ if (!c)
+ for (; i; i = i->next)
+ if (ISVISIBLE(i))
+ c = i;
+ }
+ if (c) {
+ focus(c);
+ restack(selmon);
+ }
}
Atom
@@ -1087,7 +1002,7 @@ grabkeys(void)
void
incnmaster(const Arg *arg)
{
- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0);
arrange(selmon);
}
@@ -1138,13 +1053,12 @@ killclient(const Arg *arg)
void
manage(Window w, XWindowAttributes *wa)
{
- Client *c, *t = NULL, *term = NULL;
+ Client *c, *t = NULL;
Window trans = None;
XWindowChanges wc;
c = ecalloc(1, sizeof(Client));
c->win = w;
- c->pid = winpid(w);
/* geometry */
c->x = c->oldx = wa->x;
c->y = c->oldy = wa->y;
@@ -1159,7 +1073,6 @@ manage(Window w, XWindowAttributes *wa)
} else {
c->mon = selmon;
applyrules(c);
- term = termforwin(c);
}
if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw)
@@ -1196,8 +1109,6 @@ manage(Window w, XWindowAttributes *wa)
c->mon->sel = c;
arrange(c->mon);
XMapWindow(dpy, c->win);
- if (term)
- swallow(term, c);
focus(NULL);
}
@@ -1228,16 +1139,16 @@ maprequest(XEvent *e)
void
monocle(Monitor *m)
{
- unsigned int n;
- int oh, ov, ih, iv;
+ unsigned int n = 0;
Client *c;
- getgaps(m, &oh, &ov, &ih, &iv, &n);
-
+ for (c = m->clients; c; c = c->next)
+ if (ISVISIBLE(c))
+ n++;
if (n > 0) /* override layout symbol */
snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
- resize(c, m->wx + ov, m->wy + oh, m->ww - 2 * c->bw - 2 * ov, m->wh - 2 * c->bw - 2 * oh, 0);
+ resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
}
void
@@ -1334,40 +1245,17 @@ pop(Client *c)
}
void
-pushstack(const Arg *arg) {
- int i = stackpos(arg);
- Client *sel = selmon->sel, *c, *p;
-
- if(i < 0 || !sel)
- return;
- else if(i == 0) {
- detach(sel);
- attach(sel);
- }
- else {
- for(p = NULL, c = selmon->clients; c; p = c, c = c->next)
- if(!(i -= (ISVISIBLE(c) && c != sel)))
- break;
- c = c ? c : p;
- detach(sel);
- sel->next = c->next;
- c->next = sel;
- }
- arrange(selmon);
-}
-
-void
propertynotify(XEvent *e)
{
Client *c;
Window trans;
XPropertyEvent *ev = &e->xproperty;
- if ((ev->window == root) && (ev->atom == XA_WM_NAME)) {
+ if ((ev->window == root) && (ev->atom == XA_WM_NAME))
updatestatus();
- } else if (ev->state == PropertyDelete) {
+ else if (ev->state == PropertyDelete)
return; /* ignore */
- } else if ((c = wintoclient(ev->window))) {
+ else if ((c = wintoclient(ev->window))) {
switch(ev->atom) {
default: break;
case XA_WM_TRANSIENT_FOR:
@@ -1396,7 +1284,6 @@ propertynotify(XEvent *e)
void
quit(const Arg *arg)
{
- if(arg->i) restart = 1;
running = 0;
}
@@ -1646,43 +1533,13 @@ setfullscreen(Client *c, int fullscreen)
}
}
-int
-stackpos(const Arg *arg) {
- int n, i;
- Client *c, *l;
-
- if(!selmon->clients)
- return -1;
-
- if(arg->i == PREVSEL) {
- for(l = selmon->stack; l && (!ISVISIBLE(l) || l == selmon->sel); l = l->snext);
- if(!l)
- return -1;
- for(i = 0, c = selmon->clients; c != l; i += ISVISIBLE(c) ? 1 : 0, c = c->next);
- return i;
- }
- else if(ISINC(arg->i)) {
- if(!selmon->sel)
- return -1;
- for(i = 0, c = selmon->clients; c != selmon->sel; i += ISVISIBLE(c) ? 1 : 0, c = c->next);
- for(n = i; c; n += ISVISIBLE(c) ? 1 : 0, c = c->next);
- return MOD(i + GETINC(arg->i), n);
- }
- else if(arg->i < 0) {
- for(i = 0, c = selmon->clients; c; i += ISVISIBLE(c) ? 1 : 0, c = c->next);
- return MAX(i + arg->i, 0);
- }
- else
- return arg->i;
-}
-
void
setlayout(const Arg *arg)
{
if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
- selmon->sellt ^= 1;
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1;
if (arg && arg->v)
- selmon->lt[selmon->sellt] = (Layout *)arg->v;
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v;
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
if (selmon->sel)
arrange(selmon);
@@ -1701,7 +1558,7 @@ setmfact(const Arg *arg)
f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
if (f < 0.05 || f > 0.95)
return;
- selmon->mfact = f;
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f;
arrange(selmon);
}
@@ -1715,9 +1572,6 @@ setup(void)
/* clean up any zombies immediately */
sigchld(0);
- signal(SIGHUP, sighup);
- signal(SIGTERM, sigterm);
-
/* init screen */
screen = DefaultScreen(dpy);
sw = DisplayWidth(dpy, screen);
@@ -1798,10 +1652,6 @@ showhide(Client *c)
if (!c)
return;
if (ISVISIBLE(c)) {
- /* if ((c->tags & SPTAGMASK) && c->isfloating) { */
- /* c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2); */
- /* c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2); */
- /* } */
/* show clients top down */
XMoveWindow(dpy, c->win, c->x, c->y);
if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen)
@@ -1823,20 +1673,6 @@ sigchld(int unused)
}
void
-sighup(int unused)
-{
- Arg a = {.i = 1};
- quit(&a);
-}
-
-void
-sigterm(int unused)
-{
- Arg a = {.i = 0};
- quit(&a);
-}
-
-void
spawn(const Arg *arg)
{
if (arg->v == dmenucmd)
@@ -1871,9 +1707,37 @@ tagmon(const Arg *arg)
}
void
+tile(Monitor *m)
+{
+ unsigned int i, n, h, mw, my, ty;
+ Client *c;
+
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+ if (n == 0)
+ return;
+
+ if (n > m->nmaster)
+ mw = m->nmaster ? m->ww * m->mfact : 0;
+ else
+ mw = m->ww;
+ for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
+ if (i < m->nmaster) {
+ h = (m->wh - my) / (MIN(n, m->nmaster) - i);
+ resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
+ if (my + HEIGHT(c) < m->wh)
+ my += HEIGHT(c);
+ } else {
+ h = (m->wh - ty) / (n - i);
+ resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
+ if (ty + HEIGHT(c) < m->wh)
+ ty += HEIGHT(c);
+ }
+}
+
+void
togglebar(const Arg *arg)
{
- selmon->showbar = !selmon->showbar;
+ selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar;
updatebarpos(selmon);
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
arrange(selmon);
@@ -1894,22 +1758,6 @@ togglefloating(const Arg *arg)
}
void
-togglefullscr(const Arg *arg)
-{
- if(selmon->sel)
- setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
-}
-
-void
-togglesticky(const Arg *arg)
-{
- if (!selmon->sel)
- return;
- selmon->sel->issticky = !selmon->sel->issticky;
- arrange(selmon);
-}
-
-void
togglescratch(const Arg *arg)
{
Client *c;
@@ -1954,9 +1802,33 @@ void
toggleview(const Arg *arg)
{
unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
+ int i;
if (newtagset) {
selmon->tagset[selmon->seltags] = newtagset;
+
+ if (newtagset == ~0) {
+ selmon->pertag->prevtag = selmon->pertag->curtag;
+ selmon->pertag->curtag = 0;
+ }
+
+ /* test if the user did not select the same tag */
+ if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) {
+ selmon->pertag->prevtag = selmon->pertag->curtag;
+ for (i = 0; !(newtagset & 1 << i); i++) ;
+ selmon->pertag->curtag = i + 1;
+ }
+
+ /* apply settings for this view */
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
+
+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
+ togglebar(NULL);
+
focus(NULL);
arrange(selmon);
}
@@ -1981,20 +1853,6 @@ unmanage(Client *c, int destroyed)
Monitor *m = c->mon;
XWindowChanges wc;
- if (c->swallowing) {
- unswallow(c);
- return;
- }
-
- Client *s = swallowingclient(c->win);
- if (s) {
- free(s->swallowing);
- s->swallowing = NULL;
- arrange(m);
- focus(NULL);
- return;
- }
-
detach(c);
detachstack(c);
if (!destroyed) {
@@ -2009,12 +1867,9 @@ unmanage(Client *c, int destroyed)
XUngrabServer(dpy);
}
free(c);
-
- if (!s) {
- arrange(m);
- focus(NULL);
- updateclientlist();
- }
+ focus(NULL);
+ updateclientlist();
+ arrange(m);
}
void
@@ -2220,10 +2075,8 @@ updatesizehints(Client *c)
void
updatestatus(void)
{
- if (!gettextprop(root, XA_WM_NAME, rawstext, sizeof(rawstext)))
+ if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
strcpy(stext, "dwm-"VERSION);
- else
- copyvalidchars(stext, rawstext);
drawbar(selmon);
}
@@ -2270,110 +2123,39 @@ updatewmhints(Client *c)
void
view(const Arg *arg)
{
+ int i;
+ unsigned int tmptag;
+
if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
return;
selmon->seltags ^= 1; /* toggle sel tagset */
- if (arg->ui & TAGMASK)
+ if (arg->ui & TAGMASK) {
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
- focus(NULL);
- arrange(selmon);
-}
-
-pid_t
-winpid(Window w)
-{
- pid_t result = 0;
-
- xcb_res_client_id_spec_t spec = {0};
- spec.client = w;
- spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID;
+ selmon->pertag->prevtag = selmon->pertag->curtag;
- xcb_generic_error_t *e = NULL;
- xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec);
- xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e);
-
- if (!r)
- return (pid_t)0;
-
- xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r);
- for (; i.rem; xcb_res_client_id_value_next(&i)) {
- spec = i.data->spec;
- if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) {
- uint32_t *t = xcb_res_client_id_value_value(i.data);
- result = *t;
- break;
- }
- }
-
- free(r);
-
- if (result == (pid_t)-1)
- result = 0;
- return result;
-}
-
-pid_t
-getparentprocess(pid_t p)
-{
- unsigned int v = 0;
-
-#ifdef __linux__
- FILE *f;
- char buf[256];
- snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p);
-
- if (!(f = fopen(buf, "r")))
- return 0;
-
- fscanf(f, "%*u %*s %*c %u", &v);
- fclose(f);
-#endif /* __linux__ */
-
- return (pid_t)v;
-}
-
-int
-isdescprocess(pid_t p, pid_t c)
-{
- while (p != c && c != 0)
- c = getparentprocess(c);
-
- return (int)c;
-}
-
-Client *
-termforwin(const Client *w)
-{
- Client *c;
- Monitor *m;
-
- if (!w->pid || w->isterminal)
- return NULL;
-
- for (m = mons; m; m = m->next) {
- for (c = m->clients; c; c = c->next) {
- if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid))
- return c;
+ if (arg->ui == ~0)
+ selmon->pertag->curtag = 0;
+ else {
+ for (i = 0; !(arg->ui & 1 << i); i++) ;
+ selmon->pertag->curtag = i + 1;
}
+ } else {
+ tmptag = selmon->pertag->prevtag;
+ selmon->pertag->prevtag = selmon->pertag->curtag;
+ selmon->pertag->curtag = tmptag;
}
- return NULL;
-}
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
-Client *
-swallowingclient(Window w)
-{
- Client *c;
- Monitor *m;
+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
+ togglebar(NULL);
- for (m = mons; m; m = m->next) {
- for (c = m->clients; c; c = c->next) {
- if (c->swallowing && c->swallowing->win == w)
- return c;
- }
- }
-
- return NULL;
+ focus(NULL);
+ arrange(selmon);
}
Client *
@@ -2467,10 +2249,7 @@ main(int argc, char *argv[])
fputs("warning: no locale support\n", stderr);
if (!(dpy = XOpenDisplay(NULL)))
die("dwm: cannot open display");
- if (!(xcon = XGetXCBConnection(dpy)))
- die("dwm: cannot get xcb connection\n");
checkotherwm();
- XrmInitialize();
setup();
#ifdef __OpenBSD__
if (pledge("stdio rpath proc exec", NULL) == -1)
@@ -2478,7 +2257,6 @@ main(int argc, char *argv[])
#endif /* __OpenBSD__ */
scan();
run();
- if(restart) execvp(argv[0], argv);
cleanup();
XCloseDisplay(dpy);
return EXIT_SUCCESS;