there should be a Bool usegrab in your config.h, check it against config.def.h
Here's a slightly updated patch, the bar is drawn a little better now. Jeremy On Fri 12 Dec 2008 - 01:20PM, Johannes Wegener wrote: > thanks for your approach - but I was not able to compile it (patched > against dwm 5.3.1) it does not find the function "usegrab" (used in > "movemouse" and "resizemouse"... > > On Thu, Dec 11, 2008 at 10:59:16PM -0500, Jeremy Jay wrote: > > Here's my XRandR and multi-screen patch, its pretty much not what you've > > asked for here, but I'll throw it out as a starting point. I haven't > > had a chance to test it much, so don't yell at me if your screen > > explodes... > > > > one tag for all screens. status bar is only shown on screen 0 (although > > this can very easily be set to another screen) > > > > layouts updated for multi-head: > > tile: windows are evenly divided among screens. > > monocle: one window per screen, all remaining windows on last screen. > > > > Jeremy > > > > > > On Thu 11 Dec 2008 - 10:18AM, Mate Nagy wrote: > > > Hiho, > > > On Thu, Dec 11, 2008 at 09:39:19AM +0100, yy wrote: > > > > on this list and, if somebody finds a great _general_ solution (which > > > > seems difficult, but I would be love to be wrong), I'm sure Anselm > > > > would be glad to include it in the official release. > > > > Just my 2cts, > > > I don't see anything "difficult" about this. In fact, awesome generally > > > gets this right. This is what I want from dwm: > > > > > > - handle each xrandr screen separately > > > including all data structures, so different layout, client set, > > > tagging, etc. > > > - draw statusbar everywhere (from the same input text) > > > - have a key-bindable function for: > > > - changing between screens > > > - move window to another screen > > > - do something semi-intelligent when a screen with clients goes away, > > > e.g. put clients in previous/next screen oslt. > > > > > > Basically, it should behave as multiple separate dwms, except that > > > clients can be sent from screen to screen and all dwms have the same > > > configuration. > > > > > > Speculation: in this configuration, especially when changing between > > > screens, moving the mouse pointer to the location of the focus might be > > > more important/desirable. This might be a compile-time option or patch.. > > > > > > Mate > > > > > > diff -r 79bf47074a49 config.mk > > --- a/config.mk Sat Dec 06 16:20:14 2008 +0000 > > +++ b/config.mk Thu Dec 11 22:50:24 2008 -0500 > > @@ -13,6 +13,8 @@ > > # Xinerama, un-comment if you want it > > #XINERAMALIBS = -L${X11LIB} -lXinerama > > #XINERAMAFLAGS = -DXINERAMA > > +XINERAMALIBS = -L${X11LIB} -lXrandr > > +XINERAMAFLAGS = -DXRANDR > > > > # includes and libs > > INCS = -I. -I/usr/include -I${X11INC} > > diff -r 79bf47074a49 dwm.c > > --- a/dwm.c Sat Dec 06 16:20:14 2008 +0000 > > +++ b/dwm.c Thu Dec 11 22:50:24 2008 -0500 > > @@ -42,6 +42,9 @@ > > #ifdef XINERAMA > > #include <X11/extensions/Xinerama.h> > > #endif > > +#ifdef XRANDR > > +#include <X11/extensions/Xrandr.h> > > +#endif > > > > /* macros */ > > #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) > > @@ -52,6 +55,7 @@ > > #define MAX(a, b) ((a) > (b) ? (a) : (b)) > > #define MIN(a, b) ((a) < (b) ? (a) : (b)) > > #define MAXTAGLEN 16 > > +#define MAXMONITORS 8 > > #define MOUSEMASK (BUTTONMASK|PointerMotionMask) > > #define WIDTH(x) ((x)->w + 2 * (x)->bw) > > #define HEIGHT(x) ((x)->h + 2 * (x)->bw) > > @@ -206,10 +210,11 @@ > > > > /* variables */ > > static char stext[256]; > > -static int screen; > > +static int screen, mons; > > static int sx, sy, sw, sh; /* X display screen geometry x, y, width, > > height */ > > static int by, bh, blw; /* bar geometry y, height and layout symbol > > width */ > > static int wx, wy, ww, wh; /* window area geometry x, y, width, height, > > bar excluded */ > > +static int mx[MAXMONITORS], my[MAXMONITORS], mw[MAXMONITORS], > > mh[MAXMONITORS]; /* monitor area geometry x, y, width, height, bar excluded > > */ > > static unsigned int seltags = 0, sellt = 0; > > static int (*xerrorxlib)(Display *, XErrorEvent *); > > static unsigned int numlockmask = 0; > > @@ -926,10 +931,14 @@ > > > > void > > monocle(void) { > > - Client *c; > > + int m, i; > > + Client *c = nexttiled(clients); > > > > - for(c = nexttiled(clients); c; c = nexttiled(c->next)) > > - resize(c, wx, wy, ww - 2 * c->bw, wh - 2 * c->bw, resizehints); > > + for(m=0; m<mons; m++) { > > + wx=mx[m]; wy=my[m]; ww=mw[m]; wh=mh[m]; > > + for(i=((m==(mons-1))?-1:1); c && i!=0; c = nexttiled(c->next), > > i--) > > + resize(c, wx, wy, ww - 2 * c->bw, wh - 2 * c->bw, > > resizehints); > > + } > > } > > > > void > > @@ -1427,35 +1436,39 @@ > > > > void > > tile(void) { > > - int x, y, h, w, mw; > > - unsigned int i, n; > > + int x, y, h, w, maw; > > + unsigned int i, n, r, g, m; > > Client *c; > > > > for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next), n++); > > if(n == 0) > > return; > > > > - /* master */ > > c = nexttiled(clients); > > - mw = mfact * ww; > > - resize(c, wx, wy, (n == 1 ? ww : mw) - 2 * c->bw, wh - 2 * c->bw, > > resizehints); > > + for(m=0, g=(n+(mons/2))/mons, r=n-g, n=g; c && m<mons; m++, > > n=(r<g?r:g), r-=n) { > > + wx=mx[m]; wy=my[m]; ww=mw[m]; wh=mh[m]; > > + /* master */ > > + maw = mfact * ww; > > + resize(c, wx, wy, (n == 1 ? ww : maw) - 2 * c->bw, wh - 2 * > > c->bw, resizehints); > > + c = nexttiled(c->next); > > > > - if(--n == 0) > > - return; > > + if( --n == 0 ) > > + continue; > > > > - /* tile stack */ > > - x = (wx + mw > c->x + c->w) ? c->x + c->w + 2 * c->bw : wx + mw; > > - y = wy; > > - w = (wx + mw > c->x + c->w) ? wx + ww - x : ww - mw; > > - h = wh / n; > > - if(h < bh) > > - h = wh; > > + /* tile stack */ > > + x = (wx + maw > c->x + c->w) ? c->x + c->w + 2 * c->bw : wx + > > maw; > > + y = wy; > > + w = (wx + maw > c->x + c->w) ? wx + ww - x : ww - maw; > > + h = wh / n; > > + if(h < bh) > > + h = wh; > > > > - for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) { > > - resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n) > > - ? wy + wh - y - 2 * c->bw : h - 2 * c->bw), resizehints); > > - if(h != wh) > > - y = c->y + HEIGHT(c); > > + for(i = 0; c && (m==(mons-1)?1:n); c = nexttiled(c->next), i++, > > n--) { > > + resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 > > == g) > > + ? wy + wh - y - 2 * c->bw : h - > > 2 * c->bw), resizehints); > > + if(h != wh) > > + y = c->y + HEIGHT(c); > > + } > > } > > } > > > > @@ -1565,11 +1578,45 @@ > > } > > else > > #endif > > +#ifdef XRANDR > > + if( True /* xrr is active? */ ) { > > + int i=0, j=0, k=0, o=0; > > + XRRScreenResources *screenInfo = XRRGetScreenResources( dpy, > > root ); > > + XRRCrtcInfo *crtcInfo = NULL; > > + XID seenOutputs[MAXMONITORS*16]; // 16 clones should be enough > > + for(i=0, mons=0; i<screenInfo->ncrtc; i++) { > > + crtcInfo = XRRGetCrtcInfo( dpy, screenInfo, > > screenInfo->crtcs[i] ); > > + > > + if( crtcInfo->noutput!=0 ) { > > + Bool dupe=False; > > + for(j=0; j<crtcInfo->noutput; j++) { > > + for(k=0; > > seenOutputs[k]!=crtcInfo->outputs[j] && k<o; k++); > > + if( k!=o ) > > + dupe=True; > > + else > > + > > seenOutputs[o++]=crtcInfo->outputs[j]; > > + } > > + > > + if( !dupe ) { > > + my[mons]=crtcInfo->y + (mons==0 && > > showbar && topbar ? bh : 0); > > + mh[mons]=crtcInfo->height - (mons==0 && > > showbar?bh:0); > > + mw[mons]=crtcInfo->width; > > + mx[mons++]=crtcInfo->x; > > + } > > + } > > + } > > + XRRFreeCrtcInfo(crtcInfo); > > + XRRFreeScreenResources(screenInfo); > > + > > + wx = mx[0]; wy = my[0]; ww = mw[0]; wh = mh[0]; > > + } else > > +#endif > > { > > - wx = sx; > > - wy = showbar && topbar ? sy + bh : sy; > > - ww = sw; > > - wh = showbar ? sh - bh : sh; > > + mons=1; > > + mx[0] = wx = sx; > > + my[0] = wy = showbar && topbar ? sy + bh : sy; > > + mw[0] = ww = sw; > > + mh[0] = wh = showbar ? sh - bh : sh; > > } > > > > /* bar position */ >
diff -r 79bf47074a49 config.mk --- a/config.mk Sat Dec 06 16:20:14 2008 +0000 +++ b/config.mk Thu Dec 11 23:32:19 2008 -0500 @@ -13,6 +13,8 @@ # Xinerama, un-comment if you want it #XINERAMALIBS = -L${X11LIB} -lXinerama #XINERAMAFLAGS = -DXINERAMA +XINERAMALIBS = -L${X11LIB} -lXrandr +XINERAMAFLAGS = -DXRANDR # includes and libs INCS = -I. -I/usr/include -I${X11INC} diff -r 79bf47074a49 dwm.c --- a/dwm.c Sat Dec 06 16:20:14 2008 +0000 +++ b/dwm.c Thu Dec 11 23:32:19 2008 -0500 @@ -42,6 +42,9 @@ #ifdef XINERAMA #include <X11/extensions/Xinerama.h> #endif +#ifdef XRANDR +#include <X11/extensions/Xrandr.h> +#endif /* macros */ #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) @@ -52,6 +55,7 @@ #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAXTAGLEN 16 +#define MAXMONITORS 8 #define MOUSEMASK (BUTTONMASK|PointerMotionMask) #define WIDTH(x) ((x)->w + 2 * (x)->bw) #define HEIGHT(x) ((x)->h + 2 * (x)->bw) @@ -206,10 +210,11 @@ /* variables */ static char stext[256]; -static int screen; +static int screen, mons; static int sx, sy, sw, sh; /* X display screen geometry x, y, width, height */ static int by, bh, blw; /* bar geometry y, height and layout symbol width */ static int wx, wy, ww, wh; /* window area geometry x, y, width, height, bar excluded */ +static int mx[MAXMONITORS], my[MAXMONITORS], mw[MAXMONITORS], mh[MAXMONITORS]; /* monitor area geometry x, y, width, height, bar excluded */ static unsigned int seltags = 0, sellt = 0; static int (*xerrorxlib)(Display *, XErrorEvent *); static unsigned int numlockmask = 0; @@ -514,10 +519,10 @@ else x = dc.x; dc.w = TEXTW(stext); - dc.x = ww - dc.w; + dc.x = mw[0] - dc.w; if(dc.x < x) { dc.x = x; - dc.w = ww - x; + dc.w = mw[0] - x; } drawtext(stext, dc.norm, False); if((dc.w = dc.x - x) > bh) { @@ -529,7 +534,7 @@ else drawtext(NULL, dc.norm, False); } - XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, ww, bh, 0, 0); + XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, mw[0], bh, 0, 0); XSync(dpy, False); } @@ -926,10 +931,14 @@ void monocle(void) { - Client *c; + int m, i; + Client *c = nexttiled(clients); - for(c = nexttiled(clients); c; c = nexttiled(c->next)) - resize(c, wx, wy, ww - 2 * c->bw, wh - 2 * c->bw, resizehints); + for(m=0; m<mons; m++) { + wx=mx[m]; wy=my[m]; ww=mw[m]; wh=mh[m]; + for(i=((m==(mons-1))?-1:1); c && i!=0; c = nexttiled(c->next), i--) + resize(c, wx, wy, ww - 2 * c->bw, wh - 2 * c->bw, resizehints); + } } void @@ -1351,7 +1360,7 @@ wa.background_pixmap = ParentRelative; wa.event_mask = ButtonPressMask|ExposureMask; - barwin = XCreateWindow(dpy, root, wx, by, ww, bh, 0, DefaultDepth(dpy, screen), + barwin = XCreateWindow(dpy, root, mx[0], by, mw[0], bh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); XDefineCursor(dpy, barwin, cursor[CurNormal]); @@ -1427,35 +1436,39 @@ void tile(void) { - int x, y, h, w, mw; - unsigned int i, n; + int x, y, h, w, maw; + unsigned int i, n, r, g, m; Client *c; for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next), n++); if(n == 0) return; - /* master */ c = nexttiled(clients); - mw = mfact * ww; - resize(c, wx, wy, (n == 1 ? ww : mw) - 2 * c->bw, wh - 2 * c->bw, resizehints); + for(m=0, g=(n+(mons/2))/mons, r=n-g, n=g; c && m<mons; m++, n=(r<g?r:g), r-=n) { + wx=mx[m]; wy=my[m]; ww=mw[m]; wh=mh[m]; + /* master */ + maw = mfact * ww; + resize(c, wx, wy, (n == 1 ? ww : maw) - 2 * c->bw, wh - 2 * c->bw, resizehints); + c = nexttiled(c->next); - if(--n == 0) - return; + if( --n == 0 ) + continue; - /* tile stack */ - x = (wx + mw > c->x + c->w) ? c->x + c->w + 2 * c->bw : wx + mw; - y = wy; - w = (wx + mw > c->x + c->w) ? wx + ww - x : ww - mw; - h = wh / n; - if(h < bh) - h = wh; + /* tile stack */ + x = (wx + maw > c->x + c->w) ? c->x + c->w + 2 * c->bw : wx + maw; + y = wy; + w = (wx + maw > c->x + c->w) ? wx + ww - x : ww - maw; + h = wh / n; + if(h < bh) + h = wh; - for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) { - resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n) - ? wy + wh - y - 2 * c->bw : h - 2 * c->bw), resizehints); - if(h != wh) - y = c->y + HEIGHT(c); + for(i = 0; c && (m==(mons-1)?1:n); c = nexttiled(c->next), i++, n--) { + resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == g) + ? wy + wh - y - 2 * c->bw : h - 2 * c->bw), resizehints); + if(h != wh) + y = c->y + HEIGHT(c); + } } } @@ -1537,7 +1550,7 @@ if(dc.drawable != 0) XFreePixmap(dpy, dc.drawable); dc.drawable = XCreatePixmap(dpy, root, ww, bh, DefaultDepth(dpy, screen)); - XMoveResizeWindow(dpy, barwin, wx, by, ww, bh); + XMoveResizeWindow(dpy, barwin, mx[0], by, mw[0], bh); } void @@ -1565,11 +1578,45 @@ } else #endif +#ifdef XRANDR + if( True /* xrr is active? */ ) { + int i=0, j=0, k=0, o=0; + XRRScreenResources *screenInfo = XRRGetScreenResources( dpy, root ); + XRRCrtcInfo *crtcInfo = NULL; + XID seenOutputs[MAXMONITORS*16]; // 16 clones should be enough + for(i=0, mons=0; i<screenInfo->ncrtc; i++) { + crtcInfo = XRRGetCrtcInfo( dpy, screenInfo, screenInfo->crtcs[i] ); + + if( crtcInfo->noutput!=0 ) { + Bool dupe=False; + for(j=0; j<crtcInfo->noutput; j++) { + for(k=0; seenOutputs[k]!=crtcInfo->outputs[j] && k<o; k++); + if( k!=o ) + dupe=True; + else + seenOutputs[o++]=crtcInfo->outputs[j]; + } + + if( !dupe ) { + my[mons]=crtcInfo->y + (mons==0 && showbar && topbar ? bh : 0); + mh[mons]=crtcInfo->height - (mons==0 && showbar?bh:0); + mw[mons]=crtcInfo->width; + mx[mons++]=crtcInfo->x; + } + } + } + XRRFreeCrtcInfo(crtcInfo); + XRRFreeScreenResources(screenInfo); + + wx = mx[0]; wy = my[0]; ww = mw[0]; wh = mh[0]; + } else +#endif { - wx = sx; - wy = showbar && topbar ? sy + bh : sy; - ww = sw; - wh = showbar ? sh - bh : sh; + mons=1; + mx[0] = wx = sx; + my[0] = wy = showbar && topbar ? sy + bh : sy; + mw[0] = ww = sw; + mh[0] = wh = showbar ? sh - bh : sh; } /* bar position */