Bug 1254019 - Don't attempt to resize a maximized window on DPI change; and when handling a DPI change, constrain the resized window to the screen bounds. r=emk, a=ritu
authorJonathan Kew <jkew@mozilla.com>
Tue, 15 Mar 2016 19:52:46 +0000
changeset 323469 112cb0b69503ef77205124328c00fcc44a2297f3
parent 323468 8255638a3ede9da7e0cc5afb85a062330a25a677
child 323470 2fd77fb72e36e32844715012c6bae54b0e9d34aa
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemk, ritu
bugs1254019
milestone47.0a2
Bug 1254019 - Don't attempt to resize a maximized window on DPI change; and when handling a DPI change, constrain the resized window to the screen bounds. r=emk, a=ritu
widget/windows/nsWindow.cpp
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -6870,33 +6870,49 @@ nsWindow::OnDPIChanged(int32_t x, int32_
   }
   if (DefaultScaleOverride() > 0.0) {
     return;
   }
   double oldScale = mDefaultScale;
   mDefaultScale = -1.0; // force recomputation of scale factor
   double newScale = GetDefaultScaleInternal();
 
-  if (mResizeState != RESIZING) {
+  if (mResizeState != RESIZING && mSizeMode == nsSizeMode_Normal) {
     // We want to try and maintain the size of the client area, rather than
     // the overall size of the window including non-client area, so we prefer
     // to calculate the new size instead of using Windows' suggested values.
     if (oldScale > 0.0) {
       double ratio = newScale / oldScale;
       LayoutDeviceIntRect cr, sr;
       GetClientBounds(cr);
       GetScreenBounds(sr);
       int32_t w = sr.width - cr.width + NSToIntRound(cr.width * ratio);
       int32_t h = sr.height - cr.height + NSToIntRound(cr.height * ratio);
       // Adjust x and y to preserve the center point of the suggested rect.
       x -= (w - width) / 2;
       y -= (h - height) / 2;
       width = w;
       height = h;
     }
+
+    // Limit the position & size, if it would overflow the destination screen
+    nsCOMPtr<nsIScreenManager> sm = do_GetService(sScreenManagerContractID);
+    if (sm) {
+      nsCOMPtr<nsIScreen> screen;
+      sm->ScreenForRect(x, y, width, height, getter_AddRefs(screen));
+      if (screen) {
+        int32_t availLeft, availTop, availWidth, availHeight;
+        screen->GetAvailRect(&availLeft, &availTop, &availWidth, &availHeight);
+        x = std::max(x, availLeft);
+        y = std::max(y, availTop);
+        width = std::min(width, availWidth);
+        height = std::min(height, availHeight);
+      }
+    }
+
     Resize(x, y, width, height, true);
   }
   ChangedDPI();
 }
 
 /**************************************************************
  **************************************************************
  **