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

Reply via email to