[compiz] bug in today's git snapshot with maximizing windows

Mike Cook mcook at novell.com
Fri Nov 10 12:00:38 PST 2006


On Wed, 2006-11-08 at 15:16 -0700, David Reveman wrote:
> On Wed, 2006- 11- 08 at 14:36 - 0700, Mike Cook wrote:
> > Per David's response to my comment, I'm willing to try hacking up a patch
> > for the workarea- per- output idea.  Then updates in window.c and maybe
> > the place plugin could use that and we'd get more proper placement and
> > window maximizing per output.  However, I've noticed some discussions on
> > the _NET_WORKAREA and multiple heads and it sounds like there needs to
> > be changes eventually to the spec to better handle these multiple output
> > cases.  But in the meantime, I think we can make it work mostly right.  ;)
> 
> Great, I look forward to seeing patches for this. Please keep the
> per- output workarea addition and the updates to window.c and eventually
> updates to some of the plugins in separate patches. I think at least
> place, move and wobbly plugins will need updates but just getting the
> per- output workarea into head will be a good start.
> 
> _NET_WORKAREA is a rectangle but our internal representation in compiz
> will be a set of rectangles. We should try to get the EWMH spec updated
> sometime soon as being able to communicate a non- rectangular workarea to
> apps and toolkits is important for the dynamic multi- head support that
> compiz will be able to do.
> 
> - David

Alright, here's an initial patch which implements a workarea in the CompOutput
structure, and sets it up each call to updateWorkareaForScreen.  I've been
working on some updates to window and plugins to properly use it, but haven't
had time to finish that so wanted to get this much submitted in the meantime...

...MC
-------------- next part --------------
--- include/compiz.h
+++ include/compiz.h
@@ -1389,10 +1389,11 @@ struct _CompIcon {
 };
 
 typedef struct _CompOutput {
-    char   *name;
-    REGION region;
-    int    width;
-    int    height;
+    char       *name;
+    REGION     region;
+    int        width;
+    int        height;
+    XRectangle workArea;
 } CompOutput;
 
 struct _CompScreen {
@@ -1784,6 +1785,10 @@ setDefaultViewport (CompScreen *s);
 void
 outputChangeNotify (CompScreen *s);
 
+void
+updateWorkareaForOutput (CompScreen *s,
+			 int        output,
+			 XRectangle *area);
 
 /* window.c */
 
-------------- next part --------------
--- src/screen.c
+++ src/screen.c
@@ -328,6 +328,11 @@ updateOutputDevices (CompScreen	*s)
 		o[nOutput].region.extents.x2 = x2;
 		o[nOutput].region.extents.y2 = y2;
 
+		o[nOutput].workArea.x      = x1;
+		o[nOutput].workArea.y      = y1;
+		o[nOutput].workArea.width  = x2 - x1;
+		o[nOutput].workArea.height = y2 - y1;
+
 		output = o;
 		nOutput++;
 	    }
@@ -349,6 +354,11 @@ updateOutputDevices (CompScreen	*s)
 	output->region.extents.x2 = s->width;
 	output->region.extents.y2 = s->height;
 
+	output->workArea.x      = 0;
+	output->workArea.y      = 0;
+	output->workArea.width  = s->width;
+	output->workArea.height = s->height;
+
 	nOutput = 1;
     }
 
@@ -2634,54 +2644,49 @@ updatePassiveGrabs (CompScreen *s)
 void
 updateWorkareaForScreen (CompScreen *s)
 {
-    CompWindow *w;
-    int	       leftStrut, rightStrut, topStrut, bottomStrut;
     XRectangle workArea;
+    int        i;
 
-    leftStrut   = 0;
-    rightStrut  = 0;
-    topStrut    = 0;
-    bottomStrut = 0;
-
-    for (w = s->windows; w; w = w->next)
+    for (i = 0; i < s->nOutputDev; i++)
     {
-	if (!w->mapNum)
-	    continue;
-
-	if (w->struts)
-	{
-	    if (w->struts->left.width > leftStrut)
-		leftStrut = w->struts->left.width;
-
-	    if (w->struts->right.width > rightStrut)
-		rightStrut = w->struts->right.width;
-
-	    if (w->struts->top.height > topStrut)
-		topStrut = w->struts->top.height;
-
-	    if (w->struts->bottom.height > bottomStrut)
-		bottomStrut = w->struts->bottom.height;
-	}
+	updateWorkareaForOutput (s, i, &workArea);
+	s->outputDev[i].workArea = workArea;
     }
 
-#define MIN_SANE_AREA 100
-
-    if ((leftStrut + rightStrut) > (s->width - MIN_SANE_AREA))
+    if (s->nOutputDev > 1)
     {
-	leftStrut  = (s->width - MIN_SANE_AREA) / 2;
-	rightStrut = leftStrut;
-    }
+	CompOutput *o;
+	int	   x1, y1, x2, y2;
+ 
+	x1 = 0;
+	y1 = 0;
+	x2 = s->width;
+	y2 = s->height;
 
-    if ((topStrut + bottomStrut) > (s->height - MIN_SANE_AREA))
-    {
-	topStrut    = (s->height - MIN_SANE_AREA) / 2;
-	bottomStrut = topStrut;
-    }
+	for (i = 0; i < s->nOutputDev; i++)
+	{
+	    o = &s->outputDev[i];
 
-    workArea.x      = leftStrut;
-    workArea.y      = topStrut;
-    workArea.width  = s->width  - leftStrut - rightStrut;
-    workArea.height = s->height - topStrut  - bottomStrut;
+	    /* prune only outer edges from screen workarea */
+	    if (o->region.extents.x1 == 0 &&
+		o->workArea.x > x1)
+		    x1 = o->workArea.x;
+	    if (o->region.extents.y1 == 0 &&
+		o->workArea.y > y1)
+		    y1 = o->workArea.y;
+	    if (o->region.extents.x2 == s->width &&
+		o->workArea.x + o->workArea.width  < x2)
+		    x2 = o->workArea.x + o->workArea.width;
+	    if (o->region.extents.y2 == s->height &&
+		o->workArea.y + o->workArea.height < y2)
+		    y2 = o->workArea.y + o->workArea.height;
+	}
+
+	workArea.x	= x1;
+	workArea.y	= y1;
+	workArea.width  = x2 - x1;
+	workArea.height = y2 - y1;
+    }
 
     if (memcmp (&workArea, &s->workArea, sizeof (XRectangle)))
     {
@@ -3444,32 +3449,10 @@ getWorkareaForOutput (CompScreen *s,
 		      int	 output,
 		      XRectangle *area)
 {
-    int x1, y1, x2, y2;
-    int oX1, oY1, oX2, oY2;
-
-    x1 = s->workArea.x;
-    y1 = s->workArea.y;
-    x2 = x1 + s->workArea.width;
-    y2 = y1 + s->workArea.height;
-
-    oX1 = s->outputDev[output].region.extents.x1;
-    oY1 = s->outputDev[output].region.extents.y1;
-    oX2 = s->outputDev[output].region.extents.x2;
-    oY2 = s->outputDev[output].region.extents.y2;
-
-    if (x1 < oX1)
-	x1 = oX1;
-    if (y1 < oY1)
-	y1 = oY1;
-    if (x2 > oX2)
-	x2 = oX2;
-    if (y2 > oY2)
-	y2 = oY2;
-
-    area->x      = x1;
-    area->y      = y1;
-    area->width  = x2 - x1;
-    area->height = y2 - y1;
+    area->x      = s->outputDev[output].workArea.x;
+    area->y      = s->outputDev[output].workArea.y;
+    area->width  = s->outputDev[output].workArea.width;
+    area->height = s->outputDev[output].workArea.height;
 }
 
 void
@@ -3485,3 +3468,65 @@ void
 outputChangeNotify (CompScreen *s)
 {
 }
+
+void
+updateWorkareaForOutput (CompScreen *s,
+			 int	    output,
+			 XRectangle *area)
+{
+    CompWindow *w;
+    CompOutput *o;
+    int	       leftStrut, rightStrut, topStrut, bottomStrut;
+
+    o = &s->outputDev[output];
+    leftStrut   = 0;
+    rightStrut  = 0;
+    topStrut    = 0;
+    bottomStrut = 0;
+
+    for (w = s->windows; w; w = w->next)
+    {
+	if (!w->mapNum)
+	    continue;
+
+	if (w->struts)
+	{
+            if (w->serverX + w->width  <= o->region.extents.x1 ||
+		w->serverY + w->height <= o->region.extents.y1 ||
+		w->serverX >= o->region.extents.x2             ||
+		w->serverY >= o->region.extents.y2)
+		    continue;
+
+	    if (w->struts->left.width > leftStrut)
+		leftStrut = w->struts->left.width;
+
+	    if (w->struts->right.width > rightStrut)
+		rightStrut = w->struts->right.width;
+
+	    if (w->struts->top.height > topStrut)
+		topStrut = w->struts->top.height;
+
+	    if (w->struts->bottom.height > bottomStrut)
+		bottomStrut = w->struts->bottom.height;
+	}
+    }
+
+#define MIN_SANE_AREA 100
+
+    if ((leftStrut + rightStrut) > (o->width - MIN_SANE_AREA))
+    {
+	leftStrut  = (o->width - MIN_SANE_AREA) / 2;
+	rightStrut = leftStrut;
+    }
+
+    if ((topStrut + bottomStrut) > (o->height - MIN_SANE_AREA))
+    {
+	topStrut    = (o->height - MIN_SANE_AREA) / 2;
+	bottomStrut = topStrut;
+    }
+ 
+    area->x      = o->region.extents.x1 + leftStrut;
+    area->y      = o->region.extents.y1 + topStrut;
+    area->width  = o->width  - leftStrut - rightStrut;
+    area->height = o->height - topStrut  - bottomStrut;
+}


More information about the compiz mailing list