rendered paste bodydiff --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