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 */