All pastes #894956 Raw Edit

Unbenannt

public text v1 · immutable
·published 2008-02-07 13:31 UTC
rendered paste body
diff --git a/src/window.c b/src/window.c
index b2e72bd..b89cb9b 100644
--- a/src/window.c
+++ b/src/window.c
@@ -35,6 +35,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <assert.h>
+#include <limits.h>
 
 #include <compiz-core.h>
 
@@ -4957,30 +4958,89 @@ freeWindowIcons (CompWindow *w)
     w->nIcon = 0;
 }
 
+static int
+rectangleOverlapArea (BOX *rect1,
+		      BOX *rect2)
+{
+    int left, right, top, bottom;
+
+    /* extents of overlapping rectangle */
+    left = MAX (rect1->x1, rect2->x1);
+    right = MIN (rect1->x2, rect2->x2);
+    top = MAX (rect1->y1, rect2->y1);
+    bottom = MIN (rect1->y2, rect2->y2);
+
+    if (left > right || top > bottom)
+    {
+	/* no overlap */
+	return 0;
+    }
+
+    return (right - left) * (bottom - top);
+}
+
 int
 outputDeviceForWindow (CompWindow *w)
 {
-    int output = w->screen->currentOutputDev;
-    int	width = w->serverWidth + w->serverBorderWidth * 2;
-    int	height = w->serverHeight + w->serverBorderWidth * 2;
-    int x1, y1, x2, y2;
+    int        *overlapAreas;
+    int        i, highest, seen, highestScore;
+    BOX        windowRect;
+    CompScreen *s = w->screen;
 
-    x1 = w->screen->outputDev[output].region.extents.x1;
-    y1 = w->screen->outputDev[output].region.extents.y1;
-    x2 = w->screen->outputDev[output].region.extents.x2;
-    y2 = w->screen->outputDev[output].region.extents.y2;
+    if (s->nOutputDev == 1)
+	return 0;
 
-    if (x1 > w->serverX + width  ||
-	y1 > w->serverY + height ||
-	x2 < w->serverX		 ||
-	y2 < w->serverY)
+    overlapAreas = malloc (s->nOutputDev * sizeof (int));
+    if (!overlapAreas)
+	return 0;
+
+    windowRect.x1 = w->serverX;
+    windowRect.y1 = w->serverY;
+    windowRect.x2 = w->serverX + w->serverWidth;
+    windowRect.y2 = w->serverY + w->serverHeight;
+
+    /* get amount of overlap on all output devices */
+    for (i = 0; i < s->nOutputDev; i++)
+	overlapAreas[i] = rectangleOverlapArea (&s->outputDev[i].region.extents,
+						&windowRect);
+
+    /* find head with largest overlap */
+    for (i = 0, highest = 0, highestScore = 0; i < s->nOutputDev; i++)
+	if (overlapAreas[i] > highestScore)
+	{
+	    highest = i;
+	    highestScore = overlapAreas[i];
+	}
+
+    /* look if the highest score is unique */
+    for (i = 0, seen = 0; i < s->nOutputDev; i++)
+	if (overlapAreas[i] == highestScore)
+	    seen++;
+
+    if (seen > 1)
     {
-	output = outputDeviceForPoint (w->screen,
-				       w->serverX + width  / 2,
-				       w->serverY + height / 2);
+	/* it's not unique, so find the head which is more overlapped by
+	   the window, which in turns means finding the smallest of the
+	   given heads */
+	unsigned int currentSize, smallestHead = UINT_MAX;
+
+	for (i = 0, highest = 0; i < s->nOutputDev; i++)
+	    if (overlapAreas[i] == highestScore)
+	    {
+		BOX *box = &s->outputDev[i].region.extents;
+
+		currentSize = (box->x2 - box->x1) * (box->y2 - box->y1);
+		if (currentSize < smallestHead)
+		{
+		    highest = i;
+		    smallestHead = currentSize;
+		}
+	    }
     }
+    
+    free (overlapAreas);
 
-    return output;
+    return highest;
 }
 
 Bool