[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