[dev] [patch] Xinerama bugfix + map new window *after* arrange(), again

2011-07-29 Thread Peter Hartlich
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 
#include 
#include 
#include 

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


Re: [dev] [dwm] code cleanup

2011-07-26 Thread Peter Hartlich
Hi,

>  void
>  grabkeys(void) {
> + unsigned int i, j;
> + unsigned int modifiers[] = { 0, LockMask, numlockmask, 
> numlockmask|LockMask };
> + KeyCode code;
> +
>   updatenumlockmask();
> - {
> - unsigned int i, j;
> - unsigned int modifiers[] = { 0, LockMask, numlockmask, 
> numlockmask|LockMask };
> - KeyCode code;

That would break the numlockmask stuff.

Regards,
Peter



Re: [dev] [patch] map new window *after* arrange()

2011-07-09 Thread Peter Hartlich
> To prevent the first restack, maybe something like the attached patch?

... which causes the title bar to flicker, as restack calls drawbar
before bailing out. Not sure why that's needed.

Peter



Re: [dev] [patch] map new window *after* arrange()

2011-07-09 Thread Peter Hartlich
> just one annoying issue with floating apps. eg. running save as in gimp,
> will open a window in the background.

Oh man, sorry. I should've tested it more with floating windows.

So arrange calls arrangemon, which calls restack, but the new floating
window hasn't become selmon->sel yet.

Restacking again at the end of manage fixes it, but then there's
another redraw. To prevent the first restack, maybe something like
the attached patch? Or split off (un)select functions from (un)focus,
which also came up in connection to virtual keyboards some time ago.

Regards,
Peter
--- dwm/dwm.c.orig  2011-07-10 02:34:59.982409153 +0200
+++ dwm/dwm.c   2011-07-10 03:49:19.114387186 +0200
@@ -1150,9 +1150,12 @@ manage(Window w, XWindowAttributes *wa)
attachstack(c);
XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* 
some windows require this */
setclientstate(c, NormalState);
+   unfocus(selmon->sel, False);
+   selmon->sel = NULL;
arrange(c->mon);
XMapWindow(dpy, c->win);
focus(c);
+   restack(c->mon);
 }
 
 void


Re: [dev] [patch] map new window *after* arrange()

2011-07-08 Thread Peter Hartlich
Hi Anselm,

> I reviewed your patch and concluded I can't apply it as is, because
> focus() would be called twice, once on the unmapped window, and then
> on again.

It seems to me that focusing and arranging should be independent
operations. So here comes another patch to remove focus(NULL) from
arrange and add it, if missing, everywhere arrange is called after
either a window might have vanished from selmon's view, or selmon
itself might have vanished.

Regards,
Peter
--- dwm/dwm.c.orig  2011-07-09 01:21:43.924293041 +0200
+++ dwm/dwm.c   2011-07-09 01:25:06.127245938 +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);
}
}
@@ -1616,6 +1616,7 @@ void
 tag(const Arg *arg) {
if(selmon->sel && arg->ui & TAGMASK) {
selmon->sel->tags = arg->ui & TAGMASK;
+   focus(NULL);
arrange(selmon);
}
 }
@@ -1696,6 +1697,7 @@ toggletag(const Arg *arg) {
newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
if(newtags) {
selmon->sel->tags = newtags;
+   focus(NULL);
arrange(selmon);
}
 }
@@ -1706,6 +1708,7 @@ toggleview(const Arg *arg) {
 
if(newtagset) {
selmon->tagset[selmon->seltags] = newtagset;
+   focus(NULL);
arrange(selmon);
}
 }
@@ -1971,6 +1974,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);
 }
 


[dev] [patch] map new window *after* arrange()

2011-07-06 Thread Peter Hartlich
Couldn't dwm map newly created windows *after* they have been moved
to their proper position? Less flickering (especially noticeable with
the attachabove/attachaside patches), and it feels snappier on a slow
computer.

I haven't experienced any problems with the attached patch so far.

Peter
diff -r c787646ca93f dwm.c
--- a/dwm.c Sat Jul 02 11:01:58 2011 +0200
+++ b/dwm.c Wed Jul 06 22:55:49 2011 +0200
@@ -1149,9 +1149,10 @@
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);
arrange(c->mon);
+   XMapWindow(dpy, c->win);
+   focus(c);
 }
 
 void


[dev] [patch] enternotify: fewer winto{mon,client} calls; small simplification

2011-06-25 Thread Peter Hartlich
diff -r 014df3c34b64 dwm.c
--- a/dwm.c Sat Jun 25 09:07:04 2011 +0100
+++ b/dwm.c Sat Jun 25 22:46:04 2011 +0200
@@ -827,13 +827,14 @@
if((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && 
ev->window != root)
return;
c = wintoclient(ev->window);
-   if((m = wintomon(ev->window)) && m != selmon) {
+   m = c ? c->mon : wintomon(ev->window);
+   if(m != selmon) {
unfocus(selmon->sel, True);
selmon = m;
}
-   else if(c == selmon->sel || c == NULL)
+   else if(!c || c == selmon->sel)
return;
-   focus((wintoclient(ev->window)));
+   focus(c);
 }
 
 void