Compare commits

...

27 Commits
5.6.1 ... 5.7.2

Author SHA1 Message Date
210378f198 applied Ryan Zheng's patch and re-releasing 5.7.2 2009-09-27 20:20:10 +01:00
7879616a75 Added tag 5.7.1 for changeset 48c3f87c335d 2009-09-27 10:31:20 +01:00
9e8dd3479d fixed the layout symbol bug reported by Nibble (but using a different approach as he suggested)
- optimised drawbar() and arrange() handling for multiple monitors, arrange only arranges the relevant monitors when applicable, same with drawbar
- need to release 5.7.1
2009-09-27 10:31:14 +01:00
0b72be924d Added tag 5.7 for changeset 257403d4cd96 2009-09-26 19:52:04 +01:00
91e902f7fe switching to release flags 2009-09-22 20:34:03 +01:00
30fed9a211 implemented nn < n case, k-zed please recheck 2009-09-22 20:33:42 +01:00
c45d46ad9a use buffer instead of pointer for mon->ltsymbol 2009-09-22 09:53:11 +01:00
6f55de8310 added missing scan 2009-09-22 09:16:48 +01:00
07ad298133 implemented different version of updategeom 2009-09-21 19:51:17 +01:00
f0a4845e7d added TODO to updategeom in order to implement a decent version of it soon 2009-09-19 11:52:16 +01:00
82ec7a7ed4 new experimental updategeom() additions that should avoid several problems with Xinerama, this is EXPERIMENTAL and might break something, the algorithms in use are quite complex and cumbersome, patches and comments welcome 2009-09-18 21:18:00 +01:00
e7300e0f6f implemented dynamic layout symbol stuff 2009-09-16 15:59:54 +01:00
c3feffa1e2 applied Tony Lainson's config.def.h patch 2009-09-15 13:50:41 +01:00
956a430054 update 2009-09-08 13:33:58 +01:00
01056b6636 hard-core destruction 2009-09-08 13:30:18 +01:00
eb260b1a41 renaming isdestroyed into destroyed 2009-09-08 13:18:05 +01:00
7fe81359d4 sync when a client is being killed 2009-09-08 13:16:54 +01:00
a3a859b4e9 added isdestroyed flag to unmanage 2009-09-08 13:13:03 +01:00
9c066c24b3 always updategeom when root is configured 2009-09-07 11:46:02 +02:00
0a668922a4 another small optimisation 2009-08-18 15:59:38 +01:00
5762964232 also update title if the client is on an unfocused monitor 2009-08-18 15:42:55 +01:00
cba6b211c2 applied nsz's dwm.1 patch, also added wmname 2009-08-16 21:39:24 +01:00
42750a621b applied Jukka's cosmetic patch 2009-08-16 08:18:54 +01:00
8ef465d592 applied Jukka's sigchld patch 2009-08-16 08:18:25 +01:00
33fe200b52 added merged patch of anydot and Neale 2009-08-13 10:45:59 +01:00
91fffb3f7d fixed nn declaration 2009-07-27 12:01:58 +01:00
1fa31efebf Added tag 5.6.1 for changeset e47a47bd3ed4 2009-07-26 14:02:28 +01:00
6 changed files with 238 additions and 172 deletions

View File

@ -62,3 +62,6 @@ e4bcaca8e6ef13d2c3b81f1218ad15e5da4d68bd 5.2
85a78d8afa0fe8b106a8223b5327e5bddb5dd5e3 5.4.1
deaa276abac17ca08fbeb936916e4c8292d293a4 5.5
5550702215773aad462f22a774dced9b87437c51 5.6
e47a47bd3ed42fd3cf023572147b75ebc2adef82 5.6.1
257403d4cd962cac03344a871ea56cc742bae38e 5.7
48c3f87c335d6606e55fbae97267fa6b39ca56e0 5.7.1

View File

@ -2,7 +2,7 @@ MIT/X Consortium License
© 2006-2009 Anselm R Garbe <garbeam at gmail dot com>
© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
© 2006-2007 Jukka Salmi <jukka at salmi dot ch>
© 2006-2009 Jukka Salmi <jukka at salmi dot ch>
© 2007-2009 Premysl Hruby <dfenze at gmail dot com>
© 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com>
© 2007-2009 Christof Musik <christof at sendfax dot de>

View File

@ -24,7 +24,7 @@ static const Rule rules[] = {
/* layout(s) */
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
static const Bool resizehints = True; /* False means respect size hints in tiled resizals */
static const Bool resizehints = True; /* True means respect size hints in tiled resizals */
static const Layout layouts[] = {
/* symbol arrange function */
@ -84,8 +84,7 @@ static Key keys[] = {
};
/* button definitions */
/* click can be a tag number (starting at 0),
* ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
/* click can be ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },

View File

@ -1,5 +1,5 @@
# dwm version
VERSION = 5.6.1
VERSION = 5.7.2
# Customize below to fit your system

31
dwm.1
View File

@ -20,14 +20,13 @@ Windows are grouped by tags. Each window can be tagged with one or multiple
tags. Selecting certain tags displays all windows with these tags.
.P
Each screen contains a small status bar which displays all available tags, the
layout, the number of visible windows, the title of the focused window, and the
text read from the root window name property, if the screen is focused. A
floating window is indicated with an empty square and a maximised floating
window is indicated with a filled square before the windows title. The
selected tags are indicated with a different color. The tags of the focused
window are indicated with a filled square in the top left corner. The tags
which are applied to one or more windows are indicated with an empty square in
the top left corner.
layout, the title of the focused window, and the text read from the root window
name property, if the screen is focused. A floating window is indicated with an
empty square and a maximised floating window is indicated with a filled square
before the windows title. The selected tags are indicated with a different
color. The tags of the focused window are indicated with a filled square in the
top left corner. The tags which are applied to one or more windows are
indicated with an empty square in the top left corner.
.P
dwm draws a small border around windows to indicate the focus state.
.SH OPTIONS
@ -149,11 +148,17 @@ code. This keeps it fast, secure and simple.
.SH BUGS
Java applications which use the XToolkit/XAWT backend may draw grey windows
only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early
JDK 1.6 versions, because it assumes a reparenting window manager. As a workaround
you can use JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or you
can set the following environment variable (to use the older Motif
backend instead):
.BR AWT_TOOLKIT=MToolkit .
JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds
are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the
environment variable
.BR AWT_TOOLKIT=MToolkit
(to use the older Motif backend instead) or running
.B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D
or
.B wmname LG3D
(to pretend that a non-reparenting window manager is running that the
XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable
.BR _JAVA_AWT_WM_NONREPARENTING=1 .
.P
GTK 2.10.9+ versions contain a broken
.BR Save\-As

367
dwm.c
View File

@ -121,6 +121,7 @@ typedef struct {
} Layout;
struct Monitor {
char ltsymbol[16];
float mfact;
int num;
int by; /* bar geometry */
@ -151,17 +152,19 @@ typedef struct {
/* function declarations */
static void applyrules(Client *c);
static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact);
static void arrange(void);
static void arrange(Monitor *m);
static void arrangemon(Monitor *m);
static void attach(Client *c);
static void attachstack(Client *c);
static void buttonpress(XEvent *e);
static void checkotherwm(void);
static void cleanup(void);
static void cleanupmons(void);
static void cleanupmon(Monitor *mon);
static void clearurgent(Client *c);
static void configure(Client *c);
static void configurenotify(XEvent *e);
static void configurerequest(XEvent *e);
static Monitor *createmon(void);
static void destroynotify(XEvent *e);
static void detach(Client *c);
static void detachstack(Client *c);
@ -207,7 +210,7 @@ static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg);
static void setup(void);
static void showhide(Client *c);
static void sigchld(int signal);
static void sigchld(int unused);
static void spawn(const Arg *arg);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
@ -218,9 +221,9 @@ static void togglefloating(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unfocus(Client *c);
static void unmanage(Client *c);
static void unmanage(Client *c, Bool destroyed);
static void unmapnotify(XEvent *e);
static void updategeom(void);
static Bool updategeom(void);
static void updatebarpos(Monitor *m);
static void updatebars(void);
static void updatenumlockmask(void);
@ -238,7 +241,7 @@ static void zoom(const Arg *arg);
/* variables */
static const char broken[] = "broken";
static char stext[256], ntext[8];
static char stext[256];
static int screen;
static int sw, sh; /* X display screen geometry width, height */
static int bh, blw = 0; /* bar geometry */
@ -377,17 +380,24 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact) {
}
void
arrange(void) {
Monitor *m;
for(m = mons; m; m = m->next)
arrange(Monitor *m) {
if(m)
showhide(m->stack);
else for(m = mons; m; m = m->next)
showhide(m->stack);
focus(NULL);
for(m = mons; m; m = m->next) {
if(m->lt[m->sellt]->arrange)
m->lt[m->sellt]->arrange(m);
restack(m);
}
if(m)
arrangemon(m);
else for(m = mons; m; m = m->next)
arrangemon(m);
}
void
arrangemon(Monitor *m) {
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol);
if(m->lt[m->sellt]->arrange)
m->lt[m->sellt]->arrange(m);
restack(m);
}
void
@ -466,7 +476,7 @@ cleanup(void) {
selmon->lt[selmon->sellt] = &foo;
for(m = mons; m; m = m->next)
while(m->stack)
unmanage(m->stack);
unmanage(m->stack, False);
if(dc.font.set)
XFreeFontSet(dpy, dc.font.set);
else
@ -477,22 +487,25 @@ cleanup(void) {
XFreeCursor(dpy, cursor[CurNormal]);
XFreeCursor(dpy, cursor[CurResize]);
XFreeCursor(dpy, cursor[CurMove]);
cleanupmons();
while(mons)
cleanupmon(mons);
XSync(dpy, False);
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
}
void
cleanupmons(void) {
cleanupmon(Monitor *mon) {
Monitor *m;
while(mons) {
m = mons->next;
XUnmapWindow(dpy, mons->barwin);
XDestroyWindow(dpy, mons->barwin);
free(mons);
mons = m;
if(mon == mons)
mons = mons->next;
else {
for(m = mons; m && m->next != mon; m = m->next);
m->next = mon->next;
}
XUnmapWindow(dpy, mon->barwin);
XDestroyWindow(dpy, mon->barwin);
free(mon);
}
void
@ -530,17 +543,18 @@ configurenotify(XEvent *e) {
Monitor *m;
XConfigureEvent *ev = &e->xconfigure;
if(ev->window == root && (ev->width != sw || ev->height != sh)) {
if(ev->window == root) {
sw = ev->width;
sh = ev->height;
updategeom();
if(dc.drawable != 0)
XFreePixmap(dpy, dc.drawable);
dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
updatebars();
for(m = mons; m; m = m->next)
XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
arrange();
if(updategeom()) {
if(dc.drawable != 0)
XFreePixmap(dpy, dc.drawable);
dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
updatebars();
for(m = mons; m; m = m->next)
XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
arrange(NULL);
}
}
}
@ -564,9 +578,9 @@ configurerequest(XEvent *e) {
c->w = ev->width;
if(ev->value_mask & CWHeight)
c->h = ev->height;
if((c->x - m->mx + c->w) > m->mw && c->isfloating)
if((c->x + c->w) > m->mx + m->mw && c->isfloating)
c->x = m->mx + (m->mw / 2 - c->w / 2); /* center in x direction */
if((c->y - m->my + c->h) > m->mh && c->isfloating)
if((c->y + c->h) > m->my + m->mh && c->isfloating)
c->y = m->my + (m->mh / 2 - c->h / 2); /* center in y direction */
if((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight)))
configure(c);
@ -589,13 +603,29 @@ configurerequest(XEvent *e) {
XSync(dpy, False);
}
Monitor *
createmon(void) {
Monitor *m;
if(!(m = (Monitor *)calloc(1, sizeof(Monitor))))
die("fatal: could not malloc() %u bytes\n", sizeof(Monitor));
m->tagset[0] = m->tagset[1] = 1;
m->mfact = mfact;
m->showbar = showbar;
m->topbar = topbar;
m->lt[0] = &layouts[0];
m->lt[1] = &layouts[1 % LENGTH(layouts)];
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
return m;
}
void
destroynotify(XEvent *e) {
Client *c;
XDestroyWindowEvent *ev = &e->xdestroywindow;
if((c = wintoclient(ev->window)))
unmanage(c);
unmanage(c, True);
}
void
@ -649,13 +679,11 @@ dirtomon(int dir) {
void
drawbar(Monitor *m) {
int x;
unsigned int i, n = 0, occ = 0, urg = 0;
unsigned int i, occ = 0, urg = 0;
unsigned long *col;
Client *c;
for(c = m->clients; c; c = c->next) {
if(ISVISIBLE(c))
n++;
occ |= c->tags;
if(c->isurgent)
urg |= c->tags;
@ -669,15 +697,10 @@ drawbar(Monitor *m) {
occ & 1 << i, urg & 1 << i, col);
dc.x += dc.w;
}
if(blw > 0) {
dc.w = blw;
drawtext(m->lt[m->sellt]->symbol, dc.norm, False);
dc.x += dc.w;
}
snprintf(ntext, sizeof ntext, "%u", n);
dc.w = TEXTW(ntext);
drawtext(ntext, dc.norm, False);
x = (dc.x += dc.w);
dc.w = blw = TEXTW(m->ltsymbol);
drawtext(m->ltsymbol, dc.norm, False);
dc.x += dc.w;
x = dc.x;
if(m == selmon) { /* status is only drawn on selected monitor */
dc.w = TEXTW(stext);
dc.x = m->ww - dc.w;
@ -1009,6 +1032,19 @@ isprotodel(Client *c) {
return ret;
}
#ifdef XINERAMA
static Bool
isuniquegeom(XineramaScreenInfo *unique, size_t len, XineramaScreenInfo *info) {
unsigned int i;
for(i = 0; i < len; i++)
if(unique[i].x_org == info->x_org && unique[i].y_org == info->y_org
&& unique[i].width == info->width && unique[i].height == info->height)
return False;
return True;
}
#endif /* XINERAMA */
void
keypress(XEvent *e) {
unsigned int i;
@ -1039,8 +1075,15 @@ killclient(const Arg *arg) {
ev.xclient.data.l[1] = CurrentTime;
XSendEvent(dpy, selmon->sel->win, False, NoEventMask, &ev);
}
else
else {
XGrabServer(dpy);
XSetErrorHandler(xerrordummy);
XSetCloseDownMode(dpy, DestroyAll);
XKillClient(dpy, selmon->sel->win);
XSync(dpy, False);
XSetErrorHandler(xerror);
XUngrabServer(dpy);
}
}
void
@ -1103,7 +1146,7 @@ manage(Window w, XWindowAttributes *wa) {
XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */
XMapWindow(dpy, c->win);
setclientstate(c, NormalState);
arrange();
arrange(c->mon);
}
void
@ -1130,8 +1173,14 @@ maprequest(XEvent *e) {
void
monocle(Monitor *m) {
unsigned int n = 0;
Client *c;
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, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, False);
}
@ -1223,7 +1272,7 @@ propertynotify(XEvent *e) {
case XA_WM_TRANSIENT_FOR:
XGetTransientForHint(dpy, c->win, &trans);
if(!c->isfloating && (c->isfloating = (wintoclient(trans) != NULL)))
arrange();
arrange(c->mon);
break;
case XA_WM_NORMAL_HINTS:
updatesizehints(c);
@ -1235,8 +1284,8 @@ propertynotify(XEvent *e) {
}
if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
updatetitle(c);
if(c == selmon->sel)
drawbars();
if(c == c->mon->sel)
drawbar(c->mon);
}
}
}
@ -1318,7 +1367,7 @@ restack(Monitor *m) {
XEvent ev;
XWindowChanges wc;
drawbars();
drawbar(m);
if(!m->sel)
return;
if(m->sel->isfloating || !m->lt[m->sellt]->arrange)
@ -1385,7 +1434,7 @@ sendmon(Client *c, Monitor *m) {
attach(c);
attachstack(c);
focus(NULL);
arrange();
arrange(NULL);
}
void
@ -1402,10 +1451,11 @@ setlayout(const Arg *arg) {
selmon->sellt ^= 1;
if(arg && arg->v)
selmon->lt[selmon->sellt] = (Layout *)arg->v;
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
if(selmon->sel)
arrange();
arrange(selmon);
else
drawbars();
drawbar(selmon);
}
/* arg > 1.0 will set mfact absolutly */
@ -1419,15 +1469,16 @@ setmfact(const Arg *arg) {
if(f < 0.1 || f > 0.9)
return;
selmon->mfact = f;
arrange();
arrange(selmon);
}
void
setup(void) {
unsigned int i;
int w;
XSetWindowAttributes wa;
/* clean up any zombies immediately */
sigchld(0);
/* init screen */
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
@ -1459,10 +1510,6 @@ setup(void) {
if(!dc.font.set)
XSetFont(dpy, dc.gc, dc.font.xfont->fid);
/* init bars */
for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) {
w = TEXTW(layouts[i].symbol);
blw = MAX(blw, w);
}
updatebars();
updatestatus();
/* EWMH support per view */
@ -1496,13 +1543,14 @@ showhide(Client *c) {
void
sigchld(int signal) {
sigchld(int unused) {
if(signal(SIGCHLD, sigchld) == SIG_ERR)
die("Can't install SIGCHLD handler");
while(0 < waitpid(-1, NULL, WNOHANG));
}
void
spawn(const Arg *arg) {
signal(SIGCHLD, sigchld);
if(fork() == 0) {
if(dpy)
close(ConnectionNumber(dpy));
@ -1518,7 +1566,7 @@ void
tag(const Arg *arg) {
if(selmon->sel && arg->ui & TAGMASK) {
selmon->sel->tags = arg->ui & TAGMASK;
arrange();
arrange(selmon);
}
}
@ -1575,7 +1623,7 @@ togglebar(const Arg *arg) {
selmon->showbar = !selmon->showbar;
updatebarpos(selmon);
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
arrange();
arrange(selmon);
}
void
@ -1586,29 +1634,29 @@ togglefloating(const Arg *arg) {
if(selmon->sel->isfloating)
resize(selmon->sel, selmon->sel->x, selmon->sel->y,
selmon->sel->w, selmon->sel->h, False);
arrange();
arrange(selmon);
}
void
toggletag(const Arg *arg) {
unsigned int mask;
unsigned int newtags;
if(!selmon->sel)
return;
mask = selmon->sel->tags ^ (arg->ui & TAGMASK);
if(mask) {
selmon->sel->tags = mask;
arrange();
newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
if(newtags) {
selmon->sel->tags = newtags;
arrange(selmon);
}
}
void
toggleview(const Arg *arg) {
unsigned int mask = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
if(mask) {
selmon->tagset[selmon->seltags] = mask;
arrange();
if(newtagset) {
selmon->tagset[selmon->seltags] = newtagset;
arrange(selmon);
}
}
@ -1622,24 +1670,27 @@ unfocus(Client *c) {
}
void
unmanage(Client *c) {
unmanage(Client *c, Bool destroyed) {
Monitor *m = c->mon;
XWindowChanges wc;
wc.border_width = c->oldbw;
/* The server grab construct avoids race conditions. */
XGrabServer(dpy);
XSetErrorHandler(xerrordummy);
XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
detach(c);
detachstack(c);
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
setclientstate(c, WithdrawnState);
if(!destroyed) {
wc.border_width = c->oldbw;
XGrabServer(dpy);
XSetErrorHandler(xerrordummy);
XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
setclientstate(c, WithdrawnState);
XSync(dpy, False);
XSetErrorHandler(xerror);
XUngrabServer(dpy);
}
free(c);
XSync(dpy, False);
XSetErrorHandler(xerror);
XUngrabServer(dpy);
focus(NULL);
arrange();
arrange(m);
}
void
@ -1648,7 +1699,7 @@ unmapnotify(XEvent *e) {
XUnmapEvent *ev = &e->xunmap;
if((c = wintoclient(ev->window)))
unmanage(c);
unmanage(c, False);
}
void
@ -1681,79 +1732,87 @@ updatebarpos(Monitor *m) {
m->by = -bh;
}
void
Bool
updategeom(void) {
int i, n = 1, nn;
Client *c;
Monitor *newmons = NULL, *m = NULL, *tm;
Bool dirty = False;
#ifdef XINERAMA
XineramaScreenInfo *info = NULL;
if(XineramaIsActive(dpy))
info = XineramaQueryScreens(dpy, &n);
for(i = 1, nn = n; i < n; i++)
if(info[i - 1].x_org == info[i].x_org && info[i - 1].y_org == info[i].y_org
&& info[i - 1].width == info[i].width && info[i - 1].height == info[i].height)
--nn;
n = nn; /* we only consider unique geometries as separate screens */
#endif /* XINERAMA */
/* allocate monitor(s) for the new geometry setup */
for(i = 0; i < n; i++) {
if(!(m = (Monitor *)malloc(sizeof(Monitor))))
die("fatal: could not malloc() %u bytes\n", sizeof(Monitor));
m->next = newmons;
newmons = m;
}
/* initialise monitor(s) */
#ifdef XINERAMA
if(XineramaIsActive(dpy)) {
for(i = 0, m = newmons; m; m = m->next, i++) {
m->num = info[i].screen_number;
m->mx = m->wx = info[i].x_org;
m->my = m->wy = info[i].y_org;
m->mw = m->ww = info[i].width;
m->mh = m->wh = info[i].height;
}
int i, j, n, nn;
Client *c;
Monitor *m;
XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);
XineramaScreenInfo *unique = NULL;
info = XineramaQueryScreens(dpy, &nn);
for(n = 0, m = mons; m; m = m->next, n++);
/* only consider unique geometries as separate screens */
if(!(unique = (XineramaScreenInfo *)malloc(sizeof(XineramaScreenInfo) * nn)))
die("fatal: could not malloc() %u bytes\n", sizeof(XineramaScreenInfo) * nn);
for(i = 0, j = 0; i < nn; i++)
if(isuniquegeom(unique, j, &info[i]))
memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
XFree(info);
nn = j;
if(n <= nn) {
for(i = 0; i < (nn - n); i++) { /* new monitors available */
for(m = mons; m && m->next; m = m->next);
if(m)
m->next = createmon();
else
mons = createmon();
}
for(i = 0, m = mons; i < nn && m; m = m->next, i++)
if(i >= n
|| (unique[i].x_org != m->mx || unique[i].y_org != m->my
|| unique[i].width != m->mw || unique[i].height != m->mh))
{
dirty = True;
m->num = i;
m->mx = m->wx = unique[i].x_org;
m->my = m->wy = unique[i].y_org;
m->mw = m->ww = unique[i].width;
m->mh = m->wh = unique[i].height;
updatebarpos(m);
}
}
else { /* less monitors available nn < n */
for(i = nn; i < n; i++) {
for(m = mons; m && m->next; m = m->next);
while(m->clients) {
dirty = True;
c = m->clients;
m->clients = c->next;
detachstack(c);
c->mon = mons;
attach(c);
attachstack(c);
}
if(m == selmon)
selmon = mons;
cleanupmon(m);
}
}
free(unique);
}
else
#endif /* XINERAMA */
/* default monitor setup */
{
m->num = 0;
m->mx = m->wx = 0;
m->my = m->wy = 0;
m->mw = m->ww = sw;
m->mh = m->wh = sh;
}
/* bar geometry setup */
for(m = newmons; m; m = m->next) {
m->sel = m->stack = m->clients = NULL;
m->seltags = 0;
m->sellt = 0;
m->tagset[0] = m->tagset[1] = 1;
m->mfact = mfact;
m->showbar = showbar;
m->topbar = topbar;
m->lt[0] = &layouts[0];
m->lt[1] = &layouts[1 % LENGTH(layouts)];
updatebarpos(m);
}
/* reassign left over clients of disappeared monitors */
for(tm = mons; tm; tm = tm->next)
while(tm->clients) {
c = tm->clients;
tm->clients = c->next;
detachstack(c);
c->mon = newmons;
attach(c);
attachstack(c);
if(!mons)
mons = createmon();
if(mons->mw != sw || mons->mh != sh) {
dirty = True;
mons->mw = mons->ww = sw;
mons->mh = mons->wh = sh;
updatebarpos(mons);
}
/* select focused monitor */
cleanupmons();
selmon = mons = newmons;
selmon = wintomon(root);
}
if(dirty) {
selmon = mons;
selmon = wintomon(root);
}
return dirty;
}
void
@ -1858,7 +1917,7 @@ view(const Arg *arg) {
selmon->seltags ^= 1; /* toggle sel tagset */
if(arg->ui & TAGMASK)
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
arrange();
arrange(selmon);
}
Client *
@ -1936,7 +1995,7 @@ zoom(const Arg *arg) {
detach(c);
attach(c);
focus(c);
arrange();
arrange(c->mon);
}
int