Re: [compiz] Patch to wobbly snap for outputs

2006-12-18 Thread David Reveman
On Sat, 2006-12-16 at 10:36 -0700, Mike Cook wrote:
 On Tue, Dec 13, 2006 at 11:00 AM, Mike Cook wrote: 
  Whoa!  There are definitely some issues to address here...  Kicker actually
  does set the struts right on those inner edges, which really throws things
  off in compiz.  I'll see if I can't put together a couple patches to try to 
  do a
  better job of handling the struts when they're set, and hacking around the
  fact that gnome-panel doesn't set them (currently).
 
 Alright, this patch should handle inner struts when they're properly set.  I
 toyed with hacking around the fact that gnome-panel doesn't set the strut
 size properly, but the window geometry doesn't seem reliable at the time
 the struts are set, so we'll just have to get that fixed in gnome-panel (which
 would then require some fixes in metacity to handle it, I expect).  Kicker
 (and probably others) does seem to set them and so this should handle it.

Yes, I would probably not have accepted some ugly hack that used window
geometry to work around gnome-panel not setting struts properly anyhow.

-   if (y1  pBox-y2  y2  pBox-y1)
+   /* consider strut if start/end overlaps box, size ends in box,
+  and edge is outside box or both edge  size in same output
+  (in order to handle struts across multiple outputs) */
+   if (y1  pBox-y2  y2  pBox-y1  x2  pBox-x2 
+   (x1  pBox-x1 ||
+   outputDeviceForPoint(w-screen, x1, y1) ==
+   outputDeviceForPoint(w-screen, x2-1, y2-1)))

The x2  pBox-x2  check makes a lost of sense. However I fail to see
why this:

+   (x1  pBox-x1 ||
+   outputDeviceForPoint(w-screen, x1, y1) ==
+   outputDeviceForPoint(w-screen, x2-1, y2-1))

check is necessary. We already know that x2  pBox-x2 so the only
struts that are rejected from this check is those that are partially
outside the box vertically and why we would want to reject those?

This is an obvious fix and it's in head now.

@@ -3415,7 +3429,7 @@ outputDeviceForPoint (CompScreen *s,
x2 = s-outputDev[i].region.extents.x2;
y2 = s-outputDev[i].region.extents.y2;
 
-   if (x1  x  x2 = x  y1  y  y2 = y)
+   if (x1 = x  x2  x  y1 = y  y2  y)
return i;
 }

Thanks,

-David

___
compiz mailing list
compiz@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/compiz


Re: [compiz] Patch to wobbly snap for outputs

2006-12-18 Thread Mike Cook
On Mon, Dec 18, 2006 at  9:50 AM, David Reveman wrote: 
 -if (y1  pBox- y2  y2  pBox- y1)
 +   /* consider strut if start/end overlaps box, size ends in box,
 +  and edge is outside box or both edge  size in same output
 +  (in order to handle struts across multiple outputs) */
 +   if (y1  pBox- y2  y2  pBox- y1  x2  pBox- x2 
 +   (x1  pBox- x1 ||
 +   outputDeviceForPoint(w- screen, x1, y1) ==
 +   outputDeviceForPoint(w- screen, x2- 1, y2- 1)))
 
 The x2  pBox- x2  check makes a lost of sense. However I fail to see
 why this:
 
 +   (x1  pBox- x1 ||
 +   outputDeviceForPoint(w- screen, x1, y1) ==
 +   outputDeviceForPoint(w- screen, x2- 1, y2- 1))
 
 check is necessary. We already know that x2  pBox- x2 so the only
 struts that are rejected from this check is those that are partially
 outside the box vertically and why we would want to reject those?

Since we know the strut ends within the box, that secondary check is
meant to handle the two basic cases of a smaller box (such as for an
output workarea) to allow a strut which starts outside it, and for a larger
box (such as for the screen workarea) to ignore any internal struts which
cross over multiple outputs.

I do see I forgot to set the values in the output point check to within the
box, so it would be better to constrain the non-interesting coords to be
within box coords something like:
 +   (x1  pBox- x1 ||
 +   outputDeviceForPoint(w- screen, x1, pBox-y1) ==
 +   outputDeviceForPoint(w- screen, x2- 1, pBox-y1))

I've attached an updated patch (not including the fix I think you already
have) that should take care of that.  Do you see anything I'm missing?

...MC
--- src/screen.c
+++ src/screen.c
@@ -2680,7 +2680,13 @@ computeWorkareaForBox (CompScreen *s,
x2 = x1 + w-struts-left.width;
y2 = y1 + w-struts-left.height;
 
-   if (y1  pBox-y2  y2  pBox-y1)
+   /* consider strut if start/end overlaps box, size ends in box,
+  and edge is outside box or both edge  size in same output
+  (in order to handle struts across multiple outputs) */
+   if (y1  pBox-y2  y2  pBox-y1  x2  pBox-x2 
+   (x1  pBox-x1 ||
+   outputDeviceForPoint(w-screen, x1, pBox-y1) ==
+   outputDeviceForPoint(w-screen, x2-1, pBox-y1)))
{
if (x2  strutX1)
strutX1 = x2;
@@ -2691,7 +2697,10 @@ computeWorkareaForBox (CompScreen *s,
x2 = x1 + w-struts-right.width;
y2 = y1 + w-struts-right.height;
 
-   if (y1  pBox-y2  y2  pBox-y1)
+   if (y1  pBox-y2  y2  pBox-y1  x1  pBox-x1 
+   (x2  pBox-x2 ||
+   outputDeviceForPoint(w-screen, x1, pBox-y1) ==
+   outputDeviceForPoint(w-screen, x2-1, pBox-y1)))
{
if (x1  strutX2)
strutX2 = x1;
@@ -2702,7 +2710,10 @@ computeWorkareaForBox (CompScreen *s,
x2 = x1 + w-struts-top.width;
y2 = y1 + w-struts-top.height;

-   if (x1  pBox-x2  x2  pBox-x1)
+   if (x1  pBox-x2  x2  pBox-x1  y2  pBox-y2 
+   (y1  pBox-y1 ||
+   outputDeviceForPoint(w-screen, pBox-x1, y1) ==
+   outputDeviceForPoint(w-screen, pBox-x1, y2-1)))
{
if (y2  strutY1)
strutY1 = y2;
@@ -2713,7 +2724,10 @@ computeWorkareaForBox (CompScreen *s,
x2 = x1 + w-struts-bottom.width;
y2 = y1 + w-struts-bottom.height;
 
-   if (x1  pBox-x2  x2  pBox-x1)
+   if (x1  pBox-x2  x2  pBox-x1  y1  pBox-y1 
+   (y2  pBox-y2 ||
+   outputDeviceForPoint(w-screen, pBox-x1, y1) ==
+   outputDeviceForPoint(w-screen, pBox-x1, y2-1)))
{
if (y1  strutY2)
strutY2 = y1;
___
compiz mailing list
compiz@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/compiz


Re: [compiz] Patch to wobbly snap for outputs

2006-12-18 Thread David Reveman
On Mon, 2006-12-18 at 11:03 -0700, Mike Cook wrote:
 On Mon, Dec 18, 2006 at  9:50 AM, David Reveman wrote: 
  -if (y1  pBox- y2  y2  pBox- y1)
  +   /* consider strut if start/end overlaps box, size ends in box,
  +  and edge is outside box or both edge  size in same output
  +  (in order to handle struts across multiple outputs) */
  +   if (y1  pBox- y2  y2  pBox- y1  x2  pBox- x2 
  +   (x1  pBox- x1 ||
  +   outputDeviceForPoint(w- screen, x1, y1) ==
  +   outputDeviceForPoint(w- screen, x2- 1, y2- 1)))
  
  The x2  pBox- x2  check makes a lost of sense. However I fail to see
  why this:
  
  +   (x1  pBox- x1 ||
  +   outputDeviceForPoint(w- screen, x1, y1) ==
  +   outputDeviceForPoint(w- screen, x2- 1, y2- 1))
  
  check is necessary. We already know that x2  pBox- x2 so the only
  struts that are rejected from this check is those that are partially
  outside the box vertically and why we would want to reject those?
 
 Since we know the strut ends within the box, that secondary check is
 meant to handle the two basic cases of a smaller box (such as for an
 output workarea) to allow a strut which starts outside it, and for a larger
 box (such as for the screen workarea) to ignore any internal struts which
 cross over multiple outputs.

Sorry, I still don't get it. What struts are a vertical kicker panel
setting?

+-+-+
|_|_|
|   | | |   |
|   | | |   |
|   |_|_|   |
| | |
+-+-+

If the screen looks like this and the thing in the middle is a panel
covering both outputs I assume that the struts are set to either

leftX1 = screenW / 2 - panelW / 2;
leftX2 = screenW / 2 + panelW / 2;

or

rightX1 = screenW / 2 - panelW / 2;
rightX2 = screenW / 2 + panelW / 2;

or that both those set are set.

if (y1  pBox-y2  y2  pBox-y1  x2  pBox-x2)

should set the left edge properly for both outputs in all those cases.

What am I missing?

-David

___
compiz mailing list
compiz@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/compiz


Re: [compiz] Patch to wobbly snap for outputs

2006-12-18 Thread Mike Cook
On Mon, Dec 18, 2006 at 18:18, David Reveman wrote:
 I have now pushed out some code to handle this properly. Here's what I
 think is the correct way to include each strut:
 
 (a window strut edge is valid if it's within the destination box)
 
 1. left_strut = 0.
 2. right_strut = box_max_x.
 3. update left_strut if left window strut edge is valid.
 4. update right_strut if right window strut edge is valid.
 5. horizontal struts are only valid if they are not overlapping,
 left_strut must be less than right_strut. if they are not valid go to 6.
 5.1. update max_left_strut if left_strut is greater.
 5.2. update min_right_strut if right_strut is less.
 
 6. top_strut = 0.
 7. bottom_strut = box_max_y.
 8. update top_strut if top window strut edge is valid.
 9. update bottom_strut if bottom window strut edge is valid.
 10. vertical struts are only valid if they are not overlapping,
 top_strut must be less than bottom_strut. if they are not valid go to
 11.
 10.1. update max_top_strut if top_strut is greater.
 10.2. update min_bottom_strut if bottom_strut is less.
 
 11. done.
 
 
 This will allow floating struts while still handling overlapping struts
 like what kicker sets properly.
 
 Have a look at the code I put in screen.c, it's simple and hopefully
 very easy to understand for anyone who wants to know what's going on
 there.
 
 -David

From what I've seen a window's struts are only set for a single side,
depending on which edge it's on (regardless if it's the screen edge or an
output edge).  So, a single window wouldn't overlap itself, as they would
not set both left and right struts on the same window, not currently.
You could have two separate panels that overlap in that way, which was
what I was trying to describe with the diagrams a few replies back.
Sorry if I didn't explain what I was seeing clearly...

So, I think this latest update lends itself to a better solution for floating
windows (if they set struts for more than one side), but I don't think it
will handle the current case of a single kicker panel on the center edge
between the two outputs (i.e., the screen workarea gets shifted entirely
to the non-strut side of the panel).

I'll test some more once I get back to my multi-monitor machine, but
that's what I'm thinking so far...  Cheers!

...MC
___
compiz mailing list
compiz@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/compiz


Re: [compiz] Patch to wobbly snap for outputs

2006-12-12 Thread David Reveman
On Mon, 2006-12-11 at 22:48 -0700, Mike Cook wrote: 
 On Fri, 2006-12-11 at 21:32 -0700, David Reveman wrote:
  After looking at this I found the correct solution to be to just snap to
  window struts instead of any workarea. I've pushed out changes that
  should take care of this. I don't have access to a multi-head setup
  right now so I can't verify that it works OK. Please give it a try.
 
 Hm, somebody will have to donate a couple extra monitors...  ;)  After a quick
 first test on a single head machine I think there's a typo, as it seems to be
 ignoring the struts and just snapping to screen edges for me.  Also, I'm not
 sure if the struts are the best option-- more on that below...

:) Don't worry, I have a multi-head setup at my office. I'm just not
there right now.

You're right, a typo caused it to not work at all. It should be fixed
now. While looking at this I also found an issue that caused snapping to
normal windows to be a bit incorrect, it should be correct now.

 
  I've included a few more window types in snapping. However, including
  dock windows is probably not a good idea. Sometime windows with dock
  type and below state are used for windows that shouldn't have any
  decorations and stick to the desktop. We don't want to snap to those.
 
 Ah, yeah, I wasn't sure if dock type might be used like that.
 
   I personally think we should include these inner struts when 
   calculating the
   workarea for each output (which also helps window maximizing), and only
   ignore them in the screen workarea case (for the _NET_WORKAREA hint).
  
  What do you mean by inner struts? Each workarea rectangle should be
  the maximum rectangle that doesn't intersect any struts. If that's
  currently not the case, it should be fixed.
 
 Sorry, by inner struts I was trying to refer to those on the inside edge 
 between
 two outputs.  Say I have 2 monitors, and I have a vertical dock covering the
 right edge of the left monitor, or the left edge of the right monitor-- 
 basically
 down the middle of the screen.  Those type seem to be currently ignored.

OK, lets find out why they are ignored then. What struts are those
vertical dock windows using? If those windows are not just setting any
strut hints, then it's not much we can do.

 
  If the workarea isn't good enough for a plugin it should instead look at
  the strut hints for each window like the wobbly plugin is now doing. We
  can add a region to the output struct that is the output area minus all
  window struts if that turns out useful for plugins.
 
 I can't think of any time the output's workarea wouldn't work, as however 
 that is
 calculated we should probably use it to be consistent.  Here are the issues I
 ran into as I was trying to work on this:
 1- Struts that are on those inner edges like I described before are 
 currently
ignored in the output workarea calculation.  So, for instance, a window 
 will
maximize to the output edge under that dock.

This shouldn't happen. I'll make sure it gets fixed once I know why it
currently doesn't work.

 2- A dock may cover the top or bottom of only one output.  That strut should
not be considered when snapping or maximizing on a different output.

Why this behavior?

 3- In the case of the total screen's workarea we should ignore those in #1 and
clip to those in #2 to have the largest total area (at least until the 
 workarea
hint can handle multiple regions, or whatever other solution the spec comes
up with).

The screen workarea could be the current outputs workarea and be updated
as the current output changes. This might confuse desktop windows,
though.

 4- Also, say you have two or three panels across the top of an output.  You
wouldn't want to snap to each one separately, but just to the lowest one,
which should be what the output workarea calculation would give you.

I would want to snap to each one separately and have windows placed
smarter then just in the workarea rectangle. Windows should still be
maximized to the workarea rectangle, of course.

 
 5- And finally, in the patch I was intending that a window also snaps to the
edges of each output, which is the current behavior that I get with 
 metacity,
I believe.

I agree, snapping to output edges makes sense. I can easily make the
current wobbly code do that.

 
 So, in the end, that's why I was thinking that each output workarea would be
 the best region to snap to, if they include calculations for all the struts 
 at any
 edge within that output.  That then also covers snapping to the output edges
 (strut or not).  Sorry for the long response... ;)
 

There's clearly some more work to be done here and I appreciate your
help with getting this right.

Thanks,

-David

___
compiz mailing list
compiz@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/compiz


Re: [compiz] Patch to wobbly snap for outputs

2006-12-11 Thread Mike Cook
On Fri, 2006-12-11 at 21:32 -0700, David Reveman wrote:
 After looking at this I found the correct solution to be to just snap to
 window struts instead of any workarea. I've pushed out changes that
 should take care of this. I don't have access to a multi-head setup
 right now so I can't verify that it works OK. Please give it a try.

Hm, somebody will have to donate a couple extra monitors...  ;)  After a quick
first test on a single head machine I think there's a typo, as it seems to be
ignoring the struts and just snapping to screen edges for me.  Also, I'm not
sure if the struts are the best option-- more on that below...

 I've included a few more window types in snapping. However, including
 dock windows is probably not a good idea. Sometime windows with dock
 type and below state are used for windows that shouldn't have any
 decorations and stick to the desktop. We don't want to snap to those.

Ah, yeah, I wasn't sure if dock type might be used like that.

  I personally think we should include these inner struts when calculating 
  the
  workarea for each output (which also helps window maximizing), and only
  ignore them in the screen workarea case (for the _NET_WORKAREA hint).
 
 What do you mean by inner struts? Each workarea rectangle should be
 the maximum rectangle that doesn't intersect any struts. If that's
 currently not the case, it should be fixed.

Sorry, by inner struts I was trying to refer to those on the inside edge 
between
two outputs.  Say I have 2 monitors, and I have a vertical dock covering the
right edge of the left monitor, or the left edge of the right monitor-- 
basically
down the middle of the screen.  Those type seem to be currently ignored.

 If the workarea isn't good enough for a plugin it should instead look at
 the strut hints for each window like the wobbly plugin is now doing. We
 can add a region to the output struct that is the output area minus all
 window struts if that turns out useful for plugins.

I can't think of any time the output's workarea wouldn't work, as however that 
is
calculated we should probably use it to be consistent.  Here are the issues I
ran into as I was trying to work on this:
1- Struts that are on those inner edges like I described before are currently
   ignored in the output workarea calculation.  So, for instance, a window will
   maximize to the output edge under that dock.
2- A dock may cover the top or bottom of only one output.  That strut should
   not be considered when snapping or maximizing on a different output.
3- In the case of the total screen's workarea we should ignore those in #1 and
   clip to those in #2 to have the largest total area (at least until the 
workarea
   hint can handle multiple regions, or whatever other solution the spec comes
   up with).
4- Also, say you have two or three panels across the top of an output.  You
   wouldn't want to snap to each one separately, but just to the lowest one,
   which should be what the output workarea calculation would give you.
5- And finally, in the patch I was intending that a window also snaps to the
   edges of each output, which is the current behavior that I get with metacity,
   I believe.

So, in the end, that's why I was thinking that each output workarea would be
the best region to snap to, if they include calculations for all the struts at 
any
edge within that output.  That then also covers snapping to the output edges
(strut or not).  Sorry for the long response... ;)

...MC
___
compiz mailing list
compiz@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/compiz


[compiz] Patch to wobbly snap for outputs

2006-12-08 Thread Mike Cook
Here's a patch to wobbly.c to handle edge snapping with multiple outputs...

Also, I tweaked the window edge snapping to include dock window types, to
support the case where dock windows may be on the inner edges of multiple
monitors (and thus currently ignored as struts in the output workarea setup).

I personally think we should include these inner struts when calculating the
workarea for each output (which also helps window maximizing), and only
ignore them in the screen workarea case (for the _NET_WORKAREA hint).

Any reason that wouldn't make sense?

...MC
--- plugins/wobbly.c
+++ plugins/wobbly.c
@@ -510,6 +510,9 @@ findNextWestEdge (CompWindow *w,
 int e, end;
 int x;
 
+intoutput;
+XRectangle workArea;
+
 start = -65535.0f;
 end   =  65535.0f;
 
@@ -518,15 +521,20 @@ findNextWestEdge (CompWindow *w,
 
 x = object-position.x + w-output.left - w-input.left;
 
-if (x = w-screen-workArea.x)
+output = outputDeviceForPoint (w-screen, x, object-position.y);
+workArea = w-screen-outputDev[output].workArea;
+
+if (x = workArea.x)
 {
CompWindow *p;
 
-   v1 = w-screen-workArea.x;
+   v1 = workArea.x;
 
for (p = w-screen-windows; p; p = p-next)
{
-   if (p-invisible || w == p || p-type != CompWindowTypeNormalMask)
+   if (p-invisible || w == p ||
+   (p-type != CompWindowTypeNormalMask 
+p-type != CompWindowTypeDockMask))
continue;
 
s = p-attrib.y - p-output.top;
@@ -566,7 +574,7 @@ findNextWestEdge (CompWindow *w,
 }
 else
 {
-   v2 = w-screen-workArea.x;
+   v2 = workArea.x;
 }
 
 v1 = v1 - w-output.left + w-input.left;
@@ -594,6 +602,9 @@ findNextEastEdge (CompWindow *w,
 int e, end;
 int x;
 
+intoutput;
+XRectangle workArea; 
+
 start = -65535.0f;
 end   =  65535.0f;
 
@@ -602,15 +613,20 @@ findNextEastEdge (CompWindow *w,
 
 x = object-position.x - w-output.right + w-input.right;
 
-if (x = w-screen-workArea.x + w-screen-workArea.width)
+output = outputDeviceForPoint (w-screen, x, object-position.y);
+workArea = w-screen-outputDev[output].workArea;
+
+if (x = workArea.x + workArea.width)
 {
CompWindow *p;
 
-   v1 = w-screen-workArea.x + w-screen-workArea.width;
+   v1 = workArea.x + workArea.width;
 
for (p = w-screen-windows; p; p = p-next)
{
-   if (p-invisible || w == p || p-type != CompWindowTypeNormalMask)
+   if (p-invisible || w == p ||
+   (p-type != CompWindowTypeNormalMask 
+p-type != CompWindowTypeDockMask))
continue;
 
s = p-attrib.y - p-output.top;
@@ -650,7 +666,7 @@ findNextEastEdge (CompWindow *w,
 }
 else
 {
-   v2 = w-screen-workArea.x + w-screen-workArea.width;
+   v2 = workArea.x + workArea.width;
 }
 
 v1 = v1 + w-output.right - w-input.right;
@@ -678,6 +694,9 @@ findNextNorthEdge (CompWindow *w,
 int e, end;
 int y;
 
+intoutput;
+XRectangle workArea;
+
 start = -65535.0f;
 end   =  65535.0f;
 
@@ -686,15 +705,20 @@ findNextNorthEdge (CompWindow *w,
 
 y = object-position.y + w-output.top - w-input.top;
 
-if (y = w-screen-workArea.y)
+output = outputDeviceForPoint (w-screen, object-position.x, y);
+workArea = w-screen-outputDev[output].workArea;
+
+if (y = workArea.y)
 {
CompWindow *p;
 
-   v1 = w-screen-workArea.y;
+   v1 = workArea.y;
 
for (p = w-screen-windows; p; p = p-next)
{
-   if (p-invisible || w == p || p-type != CompWindowTypeNormalMask)
+   if (p-invisible || w == p ||
+   (p-type != CompWindowTypeNormalMask 
+p-type != CompWindowTypeDockMask))
continue;
 
s = p-attrib.x - p-output.left;
@@ -734,7 +758,7 @@ findNextNorthEdge (CompWindow *w,
 }
 else
 {
-   v2 = w-screen-workArea.y;
+   v2 = workArea.y;
 }
 
 v1 = v1 - w-output.top + w-input.top;
@@ -762,6 +786,9 @@ findNextSouthEdge (CompWindow *w,
 int e, end;
 int y;
 
+intoutput;
+XRectangle workArea;
+
 start = -65535.0f;
 end   =  65535.0f;
 
@@ -770,15 +797,20 @@ findNextSouthEdge (CompWindow *w,
 
 y = object-position.y - w-output.bottom + w-input.bottom;
 
-if (y = w-screen-workArea.y + w-screen-workArea.height)
+output = outputDeviceForPoint (w-screen, object-position.x, y);
+workArea = w-screen-outputDev[output].workArea;
+
+if (y = workArea.y + workArea.height)
 {
CompWindow *p;
 
-   v1 = w-screen-workArea.y + w-screen-workArea.height;
+   v1 = workArea.y + workArea.height;
 
for (p = w-screen-windows; p; p = p-next)
{
-   if (p-invisible || w == p || p-type != CompWindowTypeNormalMask)
+   if (p-invisible || w == p ||
+