So here's another go at mapping new windows after everything has
been arranged.
This time, floating windows are stacked correctly and there are
no flickers or redraws of the title bar or the new window. The
two patches add 8 short lines. Seems not too gross as an interim
solution.
The line c-mon-sel = c; also fixes a vanilla dwm bug on
Xinerama setups:
1. Focus a floating window w belonging to a client c
2. Focus another monitor with focusmon()
3. When c pops up a transient window w' on the unfocused monitor,
w' is stacked behind w.
For testing, transient.c opens a floating window and then after
5 seconds a transient one.
Peter
--- dwm/dwm.c.orig 2011-07-28 17:55:50.482916191 +0200
+++ dwm/dwm.c 2011-07-28 17:56:27.387448688 +0200
@@ -389,7 +389,6 @@ arrange(Monitor *m) {
showhide(m-stack);
else for(m = mons; m; m = m-next)
showhide(m-stack);
- focus(NULL);
if(m)
arrangemon(m);
else for(m = mons; m; m = m-next)
@@ -598,6 +597,7 @@ configurenotify(XEvent *e) {
updatebars();
for(m = mons; m; m = m-next)
XMoveResizeWindow(dpy, m-barwin, m-wx, m-by,
m-ww, bh);
+ focus(NULL);
arrange(NULL);
}
}
@@ -1157,6 +1157,7 @@ manage(Window w, XWindowAttributes *wa)
XMapWindow(dpy, c-win);
setclientstate(c, NormalState);
arrange(c-mon);
+ focus(NULL);
}
void
@@ -1621,6 +1622,7 @@ void
tag(const Arg *arg) {
if(selmon-sel arg-ui TAGMASK) {
selmon-sel-tags = arg-ui TAGMASK;
+ focus(NULL);
arrange(selmon);
}
}
@@ -1701,6 +1703,7 @@ toggletag(const Arg *arg) {
newtags = selmon-sel-tags ^ (arg-ui TAGMASK);
if(newtags) {
selmon-sel-tags = newtags;
+ focus(NULL);
arrange(selmon);
}
}
@@ -1711,6 +1714,7 @@ toggleview(const Arg *arg) {
if(newtagset) {
selmon-tagset[selmon-seltags] = newtagset;
+ focus(NULL);
arrange(selmon);
}
}
@@ -1976,6 +1980,7 @@ view(const Arg *arg) {
selmon-seltags ^= 1; /* toggle sel tagset */
if(arg-ui TAGMASK)
selmon-tagset[selmon-seltags] = arg-ui TAGMASK;
+ focus(NULL);
arrange(selmon);
}
--- dwm/dwm.c.orig 2011-07-29 16:35:14.265835028 +0200
+++ dwm/dwm.c 2011-07-29 16:35:41.523589947 +0200
@@ -1154,9 +1154,12 @@ manage(Window w, XWindowAttributes *wa)
attach(c);
attachstack(c);
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);
+ if (c-mon == selmon)
+ unfocus(selmon-sel, False);
+ c-mon-sel = c;
arrange(c-mon);
+ XMapWindow(dpy, c-win);
focus(NULL);
}
/* cc transient.c -o transient -lX11 */
#include stdlib.h
#include unistd.h
#include X11/Xlib.h
#include X11/Xutil.h
int main(void) {
Display *d;
Window r, f, t = None;
XSizeHints h;
XEvent e;
d = XOpenDisplay(NULL);
if (!d)
exit(1);
r = DefaultRootWindow(d);
f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0);
h.min_width = h.max_width = h.min_height = h.max_height = 400;
h.flags = PMinSize | PMaxSize;
XSetWMNormalHints(d, f, h);
XStoreName(d, f, floating);
XMapWindow(d, f);
XSelectInput(d, f, ExposureMask);
while (1) {
XNextEvent(d, e);
if (t == None) {
sleep(5);
t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0);
XSetTransientForHint(d, t, f);
XStoreName(d, t, transient);
XMapWindow(d, t);
XSelectInput(d, t, ExposureMask);
}
}
XCloseDisplay(d);
exit(0);
}