bug 824386 - (win-hidpi) nsScreenWin needs to account for logical dpi (resolution scale factor). r=jimm
authorJonathan Kew <jkew@mozilla.com>
Tue, 19 Mar 2013 17:24:25 +0000
changeset 125453 d37c97ba174f73b552831396b5a08c3c8edf0470
parent 125452 008214fd37cff87288c61ef4b23b4ce240cf9cb6
child 125454 b55cc3437395e324551dbfba320e3a3d29966328
push id24459
push useremorley@mozilla.com
push dateWed, 20 Mar 2013 11:46:36 +0000
treeherdermozilla-central@1d6fe70c79c5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs824386
milestone22.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 824386 - (win-hidpi) nsScreenWin needs to account for logical dpi (resolution scale factor). r=jimm
widget/windows/nsScreenWin.cpp
widget/windows/nsScreenWin.h
widget/xpwidgets/nsBaseWidget.cpp
--- a/widget/windows/nsScreenWin.cpp
+++ b/widget/windows/nsScreenWin.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsScreenWin.h"
+#include "nsCoord.h"
 
 
 nsScreenWin :: nsScreenWin ( HMONITOR inScreen )
   : mScreen(inScreen)
 {
 #ifdef DEBUG
   HDC hDCScreen = ::GetDC(nullptr);
   NS_ASSERTION(hDCScreen,"GetDC Failure");
@@ -82,16 +83,53 @@ nsScreenWin :: GetAvailRect(int32_t *out
     *outWidth = workArea.right - workArea.left;
     *outHeight = workArea.bottom - workArea.top;
   }
 
   return NS_OK;
   
 } // GetAvailRect
 
+NS_IMETHODIMP
+nsScreenWin::GetRectDisplayPix(int32_t *outLeft,  int32_t *outTop,
+                               int32_t *outWidth, int32_t *outHeight)
+{
+  int32_t left, top, width, height;
+  nsresult rv = GetRect(&left, &top, &width, &height);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  HDC dc = ::GetDC(nullptr);
+  double scaleFactor = 96.0 / GetDeviceCaps(dc, LOGPIXELSY);
+  ::ReleaseDC(nullptr, dc);
+  *outLeft = NSToIntRound(left * scaleFactor);
+  *outTop = NSToIntRound(top * scaleFactor);
+  *outWidth = NSToIntRound(width * scaleFactor);
+  *outHeight = NSToIntRound(height * scaleFactor);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsScreenWin::GetAvailRectDisplayPix(int32_t *outLeft,  int32_t *outTop,
+                                    int32_t *outWidth, int32_t *outHeight)
+{
+  int32_t left, top, width, height;
+  nsresult rv = GetAvailRect(&left, &top, &width, &height);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  HDC dc = ::GetDC(nullptr);
+  double scaleFactor = 96.0 / GetDeviceCaps(dc, LOGPIXELSY);
+  ::ReleaseDC(nullptr, dc);
+  *outLeft = NSToIntRound(left * scaleFactor);
+  *outTop = NSToIntRound(top * scaleFactor);
+  *outWidth = NSToIntRound(width * scaleFactor);
+  *outHeight = NSToIntRound(height * scaleFactor);
+  return NS_OK;
+}
 
 
 NS_IMETHODIMP 
 nsScreenWin :: GetPixelDepth(int32_t *aPixelDepth)
 {
   //XXX not sure how to get this info for multiple monitors, this might be ok...
   HDC hDCScreen = ::GetDC(nullptr);
   NS_ASSERTION(hDCScreen,"GetDC Failure");
--- a/widget/windows/nsScreenWin.h
+++ b/widget/windows/nsScreenWin.h
@@ -12,18 +12,27 @@
 //------------------------------------------------------------------------
 
 class nsScreenWin : public nsBaseScreen
 {
 public:
   nsScreenWin ( HMONITOR inScreen );
   ~nsScreenWin();
 
+  // These methods return the size in device (physical) pixels
   NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
   NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
+
+  // And these methods get the screen size in 'display pixels' (AKA 'logical pixels')
+  // that are dependent on the logical DPI setting in windows
+  NS_IMETHOD GetRectDisplayPix(int32_t *outLeft,  int32_t *outTop,
+                               int32_t *outWidth, int32_t *outHeight);
+  NS_IMETHOD GetAvailRectDisplayPix(int32_t *outLeft,  int32_t *outTop,
+                                    int32_t *outWidth, int32_t *outHeight);
+
   NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth);
   NS_IMETHOD GetColorDepth(int32_t* aColorDepth);
 
 private:
 
   HMONITOR mScreen;
 };
 
--- a/widget/xpwidgets/nsBaseWidget.cpp
+++ b/widget/xpwidgets/nsBaseWidget.cpp
@@ -696,33 +696,37 @@ NS_IMETHODIMP nsBaseWidget::HideWindowCh
 NS_IMETHODIMP nsBaseWidget::MakeFullScreen(bool aFullScreen)
 {
   HideWindowChrome(aFullScreen);
 
   if (aFullScreen) {
     if (!mOriginalBounds)
       mOriginalBounds = new nsIntRect();
     GetScreenBounds(*mOriginalBounds);
+    // convert dev pix to display pix for window manipulation 
+    double scale = GetDefaultScale();
+    mOriginalBounds->x = NSToIntRound(mOriginalBounds->x / scale);
+    mOriginalBounds->y = NSToIntRound(mOriginalBounds->y / scale);
+    mOriginalBounds->width = NSToIntRound(mOriginalBounds->width / scale);
+    mOriginalBounds->height = NSToIntRound(mOriginalBounds->height / scale);
 
     // Move to top-left corner of screen and size to the screen dimensions
     nsCOMPtr<nsIScreenManager> screenManager;
     screenManager = do_GetService("@mozilla.org/gfx/screenmanager;1");
     NS_ASSERTION(screenManager, "Unable to grab screenManager.");
     if (screenManager) {
       nsCOMPtr<nsIScreen> screen;
-      // convert dev pix to display/CSS pix for ScreenForRect
-      double scale = GetDefaultScale();
-      screenManager->ScreenForRect(mOriginalBounds->x / scale,
-                                   mOriginalBounds->y / scale,
-                                   mOriginalBounds->width / scale,
-                                   mOriginalBounds->height / scale,
+      screenManager->ScreenForRect(mOriginalBounds->x,
+                                   mOriginalBounds->y,
+                                   mOriginalBounds->width,
+                                   mOriginalBounds->height,
                                    getter_AddRefs(screen));
       if (screen) {
         int32_t left, top, width, height;
-        if (NS_SUCCEEDED(screen->GetRect(&left, &top, &width, &height))) {
+        if (NS_SUCCEEDED(screen->GetRectDisplayPix(&left, &top, &width, &height))) {
           Resize(left, top, width, height, true);
         }
       }
     }
 
   } else if (mOriginalBounds) {
     Resize(mOriginalBounds->x, mOriginalBounds->y, mOriginalBounds->width,
            mOriginalBounds->height, true);