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);
}

Reply via email to