Bug 1363055 - Find a nearest screen if no screen overlaps. r=kanru draft
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Wed, 17 May 2017 23:30:05 +0900
changeset 580328 6bb4e59b26652ad92e7fa976a42c5f1c98fa7559
parent 580040 baf05f61bc14fdf45511bc1165ce76daa08c5c0f
child 629248 9c0cee1ece1c948f5621d29e90b7516fbf847e1e
push id59515
push userVYV03354@nifty.ne.jp
push dateThu, 18 May 2017 10:58:47 +0000
reviewerskanru
bugs1363055
milestone55.0a1
Bug 1363055 - Find a nearest screen if no screen overlaps. r=kanru MozReview-Commit-ID: 8BCcVmTC96W
widget/ScreenManager.cpp
--- a/widget/ScreenManager.cpp
+++ b/widget/ScreenManager.cpp
@@ -150,22 +150,62 @@ ScreenManager::ScreenForRect(int32_t aX,
   for (auto& screen : mScreenList) {
     int32_t  x, y, width, height;
     x = y = width = height = 0;
     screen->GetRectDisplayPix(&x, &y, &width, &height);
     // calculate the surface area
     DesktopIntRect screenRect(x, y, width, height);
     screenRect.IntersectRect(screenRect, windowRect);
     uint32_t tempArea = screenRect.width * screenRect.height;
-    if (tempArea >= area) {
+    if (tempArea > area) {
       which = screen.get();
       area = tempArea;
     }
   }
 
+  // If the rect intersects one or more screen,
+  // return the screen that has the largest intersection.
+  if (area > 0) {
+    RefPtr<Screen> ret = which;
+    ret.forget(aOutScreen);
+    return NS_OK;
+  }
+
+  // If the rect does not intersect a screen, find
+  // a screen that is nearest to the rect.
+  uint32_t distance = UINT32_MAX;
+  for (auto& screen : mScreenList) {
+    int32_t  x, y, width, height;
+    x = y = width = height = 0;
+    screen->GetRectDisplayPix(&x, &y, &width, &height);
+
+    uint32_t distanceX = 0;
+    if (aX > (x + width)) {
+      distanceX = aX - (x + width);
+    } else if ((aX + aWidth) < x) {
+      distanceX = x - (aX + aWidth);
+    }
+
+    uint32_t distanceY = 0;
+    if (aY > (y + height)) {
+      distanceY = aY - (y + height);
+    } else if ((aY + aHeight) < y) {
+      distanceY = y - (aY + aHeight);
+    }
+
+    uint32_t tempDistance = distanceX * distanceX + distanceY * distanceY;
+    if (tempDistance < distance) {
+      which = screen.get();
+      distance = tempDistance;
+      if (distance == 0) {
+        break;
+      }
+    }
+  }
+
   RefPtr<Screen> ret = which;
   ret.forget(aOutScreen);
   return NS_OK;
 }
 
 // The screen with the menubar/taskbar. This shouldn't be needed very
 // often.
 //