Backout bug 890156 from aurora-46; waiting for the next train due to not-yet-resolved regressions. a=backout
authorJonathan Kew <jkew@mozilla.com>
Fri, 12 Feb 2016 09:19:13 +0000
changeset 316845 52c479d20d2b3757d3fe56e3b2d82820b0da0c8a
parent 316844 7b96f22c3028784420b69beb7eb79da48664c7d1
child 316846 ecd280b57abb5ea57a2a99a0dac90de5657240ad
push id5703
push userraliiev@mozilla.com
push dateMon, 07 Mar 2016 14:18:41 +0000
treeherdermozilla-beta@31e373ad5b5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs890156
milestone46.0a2
Backout bug 890156 from aurora-46; waiting for the next train due to not-yet-resolved regressions. a=backout This backs out the full set of changesets that landed in bug 890156: 8d6a78297035 b9c868d65f75 87b35034828d f4b5097c00c6 cc09fb02f2c9 20c8f6d96756 443207a1d886 68d1b9a375b0 c35bafe04d6f 153848bbb30d 1be1d936e2a2 1e1764c8c518 9bde73f95ead
browser/app/firefox.exe.manifest
browser/base/content/aboutDialog.css
browser/components/sessionstore/SessionStore.jsm
docshell/base/nsDocShell.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
embedding/browser/nsDocShellTreeOwner.cpp
embedding/browser/nsWebBrowser.cpp
gfx/layers/apz/util/APZEventState.cpp
gfx/src/nsDeviceContext.cpp
gfx/tests/gtest/TestCompositor.cpp
gfx/thebes/gfxWindowsPlatform.cpp
gfx/thebes/gfxWindowsPlatform.h
ipc/app/plugin-container.exe.manifest
layout/base/Units.h
layout/xul/nsMenuPopupFrame.cpp
layout/xul/nsMenuPopupFrame.h
layout/xul/nsResizerFrame.cpp
view/nsView.cpp
widget/PluginWidgetProxy.cpp
widget/PluginWidgetProxy.h
widget/PuppetWidget.cpp
widget/PuppetWidget.h
widget/android/nsWindow.cpp
widget/android/nsWindow.h
widget/cocoa/nsChildView.h
widget/cocoa/nsChildView.mm
widget/cocoa/nsCocoaWindow.h
widget/cocoa/nsCocoaWindow.mm
widget/gonk/nsWindow.cpp
widget/gonk/nsWindow.h
widget/gtk/nsWindow.cpp
widget/gtk/nsWindow.h
widget/nsBaseDragService.h
widget/nsBaseScreen.h
widget/nsBaseWidget.cpp
widget/nsBaseWidget.h
widget/nsIBaseWindow.idl
widget/nsIScreen.idl
widget/nsIWidget.h
widget/qt/nsWindow.cpp
widget/uikit/nsWindow.mm
widget/windows/TaskbarPreview.cpp
widget/windows/WinUtils.cpp
widget/windows/WinUtils.h
widget/windows/nsDragService.cpp
widget/windows/nsLookAndFeel.cpp
widget/windows/nsNativeThemeWin.cpp
widget/windows/nsScreenManagerWin.cpp
widget/windows/nsScreenWin.cpp
widget/windows/nsScreenWin.h
widget/windows/nsWindow.cpp
widget/windows/nsWindow.h
widget/windows/nsWindowBase.cpp
widget/windows/nsWindowBase.h
xpfe/appshell/nsChromeTreeOwner.cpp
xpfe/appshell/nsContentTreeOwner.cpp
xpfe/appshell/nsWebShellWindow.cpp
xpfe/appshell/nsXULWindow.cpp
xpfe/appshell/nsXULWindow.h
--- a/browser/app/firefox.exe.manifest
+++ b/browser/app/firefox.exe.manifest
@@ -23,17 +23,17 @@
   <ms_asmv3:security>
     <ms_asmv3:requestedPrivileges>
       <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
     </ms_asmv3:requestedPrivileges>
   </ms_asmv3:security>
 </ms_asmv3:trustInfo>
   <ms_asmv3:application xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
     <ms_asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
-      <dpiAware>True/PM</dpiAware>
+      <dpiAware>true</dpiAware>
     </ms_asmv3:windowsSettings>
   </ms_asmv3:application>
   <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
     <application>
       <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
--- a/browser/base/content/aboutDialog.css
+++ b/browser/base/content/aboutDialog.css
@@ -1,18 +1,14 @@
 /* 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/. */
 
 #aboutDialog {
   width: 620px;
-  /* Set an explicit line-height to avoid discrepancies in 'auto' spacing
-     across screens with different device DPI, which may cause font metrics
-     to round differently. */
-  line-height: 1.5;
 }
 
 #rightBox {
   background-image: url("chrome://branding/content/about-wordmark.svg");
   background-repeat: no-repeat;
   /* padding-top creates room for the wordmark */
   padding-top: 38px;
   margin-top:20px;
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -3471,26 +3471,26 @@ var SessionStoreInternal = {
       if (aTop < screenTop.value) {
         aTop = screenTop.value;
       } else if (aTop + aHeight > screenTop.value + screenHeight.value) {
         aTop = screenTop.value + screenHeight.value - aHeight;
       }
     }
 
     // only modify those aspects which aren't correct yet
-    if (!isNaN(aLeft) && !isNaN(aTop) && (aLeft != win_("screenX") || aTop != win_("screenY"))) {
-      aWindow.moveTo(aLeft, aTop);
-    }
     if (aWidth && aHeight && (aWidth != win_("width") || aHeight != win_("height"))) {
       // Don't resize the window if it's currently maximized and we would
       // maximize it again shortly after.
       if (aSizeMode != "maximized" || win_("sizemode") != "maximized") {
         aWindow.resizeTo(aWidth, aHeight);
       }
     }
+    if (!isNaN(aLeft) && !isNaN(aTop) && (aLeft != win_("screenX") || aTop != win_("screenY"))) {
+      aWindow.moveTo(aLeft, aTop);
+    }
     if (aSizeMode && win_("sizemode") != aSizeMode)
     {
       switch (aSizeMode)
       {
       case "maximized":
         aWindow.maximize();
         break;
       case "minimized":
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -5780,33 +5780,16 @@ nsDocShell::GetUnscaledDevicePixelsPerCS
     return ownerWindow->GetUnscaledDevicePixelsPerCSSPixel(aScale);
   }
 
   *aScale = 1.0;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDocShell::GetDevicePixelsPerDesktopPixel(double* aScale)
-{
-  if (mParentWidget) {
-    *aScale = mParentWidget->GetDesktopToDeviceScale().scale;
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIBaseWindow> ownerWindow(do_QueryInterface(mTreeOwner));
-  if (ownerWindow) {
-    return ownerWindow->GetDevicePixelsPerDesktopPixel(aScale);
-  }
-
-  *aScale = 1.0;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsDocShell::SetPosition(int32_t aX, int32_t aY)
 {
   mBounds.x = aX;
   mBounds.y = aY;
 
   if (mContentViewer) {
     NS_ENSURE_SUCCESS(mContentViewer->Move(aX, aY), NS_ERROR_FAILURE);
   }
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -5028,48 +5028,43 @@ nsGlobalWindow::SetOuterHeight(int32_t a
 void
 nsGlobalWindow::SetOuterHeight(JSContext* aCx, JS::Handle<JS::Value> aValue,
                                ErrorResult& aError)
 {
   SetReplaceableWindowCoord(aCx, &nsGlobalWindow::SetOuterHeight,
                             aValue, "outerHeight", aError);
 }
 
-DesktopIntPoint
+nsIntPoint
 nsGlobalWindow::GetScreenXY(ErrorResult& aError)
 {
   MOZ_ASSERT(IsOuterWindow());
 
   // When resisting fingerprinting, always return (0,0)
   if (nsContentUtils::ShouldResistFingerprinting(mDocShell)) {
-    return DesktopIntPoint(0, 0);
+    return nsIntPoint(0, 0);
   }
 
   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = GetTreeOwnerWindow();
   if (!treeOwnerAsWin) {
     aError.Throw(NS_ERROR_FAILURE);
-    return DesktopIntPoint(0, 0);
+    return nsIntPoint(0, 0);
   }
 
   int32_t x = 0, y = 0;
   aError = treeOwnerAsWin->GetPosition(&x, &y);
-
-  nsCOMPtr<nsIWidget> widget = GetMainWidget();
-  DesktopToLayoutDeviceScale scale = widget ? widget->GetDesktopToDeviceScale()
-                                            : DesktopToLayoutDeviceScale(1.0);
-  DesktopPoint pt = LayoutDeviceIntPoint(x, y) / scale;
-  return DesktopIntPoint(NSToIntRound(pt.x), NSToIntRound(pt.y));
+  return nsIntPoint(x, y);
 }
 
 int32_t
 nsGlobalWindow::GetScreenXOuter(ErrorResult& aError)
 {
   MOZ_RELEASE_ASSERT(IsOuterWindow());
 
-  return GetScreenXY(aError).x;
+  return DevToCSSIntPixels(GetScreenXY(aError).x);
 }
 
 int32_t
 nsGlobalWindow::GetScreenX(ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(GetScreenXOuter, (aError), aError, 0);
 }
 
@@ -5303,17 +5298,17 @@ nsGlobalWindow::SetScreenX(JSContext* aC
                             aValue, "screenX", aError);
 }
 
 int32_t
 nsGlobalWindow::GetScreenYOuter(ErrorResult& aError)
 {
   MOZ_RELEASE_ASSERT(IsOuterWindow());
 
-  return GetScreenXY(aError).y;
+  return DevToCSSIntPixels(GetScreenXY(aError).y);
 }
 
 int32_t
 nsGlobalWindow::GetScreenY(ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(GetScreenYOuter, (aError), aError, 0);
 }
 
@@ -7011,25 +7006,23 @@ nsGlobalWindow::MoveToOuter(int32_t aXPo
   }
 
   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = GetTreeOwnerWindow();
   if (!treeOwnerAsWin) {
     aError.Throw(NS_ERROR_FAILURE);
     return;
   }
 
-  DesktopIntPoint pt(aXPos, aYPos);
-  CheckSecurityLeftAndTop(&pt.x, &pt.y, aCallerIsChrome);
-
-  nsCOMPtr<nsIWidget> widget = GetMainWidget();
-  DesktopToLayoutDeviceScale scale = widget ? widget->GetDesktopToDeviceScale()
-                                            : DesktopToLayoutDeviceScale(1.0);
-  LayoutDevicePoint devPos = pt * scale;
-
-  aError = treeOwnerAsWin->SetPosition(devPos.x, devPos.y);
+  // Mild abuse of a "size" object so we don't need more helper functions.
+  nsIntSize cssPos(aXPos, aYPos);
+  CheckSecurityLeftAndTop(&cssPos.width, &cssPos.height, aCallerIsChrome);
+
+  nsIntSize devPos = CSSToDevIntPixels(cssPos);
+
+  aError = treeOwnerAsWin->SetPosition(devPos.width, devPos.height);
 }
 
 void
 nsGlobalWindow::MoveTo(int32_t aXPos, int32_t aYPos, ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(MoveToOuter, (aXPos, aYPos, aError, nsContentUtils::IsCallerChrome()), aError, );
 }
 
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -1601,18 +1601,18 @@ protected:
   nsresult GetComputedStyleHelper(nsIDOMElement* aElt,
                                   const nsAString& aPseudoElt,
                                   bool aDefaultStylesOnly,
                                   nsIDOMCSSStyleDeclaration** aReturn);
 
   // Outer windows only.
   void PreloadLocalStorage();
 
-  // Returns desktop pixels.  Outer windows only.
-  mozilla::DesktopIntPoint GetScreenXY(mozilla::ErrorResult& aError);
+  // Returns device pixels.  Outer windows only.
+  nsIntPoint GetScreenXY(mozilla::ErrorResult& aError);
 
   nsGlobalWindow* InnerForSetTimeoutOrInterval(mozilla::ErrorResult& aError);
 
   void PostMessageMozOuter(JSContext* aCx, JS::Handle<JS::Value> aMessage,
                            const nsAString& aTargetOrigin,
                            JS::Handle<JS::Value> aTransfer,
                            mozilla::ErrorResult& aError);
   void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
--- a/embedding/browser/nsDocShellTreeOwner.cpp
+++ b/embedding/browser/nsDocShellTreeOwner.cpp
@@ -556,27 +556,16 @@ nsDocShellTreeOwner::GetUnscaledDevicePi
     return mWebBrowser->GetUnscaledDevicePixelsPerCSSPixel(aScale);
   }
 
   *aScale = 1.0;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDocShellTreeOwner::GetDevicePixelsPerDesktopPixel(double* aScale)
-{
-  if (mWebBrowser) {
-    return mWebBrowser->GetDevicePixelsPerDesktopPixel(aScale);
-  }
-
-  *aScale = 1.0;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsDocShellTreeOwner::SetPosition(int32_t aX, int32_t aY)
 {
   nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
   if (ownerWin) {
     return ownerWin->SetDimensions(nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION,
                                    aX, aY, 0, 0);
   }
   return NS_ERROR_NULL_POINTER;
--- a/embedding/browser/nsWebBrowser.cpp
+++ b/embedding/browser/nsWebBrowser.cpp
@@ -1290,24 +1290,16 @@ nsWebBrowser::Destroy()
 NS_IMETHODIMP
 nsWebBrowser::GetUnscaledDevicePixelsPerCSSPixel(double* aScale)
 {
   *aScale = mParentWidget ? mParentWidget->GetDefaultScale().scale : 1.0;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsWebBrowser::GetDevicePixelsPerDesktopPixel(double* aScale)
-{
-  *aScale = mParentWidget ? mParentWidget->GetDesktopToDeviceScale().scale
-                          : 1.0;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsWebBrowser::SetPosition(int32_t aX, int32_t aY)
 {
   int32_t cx = 0;
   int32_t cy = 0;
 
   GetSize(&cx, &cy);
 
   return SetPositionAndSize(aX, aY, cx, cy, false);
--- a/gfx/layers/apz/util/APZEventState.cpp
+++ b/gfx/layers/apz/util/APZEventState.cpp
@@ -177,17 +177,17 @@ APZEventState::ProcessSingleTap(const CS
   }
 
   if (mTouchEndCancelled) {
     return;
   }
 
   LayoutDevicePoint currentPoint =
       APZCCallbackHelper::ApplyCallbackTransform(aPoint, aGuid)
-    * widget->GetDefaultScale();
+    * widget->GetDefaultScale();;
   if (!mActiveElementManager->ActiveElementUsesStyle()) {
     // If the active element isn't visually affected by the :active style, we
     // have no need to wait the extra sActiveDurationMs to make the activation
     // visually obvious to the user.
     APZCCallbackHelper::FireSingleTapEvent(currentPoint, aModifiers, widget);
     return;
   }
 
--- a/gfx/src/nsDeviceContext.cpp
+++ b/gfx/src/nsDeviceContext.cpp
@@ -653,18 +653,16 @@ nsDeviceContext::ComputeFullAreaUsingScr
 //
 void
 nsDeviceContext::FindScreen(nsIScreen** outScreen)
 {
     if (!mWidget || !mScreenManager) {
         return;
     }
 
-    CheckDPIChange();
-
     if (mWidget->GetOwningTabChild()) {
         mScreenManager->ScreenForNativeWidget((void *)mWidget->GetOwningTabChild(),
                                               outScreen);
     }
     else if (mWidget->GetNativeData(NS_NATIVE_WINDOW)) {
         mScreenManager->ScreenForNativeWidget(mWidget->GetNativeData(NS_NATIVE_WINDOW),
                                               outScreen);
     }
--- a/gfx/tests/gtest/TestCompositor.cpp
+++ b/gfx/tests/gtest/TestCompositor.cpp
@@ -54,20 +54,16 @@ public:
     }
     return nullptr;
   }
 
   NS_IMETHOD              Create(nsIWidget* aParent,
                                  nsNativeWidget aNativeParent,
                                  const LayoutDeviceIntRect& aRect,
                                  nsWidgetInitData* aInitData = nullptr) override { return NS_OK; }
-  NS_IMETHOD              Create(nsIWidget* aParent,
-                                 nsNativeWidget aNativeParent,
-                                 const DesktopIntRect& aRect,
-                                 nsWidgetInitData* aInitData = nullptr) override { return NS_OK; }
   NS_IMETHOD              Show(bool aState) override { return NS_OK; }
   virtual bool            IsVisible() const override { return true; }
   NS_IMETHOD              ConstrainPosition(bool aAllowSlop,
                                             int32_t *aX, int32_t *aY) override { return NS_OK; }
   NS_IMETHOD              Move(double aX, double aY) override { return NS_OK; }
   NS_IMETHOD              Resize(double aWidth, double aHeight, bool aRepaint) override { return NS_OK; }
   NS_IMETHOD              Resize(double aX, double aY,
                                  double aWidth, double aHeight, bool aRepaint) override { return NS_OK; }
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -421,16 +421,22 @@ gfxWindowsPlatform::~gfxWindowsPlatform(
     mAdapter = nullptr;
 
     /* 
      * Uninitialize COM 
      */ 
     CoUninitialize();
 }
 
+double
+gfxWindowsPlatform::GetDPIScale()
+{
+  return WinUtils::LogToPhysFactor();
+}
+
 bool
 gfxWindowsPlatform::CanUseHardwareVideoDecoding()
 {
   if (!gfxPrefs::LayersPreferD3D9() && !mCompositorD3D11TextureSharingWorks) {
     return false;
   }
   return !IsWARP() && gfxPlatform::CanUseHardwareVideoDecoding();
 }
--- a/gfx/thebes/gfxWindowsPlatform.h
+++ b/gfx/thebes/gfxWindowsPlatform.h
@@ -162,16 +162,23 @@ public:
      * cairo device creation routines.
      */
     void VerifyD2DDevice(bool aAttemptForce);
 
 #ifdef CAIRO_HAS_D2D_SURFACE
     HRESULT CreateDevice(RefPtr<IDXGIAdapter1> &adapter1, int featureLevelIndex);
 #endif
 
+    /**
+     * Return the resolution scaling factor to convert between "logical" or
+     * "screen" pixels as used by Windows (dependent on the DPI scaling option
+     * in the Display control panel) and actual device pixels.
+     */
+    double GetDPIScale();
+
     nsresult GetFontList(nsIAtom *aLangGroup,
                          const nsACString& aGenericFamily,
                          nsTArray<nsString>& aListOfFonts) override;
 
     nsresult UpdateFontList();
 
     virtual void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
                                         int32_t aRunScript,
--- a/ipc/app/plugin-container.exe.manifest
+++ b/ipc/app/plugin-container.exe.manifest
@@ -23,17 +23,17 @@
     <ms_asmv3:security>
       <ms_asmv3:requestedPrivileges>
         <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
       </ms_asmv3:requestedPrivileges>
     </ms_asmv3:security>
   </ms_asmv3:trustInfo>
   <ms_asmv3:application xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
     <ms_asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
-      <dpiAware>True/PM</dpiAware>
+      <dpiAware>true</dpiAware>
     </ms_asmv3:windowsSettings>
   </ms_asmv3:application>
   <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
     <application>
       <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
--- a/layout/base/Units.h
+++ b/layout/base/Units.h
@@ -27,26 +27,24 @@ struct IsPixel : FalseType {};
 // See struct declaration for a description of each unit type.
 struct CSSPixel;
 struct LayoutDevicePixel;
 struct LayerPixel;
 struct CSSTransformedLayerPixel;
 struct RenderTargetPixel;
 struct ScreenPixel;
 struct ParentLayerPixel;
-struct DesktopPixel;
 
 template<> struct IsPixel<CSSPixel>          : TrueType {};
 template<> struct IsPixel<LayoutDevicePixel> : TrueType {};
 template<> struct IsPixel<LayerPixel>        : TrueType {};
 template<> struct IsPixel<CSSTransformedLayerPixel> : TrueType {};
 template<> struct IsPixel<RenderTargetPixel> : TrueType {};
 template<> struct IsPixel<ScreenPixel>       : TrueType {};
 template<> struct IsPixel<ParentLayerPixel>  : TrueType {};
-template<> struct IsPixel<DesktopPixel>      : TrueType {};
 
 typedef gfx::CoordTyped<CSSPixel> CSSCoord;
 typedef gfx::IntCoordTyped<CSSPixel> CSSIntCoord;
 typedef gfx::PointTyped<CSSPixel> CSSPoint;
 typedef gfx::IntPointTyped<CSSPixel> CSSIntPoint;
 typedef gfx::SizeTyped<CSSPixel> CSSSize;
 typedef gfx::IntSizeTyped<CSSPixel> CSSIntSize;
 typedef gfx::RectTyped<CSSPixel> CSSRect;
@@ -120,25 +118,16 @@ typedef gfx::IntPointTyped<ParentLayerPi
 typedef gfx::SizeTyped<ParentLayerPixel> ParentLayerSize;
 typedef gfx::IntSizeTyped<ParentLayerPixel> ParentLayerIntSize;
 typedef gfx::RectTyped<ParentLayerPixel> ParentLayerRect;
 typedef gfx::IntRectTyped<ParentLayerPixel> ParentLayerIntRect;
 typedef gfx::MarginTyped<ParentLayerPixel> ParentLayerMargin;
 typedef gfx::IntMarginTyped<ParentLayerPixel> ParentLayerIntMargin;
 typedef gfx::IntRegionTyped<ParentLayerPixel> ParentLayerIntRegion;
 
-typedef gfx::CoordTyped<DesktopPixel> DesktopCoord;
-typedef gfx::IntCoordTyped<DesktopPixel> DesktopIntCoord;
-typedef gfx::PointTyped<DesktopPixel> DesktopPoint;
-typedef gfx::IntPointTyped<DesktopPixel> DesktopIntPoint;
-typedef gfx::SizeTyped<DesktopPixel> DesktopSize;
-typedef gfx::IntSizeTyped<DesktopPixel> DesktopIntSize;
-typedef gfx::RectTyped<DesktopPixel> DesktopRect;
-typedef gfx::IntRectTyped<DesktopPixel> DesktopIntRect;
-
 typedef gfx::ScaleFactor<CSSPixel, LayoutDevicePixel> CSSToLayoutDeviceScale;
 typedef gfx::ScaleFactor<CSSPixel, LayerPixel> CSSToLayerScale;
 typedef gfx::ScaleFactor<CSSPixel, ScreenPixel> CSSToScreenScale;
 typedef gfx::ScaleFactor<CSSPixel, ParentLayerPixel> CSSToParentLayerScale;
 typedef gfx::ScaleFactor<LayoutDevicePixel, CSSPixel> LayoutDeviceToCSSScale;
 typedef gfx::ScaleFactor<LayoutDevicePixel, LayerPixel> LayoutDeviceToLayerScale;
 typedef gfx::ScaleFactor<LayoutDevicePixel, ScreenPixel> LayoutDeviceToScreenScale;
 typedef gfx::ScaleFactor<LayoutDevicePixel, ParentLayerPixel> LayoutDeviceToParentLayerScale;
@@ -150,17 +139,16 @@ typedef gfx::ScaleFactor<LayerPixel, Par
 typedef gfx::ScaleFactor<RenderTargetPixel, ScreenPixel> RenderTargetToScreenScale;
 typedef gfx::ScaleFactor<ScreenPixel, CSSPixel> ScreenToCSSScale;
 typedef gfx::ScaleFactor<ScreenPixel, LayoutDevicePixel> ScreenToLayoutDeviceScale;
 typedef gfx::ScaleFactor<ScreenPixel, LayerPixel> ScreenToLayerScale;
 typedef gfx::ScaleFactor<ScreenPixel, ParentLayerPixel> ScreenToParentLayerScale;
 typedef gfx::ScaleFactor<ParentLayerPixel, LayerPixel> ParentLayerToLayerScale;
 typedef gfx::ScaleFactor<ParentLayerPixel, ScreenPixel> ParentLayerToScreenScale;
 typedef gfx::ScaleFactor<ParentLayerPixel, ParentLayerPixel> ParentLayerToParentLayerScale;
-typedef gfx::ScaleFactor<DesktopPixel, LayoutDevicePixel> DesktopToLayoutDeviceScale;
 
 typedef gfx::ScaleFactors2D<CSSPixel, LayoutDevicePixel> CSSToLayoutDeviceScale2D;
 typedef gfx::ScaleFactors2D<CSSPixel, LayerPixel> CSSToLayerScale2D;
 typedef gfx::ScaleFactors2D<CSSPixel, ScreenPixel> CSSToScreenScale2D;
 typedef gfx::ScaleFactors2D<CSSPixel, ParentLayerPixel> CSSToParentLayerScale2D;
 typedef gfx::ScaleFactors2D<LayoutDevicePixel, CSSPixel> LayoutDeviceToCSSScale2D;
 typedef gfx::ScaleFactors2D<LayoutDevicePixel, LayerPixel> LayoutDeviceToLayerScale2D;
 typedef gfx::ScaleFactors2D<LayoutDevicePixel, ScreenPixel> LayoutDeviceToScreenScale2D;
@@ -297,20 +285,16 @@ struct LayoutDevicePixel {
   static LayoutDeviceIntPoint FromAppUnitsToNearest(const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) {
     return LayoutDeviceIntPoint::FromUnknownPoint(aPoint.ToNearestPixels(aAppUnitsPerDevPixel));
   }
 
   static LayoutDeviceIntRect FromAppUnitsToNearest(const nsRect& aRect, nscoord aAppUnitsPerDevPixel) {
     return LayoutDeviceIntRect::FromUnknownRect(aRect.ToNearestPixels(aAppUnitsPerDevPixel));
   }
 
-  static LayoutDeviceIntRect FromAppUnitsToInside(const nsRect& aRect, nscoord aAppUnitsPerDevPixel) {
-    return LayoutDeviceIntRect::FromUnknownRect(aRect.ToInsidePixels(aAppUnitsPerDevPixel));
-  }
-
   static LayoutDeviceIntSize FromAppUnitsRounded(const nsSize& aSize, nscoord aAppUnitsPerDevPixel) {
     return LayoutDeviceIntSize(
       NSAppUnitsToIntPixels(aSize.width, aAppUnitsPerDevPixel),
       NSAppUnitsToIntPixels(aSize.height, aAppUnitsPerDevPixel));
   }
 
   static nsPoint ToAppUnits(const LayoutDeviceIntPoint& aPoint, nscoord aAppUnitsPerDevPixel) {
     return nsPoint(aPoint.x * aAppUnitsPerDevPixel,
@@ -396,33 +380,16 @@ struct ScreenPixel {
  *   - Start with global screen coordinates and unapply all CSS and async
  *     transforms from the root down to and including the parent.
  * It's helpful to look at https://wiki.mozilla.org/Platform/GFX/APZ#Coordinate_systems
  * to get a picture of how the various coordinate systems relate to each other.
  */
 struct ParentLayerPixel {
 };
 
-/*
- * Pixels in the coordinate space used by the host OS to manage windows on the
- * desktop. What these mean varies between OSs:
- * - by default (unless implemented differently in platform-specific widget
- *   code) they are the same as LayoutDevicePixels
- * - on Mac OS X, they're "cocoa points", which correspond to device pixels
- *   on a non-Retina display, and to 2x device pixels on Retina
- * - on Windows *without* per-monitor DPI support, they are Windows "logical
- *   pixels", i.e. device pixels scaled according to the Windows display DPI
- *   scaling factor (typically one of 1.25, 1.5, 1.75, 2.0...)
- * - on Windows *with* per-monitor DPI support, they are physical device pixels
- *   on each screen; note that this means the scaling between CSS pixels and
- *   desktop pixels may vary across multiple displays.
- */
-struct DesktopPixel {
-};
-
 // Operators to apply ScaleFactors directly to Coords, Points, Rects, Sizes and Margins
 
 template<class src, class dst>
 gfx::CoordTyped<dst> operator*(const gfx::CoordTyped<src>& aCoord, const gfx::ScaleFactor<src, dst>& aScale) {
   return gfx::CoordTyped<dst>(aCoord.value * aScale.scale);
 }
 
 template<class src, class dst>
--- a/layout/xul/nsMenuPopupFrame.cpp
+++ b/layout/xul/nsMenuPopupFrame.cpp
@@ -1423,27 +1423,18 @@ nsMenuPopupFrame::SetPopupPosition(nsIFr
 #else
     // Other OS screen positioned popups can be flipped vertically but never horizontally
     vFlip = FlipStyle_Outside;
 #endif // #ifdef XP_MACOSX
   }
 
   // If a panel is being moved or has flip="none", don't constrain or flip it. But always do this for
   // content shells, so that the popup doesn't extend outside the containing frame.
-  if (mInContentShell || (mFlip != FlipType_None &&
-                          (!aIsMove || mPopupType != ePopupTypePanel))) {
-    int32_t appPerDev = presContext->AppUnitsPerDevPixel();
-    LayoutDeviceIntRect anchorRectDevPix =
-      LayoutDeviceIntRect::FromAppUnitsToNearest(anchorRect, appPerDev);
-    LayoutDeviceIntRect rootScreenRectDevPix =
-      LayoutDeviceIntRect::FromAppUnitsToNearest(rootScreenRect, appPerDev);
-    LayoutDeviceIntRect screenRectDevPix =
-      GetConstraintRect(anchorRectDevPix, rootScreenRectDevPix, popupLevel);
-    nsRect screenRect =
-      LayoutDeviceIntRect::ToAppUnits(screenRectDevPix, appPerDev);
+  if (mInContentShell || (mFlip != FlipType_None && (!aIsMove || mPopupType != ePopupTypePanel))) {
+    nsRect screenRect = GetConstraintRect(anchorRect, rootScreenRect, popupLevel);
 
     // Ensure that anchorRect is on screen.
     anchorRect = anchorRect.Intersect(screenRect);
 
     // shrink the the popup down if it is larger than the screen size
     if (mRect.width > screenRect.width)
       mRect.width = screenRect.width;
     if (mRect.height > screenRect.height)
@@ -1531,57 +1522,62 @@ nsMenuPopupFrame::SetPopupPosition(nsIFr
 }
 
 /* virtual */ nsMenuFrame*
 nsMenuPopupFrame::GetCurrentMenuItem()
 {
   return mCurrentMenu;
 }
 
-LayoutDeviceIntRect
-nsMenuPopupFrame::GetConstraintRect(const LayoutDeviceIntRect& aAnchorRect,
-                                    const LayoutDeviceIntRect& aRootScreenRect,
+nsRect
+nsMenuPopupFrame::GetConstraintRect(const nsRect& aAnchorRect,
+                                    const nsRect& aRootScreenRect,
                                     nsPopupLevel aPopupLevel)
 {
-  LayoutDeviceIntRect screenRectPixels;
+  nsIntRect screenRectPixels;
+  nsPresContext* presContext = PresContext();
 
   // determine the available screen space. It will be reduced by the OS chrome
   // such as menubars. It addition, for content shells, it will be the area of
   // the content rather than the screen.
   nsCOMPtr<nsIScreen> screen;
   nsCOMPtr<nsIScreenManager> sm(do_GetService("@mozilla.org/gfx/screenmanager;1"));
   if (sm) {
     // for content shells, get the screen where the root frame is located.
     // This is because we need to constrain the content to this content area,
     // so we should use the same screen. Otherwise, use the screen where the
     // anchor is located.
-    LayoutDeviceIntRect rect = mInContentShell ? aRootScreenRect : aAnchorRect;
-    int32_t width = std::max(1, rect.width);
-    int32_t height = std::max(1, rect.height);
-    sm->ScreenForRect(rect.x, rect.y, width, height, getter_AddRefs(screen));
+    nsRect rect = mInContentShell ? aRootScreenRect : aAnchorRect;
+    // nsIScreenManager::ScreenForRect wants the coordinates in CSS pixels
+    int32_t width = std::max(1, nsPresContext::AppUnitsToIntCSSPixels(rect.width));
+    int32_t height = std::max(1, nsPresContext::AppUnitsToIntCSSPixels(rect.height));
+    sm->ScreenForRect(nsPresContext::AppUnitsToIntCSSPixels(rect.x),
+                      nsPresContext::AppUnitsToIntCSSPixels(rect.y),
+                      width, height, getter_AddRefs(screen));
     if (screen) {
       // Non-top-level popups (which will always be panels)
       // should never overlap the OS bar:
       bool dontOverlapOSBar = aPopupLevel != ePopupLevelTop;
       // get the total screen area if the popup is allowed to overlap it.
       if (!dontOverlapOSBar && mMenuCanOverlapOSBar && !mInContentShell)
         screen->GetRect(&screenRectPixels.x, &screenRectPixels.y,
-          &screenRectPixels.width, &screenRectPixels.height);
+                        &screenRectPixels.width, &screenRectPixels.height);
       else
         screen->GetAvailRect(&screenRectPixels.x, &screenRectPixels.y,
-          &screenRectPixels.width, &screenRectPixels.height);
+                             &screenRectPixels.width, &screenRectPixels.height);
     }
   }
 
+  nsRect screenRect = ToAppUnits(screenRectPixels, presContext->AppUnitsPerDevPixel());
   if (mInContentShell) {
     // for content shells, clip to the client area rather than the screen area
-    screenRectPixels.IntersectRect(screenRectPixels, aRootScreenRect);
+    screenRect.IntersectRect(screenRect, aRootScreenRect);
   }
 
-  return screenRectPixels;
+  return screenRect;
 }
 
 void nsMenuPopupFrame::CanAdjustEdges(int8_t aHorizontalSide,
                                       int8_t aVerticalSide,
                                       LayoutDeviceIntPoint& aChange)
 {
   int8_t popupAlign(mPopupAlignment);
   if (IsDirectionRTL()) {
--- a/layout/xul/nsMenuPopupFrame.h
+++ b/layout/xul/nsMenuPopupFrame.h
@@ -357,21 +357,18 @@ public:
   // For a popup that should appear anchored at the given rect, determine
   // the screen area that it is constrained by. This will be the available
   // area of the screen the popup should be displayed on. Content popups,
   // however, will also be constrained by the content area, given by
   // aRootScreenRect. All coordinates are in app units.
   // For non-toplevel popups (which will always be panels), we will also
   // constrain them to the available screen rect, ie they will not fall
   // underneath the taskbar, dock or other fixed OS elements.
-  // This operates in device pixels.
-  mozilla::LayoutDeviceIntRect
-  GetConstraintRect(const mozilla::LayoutDeviceIntRect& aAnchorRect,
-                    const mozilla::LayoutDeviceIntRect& aRootScreenRect,
-                    nsPopupLevel aPopupLevel);
+  nsRect GetConstraintRect(const nsRect& aAnchorRect, const nsRect& aRootScreenRect,
+                           nsPopupLevel aPopupLevel);
 
   // Determines whether the given edges of the popup may be moved, where
   // aHorizontalSide and aVerticalSide are one of the NS_SIDE_* constants, or
   // 0 for no movement in that direction. aChange is the distance to move on
   // those sides. If will be reset to 0 if the side cannot be adjusted at all
   // in that direction. For example, a popup cannot be moved if it is anchored
   // on a particular side.
   //
--- a/layout/xul/nsResizerFrame.cpp
+++ b/layout/xul/nsResizerFrame.cpp
@@ -223,25 +223,22 @@ nsResizerFrame::HandleEvent(nsPresContex
         }
       }
       else if (menuPopupFrame) {
         nsRect frameRect = menuPopupFrame->GetScreenRectInAppUnits();
         nsIFrame* rootFrame = aPresContext->PresShell()->FrameManager()->GetRootFrame();
         nsRect rootScreenRect = rootFrame->GetScreenRectInAppUnits();
 
         nsPopupLevel popupLevel = menuPopupFrame->PopupLevel();
-        int32_t appPerDev = aPresContext->AppUnitsPerDevPixel();
-        LayoutDeviceIntRect screenRect = menuPopupFrame->GetConstraintRect
-          (LayoutDeviceIntRect::FromAppUnitsToNearest(frameRect, appPerDev),
-           // round using ...ToInside as it's better to be a pixel too small
-           // than be too large. If the popup is too large it could get flipped
-           // to the opposite side of the anchor point while resizing.
-           LayoutDeviceIntRect::FromAppUnitsToInside(rootScreenRect, appPerDev),
-           popupLevel);
-        rect.IntersectRect(rect, screenRect);
+        nsRect screenRect = menuPopupFrame->GetConstraintRect(frameRect, rootScreenRect, popupLevel);
+        // round using ToInsidePixels as it's better to be a pixel too small
+        // than be too large. If the popup is too large it could get flipped
+        // to the opposite side of the anchor point while resizing.
+        nsIntRect screenRectPixels = screenRect.ToInsidePixels(aPresContext->AppUnitsPerDevPixel());
+        rect.IntersectRect(rect, LayoutDeviceIntRect::FromUnknownRect(screenRectPixels));
       }
 
       if (contentToResize) {
         // convert the rectangle into css pixels. When changing the size in a
         // direction, don't allow the new size to be less that the resizer's
         // size. This ensures that content isn't resized too small as to make
         // the resizer invisible.
         nsRect appUnitsRect = ToAppUnits(rect.ToUnknownRect(), aPresContext->AppUnitsPerDevPixel());
--- a/view/nsView.cpp
+++ b/view/nsView.cpp
@@ -331,53 +331,54 @@ void nsView::DoResetWidgetBounds(bool aM
     return;
   }
 
   bool changedPos = curBounds.TopLeft() != newBounds.TopLeft();
   bool changedSize = curBounds.Size() != newBounds.Size();
 
   // Child views are never attached to top level widgets, this is safe.
 
-  // Coordinates are converted to desktop pixels for window Move/Resize APIs,
+  // Coordinates are converted to display pixels for window Move/Resize APIs,
   // because of the potential for device-pixel coordinate spaces for mixed
   // hidpi/lodpi screens to overlap each other and result in bad placement
   // (bug 814434).
-  DesktopToLayoutDeviceScale scale = widget->GetDesktopToDeviceScale();
+  double invScale;
 
-#ifdef XP_MACOSX
-  // On OS X, this can be called before Cocoa has updated the backing scale
-  // factor of our widget, in which case |scale| is wrong here. To work
-  // around this, we check the device context and override |scale| if it
-  // doesn't match. (This happens when a popup window that has previously
-  // been created and hidden is being moved between hi- and lo-dpi screens,
-  // but is not currently visible; Cocoa doesn't notify it of the scale
-  // factor change until it gets shown on the new screen, which is too late
-  // for us because we'll have already done the computations involving scale
-  // here to move/size it.)
-  // It might be better to avoid this by keeping calculations such as
-  // CalcWidgetBounds entirely in appUnits, rather than using device pixels,
-  // but that seems like a more extensive and potentially risky change.
-  int32_t appPerDev = dx->AppUnitsPerDevPixelAtUnitFullZoom();
-  if (NSToIntRound(60.0 / scale.scale) != appPerDev) {
-    scale = DesktopToLayoutDeviceScale(60.0 / appPerDev);
+  // Bug 861270: for correct widget manipulation at arbitrary scale factors,
+  // prefer to base scaling on widget->GetDefaultScale(). But only do this if
+  // it matches the view manager's device context scale after allowing for the
+  // quantization to app units, because of OS X multiscreen issues (where the
+  // only two scales are 1.0 or 2.0, and so the quantization doesn't actually
+  // cause problems anyhow).
+  // In the case of a mismatch, fall back to scaling based on the dev context's
+  // AppUnitsPerDevPixelAtUnitFullZoom value. On platforms where the device-pixel
+  // scale is uniform across all displays (currently all except OS X), we'll
+  // always use the precise value from mWindow->GetDefaultScale here.
+  CSSToLayoutDeviceScale scale = widget->GetDefaultScale();
+  if (NSToIntRound(60.0 / scale.scale) == dx->AppUnitsPerDevPixelAtUnitFullZoom()) {
+    invScale = 1.0 / scale.scale;
+  } else {
+    invScale = dx->AppUnitsPerDevPixelAtUnitFullZoom() / 60.0;
   }
-#endif
 
-  DesktopRect deskRect = newBounds / scale;
   if (changedPos) {
     if (changedSize && !aMoveOnly) {
-      widget->ResizeClient(deskRect.x, deskRect.y,
-                           deskRect.width, deskRect.height,
+      widget->ResizeClient(newBounds.x * invScale,
+                           newBounds.y * invScale,
+                           newBounds.width * invScale,
+                           newBounds.height * invScale,
                            aInvalidateChangedSize);
     } else {
-      widget->MoveClient(deskRect.x, deskRect.y);
+      widget->MoveClient(newBounds.x * invScale,
+                         newBounds.y * invScale);
     }
   } else {
     if (changedSize && !aMoveOnly) {
-      widget->ResizeClient(deskRect.width, deskRect.height,
+      widget->ResizeClient(newBounds.width * invScale,
+                           newBounds.height * invScale,
                            aInvalidateChangedSize);
     } // else do nothing!
   }
 
   if (!curVisibility && newVisibility) {
     widget->Show(true);
   }
 }
--- a/widget/PluginWidgetProxy.cpp
+++ b/widget/PluginWidgetProxy.cpp
@@ -57,17 +57,17 @@ PluginWidgetProxy::Create(nsIWidget* aPa
 
   nsresult rv = NS_ERROR_UNEXPECTED;
   mActor->SendCreate(&rv);
   if (NS_FAILED(rv)) {
     NS_WARNING("failed to create chrome widget, plugins won't paint.");
     return rv;
   }
 
-  BaseCreate(aParent, aInitData);
+  BaseCreate(aParent, aRect, aInitData);
 
   mBounds = aRect;
   mEnabled = true;
   mVisible = true;
 
   return NS_OK;
 }
 
--- a/widget/PluginWidgetProxy.h
+++ b/widget/PluginWidgetProxy.h
@@ -29,17 +29,16 @@ public:
 
 protected:
   virtual ~PluginWidgetProxy();
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIWidget
-  using PuppetWidget::Create; // for Create signature not overridden here
   NS_IMETHOD Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
                     const LayoutDeviceIntRect& aRect,
                     nsWidgetInitData* aInitData = nullptr) override;
   NS_IMETHOD Destroy() override;
   NS_IMETHOD SetFocus(bool aRaise = false) override;
   NS_IMETHOD SetParent(nsIWidget* aNewParent) override;
 
   virtual nsIWidget* GetParent(void) override;
--- a/widget/PuppetWidget.cpp
+++ b/widget/PuppetWidget.cpp
@@ -100,17 +100,17 @@ PuppetWidget::~PuppetWidget()
 NS_IMETHODIMP
 PuppetWidget::Create(nsIWidget* aParent,
                      nsNativeWidget aNativeParent,
                      const LayoutDeviceIntRect& aRect,
                      nsWidgetInitData* aInitData)
 {
   MOZ_ASSERT(!aNativeParent, "got a non-Puppet native parent");
 
-  BaseCreate(nullptr, aInitData);
+  BaseCreate(nullptr, aRect, aInitData);
 
   mBounds = aRect;
   mEnabled = true;
   mVisible = true;
 
   mDrawTarget = gfxPlatform::GetPlatform()->
     CreateOffscreenContentDrawTarget(IntSize(1, 1), SurfaceFormat::B8G8R8A8);
 
--- a/widget/PuppetWidget.h
+++ b/widget/PuppetWidget.h
@@ -49,17 +49,16 @@ public:
   explicit PuppetWidget(TabChild* aTabChild);
 
 protected:
   virtual ~PuppetWidget();
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
-  using nsBaseWidget::Create; // for Create signature not overridden here
   NS_IMETHOD Create(nsIWidget* aParent,
                     nsNativeWidget aNativeParent,
                     const LayoutDeviceIntRect& aRect,
                     nsWidgetInitData* aInitData = nullptr) override;
 
   void InitIMEState();
 
   virtual already_AddRefed<nsIWidget>
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -1080,17 +1080,17 @@ nsWindow::Create(nsIWidget* aParent,
     // for toplevel windows, bounds are fixed to full screen size
     if (!parent) {
         mBounds.x = 0;
         mBounds.y = 0;
         mBounds.width = gAndroidBounds.width;
         mBounds.height = gAndroidBounds.height;
     }
 
-    BaseCreate(nullptr, aInitData);
+    BaseCreate(nullptr, mBounds, aInitData);
 
     NS_ASSERTION(IsTopLevel() || parent, "non top level windowdoesn't have a parent!");
 
     if (IsTopLevel()) {
         gTopLevelWindows.AppendElement(this);
     }
 
     if (parent) {
--- a/widget/android/nsWindow.h
+++ b/widget/android/nsWindow.h
@@ -77,17 +77,16 @@ public:
 
     void InitEvent(mozilla::WidgetGUIEvent& event,
                    LayoutDeviceIntPoint* aPoint = 0);
 
     //
     // nsIWidget
     //
 
-    using nsBaseWidget::Create; // for Create signature not overridden here
     NS_IMETHOD Create(nsIWidget* aParent,
                       nsNativeWidget aNativeParent,
                       const LayoutDeviceIntRect& aRect,
                       nsWidgetInitData* aInitData) override;
     NS_IMETHOD Destroy(void) override;
     NS_IMETHOD ConfigureChildren(const nsTArray<nsIWidget::Configuration>&) override;
     NS_IMETHOD SetParent(nsIWidget* aNewParent) override;
     virtual nsIWidget *GetParent(void) override;
--- a/widget/cocoa/nsChildView.h
+++ b/widget/cocoa/nsChildView.h
@@ -385,20 +385,16 @@ public:
   // Returns the "backing scale factor" of the view's window, which is the
   // ratio of pixels in the window's backing store to Cocoa points. Prior to
   // HiDPI support in OS X 10.7, this was always 1.0, but in HiDPI mode it
   // will be 2.0 (and might potentially other values as screen resolutions
   // evolve). This gives the relationship between what Gecko calls "device
   // pixels" and the Cocoa "points" coordinate system.
   CGFloat                 BackingScaleFactor() const;
 
-  mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() final {
-    return mozilla::DesktopToLayoutDeviceScale(BackingScaleFactor());
-  }
-
   // Call if the window's backing scale factor changes - i.e., it is moved
   // between HiDPI and non-HiDPI screens
   void                    BackingScaleFactorChanged();
 
   virtual double          GetDefaultScaleInternal() override;
 
   virtual int32_t         RoundsWidgetCoordinatesTo() override;
 
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -496,17 +496,17 @@ nsresult nsChildView::Create(nsIWidget* 
     gChildViewMethodsSwizzled = true;
   }
 
   mBounds = aRect;
 
   // Ensure that the toolkit is created.
   nsToolkit::GetToolkit();
 
-  BaseCreate(aParent, aInitData);
+  BaseCreate(aParent, aRect, aInitData);
 
   // inherit things from the parent view and create our parallel
   // NSView in the Cocoa display system
   mParentView = nil;
   if (aParent) {
     // inherit the top-level window. NS_NATIVE_WIDGET is always a NSView
     // regardless of if we're asking a window or a view (for compatibility
     // with windows).
--- a/widget/cocoa/nsCocoaWindow.h
+++ b/widget/cocoa/nsCocoaWindow.h
@@ -252,21 +252,16 @@ public:
 
     nsCocoaWindow();
 
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSPIWIDGETCOCOA
 
     NS_IMETHOD              Create(nsIWidget* aParent,
                                    nsNativeWidget aNativeParent,
-                                   const DesktopIntRect& aRect,
-                                   nsWidgetInitData* aInitData = nullptr) override;
-
-    NS_IMETHOD              Create(nsIWidget* aParent,
-                                   nsNativeWidget aNativeParent,
                                    const LayoutDeviceIntRect& aRect,
                                    nsWidgetInitData* aInitData = nullptr) override;
 
     NS_IMETHOD              Destroy() override;
 
     NS_IMETHOD              Show(bool aState) override;
     virtual nsIWidget*      GetSheetWindowParent(void) override;
     NS_IMETHOD              Enable(bool aState) override;
@@ -319,20 +314,16 @@ public:
     NS_IMETHOD              SetCursor(nsCursor aCursor) override;
     NS_IMETHOD              SetCursor(imgIContainer* aCursor, uint32_t aHotspotX, uint32_t aHotspotY) override;
 
     CGFloat                 BackingScaleFactor();
     void                    BackingScaleFactorChanged();
     virtual double          GetDefaultScaleInternal() override;
     virtual int32_t         RoundsWidgetCoordinatesTo() override;
 
-    mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() final {
-      return mozilla::DesktopToLayoutDeviceScale(BackingScaleFactor());
-    }
-
     NS_IMETHOD              SetTitle(const nsAString& aTitle) override;
 
     NS_IMETHOD Invalidate(const LayoutDeviceIntRect& aRect) override;
     virtual nsresult ConfigureChildren(const nsTArray<Configuration>& aConfigurations) override;
     virtual LayerManager* GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr,
                                           LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE,
                                           LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
                                           bool* aAllowRetaining = nullptr) override;
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -178,40 +178,40 @@ nsCocoaWindow::~nsCocoaWindow()
   }
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 // Find the screen that overlaps aRect the most,
 // if none are found default to the mainScreen.
 static NSScreen*
-FindTargetScreenForRect(const DesktopIntRect& aRect)
+FindTargetScreenForRect(const LayoutDeviceIntRect& aRect)
 {
   NSScreen *targetScreen = [NSScreen mainScreen];
   NSEnumerator *screenEnum = [[NSScreen screens] objectEnumerator];
   int largestIntersectArea = 0;
   while (NSScreen *screen = [screenEnum nextObject]) {
-    DesktopIntRect screenRect =
-      DesktopIntRect::FromUnknownRect(
+    LayoutDeviceIntRect screenRect =
+      LayoutDeviceIntRect::FromUnknownRect(
         nsCocoaUtils::CocoaRectToGeckoRect([screen visibleFrame]));
     screenRect = screenRect.Intersect(aRect);
     int area = screenRect.width * screenRect.height;
     if (area > largestIntersectArea) {
       largestIntersectArea = area;
       targetScreen = screen;
     }
   }
   return targetScreen;
 }
 
 // fits the rect to the screen that contains the largest area of it,
 // or to aScreen if a screen is passed in
-// NB: this operates with aRect in desktop pixels
+// NB: this operates with aRect in global display pixels
 static void
-FitRectToVisibleAreaForScreen(DesktopIntRect& aRect, NSScreen* aScreen)
+FitRectToVisibleAreaForScreen(LayoutDeviceIntRect& aRect, NSScreen* aScreen)
 {
   if (!aScreen) {
     aScreen = FindTargetScreenForRect(aRect);
   }
 
   nsIntRect screenBounds(nsCocoaUtils::CocoaRectToGeckoRect([aScreen visibleFrame]));
 
   if (aRect.width > screenBounds.width) {
@@ -244,39 +244,43 @@ static bool UseNativePopupWindows()
 {
 #ifdef MOZ_USE_NATIVE_POPUP_WINDOWS
   return true;
 #else
   return false;
 #endif /* MOZ_USE_NATIVE_POPUP_WINDOWS */
 }
 
-// aRect here is specified in desktop pixels
+// aRect here is specified in global display pixels
 nsresult nsCocoaWindow::Create(nsIWidget* aParent,
                                nsNativeWidget aNativeParent,
-                               const DesktopIntRect& aRect,
+                               const LayoutDeviceIntRect& aRect,
                                nsWidgetInitData* aInitData)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   // Because the hidden window is created outside of an event loop,
   // we have to provide an autorelease pool (see bug 559075).
   nsAutoreleasePool localPool;
 
-  DesktopIntRect newBounds = aRect;
+  LayoutDeviceIntRect newBounds = aRect;
   FitRectToVisibleAreaForScreen(newBounds, nullptr);
 
   // Set defaults which can be overriden from aInitData in BaseCreate
   mWindowType = eWindowType_toplevel;
   mBorderStyle = eBorderStyle_default;
 
   // Ensure that the toolkit is created.
   nsToolkit::GetToolkit();
 
-  Inherited::BaseCreate(aParent, aInitData);
+  // newBounds is still display (global screen) pixels at this point;
+  // fortunately, BaseCreate doesn't actually use it so we don't
+  // need to worry about trying to convert it to device pixels
+  // when we don't have a window (or dev context, perhaps) yet
+  Inherited::BaseCreate(aParent, newBounds, aInitData);
 
   mParent = aParent;
   mAncestorLink = aParent;
 
   // Applications that use native popups don't want us to create popup windows.
   if ((mWindowType == eWindowType_popup) && UseNativePopupWindows())
     return NS_OK;
 
@@ -286,38 +290,31 @@ nsresult nsCocoaWindow::Create(nsIWidget
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (mWindowType == eWindowType_popup) {
     if (aInitData->mMouseTransparent) {
       [mWindow setIgnoresMouseEvents:YES];
     }
     // now we can convert newBounds to device pixels for the window we created,
     // as the child view expects a rect expressed in the dev pix of its parent
-    LayoutDeviceIntRect devRect =
-      RoundedToInt(newBounds * GetDesktopToDeviceScale());
-    return CreatePopupContentView(devRect);
+    double scale = BackingScaleFactor();
+    newBounds.x *= scale;
+    newBounds.y *= scale;
+    newBounds.width *= scale;
+    newBounds.height *= scale;
+    return CreatePopupContentView(newBounds);
   }
 
   mIsAnimationSuppressed = aInitData->mIsAnimationSuppressed;
 
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
-nsresult nsCocoaWindow::Create(nsIWidget* aParent,
-                               nsNativeWidget aNativeParent,
-                               const LayoutDeviceIntRect& aRect,
-                               nsWidgetInitData* aInitData)
-{
-  DesktopIntRect desktopRect =
-    RoundedToInt(aRect / GetDesktopToDeviceScale());
-  return Create(aParent, aNativeParent, desktopRect, aInitData);
-}
-
 static unsigned int WindowMaskForBorderStyle(nsBorderStyle aBorderStyle)
 {
   bool allOrDefault = (aBorderStyle == eBorderStyle_all ||
                          aBorderStyle == eBorderStyle_default);
 
   /* Apple's docs on NSWindow styles say that "a window's style mask should
    * include NSTitledWindowMask if it includes any of the others [besides
    * NSBorderlessWindowMask]".  This implies that a borderless window
@@ -1181,17 +1178,17 @@ void nsCocoaWindow::SetSizeConstraints(c
   };
   [mWindow setMaxSize:maxSize];
 
   nsBaseWidget::SetSizeConstraints(c);
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
-// Coordinates are desktop pixels
+// Coordinates are global display pixels
 NS_IMETHODIMP nsCocoaWindow::Move(double aX, double aY)
 {
   if (!mWindow) {
     return NS_OK;
   }
 
   // The point we have is in Gecko coordinates (origin top-left). Convert
   // it to Cocoa ones (origin bottom-left).
@@ -1515,17 +1512,17 @@ nsCocoaWindow::DoMakeFullScreen(bool aFu
     EnteredFullScreen(aFullScreen, /* aNativeMode */ false);
   }
 
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
-// Coordinates are desktop pixels
+// Coordinates are global display pixels
 nsresult nsCocoaWindow::DoResize(double aX, double aY,
                                  double aWidth, double aHeight,
                                  bool aRepaint,
                                  bool aConstrainToCurrentScreen)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   if (!mWindow || mInResize) {
@@ -1537,19 +1534,19 @@ nsresult nsCocoaWindow::DoResize(double 
 
   // ConstrainSize operates in device pixels, so we need to convert using
   // the backing scale factor here
   CGFloat scale = BackingScaleFactor();
   int32_t width = NSToIntRound(aWidth * scale);
   int32_t height = NSToIntRound(aHeight * scale);
   ConstrainSize(&width, &height);
 
-  DesktopIntRect newBounds(NSToIntRound(aX), NSToIntRound(aY),
-                           NSToIntRound(width / scale),
-                           NSToIntRound(height / scale));
+  LayoutDeviceIntRect newBounds(NSToIntRound(aX), NSToIntRound(aY),
+                                NSToIntRound(width / scale),
+                                NSToIntRound(height / scale));
 
   // constrain to the screen that contains the largest area of the new rect
   FitRectToVisibleAreaForScreen(newBounds, aConstrainToCurrentScreen ?
                                            [mWindow screen] : nullptr);
 
   // convert requested bounds into Cocoa coordinate system
   NSRect newFrame =
     nsCocoaUtils::GeckoRectToCocoaRect(newBounds.ToUnknownRect());
@@ -1569,25 +1566,25 @@ nsresult nsCocoaWindow::DoResize(double 
   // the wrong place, leading to a visual jump.
   [mWindow setFrame:newFrame display:YES];
 
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
-// Coordinates are desktop pixels
+// Coordinates are global display pixels
 NS_IMETHODIMP nsCocoaWindow::Resize(double aX, double aY,
                                     double aWidth, double aHeight,
                                     bool aRepaint)
 {
   return DoResize(aX, aY, aWidth, aHeight, aRepaint, false);
 }
 
-// Coordinates are desktop pixels
+// Coordinates are global display pixels
 NS_IMETHODIMP nsCocoaWindow::Resize(double aWidth, double aHeight, bool aRepaint)
 {
   double invScale = 1.0 / GetDefaultScale().scale;
   return DoResize(mBounds.x * invScale, mBounds.y * invScale,
                   aWidth, aHeight, aRepaint, true);
 }
 
 NS_IMETHODIMP nsCocoaWindow::GetClientBounds(mozilla::LayoutDeviceIntRect& aRect)
@@ -1684,17 +1681,17 @@ GetBackingScaleFactor(NSWindow* aWindow)
   }
   if (frame.size.height == 0) {
     frame.size.height = 1;
   }
 
   // Then identify the screen it belongs to, and return its scale factor.
   NSScreen *screen =
     FindTargetScreenForRect(
-      DesktopIntRect::FromUnknownRect(nsCocoaUtils::CocoaRectToGeckoRect(frame)));
+      LayoutDeviceIntRect::FromUnknownRect(nsCocoaUtils::CocoaRectToGeckoRect(frame)));
   return nsCocoaUtils::GetBackingScaleFactor(screen);
 }
 
 CGFloat
 nsCocoaWindow::BackingScaleFactor()
 {
   if (mBackingScaleFactor > 0.0) {
     return mBackingScaleFactor;
--- a/widget/gonk/nsWindow.cpp
+++ b/widget/gonk/nsWindow.cpp
@@ -327,17 +327,17 @@ nsWindow::SynthesizeNativeTouchPoint(uin
 }
 
 NS_IMETHODIMP
 nsWindow::Create(nsIWidget* aParent,
                  void* aNativeParent,
                  const LayoutDeviceIntRect& aRect,
                  nsWidgetInitData* aInitData)
 {
-    BaseCreate(aParent, aInitData);
+    BaseCreate(aParent, aRect, aInitData);
 
     nsCOMPtr<nsIScreen> screen;
 
     uint32_t screenId = aParent ? ((nsWindow*)aParent)->mScreen->GetId() :
                                   aInitData->mScreenId;
 
     RefPtr<nsScreenManagerGonk> screenManager = nsScreenManagerGonk::GetInstance();
     screenManager->ScreenForId(screenId, getter_AddRefs(screen));
--- a/widget/gonk/nsWindow.h
+++ b/widget/gonk/nsWindow.h
@@ -41,21 +41,20 @@ public:
     nsWindow();
 
     NS_DECL_ISUPPORTS_INHERITED
 
     static void DoDraw(void);
     static nsEventStatus DispatchKeyInput(mozilla::WidgetKeyboardEvent& aEvent);
     static void DispatchTouchInput(mozilla::MultiTouchInput& aInput);
 
-    using nsBaseWidget::Create; // for Create signature not overridden here
     NS_IMETHOD Create(nsIWidget* aParent,
                       void* aNativeParent,
                       const LayoutDeviceIntRect& aRect,
-                      nsWidgetInitData* aInitData) override;
+                      nsWidgetInitData* aInitData);
     NS_IMETHOD Destroy(void);
 
     NS_IMETHOD Show(bool aState);
     virtual bool IsVisible() const;
     NS_IMETHOD ConstrainPosition(bool aAllowSlop,
                                  int32_t *aX,
                                  int32_t *aY);
     NS_IMETHOD Move(double aX,
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -1081,17 +1081,17 @@ nsWindow::Show(bool aState)
     NativeShow(aState);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::Resize(double aWidth, double aHeight, bool aRepaint)
 {
-    CSSToLayoutDeviceScale scale = BoundsUseDesktopPixels() ? GetDefaultScale()
+    CSSToLayoutDeviceScale scale = BoundsUseDisplayPixels() ? GetDefaultScale()
                                     : CSSToLayoutDeviceScale(1.0);
     int32_t width = NSToIntRound(scale.scale * aWidth);
     int32_t height = NSToIntRound(scale.scale * aHeight);
     ConstrainSize(&width, &height);
 
     // For top-level windows, aWidth and aHeight should possibly be
     // interpreted as frame bounds, but NativeResize treats these as window
     // bounds (Bug 581866).
@@ -1113,17 +1113,17 @@ nsWindow::Resize(double aWidth, double a
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::Resize(double aX, double aY, double aWidth, double aHeight,
                  bool aRepaint)
 {
-    CSSToLayoutDeviceScale scale = BoundsUseDesktopPixels() ? GetDefaultScale()
+    CSSToLayoutDeviceScale scale = BoundsUseDisplayPixels() ? GetDefaultScale()
                                     : CSSToLayoutDeviceScale(1.0);
     int32_t width = NSToIntRound(scale.scale * aWidth);
     int32_t height = NSToIntRound(scale.scale * aHeight);
     ConstrainSize(&width, &height);
 
     int32_t x = NSToIntRound(scale.scale * aX);
     int32_t y = NSToIntRound(scale.scale * aY);
     mBounds.x = x;
@@ -1179,17 +1179,17 @@ nsWindow::IsEnabled() const
 
 
 NS_IMETHODIMP
 nsWindow::Move(double aX, double aY)
 {
     LOG(("nsWindow::Move [%p] %f %f\n", (void *)this,
          aX, aY));
 
-    CSSToLayoutDeviceScale scale = BoundsUseDesktopPixels() ? GetDefaultScale()
+    CSSToLayoutDeviceScale scale = BoundsUseDisplayPixels() ? GetDefaultScale()
                                    : CSSToLayoutDeviceScale(1.0);
     int32_t x = NSToIntRound(aX * scale.scale);
     int32_t y = NSToIntRound(aY * scale.scale);
 
     if (mWindowType == eWindowType_toplevel ||
         mWindowType == eWindowType_dialog) {
         SetSizeMode(nsSizeMode_Normal);
     }
@@ -3524,17 +3524,17 @@ nsWindow::Create(nsIWidget* aParent,
     // Send a DBus message to check whether a11y is enabled
     a11y::PreInit();
 #endif
 
     // Ensure that the toolkit is created.
     nsGTKToolkit::GetToolkit();
 
     // initialize all the common bits of this class
-    BaseCreate(baseParent, aInitData);
+    BaseCreate(baseParent, aRect, aInitData);
 
     // Do we need to listen for resizes?
     bool listenForResizes = false;;
     if (aNativeParent || (aInitData && aInitData->mListenForResizes))
         listenForResizes = true;
 
     // and do our common creation
     CommonCreate(aParent, listenForResizes);
--- a/widget/gtk/nsWindow.h
+++ b/widget/gtk/nsWindow.h
@@ -90,17 +90,16 @@ public:
     
     // called when we are destroyed
     virtual void OnDestroy(void) override;
 
     // called to check and see if a widget's dimensions are sane
     bool AreBoundsSane(void);
 
     // nsIWidget
-    using nsBaseWidget::Create; // for Create signature not overridden here
     NS_IMETHOD         Create(nsIWidget* aParent,
                               nsNativeWidget aNativeParent,
                               const LayoutDeviceIntRect& aRect,
                               nsWidgetInitData* aInitData) override;
     NS_IMETHOD         Destroy(void) override;
     virtual nsIWidget *GetParent() override;
     virtual float      GetDPI() override;
     virtual double     GetDefaultScaleInternal() override; 
--- a/widget/nsBaseDragService.h
+++ b/widget/nsBaseDragService.h
@@ -83,17 +83,17 @@ protected:
    * Draw the drag image, if any, to a surface and return it. The drag image
    * is constructed from mImage if specified, or aDOMNode if mImage is null.
    *
    * aRegion may be used to draw only a subset of the element. This region
    * should be supplied using x and y coordinates measured in css pixels
    * that are relative to the upper-left corner of the window.
    *
    * aScreenX and aScreenY should be the screen coordinates of the mouse click
-   * for the drag. These are in desktop pixels.
+   * for the drag. These are in global display pixels.
    *
    * On return, aScreenDragRect will contain the screen coordinates of the
    * area being dragged. This is used by the platform-specific part of the
    * drag service to determine the drag feedback. This rect will be in the
    * device pixels of the presContext.
    *
    * If there is no drag image, the returned surface will be null, but
    * aScreenDragRect will still be set to the drag area.
--- a/widget/nsBaseScreen.h
+++ b/widget/nsBaseScreen.h
@@ -16,17 +16,17 @@ class nsBaseScreen : public nsIScreen
 public:
   nsBaseScreen();
 
   NS_DECL_ISUPPORTS
 
   // nsIScreen interface
 
   // These simply forward to the device-pixel versions;
-  // implementations where desktop pixels may not correspond
+  // implementations where global display pixels may not correspond
   // to per-screen device pixels must override.
   NS_IMETHOD GetRectDisplayPix(int32_t *outLeft,  int32_t *outTop,
                                int32_t *outWidth, int32_t *outHeight) override;
   NS_IMETHOD GetAvailRectDisplayPix(int32_t *outLeft,  int32_t *outTop,
                                     int32_t *outWidth, int32_t *outHeight) override;
 
   /**
    * Simple management of screen brightness locks. This abstract base class
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -328,16 +328,17 @@ nsBaseWidget::~nsBaseWidget()
 }
 
 //-------------------------------------------------------------------------
 //
 // Basic create.
 //
 //-------------------------------------------------------------------------
 void nsBaseWidget::BaseCreate(nsIWidget* aParent,
+                              const LayoutDeviceIntRect& aRect,
                               nsWidgetInitData* aInitData)
 {
   static bool gDisableNativeThemeCached = false;
   if (!gDisableNativeThemeCached) {
     Preferences::AddBoolVarCache(&gDisableNativeTheme,
                                  "mozilla.widget.disable-native-theme",
                                  gDisableNativeTheme);
     gDisableNativeThemeCached = true;
@@ -826,39 +827,34 @@ nsBaseWidget::PerformFullscreenTransitio
 //
 //-------------------------------------------------------------------------
 NS_IMETHODIMP nsBaseWidget::MakeFullScreen(bool aFullScreen, nsIScreen* aScreen)
 {
   HideWindowChrome(aFullScreen);
 
   if (aFullScreen) {
     if (!mOriginalBounds) {
-      mOriginalBounds = new LayoutDeviceIntRect();
+      mOriginalBounds = new CSSIntRect();
     }
-    GetScreenBounds(*mOriginalBounds);
+    *mOriginalBounds = GetScaledScreenBounds();
 
     // Move to top-left corner of screen and size to the screen dimensions
     nsCOMPtr<nsIScreen> screen = aScreen;
     if (!screen) {
       screen = GetWidgetScreen();
     }
     if (screen) {
       int32_t left, top, width, height;
       if (NS_SUCCEEDED(screen->GetRectDisplayPix(&left, &top, &width, &height))) {
         Resize(left, top, width, height, true);
       }
     }
   } else if (mOriginalBounds) {
-    if (BoundsUseDesktopPixels()) {
-      DesktopRect deskRect = *mOriginalBounds / GetDesktopToDeviceScale();
-      Resize(deskRect.x, deskRect.y, deskRect.width, deskRect.height, true);
-    } else {
-      Resize(mOriginalBounds->x, mOriginalBounds->y, mOriginalBounds->width,
-             mOriginalBounds->height, true);
-    }
+    Resize(mOriginalBounds->x, mOriginalBounds->y, mOriginalBounds->width,
+           mOriginalBounds->height, true);
   }
 
   return NS_OK;
 }
 
 nsBaseWidget::AutoLayerManagerSetup::AutoLayerManagerSetup(
     nsBaseWidget* aWidget, gfxContext* aTarget,
     BufferMode aDoubleBuffering, ScreenRotation aRotation)
@@ -1352,79 +1348,70 @@ NS_METHOD nsBaseWidget::SetWindowClass(c
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_METHOD nsBaseWidget::MoveClient(double aX, double aY)
 {
   LayoutDeviceIntPoint clientOffset(GetClientOffset());
 
-  // GetClientOffset returns device pixels; scale back to desktop pixels
+  // GetClientOffset returns device pixels; scale back to display pixels
   // if that's what this widget uses for the Move/Resize APIs
-  if (BoundsUseDesktopPixels()) {
-    DesktopPoint desktopOffset = clientOffset / GetDesktopToDeviceScale();
-    return Move(aX - desktopOffset.x, aY - desktopOffset.y);
-  } else {
-    return Move(aX - clientOffset.x, aY - clientOffset.y);
-  }
+  CSSToLayoutDeviceScale scale = BoundsUseDisplayPixels()
+                                    ? GetDefaultScale()
+                                    : CSSToLayoutDeviceScale(1.0);
+  aX -= clientOffset.x * 1.0 / scale.scale;
+  aY -= clientOffset.y * 1.0 / scale.scale;
+
+  return Move(aX, aY);
 }
 
 NS_METHOD nsBaseWidget::ResizeClient(double aWidth,
                                      double aHeight,
                                      bool aRepaint)
 {
   NS_ASSERTION((aWidth >=0) , "Negative width passed to ResizeClient");
   NS_ASSERTION((aHeight >=0), "Negative height passed to ResizeClient");
 
   LayoutDeviceIntRect clientBounds;
   GetClientBounds(clientBounds);
 
-  // GetClientBounds and mBounds are device pixels; scale back to desktop pixels
+  // GetClientBounds and mBounds are device pixels; scale back to display pixels
   // if that's what this widget uses for the Move/Resize APIs
-  if (BoundsUseDesktopPixels()) {
-    DesktopSize desktopDelta =
-      (LayoutDeviceIntSize(mBounds.width, mBounds.height) -
-       clientBounds.Size()) / GetDesktopToDeviceScale();
-    return Resize(aWidth + desktopDelta.width, aHeight + desktopDelta.height,
-                  aRepaint);
-  } else {
-    return Resize(mBounds.width + (aWidth - clientBounds.width),
-                  mBounds.height + (aHeight - clientBounds.height), aRepaint);
-  }
+  CSSToLayoutDeviceScale scale = BoundsUseDisplayPixels()
+                                    ? GetDefaultScale()
+                                    : CSSToLayoutDeviceScale(1.0);
+  double invScale = 1.0 / scale.scale;
+  aWidth = mBounds.width * invScale + (aWidth - clientBounds.width * invScale);
+  aHeight = mBounds.height * invScale + (aHeight - clientBounds.height * invScale);
+
+  return Resize(aWidth, aHeight, aRepaint);
 }
 
 NS_METHOD nsBaseWidget::ResizeClient(double aX,
                                      double aY,
                                      double aWidth,
                                      double aHeight,
                                      bool aRepaint)
 {
   NS_ASSERTION((aWidth >=0) , "Negative width passed to ResizeClient");
   NS_ASSERTION((aHeight >=0), "Negative height passed to ResizeClient");
 
   LayoutDeviceIntRect clientBounds;
   GetClientBounds(clientBounds);
 
+  double scale = BoundsUseDisplayPixels() ? 1.0 / GetDefaultScale().scale : 1.0;
+  aWidth = mBounds.width * scale + (aWidth - clientBounds.width * scale);
+  aHeight = mBounds.height * scale + (aHeight - clientBounds.height * scale);
+
   LayoutDeviceIntPoint clientOffset(GetClientOffset());
-
-  if (BoundsUseDesktopPixels()) {
-    DesktopToLayoutDeviceScale scale = GetDesktopToDeviceScale();
-    DesktopPoint desktopOffset = clientOffset / scale;
-    DesktopSize desktopDelta =
-      (LayoutDeviceIntSize(mBounds.width, mBounds.height) -
-       clientBounds.Size()) / scale;
-    return Resize(aX - desktopOffset.x, aY - desktopOffset.y,
-                  aWidth + desktopDelta.width, aHeight + desktopDelta.height,
-                  aRepaint);
-  } else {
-    return Resize(aX - clientOffset.x, aY - clientOffset.y,
-                  aWidth + mBounds.width - clientBounds.width,
-                  aHeight + mBounds.height - clientBounds.height,
-                  aRepaint);
-  }
+  aX -= clientOffset.x * scale;
+  aY -= clientOffset.y * scale;
+
+  return Resize(aX, aY, aWidth, aHeight, aRepaint);
 }
 
 //-------------------------------------------------------------------------
 //
 // Bounds
 //
 //-------------------------------------------------------------------------
 
@@ -1616,17 +1603,17 @@ nsBaseWidget::GetGLFrameBufferFormat()
 
 void nsBaseWidget::SetSizeConstraints(const SizeConstraints& aConstraints)
 {
   mSizeConstraints = aConstraints;
   // We can't ensure that the size is honored at this point because we're
   // probably in the middle of a reflow.
 }
 
-const widget::SizeConstraints nsBaseWidget::GetSizeConstraints()
+const widget::SizeConstraints& nsBaseWidget::GetSizeConstraints() const
 {
   return mSizeConstraints;
 }
 
 // static
 nsIRollupListener*
 nsBaseWidget::GetActiveRollupListener()
 {
@@ -1813,27 +1800,38 @@ nsBaseWidget::StartAsyncScrollbarDrag(co
 
   int layersId = mCompositorParent->RootLayerTreeId();;
   ScrollableLayerGuid guid(layersId, aDragMetrics.mPresShellId, aDragMetrics.mViewId);
 
   APZThreadUtils::RunOnControllerThread(
     NewRunnableMethod(mAPZC.get(), &APZCTreeManager::StartScrollbarDrag, guid, aDragMetrics));
 }
 
+CSSIntRect
+nsBaseWidget::GetScaledScreenBounds()
+{
+  LayoutDeviceIntRect bounds;
+  GetScreenBounds(bounds);
+
+  // *Dividing* a LayoutDeviceIntRect by a CSSToLayoutDeviceScale gives a
+  // CSSIntRect.
+  CSSToLayoutDeviceScale scale = GetDefaultScale();
+  return RoundedToInt(bounds / scale);
+}
+
 already_AddRefed<nsIScreen>
 nsBaseWidget::GetWidgetScreen()
 {
   nsCOMPtr<nsIScreenManager> screenManager;
   screenManager = do_GetService("@mozilla.org/gfx/screenmanager;1");
   if (!screenManager) {
     return nullptr;
   }
 
-  LayoutDeviceIntRect bounds;
-  GetScreenBounds(bounds);
+  CSSIntRect bounds = GetScaledScreenBounds();
   nsCOMPtr<nsIScreen> screen;
   screenManager->ScreenForRect(bounds.x, bounds.y,
                                bounds.width, bounds.height,
                                getter_AddRefs(screen));
   return screen.forget();
 }
 
 nsresult
--- a/widget/nsBaseWidget.h
+++ b/widget/nsBaseWidget.h
@@ -173,30 +173,25 @@ public:
   virtual void            EndRemoteDrawing() override { };
   virtual void            CleanupRemoteDrawing() override { };
   virtual void            UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) override {}
   NS_IMETHOD              SetModal(bool aModal) override;
   virtual uint32_t        GetMaxTouchPoints() const override;
   NS_IMETHOD              SetWindowClass(const nsAString& xulWinType) override;
   virtual nsresult        SetWindowClipRegion(const nsTArray<LayoutDeviceIntRect>& aRects, bool aIntersectWithExisting) override;
   // Return whether this widget interprets parameters to Move and Resize APIs
-  // as "desktop pixels" rather than "device pixels", and therefore
+  // as "global display pixels" rather than "device pixels", and therefore
   // applies its GetDefaultScale() value to them before using them as mBounds
   // etc (which are always stored in device pixels).
   // Note that APIs that -get- the widget's position/size/bounds, rather than
   // -setting- them (i.e. moving or resizing the widget) will always return
   // values in the widget's device pixels.
-  bool                    BoundsUseDesktopPixels() const {
+  bool                    BoundsUseDisplayPixels() const {
     return mWindowType <= eWindowType_popup;
   }
-  // Default implementation, to be overridden by platforms where desktop coords
-  // are virtualized and may not correspond to device pixels on the screen.
-  mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() override {
-    return mozilla::DesktopToLayoutDeviceScale(1.0);
-  }
   NS_IMETHOD              MoveClient(double aX, double aY) override;
   NS_IMETHOD              ResizeClient(double aWidth, double aHeight, bool aRepaint) override;
   NS_IMETHOD              ResizeClient(double aX, double aY, double aWidth, double aHeight, bool aRepaint) override;
   NS_IMETHOD              GetBounds(LayoutDeviceIntRect& aRect) override;
   NS_IMETHOD              GetClientBounds(LayoutDeviceIntRect& aRect) override;
   NS_IMETHOD              GetScreenBounds(LayoutDeviceIntRect& aRect) override;
   NS_IMETHOD              GetRestoredBounds(LayoutDeviceIntRect& aRect) override;
   NS_IMETHOD              GetNonClientMargins(LayoutDeviceIntMargin& aMargins) override;
@@ -293,32 +288,36 @@ public:
   nsPopupLevel PopupLevel() { return mPopupLevel; }
 
   virtual LayoutDeviceIntSize
   ClientToWindowSize(const LayoutDeviceIntSize& aClientSize) override
   {
     return aClientSize;
   }
 
+  // return the widget's outside dimensions
+  // in global coordinates in display pixel.
+  CSSIntRect GetScaledScreenBounds();
+
   // return the screen the widget is in.
   already_AddRefed<nsIScreen> GetWidgetScreen();
 
   // return true if this is a popup widget with a native titlebar
   bool IsPopupWithTitleBar() const
   {
     return (mWindowType == eWindowType_popup && 
             mBorderStyle != eBorderStyle_default &&
             mBorderStyle & eBorderStyle_title);
   }
 
   NS_IMETHOD              ReparentNativeWidget(nsIWidget* aNewParent) override = 0;
 
   virtual uint32_t GetGLFrameBufferFormat() override;
 
-  virtual const SizeConstraints GetSizeConstraints() override;
+  virtual const SizeConstraints& GetSizeConstraints() const override;
   virtual void SetSizeConstraints(const SizeConstraints& aConstraints) override;
 
   virtual bool CaptureWidgetOnScreen(RefPtr<mozilla::gfx::DrawTarget> aDT) override {
     return false;
   }
 
   virtual void StartAsyncScrollbarDrag(const AsyncDragMetrics& aDragMetrics) override;
 
@@ -352,16 +351,17 @@ public:
 
 protected:
 
   void            ResolveIconName(const nsAString &aIconName,
                                   const nsAString &aIconSuffix,
                                   nsIFile **aResult);
   virtual void    OnDestroy();
   void            BaseCreate(nsIWidget *aParent,
+                             const LayoutDeviceIntRect& aRect,
                              nsWidgetInitData* aInitData);
 
   virtual void ConfigureAPZCTreeManager();
   virtual void ConfigureAPZControllerThread();
   virtual already_AddRefed<GeckoContentController> CreateRootContentController();
 
   // Dispatch an event that has already been routed through APZ.
   nsEventStatus ProcessUntransformedAPZEvent(mozilla::WidgetInputEvent* aEvent,
@@ -462,23 +462,22 @@ protected:
   }
 
   /**
    * Apply the current size constraints to the given size.
    *
    * @param aWidth width to constrain
    * @param aHeight height to constrain
    */
-  void ConstrainSize(int32_t* aWidth, int32_t* aHeight)
+  void ConstrainSize(int32_t* aWidth, int32_t* aHeight) const
   {
-    SizeConstraints c = GetSizeConstraints();
-    *aWidth = std::max(c.mMinSize.width,
-                       std::min(c.mMaxSize.width, *aWidth));
-    *aHeight = std::max(c.mMinSize.height,
-                        std::min(c.mMaxSize.height, *aHeight));
+    *aWidth = std::max(mSizeConstraints.mMinSize.width,
+                     std::min(mSizeConstraints.mMaxSize.width, *aWidth));
+    *aHeight = std::max(mSizeConstraints.mMinSize.height,
+                      std::min(mSizeConstraints.mMaxSize.height, *aHeight));
   }
 
   virtual CompositorChild* GetRemoteRenderer() override;
 
   /**
    * Notify the widget that this window is being used with OMTC.
    */
   virtual void WindowUsesOMTC() {}
@@ -511,17 +510,17 @@ protected:
   RefPtr<APZCTreeManager> mAPZC;
   RefPtr<APZEventState> mAPZEventState;
   SetAllowedTouchBehaviorCallback mSetAllowedTouchBehaviorCallback;
   RefPtr<WidgetShutdownObserver> mShutdownObserver;
   RefPtr<TextEventDispatcher> mTextEventDispatcher;
   nsCursor          mCursor;
   nsBorderStyle     mBorderStyle;
   LayoutDeviceIntRect mBounds;
-  LayoutDeviceIntRect* mOriginalBounds;
+  CSSIntRect* mOriginalBounds;
   // When this pointer is null, the widget is not clipped
   mozilla::UniquePtr<LayoutDeviceIntRect[]> mClipRects;
   uint32_t          mClipRectCount;
   nsSizeMode        mSizeMode;
   nsPopupLevel      mPopupLevel;
   nsPopupType       mPopupType;
   SizeConstraints   mSizeConstraints;
 
--- a/widget/nsIBaseWindow.idl
+++ b/widget/nsIBaseWindow.idl
@@ -16,17 +16,17 @@ class nsIWidget;
 typedef voidPtr nativeWindow;
 
 /**
  * The nsIBaseWindow describes a generic window and basic operations that 
  * can be performed on it.  This is not to be a complete windowing interface
  * but rather a common set that nearly all windowed objects support.    
  */
 
-[scriptable, uuid(ca635529-a977-4552-9b8a-66187e54d882)]
+[scriptable, uuid(9DA319F3-EEE6-4504-81A5-6A19CF6215BF)]
 interface nsIBaseWindow : nsISupports
 {
 	/*
 	Allows a client to initialize an object implementing this interface with
 	the usually required window setup information.
 	It is possible to pass null for both parentNativeWindow and parentWidget,
 	but only docshells support this.
 
@@ -187,30 +187,16 @@ interface nsIBaseWindow : nsISupports
 	The number of	device pixels per CSS pixel used on this window's current
 	screen at the default zoom level.
 	This is the value returned by GetDefaultScale() of the underlying widget.
 	Note that this may change if the window is moved between screens with
 	differing resolutions.
 	*/
 	readonly attribute double unscaledDevicePixelsPerCSSPixel;
 
-	/*
-	The number of device pixels per display pixel on this window's current
-	screen. (The meaning of "display pixel" varies across OS environments;
-	it is the pixel units used by the desktop environment to manage screen
-	real estate and window positioning, which may correspond to (per-screen)
-	device pixels, or may be a virtual coordinate space that covers a multi-
-	monitor, mixed-dpi desktop space.)
-	This is the value returned by DevicePixelsPerDesktopPixel() of the underlying
-	widget.
-	Note that this may change if the window is moved between screens with
-	differing resolutions.
-	*/
-	readonly attribute double devicePixelsPerDesktopPixel;
-
 	/**
 	* Give the window focus.
 	*/
 	void setFocus();
 
 	/*
 	Title of the window.
 	*/
--- a/widget/nsIScreen.idl
+++ b/widget/nsIScreen.idl
@@ -37,17 +37,17 @@ interface nsIScreen : nsISupports
 
   /**
    * These report screen dimensions in (screen-specific) device pixels
    */
   void GetRect(out long left, out long top, out long width, out long height);
   void GetAvailRect(out long left, out long top, out long width, out long height);
 
   /**
-   * And these report in desktop pixels
+   * And these report in global display pixels
    */
   void GetRectDisplayPix(out long left, out long top, out long width, out long height);
   void GetAvailRectDisplayPix(out long left, out long top, out long width, out long height);
 
   /**
    * Locks the minimum brightness of the screen, forcing it to be at
    * least as bright as a certain brightness level. Each call to this
    * function must eventually be followed by a corresponding call to
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -344,17 +344,16 @@ class nsIWidget : public nsISupports {
     typedef mozilla::widget::TextEventDispatcher TextEventDispatcher;
     typedef mozilla::CompositorVsyncDispatcher CompositorVsyncDispatcher;
     typedef mozilla::LayoutDeviceIntMargin LayoutDeviceIntMargin;
     typedef mozilla::LayoutDeviceIntPoint LayoutDeviceIntPoint;
     typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
     typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion;
     typedef mozilla::LayoutDeviceIntSize LayoutDeviceIntSize;
     typedef mozilla::ScreenIntPoint ScreenIntPoint;
-    typedef mozilla::DesktopIntRect DesktopIntRect;
     typedef mozilla::CSSRect CSSRect;
 
     // Used in UpdateThemeGeometries.
     struct ThemeGeometry {
       // The ThemeGeometryType value for the themed widget, see
       // nsITheme::ThemeGeometryTypeForWidget.
       nsITheme::ThemeGeometryType mType;
       // The device-pixel rect within the window for the themed widget
@@ -396,50 +395,30 @@ class nsIWidget : public nsISupports {
      * calling code must handle paint messages and clear the background 
      * itself. 
      *
      * In practice at least one of aParent and aNativeParent will be null. If
      * both are null the widget isn't parented (e.g. context menus or
      * independent top level windows).
      *
      * The dimensions given in aRect are specified in the parent's
-     * device coordinate system.
-     * This must not be called for parentless widgets such as top-level
-     * windows, which use the desktop pixel coordinate system; a separate
-     * method is provided for these.
+     * coordinate system, or for parentless widgets such as top-level
+     * windows, in global CSS pixels.
      *
      * @param     aParent       parent nsIWidget
      * @param     aNativeParent native parent widget
      * @param     aRect         the widget dimension
      * @param     aInitData     data that is used for widget initialization
      *
      */
     NS_IMETHOD Create(nsIWidget* aParent,
                       nsNativeWidget aNativeParent,
                       const LayoutDeviceIntRect& aRect,
                       nsWidgetInitData* aInitData = nullptr) = 0;
 
-    /*
-     * As above, but with aRect specified in DesktopPixel units (for top-level
-     * widgets).
-     * Default implementation just converts aRect to device pixels and calls
-     * through to device-pixel Create, but platforms may override this if the
-     * mapping is not straightforward or the native platform needs to use the
-     * desktop pixel values directly.
-     */
-    NS_IMETHOD Create(nsIWidget* aParent,
-                      nsNativeWidget aNativeParent,
-                      const DesktopIntRect& aRect,
-                      nsWidgetInitData* aInitData = nullptr)
-    {
-        LayoutDeviceIntRect devPixRect =
-          RoundedToInt(aRect * GetDesktopToDeviceScale());
-        return Create(aParent, aNativeParent, devPixRect, aInitData);
-    }
-
     /**
      * Allocate, initialize, and return a widget that is a child of
      * |this|.  The returned widget (if nonnull) has gone through the
      * equivalent of CreateInstance(widgetCID) + Create(...).
      *
      * |CreateChild()| lets widget backends decide whether to parent
      * the new child widget to this, nonnatively parent it, or both.
      * This interface exists to support the PuppetWidget backend,
@@ -541,23 +520,16 @@ class nsIWidget : public nsISupports {
 
     /**
      * Return the physical DPI of the screen containing the window ...
      * the number of device pixels per inch.
      */
     virtual float GetDPI() = 0;
 
     /**
-     * Return the scaling factor between device pixels and the platform-
-     * dependent "desktop pixels" used to manage window positions on a
-     * potentially multi-screen, mixed-resolution desktop.
-     */
-    virtual mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() = 0;
-
-    /**
      * Returns the CompositorVsyncDispatcher associated with this widget
      */
     virtual CompositorVsyncDispatcher* GetCompositorVsyncDispatcher() = 0;
 
     /**
      * Return the default scale factor for the window. This is the
      * default number of device pixels per CSS pixel to use. This should
      * depend on OS/platform settings such as the Mac's "UI scale factor"
@@ -859,17 +831,17 @@ class nsIWidget : public nsISupports {
      * relative to its parent widget.
      *
      * @param aRect   On return it holds the  x, y, width and height of
      *                this widget.
      */
     NS_IMETHOD GetBounds(LayoutDeviceIntRect& aRect) = 0;
 
     /**
-     * Get this widget's outside dimensions in device coordinates. This
+     * Get this widget's outside dimensions in global coordinates. This
      * includes any title bar on the window.
      *
      * @param aRect   On return it holds the  x, y, width and height of
      *                this widget.
      */
     NS_IMETHOD GetScreenBounds(LayoutDeviceIntRect& aRect) = 0;
 
     /**
@@ -879,28 +851,28 @@ class nsIWidget : public nsISupports {
      * This method will fail if the size mode is not nsSizeMode_Normal and
      * the platform doesn't have the ability.
      * This method will always succeed if the current size mode is
      * nsSizeMode_Normal.
      *
      * @param aRect   On return it holds the  x, y, width and height of
      *                this widget.
      */
-    NS_IMETHOD GetRestoredBounds(LayoutDeviceIntRect& aRect) = 0;
+    NS_IMETHOD GetRestoredBounds(mozilla::LayoutDeviceIntRect& aRect) = 0;
 
     /**
      * Get this widget's client area bounds, if the window has a 3D border
      * appearance this returns the area inside the border. The position is the
      * position of the client area relative to the client area of the parent
      * widget (for root widgets and popup widgets it is in screen coordinates).
      *
      * @param aRect   On return it holds the  x. y, width and height of
      *                the client area of this widget.
      */
-    NS_IMETHOD GetClientBounds(LayoutDeviceIntRect& aRect) = 0;
+    NS_IMETHOD GetClientBounds(mozilla::LayoutDeviceIntRect& aRect) = 0;
 
     /**
      * Get the non-client area dimensions of the window.
      */
     NS_IMETHOD GetNonClientMargins(LayoutDeviceIntMargin& aMargins) = 0;
 
     /**
      * Sets the non-client area dimensions of the window. Pass -1 to restore
@@ -1997,17 +1969,17 @@ public:
      */
     virtual void SetSizeConstraints(const SizeConstraints& aConstraints) = 0;
 
     /**
      * Return the size constraints currently observed by the widget.
      *
      * @return the constraints in device pixels
      */
-    virtual const SizeConstraints GetSizeConstraints() = 0;
+    virtual const SizeConstraints& GetSizeConstraints() const = 0;
 
     /**
      * If this is owned by a TabChild, return that.  Otherwise return
      * null.
      */
     virtual TabChild* GetOwningTabChild() { return nullptr; }
 
     /**
--- a/widget/qt/nsWindow.cpp
+++ b/widget/qt/nsWindow.cpp
@@ -138,17 +138,17 @@ nsWindow::Create(nsIWidget* aParent,
                  const LayoutDeviceIntRect& aRect,
                  nsWidgetInitData* aInitData)
 {
     // only set the base parent if we're not going to be a dialog or a
     // toplevel
     nsIWidget *baseParent = aParent;
 
     // initialize all the common bits of this class
-    BaseCreate(baseParent, aInitData);
+    BaseCreate(baseParent, aRect, aInitData);
 
     mVisible = true;
 
     // and do our common creation
     mParent = (nsWindow *)aParent;
 
     // save our bounds
     mBounds = aRect;
--- a/widget/uikit/nsWindow.mm
+++ b/widget/uikit/nsWindow.mm
@@ -498,17 +498,19 @@ nsWindow::Create(nsIWidget* aParent,
 
     ALOG("nsWindow[%p]::Create bounds: %d %d %d %d", (void*)this,
          mBounds.x, mBounds.y, mBounds.width, mBounds.height);
 
     // Set defaults which can be overriden from aInitData in BaseCreate
     mWindowType = eWindowType_toplevel;
     mBorderStyle = eBorderStyle_default;
 
-    Inherited::BaseCreate(aParent, aInitData);
+    Inherited::BaseCreate(aParent,
+                          LayoutDeviceIntRect::FromUnknownRect(mBounds),
+                          aInitData);
 
     NS_ASSERTION(IsTopLevel() || parent, "non top level window doesn't have a parent!");
 
     mNativeView = [[ChildView alloc] initWithFrame:DevPixelsToUIKitPoints(mBounds, BackingScaleFactor()) geckoChild:this];
     mNativeView.hidden = YES;
 
     if (parent) {
         parent->mChildren.AppendElement(this);
--- a/widget/windows/TaskbarPreview.cpp
+++ b/widget/windows/TaskbarPreview.cpp
@@ -16,16 +16,17 @@
 #include <nsIObserverService.h>
 #include <nsServiceManagerUtils.h>
 
 #include "nsUXThemeData.h"
 #include "nsWindow.h"
 #include "nsAppShell.h"
 #include "TaskbarPreviewButton.h"
 #include "WinUtils.h"
+#include "gfxWindowsPlatform.h"
 
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/DataSurfaceHelpers.h"
 #include "mozilla/Telemetry.h"
 
 // Defined in dwmapi in a header that needs a higher numbered _WINNT #define
 #define DWM_SIT_DISPLAYFRAME 0x1
@@ -233,19 +234,19 @@ TaskbarPreview::WndProc(UINT nMsg, WPARA
         rv = mController->GetWidth(&width);
         if (NS_FAILED(rv))
           break;
         rv = mController->GetHeight(&height);
         if (NS_FAILED(rv))
           break;
 
         double scale = nsIWidget::DefaultScaleOverride();
-        if (scale <= 0.0) {
-          scale = WinUtils::LogToPhysFactor(PreviewWindow());
-        }
+        if (scale <= 0.0)
+          scale = gfxWindowsPlatform::GetPlatform()->GetDPIScale();
+
         DrawBitmap(NSToIntRound(scale * width), NSToIntRound(scale * height), true);
       }
       break;
   }
   return ::DefWindowProcW(PreviewWindow(), nMsg, wParam, lParam);
 }
 
 bool
--- a/widget/windows/WinUtils.cpp
+++ b/widget/windows/WinUtils.cpp
@@ -519,129 +519,55 @@ WinUtils::Log(const char *fmt, ...)
   printf("%s\n", buffer);
 
   NS_ASSERTION(gWindowsLog, "Called WinUtils Log() but Widget "
                                "log module doesn't exist!");
   MOZ_LOG(gWindowsLog, LogLevel::Error, (buffer));
   delete[] buffer;
 }
 
-#ifndef WM_DPICHANGED
-typedef enum {
-  MDT_EFFECTIVE_DPI = 0,
-  MDT_ANGULAR_DPI = 1,
-  MDT_RAW_DPI = 2,
-  MDT_DEFAULT = MDT_EFFECTIVE_DPI
-} MONITOR_DPI_TYPE;
-
-typedef enum {
-  PROCESS_DPI_UNAWARE = 0,
-  PROCESS_SYSTEM_DPI_AWARE = 1,
-  PROCESS_PER_MONITOR_DPI_AWARE = 2
-} PROCESS_DPI_AWARENESS;
-#endif
-
-typedef HRESULT
-(WINAPI *GETDPIFORMONITORPROC)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*);
-
-typedef HRESULT
-(WINAPI *GETPROCESSDPIAWARENESSPROC)(HANDLE, PROCESS_DPI_AWARENESS*);
-
-GETDPIFORMONITORPROC sGetDpiForMonitor;
-GETPROCESSDPIAWARENESSPROC sGetProcessDpiAwareness;
-
-static bool
-SlowIsPerMonitorDPIAware()
-{
-  if (IsVistaOrLater()) {
-    // Intentionally leak the handle.
-    HMODULE shcore =
-      LoadLibraryEx(L"shcore", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
-    if (shcore) {
-      sGetDpiForMonitor =
-        (GETDPIFORMONITORPROC) GetProcAddress(shcore, "GetDpiForMonitor");
-      sGetProcessDpiAwareness =
-        (GETPROCESSDPIAWARENESSPROC) GetProcAddress(shcore, "GetProcessDpiAwareness");
-    }
-  }
-  PROCESS_DPI_AWARENESS dpiAwareness;
-  return sGetDpiForMonitor && sGetProcessDpiAwareness &&
-      SUCCEEDED(sGetProcessDpiAwareness(GetCurrentProcess(), &dpiAwareness)) &&
-      dpiAwareness == PROCESS_PER_MONITOR_DPI_AWARE;
-}
-
-/* static */ bool
-WinUtils::IsPerMonitorDPIAware()
-{
-  static bool perMonitorDPIAware = SlowIsPerMonitorDPIAware();
-  return perMonitorDPIAware;
-}
-
 /* static */
 double
-WinUtils::LogToPhysFactor(HMONITOR aMonitor)
+WinUtils::LogToPhysFactor()
 {
-  if (IsPerMonitorDPIAware()) {
-    UINT dpiX, dpiY = 96;
-    sGetDpiForMonitor(aMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
-    return dpiY / 96.0;
-  }
-
-  // The system DPI will never change during the session.
+  // dpi / 96.0
   HDC hdc = ::GetDC(nullptr);
   double result = ::GetDeviceCaps(hdc, LOGPIXELSY) / 96.0;
   ::ReleaseDC(nullptr, hdc);
 
   if (result == 0) {
     // Bug 1012487 - This can occur when the Screen DC is used off the
     // main thread on windows. For now just assume a 100% DPI for this
     // drawing call.
     // XXX - fixme!
     result = 1.0;
   }
   return result;
 }
 
 /* static */
-int32_t
-WinUtils::LogToPhys(HMONITOR aMonitor, double aValue)
+double
+WinUtils::PhysToLogFactor()
 {
-  return int32_t(NS_round(aValue * LogToPhysFactor(aMonitor)));
-}
-
-/* static */
-HMONITOR
-WinUtils::GetPrimaryMonitor()
-{
-  const POINT pt = { 0, 0 };
-  return ::MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
+  // 1.0 / (dpi / 96.0)
+  return 1.0 / LogToPhysFactor();
 }
 
 /* static */
-HMONITOR
-WinUtils::MonitorFromRect(const gfx::Rect& rect)
+double
+WinUtils::PhysToLog(int32_t aValue)
 {
-  // convert coordinates from logical to device pixels for MonitorFromRect
-  double dpiScale = nsIWidget::DefaultScaleOverride();
-  if (dpiScale <= 0.0) {
-    if (IsPerMonitorDPIAware()) {
-      dpiScale = 1.0;
-    } else {
-      dpiScale = LogToPhysFactor(GetPrimaryMonitor());
-    }
-  }
+  return double(aValue) * PhysToLogFactor();
+}
 
-  RECT globalWindowBounds = {
-    NSToIntRound(dpiScale * rect.x),
-    NSToIntRound(dpiScale * rect.y),
-    NSToIntRound(dpiScale * (rect.x + rect.width)),
-    NSToIntRound(dpiScale * (rect.y + rect.height))
-  };
-
-  return ::MonitorFromRect(&globalWindowBounds, MONITOR_DEFAULTTONEAREST);
+/* static */
+int32_t
+WinUtils::LogToPhys(double aValue)
+{
+  return int32_t(NS_round(aValue * LogToPhysFactor()));
 }
 
 /* static */
 bool
 WinUtils::PeekMessage(LPMSG aMsg, HWND aWnd, UINT aFirstMessage,
                       UINT aLastMessage, UINT aOption)
 {
 #ifdef NS_ENABLE_TSF
--- a/widget/windows/WinUtils.h
+++ b/widget/windows/WinUtils.h
@@ -123,32 +123,24 @@ public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOWNLOADOBSERVER
 };
 #endif
 
 class WinUtils
 {
 public:
-
-  static bool IsPerMonitorDPIAware();
   /**
    * Functions to convert between logical pixels as used by most Windows APIs
    * and physical (device) pixels.
    */
-  static double LogToPhysFactor(HMONITOR aMonitor);
-  static double LogToPhysFactor(HWND aWnd) {
-    return LogToPhysFactor(::MonitorFromWindow(aWnd, MONITOR_DEFAULTTOPRIMARY));
-  }
-  static double LogToPhysFactor(HDC aDC) {
-    return LogToPhysFactor(::WindowFromDC(aDC));
-  }
-  static int32_t LogToPhys(HMONITOR aMonitor, double aValue);
-  static HMONITOR GetPrimaryMonitor();
-  static HMONITOR MonitorFromRect(const gfx::Rect& rect);
+  static double LogToPhysFactor();
+  static double PhysToLogFactor();
+  static int32_t LogToPhys(double aValue);
+  static double PhysToLog(int32_t aValue);
 
   /**
    * Logging helpers that dump output to prlog module 'Widget', console, and
    * OutputDebugString. Note these output in both debug and release builds.
    */
   static void Log(const char *fmt, ...);
   static void LogW(const wchar_t *fmt, ...);
 
--- a/widget/windows/nsDragService.cpp
+++ b/widget/windows/nsDragService.cpp
@@ -32,17 +32,17 @@
 #include "nsCWebBrowserPersist.h"
 #include "nsToolkit.h"
 #include "nsCRT.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsUnicharUtils.h"
 #include "gfxContext.h"
 #include "nsRect.h"
 #include "nsMathUtils.h"
-#include "WinUtils.h"
+#include "gfxWindowsPlatform.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/DataSurfaceHelpers.h"
 #include "mozilla/gfx/Tools.h"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 
 //-------------------------------------------------------------------------
@@ -320,19 +320,17 @@ nsDragService::StartInvokingDragSession(
   mUserCancelled = nativeDragSrc->UserCancelled();
 
   // We're done dragging, get the cursor position and end the drag
   // Use GetMessagePos to get the position of the mouse at the last message
   // seen by the event loop. (Bug 489729)
   // Note that we must convert this from device pixels back to Windows logical
   // pixels (bug 818927).
   DWORD pos = ::GetMessagePos();
-  POINT pt = { GET_X_LPARAM(pos), GET_Y_LPARAM(pos) };
-  HMONITOR monitor = ::MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
-  double dpiScale = widget::WinUtils::LogToPhysFactor(monitor);
+  FLOAT dpiScale = gfxWindowsPlatform::GetPlatform()->GetDPIScale();
   nsIntPoint logPos(NSToIntRound(GET_X_LPARAM(pos) / dpiScale),
                     NSToIntRound(GET_Y_LPARAM(pos) / dpiScale));
   SetDragEndPoint(logPos);
   EndDragSession(true);
 
   mDoingDrag = false;
 
   return DRAGDROP_S_DROP == res ? NS_OK : NS_ERROR_FAILURE;
--- a/widget/windows/nsLookAndFeel.cpp
+++ b/widget/windows/nsLookAndFeel.cpp
@@ -5,17 +5,17 @@
 
 #include "nsLookAndFeel.h"
 #include <windows.h>
 #include <shellapi.h>
 #include "nsStyleConsts.h"
 #include "nsUXThemeData.h"
 #include "nsUXThemeConstants.h"
 #include "gfxFont.h"
-#include "WinUtils.h"
+#include "gfxWindowsPlatform.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/WindowsVersion.h"
 #include "gfxFontConstants.h"
 
 using namespace mozilla;
 using namespace mozilla::widget;
 
 //static
@@ -579,17 +579,17 @@ GetSysFontInfo(HDC aHDC, LookAndFeel::Fo
     default:
       ptrLogFont = &ncm.lfMessageFont;
       break;
     }
     break;
   }
 
   // Get scaling factor from physical to logical pixels
-  double pixelScale = 1.0 / WinUtils::LogToPhysFactor(aHDC);
+  float pixelScale = 1.0f / gfxWindowsPlatform::GetPlatform()->GetDPIScale();
 
   // The lfHeight is in pixels, and it needs to be adjusted for the
   // device it will be displayed on.
   // Screens and Printers will differ in DPI
   //
   // So this accounts for the difference in the DeviceContexts
   // The pixelScale will typically be 1.0 for the screen
   // (though larger for hi-dpi screens where the Windows resolution
--- a/widget/windows/nsNativeThemeWin.cpp
+++ b/widget/windows/nsNativeThemeWin.cpp
@@ -191,17 +191,17 @@ GetGutterSize(HANDLE theme, HDC hdc)
     SIZE checkboxBGSize(GetCheckboxBGBounds(theme, hdc));
 
     SIZE itemSize;
     GetThemePartSize(theme, hdc, MENU_POPUPITEM, MPI_NORMAL, nullptr, TS_TRUE, &itemSize);
 
     // Figure out how big the menuitem's icon will be (if present) at current DPI
     double scaleFactor = nsIWidget::DefaultScaleOverride();
     if (scaleFactor <= 0.0) {
-      scaleFactor = WinUtils::LogToPhysFactor(hdc);
+      scaleFactor = gfxWindowsPlatform::GetPlatform()->GetDPIScale();
     }
     int iconDevicePixels = NSToIntRound(16 * scaleFactor);
     SIZE iconSize = {
       iconDevicePixels, iconDevicePixels
     };
     // Not really sure what margins should be used here, but this seems to work in practice...
     MARGINS margins = {0};
     GetThemeMargins(theme, hdc, MENU_POPUPCHECKBACKGROUND, MCB_NORMAL,
@@ -1541,29 +1541,16 @@ static bool
 AssumeThemePartAndStateAreTransparent(int32_t aPart, int32_t aState)
 {
   if (aPart == MENU_POPUPITEM && aState == MBI_NORMAL) {
     return true;
   }
   return false;
 }
 
-// When running with per-monitor DPI (on Win8.1+), and rendering on a display
-// with a different DPI setting from the system's primary monitor, we need to
-// apply scaling to native-themed elements as the Windows theme APIs assume
-// the primary monitor's resolution.
-static double
-GetThemeDpiScaleFactor(nsIFrame* aFrame)
-{
-  double primaryScale =
-    WinUtils::LogToPhysFactor(WinUtils::GetPrimaryMonitor());
-  nsIWidget* rootWidget = aFrame->PresContext()->GetRootWidget();
-  return rootWidget ? rootWidget->GetDefaultScale().scale / primaryScale : 1.0;
-}
-
 NS_IMETHODIMP
 nsNativeThemeWin::DrawWidgetBackground(nsRenderingContext* aContext,
                                        nsIFrame* aFrame,
                                        uint8_t aWidgetType,
                                        const nsRect& aRect,
                                        const nsRect& aDirtyRect)
 {
   HANDLE theme = GetTheme(aWidgetType);
@@ -1607,32 +1594,26 @@ nsNativeThemeWin::DrawWidgetBackground(n
   nsresult rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
   if (NS_FAILED(rv))
     return rv;
 
   if (AssumeThemePartAndStateAreTransparent(part, state)) {
     return NS_OK;
   }
 
-  RefPtr<gfxContext> ctx = aContext->ThebesContext();
-  gfxContextMatrixAutoSaveRestore save(ctx);
-
-  double themeScale = GetThemeDpiScaleFactor(aFrame);
-  if (themeScale != 1.0) {
-    ctx->SetMatrix(ctx->CurrentMatrix().Scale(themeScale, themeScale));
-  }
-
   gfxFloat p2a = gfxFloat(aFrame->PresContext()->AppUnitsPerDevPixel());
   RECT widgetRect;
   RECT clipRect;
   gfxRect tr(aRect.x, aRect.y, aRect.width, aRect.height),
           dr(aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);
 
-  tr.ScaleInverse(p2a * themeScale);
-  dr.ScaleInverse(p2a * themeScale);
+  tr.ScaleInverse(p2a);
+  dr.ScaleInverse(p2a);
+
+  RefPtr<gfxContext> ctx = aContext->ThebesContext();
 
   gfxWindowsNativeDrawing nativeDrawing(ctx, dr, GetWidgetNativeDrawingFlags(aWidgetType));
 
 RENDER_AGAIN:
 
   HDC hdc = nativeDrawing.BeginNativeDrawing();
   if (!hdc)
     return NS_ERROR_FAILURE;
@@ -1986,53 +1967,27 @@ RENDER_AGAIN:
   if (nativeDrawing.ShouldRenderAgain())
     goto RENDER_AGAIN;
 
   nativeDrawing.PaintToContext();
 
   return NS_OK;
 }
 
-static void
-ScaleForFrameDPI(nsIntMargin* aMargin, nsIFrame* aFrame)
-{
-  double themeScale = GetThemeDpiScaleFactor(aFrame);
-  if (themeScale != 1.0) {
-    aMargin->top = NSToIntRound(aMargin->top * themeScale);
-    aMargin->left = NSToIntRound(aMargin->left * themeScale);
-    aMargin->bottom = NSToIntRound(aMargin->bottom * themeScale);
-    aMargin->right = NSToIntRound(aMargin->right * themeScale);
-  }
-}
-
-static void
-ScaleForFrameDPI(LayoutDeviceIntSize* aSize, nsIFrame* aFrame)
-{
-  double themeScale = GetThemeDpiScaleFactor(aFrame);
-  if (themeScale != 1.0) {
-    aSize->width = NSToIntRound(aSize->width * themeScale);
-    aSize->height = NSToIntRound(aSize->height * themeScale);
-  }
-}
-
 NS_IMETHODIMP
 nsNativeThemeWin::GetWidgetBorder(nsDeviceContext* aContext, 
                                   nsIFrame* aFrame,
                                   uint8_t aWidgetType,
                                   nsIntMargin* aResult)
 {
   HANDLE theme = GetTheme(aWidgetType);
-  nsresult rv = NS_OK;
-  if (!theme) {
-    rv = ClassicGetWidgetBorder(aContext, aFrame, aWidgetType, aResult);
-    ScaleForFrameDPI(aResult, aFrame);
-    return rv;
-  }
-
-  aResult->top = aResult->bottom = aResult->left = aResult->right = 0;
+  if (!theme)
+    return ClassicGetWidgetBorder(aContext, aFrame, aWidgetType, aResult); 
+
+  (*aResult).top = (*aResult).bottom = (*aResult).left = (*aResult).right = 0;
 
   if (!WidgetIsContainer(aWidgetType) ||
       aWidgetType == NS_THEME_TOOLBOX || 
       aWidgetType == NS_THEME_WIN_MEDIA_TOOLBOX ||
       aWidgetType == NS_THEME_WIN_COMMUNICATIONS_TOOLBOX ||
       aWidgetType == NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX ||
       aWidgetType == NS_THEME_STATUSBAR || 
       aWidgetType == NS_THEME_RESIZER || aWidgetType == NS_THEME_TAB_PANEL ||
@@ -2043,17 +1998,17 @@ nsNativeThemeWin::GetWidgetBorder(nsDevi
       aWidgetType == NS_THEME_MENUIMAGE || aWidgetType == NS_THEME_MENUITEMTEXT ||
       aWidgetType == NS_THEME_TOOLBAR_SEPARATOR ||
       aWidgetType == NS_THEME_WINDOW_TITLEBAR ||
       aWidgetType == NS_THEME_WINDOW_TITLEBAR_MAXIMIZED ||
       aWidgetType == NS_THEME_WIN_GLASS || aWidgetType == NS_THEME_WIN_BORDERLESS_GLASS)
     return NS_OK; // Don't worry about it.
 
   int32_t part, state;
-  rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
+  nsresult rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
   if (NS_FAILED(rv))
     return rv;
 
   if (aWidgetType == NS_THEME_TOOLBAR) {
     // make space for the separator line above all toolbars but the first
     if (state == 0)
       aResult->top = TB_SEPARATOR_HEIGHT;
     return NS_OK;
@@ -2095,18 +2050,17 @@ nsNativeThemeWin::GetWidgetBorder(nsDevi
       // flush against the edge by default if we don't.
       aResult->top++;
       aResult->left++;
       aResult->bottom++;
       aResult->right++;
     }
   }
 
-  ScaleForFrameDPI(aResult, aFrame);
-  return rv;
+  return NS_OK;
 }
 
 bool
 nsNativeThemeWin::GetWidgetPadding(nsDeviceContext* aContext, 
                                    nsIFrame* aFrame,
                                    uint8_t aWidgetType,
                                    nsIntMargin* aResult)
 {
@@ -2115,63 +2069,56 @@ nsNativeThemeWin::GetWidgetPadding(nsDev
     // and have a meaningful baseline, so they can't have
     // author-specified padding.
     case NS_THEME_CHECKBOX:
     case NS_THEME_RADIO:
       aResult->SizeTo(0, 0, 0, 0);
       return true;
   }
 
-  bool ok = true;
+  HANDLE theme = GetTheme(aWidgetType);
 
   if (aWidgetType == NS_THEME_WINDOW_BUTTON_BOX ||
       aWidgetType == NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED) {
     aResult->SizeTo(0, 0, 0, 0);
 
     // aero glass doesn't display custom buttons
     if (nsUXThemeData::CheckForCompositor())
       return true;
 
     // button padding for standard windows
     if (aWidgetType == NS_THEME_WINDOW_BUTTON_BOX) {
       aResult->top = GetSystemMetrics(SM_CXFRAME);
     }
-    ScaleForFrameDPI(aResult, aFrame);
-    return ok;
+    return true;
   }
 
   // Content padding
   if (aWidgetType == NS_THEME_WINDOW_TITLEBAR ||
       aWidgetType == NS_THEME_WINDOW_TITLEBAR_MAXIMIZED) {
     aResult->SizeTo(0, 0, 0, 0);
     // XXX Maximized windows have an offscreen offset equal to
     // the border padding. This should be addressed in nsWindow,
     // but currently can't be, see UpdateNonClientMargins.
     if (aWidgetType == NS_THEME_WINDOW_TITLEBAR_MAXIMIZED)
       aResult->top = GetSystemMetrics(SM_CXFRAME)
                    + GetSystemMetrics(SM_CXPADDEDBORDER);
-    ScaleForFrameDPI(aResult, aFrame);
-    return ok;
+    return true;
   }
 
-  HANDLE theme = GetTheme(aWidgetType);
-  if (!theme) {
-    ok = ClassicGetWidgetPadding(aContext, aFrame, aWidgetType, aResult);
-    ScaleForFrameDPI(aResult, aFrame);
-    return ok;
-  }
+  if (!theme)
+    return ClassicGetWidgetPadding(aContext, aFrame, aWidgetType, aResult);
 
   if (aWidgetType == NS_THEME_MENUPOPUP)
   {
     SIZE popupSize;
     GetThemePartSize(theme, nullptr, MENU_POPUPBORDERS, /* state */ 0, nullptr, TS_TRUE, &popupSize);
     aResult->top = aResult->bottom = popupSize.cy;
     aResult->left = aResult->right = popupSize.cx;
-    ScaleForFrameDPI(aResult, aFrame);
-    return ok;
+    return true;
   }
 
   if (IsVistaOrLater()) {
     if (aWidgetType == NS_THEME_NUMBER_INPUT ||
         aWidgetType == NS_THEME_TEXTFIELD ||
         aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
         aWidgetType == NS_THEME_DROPDOWN)
     {
@@ -2186,28 +2133,26 @@ nsNativeThemeWin::GetWidgetPadding(nsDev
      * contents look too small.  Instead, we add 2px padding for the
      * contents and fix this. (Used to be 1px added, see bug 430212)
      */
     if (aWidgetType == NS_THEME_NUMBER_INPUT ||
         aWidgetType == NS_THEME_TEXTFIELD ||
         aWidgetType == NS_THEME_TEXTFIELD_MULTILINE) {
       aResult->top = aResult->bottom = 2;
       aResult->left = aResult->right = 2;
-      ScaleForFrameDPI(aResult, aFrame);
-      return ok;
+      return true;
     } else if (IsHTMLContent(aFrame) && aWidgetType == NS_THEME_DROPDOWN) {
       /* For content menulist controls, we need an extra pixel so
        * that we have room to draw our focus rectangle stuff.
        * Otherwise, the focus rect might overlap the control's
        * border.
        */
       aResult->top = aResult->bottom = 1;
       aResult->left = aResult->right = 1;
-      ScaleForFrameDPI(aResult, aFrame);
-      return ok;
+      return true;
     }
   }
 
   int32_t right, left, top, bottom;
   right = left = top = bottom = 0;
   switch (aWidgetType)
   {
     case NS_THEME_MENUIMAGE:
@@ -2244,19 +2189,18 @@ nsNativeThemeWin::GetWidgetPadding(nsDev
     aResult->right = left;
     aResult->left = right;
   }
   else
   {
     aResult->right = right;
     aResult->left = left;
   }
-
-  ScaleForFrameDPI(aResult, aFrame);
-  return ok;
+  
+  return true;
 }
 
 bool
 nsNativeThemeWin::GetWidgetOverflow(nsDeviceContext* aContext, 
                                     nsIFrame* aFrame,
                                     uint8_t aWidgetType,
                                     nsRect* aOverflowRect)
 {
@@ -2305,25 +2249,22 @@ nsNativeThemeWin::GetWidgetOverflow(nsDe
   return false;
 }
 
 NS_IMETHODIMP
 nsNativeThemeWin::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aFrame,
                                        uint8_t aWidgetType,
                                        LayoutDeviceIntSize* aResult, bool* aIsOverridable)
 {
-  aResult->width = aResult->height = 0;
+  (*aResult).width = (*aResult).height = 0;
   *aIsOverridable = true;
-  nsresult rv = NS_OK;
 
   HANDLE theme = GetTheme(aWidgetType);
   if (!theme) {
-    rv = ClassicGetMinimumWidgetSize(aFrame, aWidgetType, aResult, aIsOverridable);
-    ScaleForFrameDPI(aResult, aFrame);
-    return rv;
+    return ClassicGetMinimumWidgetSize(aFrame, aWidgetType, aResult, aIsOverridable);
   }
   switch (aWidgetType) {
     case NS_THEME_GROUPBOX:
     case NS_THEME_NUMBER_INPUT:
     case NS_THEME_TEXTFIELD:
     case NS_THEME_TOOLBOX:
     case NS_THEME_WIN_MEDIA_TOOLBOX:
     case NS_THEME_WIN_COMMUNICATIONS_TOOLBOX:
@@ -2353,44 +2294,39 @@ nsNativeThemeWin::GetMinimumWidgetSize(n
     case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
     case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
     case NS_THEME_SCROLLBAR_BUTTON_UP:
     case NS_THEME_SCROLLBAR_BUTTON_DOWN:
     case NS_THEME_SCROLLBAR_BUTTON_LEFT:
     case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
     case NS_THEME_SCROLLBAR_HORIZONTAL:
     case NS_THEME_SCROLLBAR_VERTICAL:
-    case NS_THEME_DROPDOWN_BUTTON: {
-      rv = ClassicGetMinimumWidgetSize(aFrame, aWidgetType, aResult, aIsOverridable);
-      ScaleForFrameDPI(aResult, aFrame);
-      return rv;
-    }
+    case NS_THEME_DROPDOWN_BUTTON:
+      return ClassicGetMinimumWidgetSize(aFrame, aWidgetType, aResult, aIsOverridable);
+
     case NS_THEME_MENUITEM:
     case NS_THEME_CHECKMENUITEM:
     case NS_THEME_RADIOMENUITEM:
       if(!IsTopLevelMenu(aFrame))
       {
         SIZE gutterSize(GetGutterSize(theme, nullptr));
         aResult->width = gutterSize.cx;
         aResult->height = gutterSize.cy;
-        ScaleForFrameDPI(aResult, aFrame);
-        return rv;
+        return NS_OK;
       }
       break;
 
     case NS_THEME_MENUIMAGE:
     case NS_THEME_MENUCHECKBOX:
     case NS_THEME_MENURADIO:
       {
         SIZE boxSize(GetGutterSize(theme, nullptr));
         aResult->width = boxSize.cx+2;
         aResult->height = boxSize.cy;
         *aIsOverridable = false;
-        ScaleForFrameDPI(aResult, aFrame);
-        return rv;
       }
 
     case NS_THEME_MENUITEMTEXT:
       return NS_OK;
 
     case NS_THEME_PROGRESSBAR:
     case NS_THEME_PROGRESSBAR_VERTICAL:
       // Best-fit size for progress meters is too large for most 
@@ -2415,40 +2351,37 @@ nsNativeThemeWin::GetMinimumWidgetSize(n
             (aWidgetType == NS_THEME_RANGE_THUMB && IsRangeHorizontal(aFrame))) {
           aResult->width = 12;
           aResult->height = 20;
         }
         else {
           aResult->width = 20;
           aResult->height = 12;
         }
-        ScaleForFrameDPI(aResult, aFrame);
-        return rv;
+        return NS_OK;
       }
       break;
     }
 
     case NS_THEME_SCROLLBAR:
     {
       if (nsLookAndFeel::GetInt(
             nsLookAndFeel::eIntID_UseOverlayScrollbars) != 0) {
         aResult->SizeTo(::GetSystemMetrics(SM_CXHSCROLL),
                         ::GetSystemMetrics(SM_CYVSCROLL));
-        ScaleForFrameDPI(aResult, aFrame);
-        return rv;
+        return NS_OK;
       }
       break;
     }
 
     case NS_THEME_TOOLBAR_SEPARATOR:
       // that's 2px left margin, 2px right margin and 2px separator
       // (the margin is drawn as part of the separator, though)
       aResult->width = 6;
-      ScaleForFrameDPI(aResult, aFrame);
-      return rv;
+      return NS_OK;
 
     case NS_THEME_BUTTON:
       // We should let HTML buttons shrink to their min size.
       // FIXME bug 403934: We should probably really separate
       // GetPreferredWidgetSize from GetMinimumWidgetSize, so callers can
       // use the one they want.
       if (aFrame->GetContent()->IsHTMLElement()) {
         sizeReq = TS_MIN;
@@ -2464,85 +2397,79 @@ nsNativeThemeWin::GetMinimumWidgetSize(n
       aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_RESTORE].cy;
       // For XP, subtract 4 from system metrics dimensions.
       if (!IsVistaOrLater()) {
         aResult->width -= 4;
         aResult->height -= 4;
       }
       AddPaddingRect(aResult, CAPTIONBUTTON_RESTORE);
       *aIsOverridable = false;
-      ScaleForFrameDPI(aResult, aFrame);
-      return rv;
+      return NS_OK;
 
     case NS_THEME_WINDOW_BUTTON_MINIMIZE:
       aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_MINIMIZE].cx;
       aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_MINIMIZE].cy;
       if (!IsVistaOrLater()) {
         aResult->width -= 4;
         aResult->height -= 4;
       }
       AddPaddingRect(aResult, CAPTIONBUTTON_MINIMIZE);
       *aIsOverridable = false;
-      ScaleForFrameDPI(aResult, aFrame);
-      return rv;
+      return NS_OK;
 
     case NS_THEME_WINDOW_BUTTON_CLOSE:
       aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_CLOSE].cx;
       aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_CLOSE].cy;
       if (!IsVistaOrLater()) {
         aResult->width -= 4;
         aResult->height -= 4;
       }
       AddPaddingRect(aResult, CAPTIONBUTTON_CLOSE);
       *aIsOverridable = false;
-      ScaleForFrameDPI(aResult, aFrame);
-      return rv;
+      return NS_OK;
 
     case NS_THEME_WINDOW_TITLEBAR:
     case NS_THEME_WINDOW_TITLEBAR_MAXIMIZED:
       aResult->height = GetSystemMetrics(SM_CYCAPTION);
       aResult->height += GetSystemMetrics(SM_CYFRAME);
       aResult->height += GetSystemMetrics(SM_CXPADDEDBORDER);
       *aIsOverridable = false;
-      ScaleForFrameDPI(aResult, aFrame);
-      return rv;
+      return NS_OK;
 
     case NS_THEME_WINDOW_BUTTON_BOX:
     case NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED:
       if (nsUXThemeData::CheckForCompositor()) {
         aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_BUTTONBOX].cx;
         aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_BUTTONBOX].cy
                           - GetSystemMetrics(SM_CYFRAME)
                           - GetSystemMetrics(SM_CXPADDEDBORDER);
         if (aWidgetType == NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED) {
           aResult->width += 1;
           aResult->height -= 2;
         }
         *aIsOverridable = false;
-        ScaleForFrameDPI(aResult, aFrame);
-        return rv;
+        return NS_OK;
       }
       break;
 
     case NS_THEME_WINDOW_FRAME_LEFT:
     case NS_THEME_WINDOW_FRAME_RIGHT:
     case NS_THEME_WINDOW_FRAME_BOTTOM:
       aResult->width = GetSystemMetrics(SM_CXFRAME);
       aResult->height = GetSystemMetrics(SM_CYFRAME);
       *aIsOverridable = false;
-      ScaleForFrameDPI(aResult, aFrame);
-      return rv;
+      return NS_OK;
   }
 
   int32_t part, state;
-  rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
+  nsresult rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
   if (NS_FAILED(rv))
     return rv;
 
-  HDC hdc = ::GetDC(NULL);
+  HDC hdc = ::GetDC(nullptr);
   if (!hdc)
     return NS_ERROR_FAILURE;
 
   SIZE sz;
   GetThemePartSize(theme, hdc, part, state, nullptr, sizeReq, &sz);
   aResult->width = sz.cx;
   aResult->height = sz.cy;
 
@@ -2565,19 +2492,17 @@ nsNativeThemeWin::GetMinimumWidgetSize(n
       // Use the width of the arrow glyph as padding. See the drawing
       // code for details.
       aResult->width *= 2;
       break;
     }
   }
 
   ::ReleaseDC(nullptr, hdc);
-
-  ScaleForFrameDPI(aResult, aFrame);
-  return rv;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNativeThemeWin::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, 
                                      nsIAtom* aAttribute, bool* aShouldRepaint)
 {
   // Some widget types just never change state.
   if (aWidgetType == NS_THEME_TOOLBOX ||
--- a/widget/windows/nsScreenManagerWin.cpp
+++ b/widget/windows/nsScreenManagerWin.cpp
@@ -1,21 +1,18 @@
 /* -*- 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 "nsScreenManagerWin.h"
-#include "mozilla/gfx/2D.h"
 #include "nsScreenWin.h"
 #include "gfxWindowsPlatform.h"
 #include "nsIWidget.h"
-#include "WinUtils.h"
 
-using namespace mozilla;
 
 BOOL CALLBACK CountMonitors(HMONITOR, HDC, LPRECT, LPARAM ioCount);
 
 nsScreenManagerWin::nsScreenManagerWin()
   : mNumberOfScreens(0)
 {
   // nothing to do. I guess we could cache a bunch of information
   // here, but we want to ask the device at runtime in case anything
@@ -84,28 +81,38 @@ nsScreenManagerWin::ScreenForId(uint32_t
 // ScreenForRect 
 //
 // Returns the screen that contains the rectangle. If the rect overlaps
 // multiple screens, it picks the screen with the greatest area of intersection.
 //
 // The coordinates are in pixels (not twips) and in logical screen coordinates.
 //
 NS_IMETHODIMP
-nsScreenManagerWin::ScreenForRect(int32_t inLeft, int32_t inTop,
-                                  int32_t inWidth, int32_t inHeight,
+nsScreenManagerWin::ScreenForRect(int32_t inLeft, int32_t inTop, int32_t inWidth, int32_t inHeight,
                                   nsIScreen **outScreen)
 {
   if (!(inWidth || inHeight)) {
     NS_WARNING("trying to find screen for sizeless window, using primary monitor");
     *outScreen = CreateNewScreenObject(nullptr);    // addrefs
     return NS_OK;
   }
 
-  gfx::Rect logicalBounds(inLeft, inTop, inWidth, inHeight);
-  HMONITOR genScreen = widget::WinUtils::MonitorFromRect(logicalBounds);
+  // convert coordinates from logical to device pixels for MonitorFromRect
+  double dpiScale = nsIWidget::DefaultScaleOverride();
+  if (dpiScale <= 0.0) {
+    dpiScale = gfxWindowsPlatform::GetPlatform()->GetDPIScale(); 
+  }
+  RECT globalWindowBounds = {
+    NSToIntRound(dpiScale * inLeft),
+    NSToIntRound(dpiScale * inTop),
+    NSToIntRound(dpiScale * (inLeft + inWidth)),
+    NSToIntRound(dpiScale * (inTop + inHeight))
+  };
+
+  HMONITOR genScreen = ::MonitorFromRect(&globalWindowBounds, MONITOR_DEFAULTTOPRIMARY);
  
   *outScreen = CreateNewScreenObject(genScreen);    // addrefs
  
   return NS_OK;
     
 } // ScreenForRect
 
 
@@ -162,18 +169,17 @@ nsScreenManagerWin::GetNumberOfScreens(u
 
   return NS_OK;
   
 } // GetNumberOfScreens
 
 NS_IMETHODIMP
 nsScreenManagerWin::GetSystemDefaultScale(float *aDefaultScale)
 {
-  HMONITOR primary = widget::WinUtils::GetPrimaryMonitor();
-  *aDefaultScale = float(widget::WinUtils::LogToPhysFactor(primary));
+  *aDefaultScale = float(gfxWindowsPlatform::GetPlatform()->GetDPIScale());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScreenManagerWin::ScreenForNativeWidget(void *aWidget, nsIScreen **outScreen)
 {
   HMONITOR mon = MonitorFromWindow((HWND) aWidget, MONITOR_DEFAULTTOPRIMARY);
   *outScreen = CreateNewScreenObject(mon);
--- a/widget/windows/nsScreenWin.cpp
+++ b/widget/windows/nsScreenWin.cpp
@@ -1,19 +1,17 @@
 /* -*- 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"
+#include "gfxWindowsPlatform.h"
 #include "nsIWidget.h"
-#include "WinUtils.h"
-
-using namespace mozilla;
 
 static uint32_t sScreenId;
 
 nsScreenWin::nsScreenWin(HMONITOR inScreen)
   : mScreen(inScreen)
   , mId(++sScreenId)
 {
 #ifdef DEBUG
@@ -97,34 +95,30 @@ nsScreenWin::GetAvailRect(int32_t *outLe
     *outWidth = workArea.right - workArea.left;
     *outHeight = workArea.bottom - workArea.top;
   }
 
   return NS_OK;
   
 } // GetAvailRect
 
- double
-nsScreenWin::GetDPIScale()
+static double
+GetDPIScale()
 {
   double dpiScale= nsIWidget::DefaultScaleOverride();
   if (dpiScale <= 0.0) {
-    dpiScale = widget::WinUtils::LogToPhysFactor(mScreen);
+    dpiScale = gfxWindowsPlatform::GetPlatform()->GetDPIScale(); 
   }
   return dpiScale;
 }
 
 NS_IMETHODIMP
 nsScreenWin::GetRectDisplayPix(int32_t *outLeft,  int32_t *outTop,
                                int32_t *outWidth, int32_t *outHeight)
 {
-  if (widget::WinUtils::IsPerMonitorDPIAware()) {
-    // on per-monitor-dpi config, display pixels are device pixels
-    return GetRect(outLeft, outTop, outWidth, outHeight);
-  }
   int32_t left, top, width, height;
   nsresult rv = GetRect(&left, &top, &width, &height);
   if (NS_FAILED(rv)) {
     return rv;
   }
   double scaleFactor = 1.0 / GetDPIScale();
   *outLeft = NSToIntRound(left * scaleFactor);
   *outTop = NSToIntRound(top * scaleFactor);
@@ -132,20 +126,16 @@ nsScreenWin::GetRectDisplayPix(int32_t *
   *outHeight = NSToIntRound(height * scaleFactor);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScreenWin::GetAvailRectDisplayPix(int32_t *outLeft,  int32_t *outTop,
                                     int32_t *outWidth, int32_t *outHeight)
 {
-  if (widget::WinUtils::IsPerMonitorDPIAware()) {
-    // on per-monitor-dpi config, display pixels are device pixels
-    return GetAvailRect(outLeft, outTop, outWidth, outHeight);
-  }
   int32_t left, top, width, height;
   nsresult rv = GetAvailRect(&left, &top, &width, &height);
   if (NS_FAILED(rv)) {
     return rv;
   }
   double scaleFactor = 1.0 / GetDPIScale();
   *outLeft = NSToIntRound(left * scaleFactor);
   *outTop = NSToIntRound(top * scaleFactor);
@@ -180,19 +170,8 @@ nsScreenWin :: GetPixelDepth(int32_t *aP
 NS_IMETHODIMP 
 nsScreenWin::GetColorDepth(int32_t *aColorDepth)
 {
   return GetPixelDepth(aColorDepth);
 
 } // GetColorDepth
 
 
-NS_IMETHODIMP
-nsScreenWin::GetContentsScaleFactor(double *aContentsScaleFactor)
-{
-  if (widget::WinUtils::IsPerMonitorDPIAware()) {
-    *aContentsScaleFactor = 1.0;
-  } else {
-    *aContentsScaleFactor = widget::WinUtils::LogToPhysFactor(mScreen);
-  }
-  return NS_OK;
-}
-
--- a/widget/windows/nsScreenWin.h
+++ b/widget/windows/nsScreenWin.h
@@ -6,40 +6,37 @@
 #ifndef nsScreenWin_h___
 #define nsScreenWin_h___
 
 #include <windows.h>
 #include "nsBaseScreen.h"
 
 //------------------------------------------------------------------------
 
-class nsScreenWin final : public nsBaseScreen
+class nsScreenWin : public nsBaseScreen
 {
 public:
   nsScreenWin ( HMONITOR inScreen );
   ~nsScreenWin();
 
   NS_IMETHOD GetId(uint32_t* aId);
 
   // 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 'desktop pixels' (AKA 'logical pixels')
+  // 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);
 
-  NS_IMETHOD GetContentsScaleFactor(double *aContentsScaleFactor) override;
-
 private:
-  double GetDPIScale();
 
   HMONITOR mScreen;
   uint32_t mId;
 };
 
 #endif  // nsScreenWin_h___ 
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -119,16 +119,17 @@
 #include "nsWindowGfx.h"
 #include "gfxWindowsPlatform.h"
 #include "Layers.h"
 #include "nsPrintfCString.h"
 #include "mozilla/Preferences.h"
 #include "nsISound.h"
 #include "SystemTimeConverter.h"
 #include "WinTaskbar.h"
+#include "WinUtils.h"
 #include "WidgetUtils.h"
 #include "nsIWidgetListener.h"
 #include "mozilla/dom/Touch.h"
 #include "mozilla/gfx/2D.h"
 #include "nsToolkitCompsCID.h"
 #include "nsIAppStartup.h"
 #include "mozilla/WindowsVersion.h"
 #include "mozilla/TextEvents.h" // For WidgetKeyboardEvent
@@ -178,20 +179,16 @@
 #include <d3d11.h>
 
 #include "InkCollector.h"
 
 #if !defined(SM_CONVERTIBLESLATEMODE)
 #define SM_CONVERTIBLESLATEMODE 0x2003
 #endif
 
-#if !defined(WM_DPICHANGED)
-#define WM_DPICHANGED 0x02E0
-#endif
-
 #include "mozilla/layers/APZCTreeManager.h"
 #include "mozilla/layers/InputAPZContext.h"
 #include "ClientLayerManager.h"
 #include "InputData.h"
 
 #include "mozilla/Telemetry.h"
 
 using namespace mozilla;
@@ -425,17 +422,16 @@ nsWindow::nsWindow()
   mTransparentSurface   = nullptr;
   mMemoryDC             = nullptr;
   mTransparencyMode     = eTransparencyOpaque;
   memset(&mGlassMargins, 0, sizeof mGlassMargins);
 #endif
   DWORD background      = ::GetSysColor(COLOR_BTNFACE);
   mBrush                = ::CreateSolidBrush(NSRGB_2_COLOREF(background));
   mSendingSetText       = false;
-  mDefaultScale         = -1.0; // not yet set, will be calculated on first use
 
   mTaskbarPreview = nullptr;
 
   // Global initialization
   if (!sInstanceCount) {
     // Global app registration id for Win7 and up. See
     // WinTaskbar.cpp for details.
     mozilla::widget::WinTaskbar::RegisterAppUserModelID();
@@ -456,17 +452,16 @@ nsWindow::nsWindow()
     Preferences::AddBoolVarCache(&gIsPointerEventsEnabled,
                                  "dom.w3c_pointer_events.enabled",
                                  gIsPointerEventsEnabled);
   } // !sInstanceCount
 
   mIdleService = nullptr;
 
   ::InitializeCriticalSection(&mPresentLock);
-  mSizeConstraintsScale = GetDefaultScale().scale;
 
   sInstanceCount++;
 }
 
 nsWindow::~nsWindow()
 {
   mInDtor = true;
 
@@ -548,17 +543,17 @@ nsWindow::Create(nsIWidget* aParent,
                           nullptr : aParent;
 
   mIsTopWidgetWindow = (nullptr == baseParent);
   mBounds = aRect;
 
   // Ensure that the toolkit is created.
   nsToolkit::GetToolkit();
 
-  BaseCreate(baseParent, aInitData);
+  BaseCreate(baseParent, aRect, aInitData);
 
   HWND parent;
   if (aParent) { // has a nsIWidget parent
     parent = aParent ? (HWND)aParent->GetNativeData(NS_NATIVE_WINDOW) : nullptr;
     mParent = aParent;
   } else { // has a nsNative parent
     parent = (HWND)aNativeParent;
     mParent = aNativeParent ?
@@ -1080,27 +1075,17 @@ float nsWindow::GetDPI()
     // Something's broken
     return 96.0f;
   }
   return float(heightPx/heightInches);
 }
 
 double nsWindow::GetDefaultScaleInternal()
 {
-  if (mDefaultScale <= 0.0) {
-    mDefaultScale = WinUtils::LogToPhysFactor(mWnd);
-  }
-  return WinUtils::LogToPhysFactor(mWnd);
-}
-
-int32_t nsWindow::LogToPhys(double aValue)
-{
-  return WinUtils::LogToPhys(::MonitorFromWindow(mWnd,
-                                                 MONITOR_DEFAULTTOPRIMARY),
-                             aValue);
+  return WinUtils::LogToPhysFactor();
 }
 
 nsWindow*
 nsWindow::GetParentWindow(bool aIncludeOwner)
 {
   return static_cast<nsWindow*>(GetParentWindowBase(aIncludeOwner));
 }
 
@@ -1420,58 +1405,33 @@ nsWindow::SetSizeConstraints(const SizeC
     int32_t maxSize = clientLayerManager->GetMaxTextureSize();
     // We can't make ThebesLayers bigger than this anyway.. no point it letting
     // a window grow bigger as we won't be able to draw content there in
     // general.
     c.mMaxSize.width = std::min(c.mMaxSize.width, maxSize);
     c.mMaxSize.height = std::min(c.mMaxSize.height, maxSize);
   }
 
-  mSizeConstraintsScale = GetDefaultScale().scale;
-
   nsBaseWidget::SetSizeConstraints(c);
 }
 
-const SizeConstraints
-nsWindow::GetSizeConstraints()
-{
-  double scale = GetDefaultScale().scale;
-  if (mSizeConstraintsScale == scale || mSizeConstraintsScale == 0.0) {
-    return mSizeConstraints;
-  }
-  scale /= mSizeConstraintsScale;
-  SizeConstraints c = mSizeConstraints;
-  if (c.mMinSize.width != NS_UNCONSTRAINEDSIZE) {
-    c.mMinSize.width = NSToIntRound(c.mMinSize.width * scale);
-  }
-  if (c.mMinSize.height != NS_UNCONSTRAINEDSIZE) {
-    c.mMinSize.height = NSToIntRound(c.mMinSize.height * scale);
-  }
-  if (c.mMaxSize.width != NS_UNCONSTRAINEDSIZE) {
-    c.mMaxSize.width = NSToIntRound(c.mMaxSize.width * scale);
-  }
-  if (c.mMaxSize.height != NS_UNCONSTRAINEDSIZE) {
-    c.mMaxSize.height = NSToIntRound(c.mMaxSize.height * scale);
-  }
-  return c;
-}
-
 // Move this component
 NS_METHOD nsWindow::Move(double aX, double aY)
 {
   if (mWindowType == eWindowType_toplevel ||
       mWindowType == eWindowType_dialog) {
     SetSizeMode(nsSizeMode_Normal);
   }
 
-  // for top-level windows only, convert coordinates from desktop pixels
+  // for top-level windows only, convert coordinates from global display pixels
   // (the "parent" coordinate space) to the window's device pixel space
-  double scale = BoundsUseDesktopPixels() ? GetDesktopToDeviceScale().scale : 1.0;
-  int32_t x = NSToIntRound(aX * scale);
-  int32_t y = NSToIntRound(aY * scale);
+  CSSToLayoutDeviceScale scale = BoundsUseDisplayPixels() ? GetDefaultScale()
+                                    : CSSToLayoutDeviceScale(1.0);
+  int32_t x = NSToIntRound(aX * scale.scale);
+  int32_t y = NSToIntRound(aY * scale.scale);
 
   // Check to see if window needs to be moved first
   // to avoid a costly call to SetWindowPos. This check
   // can not be moved to the calling code in nsView, because
   // some platforms do not position child windows correctly
 
   // Only perform this check for non-popup windows, since the positioning can
   // in fact change even when the x/y do not.  We always need to perform the
@@ -1513,38 +1473,33 @@ NS_METHOD nsWindow::Move(double aX, doub
     // region, some drivers or OSes may incorrectly copy into the clipped-out
     // area.
     if (IsPlugin() &&
         (!mLayerManager || mLayerManager->GetBackendType() == LayersBackend::LAYERS_D3D9) &&
         mClipRects &&
         (mClipRectCount != 1 || !mClipRects[0].IsEqualInterior(LayoutDeviceIntRect(0, 0, mBounds.width, mBounds.height)))) {
       flags |= SWP_NOCOPYBITS;
     }
-    double oldScale = mDefaultScale;
-    mResizeState = IN_SIZEMOVE;
     VERIFY(::SetWindowPos(mWnd, nullptr, x, y, 0, 0, flags));
-    mResizeState = NOT_RESIZING;
-    if (WinUtils::LogToPhysFactor(mWnd) != oldScale) {
-      ChangedDPI();
-    }
 
     SetThemeRegion();
   }
   NotifyRollupGeometryChange();
   return NS_OK;
 }
 
 // Resize this component
 NS_METHOD nsWindow::Resize(double aWidth, double aHeight, bool aRepaint)
 {
-  // for top-level windows only, convert coordinates from desktop pixels
+  // for top-level windows only, convert coordinates from global display pixels
   // (the "parent" coordinate space) to the window's device pixel space
-  double scale = BoundsUseDesktopPixels() ? GetDesktopToDeviceScale().scale : 1.0;
-  int32_t width = NSToIntRound(aWidth * scale);
-  int32_t height = NSToIntRound(aHeight * scale);
+  CSSToLayoutDeviceScale scale = BoundsUseDisplayPixels() ? GetDefaultScale()
+                                    : CSSToLayoutDeviceScale(1.0);
+  int32_t width = NSToIntRound(aWidth * scale.scale);
+  int32_t height = NSToIntRound(aHeight * scale.scale);
 
   NS_ASSERTION((width >= 0) , "Negative width passed to nsWindow::Resize");
   NS_ASSERTION((height >= 0), "Negative height passed to nsWindow::Resize");
 
   ConstrainSize(&width, &height);
 
   // Avoid unnecessary resizing calls
   if (mBounds.width == width && mBounds.height == height) {
@@ -1566,42 +1521,39 @@ NS_METHOD nsWindow::Resize(double aWidth
   if (mWnd) {
     UINT  flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE;
 
     if (!aRepaint) {
       flags |= SWP_NOREDRAW;
     }
 
     ClearThemeRegion();
-    double oldScale = mDefaultScale;
     VERIFY(::SetWindowPos(mWnd, nullptr, 0, 0,
                           width, GetHeight(height), flags));
-    if (WinUtils::LogToPhysFactor(mWnd) != oldScale) {
-      ChangedDPI();
-    }
     SetThemeRegion();
   }
 
   if (aRepaint)
     Invalidate();
 
   NotifyRollupGeometryChange();
   return NS_OK;
 }
 
 // Resize this component
 NS_METHOD nsWindow::Resize(double aX, double aY, double aWidth, double aHeight, bool aRepaint)
 {
-  // for top-level windows only, convert coordinates from desktop pixels
+  // for top-level windows only, convert coordinates from global display pixels
   // (the "parent" coordinate space) to the window's device pixel space
-  double scale = BoundsUseDesktopPixels() ? GetDesktopToDeviceScale().scale : 1.0;
-  int32_t x = NSToIntRound(aX * scale);
-  int32_t y = NSToIntRound(aY * scale);
-  int32_t width = NSToIntRound(aWidth * scale);
-  int32_t height = NSToIntRound(aHeight * scale);
+  CSSToLayoutDeviceScale scale = BoundsUseDisplayPixels() ? GetDefaultScale()
+                                    : CSSToLayoutDeviceScale(1.0);
+  int32_t x = NSToIntRound(aX * scale.scale);
+  int32_t y = NSToIntRound(aY * scale.scale);
+  int32_t width = NSToIntRound(aWidth * scale.scale);
+  int32_t height = NSToIntRound(aHeight * scale.scale);
 
   NS_ASSERTION((width >= 0),  "Negative width passed to nsWindow::Resize");
   NS_ASSERTION((height >= 0), "Negative height passed to nsWindow::Resize");
 
   ConstrainSize(&width, &height);
 
   // Avoid unnecessary resizing calls
   if (mBounds.x == x && mBounds.y == y &&
@@ -1625,22 +1577,18 @@ NS_METHOD nsWindow::Resize(double aX, do
 
   if (mWnd) {
     UINT  flags = SWP_NOZORDER | SWP_NOACTIVATE;
     if (!aRepaint) {
       flags |= SWP_NOREDRAW;
     }
 
     ClearThemeRegion();
-    double oldScale = mDefaultScale;
     VERIFY(::SetWindowPos(mWnd, nullptr, x, y,
                           width, GetHeight(height), flags));
-    if (WinUtils::LogToPhysFactor(mWnd) != oldScale) {
-      ChangedDPI();
-    }
     if (mTransitionWnd) {
       // If we have a fullscreen transition window, we need to make
       // it topmost again, otherwise the taskbar may be raised by
       // the system unexpectedly when we leave fullscreen state.
       ::SetWindowPos(mTransitionWnd, HWND_TOPMOST, 0, 0, 0, 0,
                      SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
       // Every transition window is only used once.
       mTransitionWnd = nullptr;
@@ -1813,33 +1761,31 @@ nsWindow::SetSizeMode(nsSizeMode aMode) 
     // we activate here to ensure that the right child window is focused
     if (mode == SW_MAXIMIZE || mode == SW_SHOW)
       DispatchFocusToTopLevelWindow(true);
   }
   return rv;
 }
 
 // Constrain a potential move to fit onscreen
-// Position (aX, aY) is specified in Windows screen (logical) pixels,
-// except when using per-monitor DPI, in which case it's device pixels.
+// Position (aX, aY) is specified in Windows screen (logical) pixels
 NS_METHOD nsWindow::ConstrainPosition(bool aAllowSlop,
                                       int32_t *aX, int32_t *aY)
 {
   if (!mIsTopWidgetWindow) // only a problem for top-level windows
     return NS_OK;
 
-  double dpiScale = GetDesktopToDeviceScale().scale;
-
-  // We need to use the window size in the kind of pixels used for window-
-  // manipulation APIs.
+  double dpiScale = GetDefaultScale().scale;
+
+  // we need to use the window size in logical screen pixels
   int32_t logWidth = std::max<int32_t>(NSToIntRound(mBounds.width / dpiScale), 1);
   int32_t logHeight = std::max<int32_t>(NSToIntRound(mBounds.height / dpiScale), 1);
 
   /* get our playing field. use the current screen, or failing that
-  for any reason, use device caps for the default screen. */
+    for any reason, use device caps for the default screen. */
   RECT screenRect;
 
   nsCOMPtr<nsIScreenManager> screenmgr = do_GetService(sScreenManagerContractID);
   if (screenmgr) {
     nsCOMPtr<nsIScreen> screen;
     int32_t left, top, width, height;
 
     screenmgr->ScreenForRect(*aX, *aY, logWidth, logHeight,
@@ -2325,28 +2271,16 @@ nsWindow::UpdateNonClientMargins(int32_t
     // makes the whole caption part of our client area, allowing us to draw
     // in the whole caption area.  Use default frame size on left, right, and
     // bottom. The reason this works is that, for maximized windows,
     // Windows positions them so that their frames fall off the screen.
     // This gives the illusion of windows having no frames when they are
     // maximized.  If we try to mess with the frame sizes by setting these
     // offsets to positive values, our client area will fall off the screen.
     mNonClientOffset.top = mCaptionHeight;
-    // Adjust for the case where the window is maximized on a screen with DPI
-    // different from the primary monitor; this seems to be linked to Windows'
-    // failure to scale the non-client area the same as the client area.
-    // Any modifications here need to be tested for both high- and low-dpi
-    // secondary displays, and for windows both with and without the titlebar
-    // and/or menubar displayed.
-    double ourScale = WinUtils::LogToPhysFactor(mWnd);
-    double primaryScale =
-      WinUtils::LogToPhysFactor(WinUtils::GetPrimaryMonitor());
-    mNonClientOffset.top +=
-      NSToIntRound(mVertResizeMargin * (ourScale - primaryScale));
-
     mNonClientOffset.bottom = 0;
     mNonClientOffset.left = 0;
     mNonClientOffset.right = 0;
 
     APPBARDATA appBarData;
     appBarData.cbSize = sizeof(appBarData);
     UINT taskbarState = SHAppBarMessage(ABM_GETSTATE, &appBarData);
     if (ABS_AUTOHIDE & taskbarState) {
@@ -3127,23 +3061,23 @@ nsWindow::PrepareForFullscreenTransition
   if (!nsUXThemeData::CheckForCompositor()) {
     return false;
   }
 
   FullscreenTransitionInitData initData;
   nsCOMPtr<nsIScreen> screen = GetWidgetScreen();
   int32_t x, y, width, height;
   screen->GetRectDisplayPix(&x, &y, &width, &height);
-  MOZ_ASSERT(BoundsUseDesktopPixels(),
+  MOZ_ASSERT(BoundsUseDisplayPixels(),
              "Should only be called on top-level window");
-  double scale = GetDesktopToDeviceScale().scale; // XXX or GetDefaultScale() ?
-  initData.mBounds.x = NSToIntRound(x * scale);
-  initData.mBounds.y = NSToIntRound(y * scale);
-  initData.mBounds.width = NSToIntRound(width * scale);
-  initData.mBounds.height = NSToIntRound(height * scale);
+  CSSToLayoutDeviceScale scale = GetDefaultScale();
+  initData.mBounds.x = NSToIntRound(x * scale.scale);
+  initData.mBounds.y = NSToIntRound(y * scale.scale);
+  initData.mBounds.width = NSToIntRound(width * scale.scale);
+  initData.mBounds.height = NSToIntRound(height * scale.scale);
 
   // Create a semaphore for synchronizing the window handle which will
   // be created by the transition thread and used by the main thread for
   // posting the transition messages.
   initData.mSemaphore = ::CreateSemaphore(nullptr, 0, 1, nullptr);
   if (initData.mSemaphore) {
     initData.mThread = ::CreateThread(
       nullptr, 0, FullscreenTransitionThreadProc, &initData, 0, nullptr);
@@ -3789,17 +3723,17 @@ nsWindow::UpdateThemeGeometries(const ns
     return;
   }
 
   // On Win10, force show the top border:
   if (IsWin10OrLater() && mCustomNonClient && mSizeMode == nsSizeMode_Normal) {
     RECT rect;
     ::GetWindowRect(mWnd, &rect);
     // We want 1 pixel of border for every whole 100% of scaling
-    double borderSize = std::min(1, RoundDown(GetDesktopToDeviceScale().scale));
+    double borderSize = RoundDown(GetDefaultScale().scale);
     clearRegion.Or(clearRegion, nsIntRect(0, 0, rect.right - rect.left, borderSize));
   }
 
   if (!IsWin10OrLater()) {
     for (size_t i = 0; i < aThemeGeometries.Length(); i++) {
       if (aThemeGeometries[i].mType == nsNativeThemeWin::eThemeGeometryTypeWindowButtons) {
         LayoutDeviceIntRect bounds = aThemeGeometries[i].mRect;
         clearRegion.Or(clearRegion, nsIntRect(bounds.X(), bounds.Y(), bounds.Width(), bounds.Height() - 2.0));
@@ -5396,22 +5330,23 @@ nsWindow::ProcessMessage(UINT msg, WPARA
         mResizeState = IN_SIZEMOVE;
       }
       break;
     }
 
     case WM_EXITSIZEMOVE:
     {
       if (mResizeState == RESIZING) {
+        mResizeState = NOT_RESIZING;
         nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
+
         if (observerService) {
           observerService->NotifyObservers(nullptr, "live-resize-end", nullptr);
         }
       }
-      mResizeState = NOT_RESIZING;
 
       if (!sIsInMouseCapture) {
         NotifySizeMoveDone();
       }
 
       break;
     }
 
@@ -5609,24 +5544,16 @@ nsWindow::ProcessMessage(UINT msg, WPARA
 
     UpdateNonClientMargins();
     BroadcastMsg(mWnd, WM_DWMCOMPOSITIONCHANGED);
     NotifyThemeChanged();
     UpdateGlass();
     Invalidate(true, true, true);
     break;
 
-  case WM_DPICHANGED:
-  {
-    LPRECT rect = (LPRECT) lParam;
-    OnDPIChanged(rect->left, rect->top, rect->right - rect->left,
-                 rect->bottom - rect->top);
-    break;
-  }
-
   case WM_UPDATEUISTATE:
   {
     // If the UI state has changed, fire an event so the UI updates the
     // keyboard cues based on the system setting and how the window was
     // opened. For example, a dialog opened via a keyboard press on a button
     // should enable cues, whereas the same dialog opened via a mouse click of
     // the button should not.
     int32_t action = LOWORD(wParam);
@@ -6892,47 +6819,16 @@ nsWindow::OnSysColorChanged()
     // The Win32 toolkit normally only sends these events to top-level windows.
     // But we cycle through all of the childwindows and send it to them as well
     // so all presentations get notified properly.
     // See nsWindow::GlobalMsgWindowProc.
     NotifySysColorChanged();
   }
 }
 
-void
-nsWindow::OnDPIChanged(int32_t x, int32_t y, int32_t width, int32_t height)
-{
-  if (DefaultScaleOverride() > 0.0) {
-    return;
-  }
-  double oldScale = mDefaultScale;
-  mDefaultScale = -1.0; // force recomputation of scale factor
-  double newScale = GetDefaultScaleInternal();
-  if (mResizeState != NOT_RESIZING) {
-    // 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;
-    }
-    Resize(x, y, width, height, true);
-  }
-  ChangedDPI();
-}
-
 /**************************************************************
  **************************************************************
  **
  ** BLOCK: IME management and accessibility
  **
  ** Handles managing IME input and accessibility.
  **
  **************************************************************
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -26,17 +26,17 @@
 #include "nsRegion.h"
 #include "mozilla/EventForwards.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/TimeStamp.h"
 #include "nsMargin.h"
 #include "nsRegionFwd.h"
 
 #include "nsWinGesture.h"
-#include "WinUtils.h"
+
 #include "WindowHook.h"
 #include "TaskbarWindowPreview.h"
 
 #ifdef ACCESSIBILITY
 #include "oleacc.h"
 #include "mozilla/a11y/Accessible.h"
 #endif
 
@@ -90,41 +90,29 @@ public:
   virtual bool DispatchWheelEvent(mozilla::WidgetWheelEvent* aEvent) override;
   virtual bool DispatchContentCommandEvent(mozilla::WidgetContentCommandEvent* aEvent) override;
   virtual nsWindowBase* GetParentWindowBase(bool aIncludeOwner) override;
   virtual bool IsTopLevelWidget() override { return mIsTopWidgetWindow; }
 
   using nsWindowBase::DispatchPluginEvent;
 
   // nsIWidget interface
-  using nsWindowBase::Create; // for Create signature not overridden here
   NS_IMETHOD              Create(nsIWidget* aParent,
                                  nsNativeWidget aNativeParent,
                                  const LayoutDeviceIntRect& aRect,
                                  nsWidgetInitData* aInitData = nullptr) override;
   NS_IMETHOD              Destroy() override;
   NS_IMETHOD              SetParent(nsIWidget *aNewParent) override;
   virtual nsIWidget*      GetParent(void) override;
   virtual float           GetDPI() override;
-  double                  GetDefaultScaleInternal() final;
-  int32_t                 LogToPhys(double aValue) final;
-  mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() final
-  {
-    if (mozilla::widget::WinUtils::IsPerMonitorDPIAware()) {
-      return mozilla::DesktopToLayoutDeviceScale(1.0);
-    } else {
-      return mozilla::DesktopToLayoutDeviceScale(GetDefaultScaleInternal());
-    }
-  }
-
+  virtual double          GetDefaultScaleInternal() override;
   NS_IMETHOD              Show(bool bState) override;
   virtual bool            IsVisible() const override;
   NS_IMETHOD              ConstrainPosition(bool aAllowSlop, int32_t *aX, int32_t *aY) override;
   virtual void            SetSizeConstraints(const SizeConstraints& aConstraints) override;
-  virtual const SizeConstraints GetSizeConstraints() override;
   NS_IMETHOD              Move(double aX, double aY) override;
   NS_IMETHOD              Resize(double aWidth, double aHeight, bool aRepaint) override;
   NS_IMETHOD              Resize(double aX, double aY, double aWidth, double aHeight, bool aRepaint) override;
   NS_IMETHOD              BeginResizeDrag(mozilla::WidgetGUIEvent* aEvent,
                                           int32_t aHorizontal,
                                           int32_t aVertical) override;
   NS_IMETHOD              PlaceBehind(nsTopLevelWidgetZPlacement aPlacement, nsIWidget *aWidget, bool aActivate) override;
   NS_IMETHOD              SetSizeMode(nsSizeMode aMode) override;
@@ -407,18 +395,16 @@ protected:
   virtual bool            OnResize(nsIntRect &aWindowRect);
   bool                    OnGesture(WPARAM wParam, LPARAM lParam);
   bool                    OnTouch(WPARAM wParam, LPARAM lParam);
   bool                    OnHotKey(WPARAM wParam, LPARAM lParam);
   bool                    OnPaint(HDC aDC, uint32_t aNestingLevel);
   void                    OnWindowPosChanged(WINDOWPOS* wp);
   void                    OnWindowPosChanging(LPWINDOWPOS& info);
   void                    OnSysColorChanged();
-  void                    OnDPIChanged(int32_t x, int32_t y,
-                                       int32_t width, int32_t height);
 
   /**
    * Function that registers when the user has been active (used for detecting
    * when the user is idle).
    */
   void                    UserActivity();
 
   int32_t                 GetHeight(int32_t aProposedHeight);
@@ -545,18 +531,16 @@ protected:
   // Indicates custom frames are enabled
   bool                  mCustomNonClient;
   // Cached copy of L&F's resize border  
   int32_t               mHorResizeMargin;
   int32_t               mVertResizeMargin;
   // Height of the caption plus border
   int32_t               mCaptionHeight;
 
-  double                mDefaultScale;
-
   nsCOMPtr<nsIIdleServiceInternal> mIdleService;
 
   // Draggable titlebar region maintained by UpdateWindowDraggingRegion
   LayoutDeviceIntRegion mDraggableRegion;
 
   // Hook Data Memebers for Dropdowns. sProcessHook Tells the
   // hook methods whether they should be processing the hook
   // messages.
@@ -624,18 +608,16 @@ protected:
   POINT mCachedHitTestPoint;
   TimeStamp mCachedHitTestTime;
   int32_t mCachedHitTestResult;
 
   static bool sNeedsToInitMouseWheelSettings;
   static void InitMouseWheelScrollData();
 
   CRITICAL_SECTION mPresentLock;
-
-  double mSizeConstraintsScale; // scale in effect when setting constraints
 };
 
 /**
  * A child window is a window with different style.
  */
 class ChildWindow : public nsWindow {
 
 public:
--- a/widget/windows/nsWindowBase.cpp
+++ b/widget/windows/nsWindowBase.cpp
@@ -85,41 +85,31 @@ nsWindowBase::InjectTouchPoint(uint32_t 
   info.touchFlags = TOUCH_FLAG_NONE;
   info.touchMask = TOUCH_MASK_CONTACTAREA|TOUCH_MASK_ORIENTATION|TOUCH_MASK_PRESSURE;
   info.pressure = aPressure;
   info.orientation = aOrientation;
   
   info.pointerInfo.pointerFlags = aFlags;
   info.pointerInfo.pointerType =  PT_TOUCH;
   info.pointerInfo.pointerId = aId;
-  info.pointerInfo.ptPixelLocation.x = LogToPhys(aPointerScreenPoint.x);
-  info.pointerInfo.ptPixelLocation.y = LogToPhys(aPointerScreenPoint.y);
+  info.pointerInfo.ptPixelLocation.x = WinUtils::LogToPhys(aPointerScreenPoint.x);
+  info.pointerInfo.ptPixelLocation.y = WinUtils::LogToPhys(aPointerScreenPoint.y);
 
   info.rcContact.top = info.pointerInfo.ptPixelLocation.y - 2;
   info.rcContact.bottom = info.pointerInfo.ptPixelLocation.y + 2;
   info.rcContact.left = info.pointerInfo.ptPixelLocation.x - 2;
   info.rcContact.right = info.pointerInfo.ptPixelLocation.x + 2;
   
   if (!sInjectTouchFuncPtr(1, &info)) {
     WinUtils::Log("InjectTouchInput failure. GetLastError=%d", GetLastError());
     return false;
   }
   return true;
 }
 
-void nsWindowBase::ChangedDPI()
-{
-  if (mWidgetListener) {
-    nsIPresShell* presShell = mWidgetListener->GetPresShell();
-    if (presShell) {
-      presShell->BackingScaleFactorChanged();
-    }
-  }
-}
-
 nsresult
 nsWindowBase::SynthesizeNativeTouchPoint(uint32_t aPointerId,
                                          nsIWidget::TouchPointerState aPointerState,
                                          ScreenIntPoint aPointerScreenPoint,
                                          double aPointerPressure,
                                          uint32_t aPointerOrientation,
                                          nsIObserver* aObserver)
 {
--- a/widget/windows/nsWindowBase.h
+++ b/widget/windows/nsWindowBase.h
@@ -91,19 +91,16 @@ public:
   /*
    * WM_APPCOMMAND common handler.
    * Sends events via NativeKey::HandleAppCommandMessage().
    */
   virtual bool HandleAppCommandMsg(const MSG& aAppCommandMsg,
                                    LRESULT *aRetValue);
 
 protected:
-  virtual int32_t LogToPhys(double aValue) = 0;
-  void ChangedDPI();
-
   static bool InitTouchInjection();
   bool InjectTouchPoint(uint32_t aId, ScreenIntPoint& aPointerScreenPoint,
                         POINTER_FLAGS aFlags, uint32_t aPressure = 1024,
                         uint32_t aOrientation = 90);
 
   class PointerInfo
   {
   public:
--- a/xpfe/appshell/nsChromeTreeOwner.cpp
+++ b/xpfe/appshell/nsChromeTreeOwner.cpp
@@ -377,22 +377,16 @@ NS_IMETHODIMP nsChromeTreeOwner::Destroy
 }
 
 NS_IMETHODIMP nsChromeTreeOwner::GetUnscaledDevicePixelsPerCSSPixel(double *aScale)
 {
    NS_ENSURE_STATE(mXULWindow);
    return mXULWindow->GetUnscaledDevicePixelsPerCSSPixel(aScale);
 }
 
-NS_IMETHODIMP nsChromeTreeOwner::GetDevicePixelsPerDesktopPixel(double *aScale)
-{
-   NS_ENSURE_STATE(mXULWindow);
-   return mXULWindow->GetDevicePixelsPerDesktopPixel(aScale);
-}
-
 NS_IMETHODIMP nsChromeTreeOwner::SetPosition(int32_t x, int32_t y)
 {
    NS_ENSURE_STATE(mXULWindow);
    return mXULWindow->SetPosition(x, y);
 }
 
 NS_IMETHODIMP nsChromeTreeOwner::GetPosition(int32_t* x, int32_t* y)
 {
--- a/xpfe/appshell/nsContentTreeOwner.cpp
+++ b/xpfe/appshell/nsContentTreeOwner.cpp
@@ -616,22 +616,16 @@ NS_IMETHODIMP nsContentTreeOwner::Destro
 }
 
 NS_IMETHODIMP nsContentTreeOwner::GetUnscaledDevicePixelsPerCSSPixel(double* aScale)
 {
    NS_ENSURE_STATE(mXULWindow);
    return mXULWindow->GetUnscaledDevicePixelsPerCSSPixel(aScale);
 }
 
-NS_IMETHODIMP nsContentTreeOwner::GetDevicePixelsPerDesktopPixel(double* aScale)
-{
-   NS_ENSURE_STATE(mXULWindow);
-   return mXULWindow->GetDevicePixelsPerDesktopPixel(aScale);
-}
-
 NS_IMETHODIMP nsContentTreeOwner::SetPosition(int32_t aX, int32_t aY)
 {
    NS_ENSURE_STATE(mXULWindow);
    return mXULWindow->SetPosition(aX, aY);
 }
 
 NS_IMETHODIMP nsContentTreeOwner::GetPosition(int32_t* aX, int32_t* aY)
 {
--- a/xpfe/appshell/nsWebShellWindow.cpp
+++ b/xpfe/appshell/nsWebShellWindow.cpp
@@ -140,17 +140,17 @@ nsresult nsWebShellWindow::Initialize(ns
       initialX = mOpenerScreenRect.x;
       initialY = mOpenerScreenRect.y;
       ConstrainToOpenerScreen(&initialX, &initialY);
     }
   }
 
   // XXX: need to get the default window size from prefs...
   // Doesn't come from prefs... will come from CSS/XUL/RDF
-  DesktopIntRect deskRect(initialX, initialY, aInitialWidth, aInitialHeight);
+  LayoutDeviceIntRect r(initialX, initialY, aInitialWidth, aInitialHeight);
 
   // Create top level window
   mWindow = do_CreateInstance(kWindowCID, &rv);
   if (NS_OK != rv) {
     return rv;
   }
 
   /* This next bit is troublesome. We carry two different versions of a pointer
@@ -168,20 +168,18 @@ nsresult nsWebShellWindow::Initialize(ns
   if (parentAsWin) {
     parentAsWin->GetMainWidget(getter_AddRefs(parentWidget));
     mParentWindow = do_GetWeakReference(aParent);
   }
 
   mWindow->SetWidgetListener(this);
   mWindow->Create((nsIWidget *)parentWidget,          // Parent nsIWidget
                   nullptr,                            // Native parent widget
-                  deskRect,                           // Widget dimensions
+                  r,                                  // Widget dimensions
                   &widgetInitData);                   // Widget initialization data
-
-  LayoutDeviceIntRect r;
   mWindow->GetClientBounds(r);
   // Match the default background color of content. Important on windows
   // since we no longer use content child widgets.
   mWindow->SetBackgroundColor(NS_RGB(255,255,255));
 
   // Create web shell
   mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
   NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
--- a/xpfe/appshell/nsXULWindow.cpp
+++ b/xpfe/appshell/nsXULWindow.cpp
@@ -554,73 +554,29 @@ NS_IMETHODIMP nsXULWindow::Destroy()
 
     if (obssvc)
       obssvc->NotifyObservers(nullptr, "xul-window-destroyed", nullptr);
   }
 
   return NS_OK;
 }
 
-NS_IMETHODIMP nsXULWindow::GetDevicePixelsPerDesktopPixel(double *aScale)
-{
-  *aScale = mWindow ? mWindow->GetDesktopToDeviceScale().scale : 1.0;
-  return NS_OK;
-}
-
 NS_IMETHODIMP nsXULWindow::GetUnscaledDevicePixelsPerCSSPixel(double *aScale)
 {
   *aScale = mWindow ? mWindow->GetDefaultScale().scale : 1.0;
   return NS_OK;
 }
 
-DesktopToLayoutDeviceScale
-nsXULWindow::GetScaleForDestinationPosition(int32_t aX, int32_t aY)
-{
-  DesktopToLayoutDeviceScale scale(nsIWidget::DefaultScaleOverride());
-  if (scale.scale <= 0.0) {
-    // The destination monitor may have the different dpi from the source.
-    nsCOMPtr<nsIScreenManager> screenMgr(do_GetService(
-                                         "@mozilla.org/gfx/screenmanager;1"));
-    if (screenMgr) {
-      int32_t width, height;
-      // Use current size, converted to desktop pixels
-      GetSize(&width, &height);
-      DesktopToLayoutDeviceScale curr = mWindow->GetDesktopToDeviceScale();
-      width /= curr.scale;
-      height /= curr.scale;
-      width = std::max(1, width);
-      height = std::max(1, height);
-      nsCOMPtr<nsIScreen> screen;
-      screenMgr->ScreenForRect(aX, aY, width, height,
-                               getter_AddRefs(screen));
-      if (screen) {
-        double contentsScaleFactor;
-        if (NS_SUCCEEDED(screen->GetContentsScaleFactor(
-                         &contentsScaleFactor))) {
-          scale = DesktopToLayoutDeviceScale(contentsScaleFactor);
-        } else {
-          // Fallback to the scale from the widget.
-          scale = mWindow->GetDesktopToDeviceScale();
-        }
-      }
-    } else {
-      // this fallback should never actually be needed
-      scale = mWindow->GetDesktopToDeviceScale();
-    }
-  }
-  return scale;
-}
-
 NS_IMETHODIMP nsXULWindow::SetPosition(int32_t aX, int32_t aY)
 {
   // Don't reset the window's size mode here - platforms that don't want to move
   // maximized windows should reset it in their respective Move implementation.
-  DesktopToLayoutDeviceScale scale = GetScaleForDestinationPosition(aX, aY);
-  DesktopPoint pos = LayoutDeviceIntPoint(aX, aY) / scale;
-  nsresult rv = mWindow->Move(pos.x, pos.y);
+  CSSToLayoutDeviceScale scale = mWindow->GetDefaultScale();
+  double invScale = 1.0 / scale.scale;
+  nsresult rv = mWindow->Move(aX * invScale, aY * invScale);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
   if (!mChromeLoaded) {
     // If we're called before the chrome is loaded someone obviously wants this
     // window at this position. We don't persist this one-time position.
     mIgnoreXULPosition = true;
     return NS_OK;
   }
   PersistentAttributesDirty(PAD_POSITION);
@@ -637,19 +593,19 @@ NS_IMETHODIMP nsXULWindow::SetSize(int32
 {
   /* any attempt to set the window's size or position overrides the window's
      zoom state. this is important when these two states are competing while
      the window is being opened. but it should probably just always be so. */
   mWindow->SetSizeMode(nsSizeMode_Normal);
 
   mIntrinsicallySized = false;
 
-  DesktopToLayoutDeviceScale scale = mWindow->GetDesktopToDeviceScale();
-  DesktopSize size = LayoutDeviceIntSize(aCX, aCY) / scale;
-  nsresult rv = mWindow->Resize(size.width, size.height, aRepaint);
+  CSSToLayoutDeviceScale scale = mWindow->GetDefaultScale();
+  double invScale = 1.0 / scale.scale;
+  nsresult rv = mWindow->Resize(aCX * invScale, aCY * invScale, aRepaint);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
   if (!mChromeLoaded) {
     // If we're called before the chrome is loaded someone obviously wants this
     // window at this size & in the normal size mode (since it is the only mode
     // in which setting dimensions makes sense). We don't persist this one-time
     // size.
     mIgnoreXULSize = true;
     mIgnoreXULSizeMode = true;
@@ -670,19 +626,20 @@ NS_IMETHODIMP nsXULWindow::SetPositionAn
 {
   /* any attempt to set the window's size or position overrides the window's
      zoom state. this is important when these two states are competing while
      the window is being opened. but it should probably just always be so. */
   mWindow->SetSizeMode(nsSizeMode_Normal);
 
   mIntrinsicallySized = false;
 
-  DesktopToLayoutDeviceScale scale = mWindow->GetDesktopToDeviceScale();
-  DesktopRect rect = LayoutDeviceIntRect(aX, aY, aCX, aCY) / scale;
-  nsresult rv = mWindow->Resize(rect.x, rect.y, rect.width, rect.height,
+  CSSToLayoutDeviceScale scale = mWindow->GetDefaultScale();
+  double invScale = 1.0 / scale.scale;
+  nsresult rv = mWindow->Resize(aX * invScale, aY * invScale,
+                                aCX * invScale, aCY * invScale,
                                 aRepaint);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
   if (!mChromeLoaded) {
     // If we're called before the chrome is loaded someone obviously wants this
     // window at this size and position. We don't persist this one-time setting.
     mIgnoreXULPosition = true;
     mIgnoreXULSize = true;
     mIgnoreXULSizeMode = true;
@@ -740,17 +697,18 @@ NS_IMETHODIMP nsXULWindow::Center(nsIXUL
 
   if (aRelative) {
     nsCOMPtr<nsIBaseWindow> base(do_QueryInterface(aRelative, &result));
     if (base) {
       // get window rect
       result = base->GetPositionAndSize(&left, &top, &width, &height);
       if (NS_SUCCEEDED(result)) {
         double scale;
-        if (NS_SUCCEEDED(base->GetDevicePixelsPerDesktopPixel(&scale))) {
+        if (NS_SUCCEEDED(base->GetUnscaledDevicePixelsPerCSSPixel(&scale))) {
+          // convert device-pixel coordinates to global display pixels
           left = NSToIntRound(left / scale);
           top = NSToIntRound(top / scale);
           width = NSToIntRound(width / scale);
           height = NSToIntRound(height / scale);
         }
         // if centering on screen, convert that to the corresponding screen
         if (aScreen)
           screenmgr->ScreenForRect(left, top, width, height, getter_AddRefs(screen));
@@ -777,38 +735,28 @@ NS_IMETHODIMP nsXULWindow::Center(nsIXUL
 
   if (aScreen && screen) {
     screen->GetAvailRectDisplayPix(&left, &top, &width, &height);
     screenCoordinates = true;
   }
 
   if (screenCoordinates || windowCoordinates) {
     NS_ASSERTION(mWindow, "what, no window?");
-    double scale = mWindow->GetDesktopToDeviceScale().scale;
+    CSSToLayoutDeviceScale scale = mWindow->GetDefaultScale();
     GetSize(&ourWidth, &ourHeight);
-    int32_t scaledWidth, scaledHeight;
-    scaledWidth = NSToIntRound(ourWidth / scale);
-    scaledHeight = NSToIntRound(ourHeight / scale);
-    left += (width - scaledWidth) / 2;
-    top += (height - scaledHeight) / (aAlert ? 3 : 2);
+    ourWidth = NSToIntRound(ourWidth / scale.scale);
+    ourHeight = NSToIntRound(ourHeight / scale.scale);
+    left += (width - ourWidth) / 2;
+    top += (height - ourHeight) / (aAlert ? 3 : 2);
     if (windowCoordinates) {
       mWindow->ConstrainPosition(false, &left, &top);
     }
-    SetPosition(left * scale, top * scale);
-
-    // If moving the window caused it to change size,
-    // re-do the centering.
-    int32_t newWidth, newHeight;
-    GetSize(&newWidth, &newHeight);
-    if (newWidth != ourWidth || newHeight != ourHeight) {
-      return Center(aRelative, aScreen, aAlert);
-    }
+    SetPosition(left * scale.scale, top * scale.scale);
     return NS_OK;
   }
-
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP nsXULWindow::Repaint(bool aForce)
 {
   //XXX First Check In
   NS_ASSERTION(false, "Not Yet Implemented");
   return NS_OK;
@@ -1063,29 +1011,16 @@ NS_IMETHODIMP nsXULWindow::EnsureAuthPro
 void nsXULWindow::OnChromeLoaded()
 {
   nsresult rv = EnsureContentTreeOwner();
 
   if (NS_SUCCEEDED(rv)) {
     mChromeLoaded = true;
     ApplyChromeFlags();
     SyncAttributesToWidget();
-
-    bool positionSet = !mIgnoreXULPosition;
-    nsCOMPtr<nsIXULWindow> parentWindow(do_QueryReferent(mParentWindow));
-#if defined(XP_UNIX) && !defined(XP_MACOSX)
-    // don't override WM placement on unix for independent, top-level windows
-    // (however, we think the benefits of intelligent dependent window placement
-    // trump that override.)
-    if (!parentWindow)
-      positionSet = false;
-#endif
-    if (positionSet)
-      positionSet = LoadPositionFromXUL();
-
     if (!mIgnoreXULSize)
       LoadSizeFromXUL();
     if (mIntrinsicallySized) {
       // (if LoadSizeFromXUL set the size, mIntrinsicallySized will be false)
       nsCOMPtr<nsIContentViewer> cv;
       mDocShell->GetContentViewer(getter_AddRefs(cv));
       if (cv) {
         nsCOMPtr<nsIDocShellTreeItem> docShellAsItem = do_QueryInterface(mDocShell);
@@ -1097,16 +1032,27 @@ void nsXULWindow::OnChromeLoaded()
           int32_t width = 0, height = 0;
           if (NS_SUCCEEDED(cv->GetContentSize(&width, &height))) {
             treeOwner->SizeShellTo(docShellAsItem, width, height);
           }
         }
       }
     }
 
+    bool positionSet = !mIgnoreXULPosition;
+    nsCOMPtr<nsIXULWindow> parentWindow(do_QueryReferent(mParentWindow));
+#if defined(XP_UNIX) && !defined(XP_MACOSX)
+    // don't override WM placement on unix for independent, top-level windows
+    // (however, we think the benefits of intelligent dependent window placement
+    // trump that override.)
+    if (!parentWindow)
+      positionSet = false;
+#endif
+    if (positionSet)
+      positionSet = LoadPositionFromXUL();
     LoadMiscPersistentAttributesFromXUL();
 
     if (mCenterAfterLoad && !positionSet)
       Center(parentWindow, parentWindow ? false : true, false);
 
     if (mShowAfterLoad) {
       SetVisibility(true);
       // At this point the window may have been closed during Show(), so
@@ -1134,21 +1080,21 @@ bool nsXULWindow::LoadPositionFromXUL()
   int32_t currHeight = 0;
   nsresult errorCode;
   int32_t temp;
 
   GetPositionAndSize(&currX, &currY, &currWidth, &currHeight);
 
   // Convert to global display pixels for consistent window management across
   // screens with diverse resolutions
-  double scale = mWindow->GetDesktopToDeviceScale().scale;
-  currX = NSToIntRound(currX / scale);
-  currY = NSToIntRound(currY / scale);
-  currWidth = NSToIntRound(currWidth / scale);
-  currHeight = NSToIntRound(currHeight / scale);
+  CSSToLayoutDeviceScale scale = mWindow->GetDefaultScale();
+  currX = NSToIntRound(currX / scale.scale);
+  currY = NSToIntRound(currY / scale.scale);
+  currWidth = NSToIntRound(currWidth / scale.scale);
+  currHeight = NSToIntRound(currHeight / scale.scale);
 
   // Obtain the position information from the <xul:window> element.
   int32_t specX = currX;
   int32_t specY = currY;
   nsAutoString posString;
 
   windowElement->GetAttribute(SCREENX_ATTRIBUTE, posString);
   temp = posString.ToInteger(&errorCode);
@@ -1165,34 +1111,32 @@ bool nsXULWindow::LoadPositionFromXUL()
 
   if (gotPosition) {
     // our position will be relative to our parent, if any
     nsCOMPtr<nsIBaseWindow> parent(do_QueryReferent(mParentWindow));
     if (parent) {
       int32_t parentX, parentY;
       if (NS_SUCCEEDED(parent->GetPosition(&parentX, &parentY))) {
         double scale;
-        if (NS_SUCCEEDED(parent->GetDevicePixelsPerDesktopPixel(&scale))) {
+        if (NS_SUCCEEDED(parent->GetUnscaledDevicePixelsPerCSSPixel(&scale))) {
           parentX = NSToIntRound(parentX / scale);
           parentY = NSToIntRound(parentY / scale);
         }
         specX += parentX;
         specY += parentY;
       }
     }
     else {
       StaggerPosition(specX, specY, currWidth, currHeight);
     }
   }
   mWindow->ConstrainPosition(false, &specX, &specY);
   if (specX != currX || specY != currY) {
-    DesktopToLayoutDeviceScale destScale =
-      GetScaleForDestinationPosition(specX, specY);
-    LayoutDevicePoint devPos = DesktopIntPoint(specX, specY) * destScale;
-    SetPosition(devPos.x, devPos.y);
+    CSSToLayoutDeviceScale scale = mWindow->GetDefaultScale();
+    SetPosition(specX * scale.scale, specY * scale.scale);
   }
 
   return gotPosition;
 }
 
 bool nsXULWindow::LoadSizeFromXUL()
 {
   bool     gotSize = false;
@@ -1207,22 +1151,21 @@ bool nsXULWindow::LoadSizeFromXUL()
 
   int32_t currWidth = 0;
   int32_t currHeight = 0;
   nsresult errorCode;
   int32_t temp;
 
   NS_ASSERTION(mWindow, "we expected to have a window already");
 
+  CSSToLayoutDeviceScale scale = mWindow ? mWindow->GetDefaultScale()
+                                         : CSSToLayoutDeviceScale(1.0);
   GetSize(&currWidth, &currHeight);
-  double displayToDevPx =
-    mWindow ? mWindow->GetDesktopToDeviceScale().scale : 1.0;
-  double cssToDevPx = mWindow ? mWindow->GetDefaultScale().scale : 1.0;
-  currWidth = NSToIntRound(currWidth * displayToDevPx / cssToDevPx);
-  currHeight = NSToIntRound(currHeight * displayToDevPx / cssToDevPx);
+  currWidth = NSToIntRound(currWidth / scale.scale);
+  currHeight = NSToIntRound(currHeight / scale.scale);
 
   // Obtain the position and sizing information from the <xul:window> element.
   int32_t specWidth = currWidth;
   int32_t specHeight = currHeight;
   nsAutoString sizeString;
 
   windowElement->GetAttribute(WIDTH_ATTRIBUTE, sizeString);
   temp = sizeString.ToInteger(&errorCode);
@@ -1241,28 +1184,29 @@ bool nsXULWindow::LoadSizeFromXUL()
     // constrain to screen size
     nsCOMPtr<nsIDOMWindow> domWindow;
     GetWindowDOMWindow(getter_AddRefs(domWindow));
     if (nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(domWindow)) {
       nsCOMPtr<nsIDOMScreen> screen = window->GetScreen();
       if (screen) {
         int32_t screenWidth;
         int32_t screenHeight;
-        screen->GetAvailWidth(&screenWidth); // CSS pixels
+        screen->GetAvailWidth(&screenWidth);
         screen->GetAvailHeight(&screenHeight);
         if (specWidth > screenWidth)
           specWidth = screenWidth;
         if (specHeight > screenHeight)
           specHeight = screenHeight;
       }
     }
 
     mIntrinsicallySized = false;
     if (specWidth != currWidth || specHeight != currHeight) {
-      SetSize(specWidth * cssToDevPx, specHeight * cssToDevPx, false);
+      CSSToLayoutDeviceScale scale = mWindow->GetDefaultScale();
+      SetSize(specWidth * scale.scale, specHeight * scale.scale, false);
     }
   }
 
   return gotSize;
 }
 
 /* Miscellaneous persistent attributes are attributes named in the
    |persist| attribute, other than size and position. Those are special
@@ -1544,19 +1488,17 @@ NS_IMETHODIMP nsXULWindow::SavePersisten
   if (nsPIDOMWindow* domWindow = mDocShell->GetWindow()) {
     isFullscreen = domWindow->GetFullScreen();
   }
 
   // get our size, position and mode to persist
   LayoutDeviceIntRect rect;
   bool gotRestoredBounds = NS_SUCCEEDED(mWindow->GetRestoredBounds(rect));
 
-  // we use CSS pixels for size, but desktop pixels for position
-  CSSToLayoutDeviceScale sizeScale = mWindow->GetDefaultScale();
-  DesktopToLayoutDeviceScale posScale = mWindow->GetDesktopToDeviceScale();
+  CSSToLayoutDeviceScale scale = mWindow->GetDefaultScale();
 
   // make our position relative to our parent, if any
   nsCOMPtr<nsIBaseWindow> parent(do_QueryReferent(mParentWindow));
   if (parent && gotRestoredBounds) {
     int32_t parentX, parentY;
     if (NS_SUCCEEDED(parent->GetPosition(&parentX, &parentY))) {
       rect.x -= parentX;
       rect.y -= parentY;
@@ -1574,48 +1516,44 @@ NS_IMETHODIMP nsXULWindow::SavePersisten
     docShellElement->GetId(windowElementId);
   }
 
   bool shouldPersist = !isFullscreen && ownerXULDoc;
   ErrorResult rv;
   // (only for size elements which are persisted)
   if ((mPersistentAttributesDirty & PAD_POSITION) && gotRestoredBounds) {
     if (persistString.Find("screenX") >= 0) {
-      PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d",
-                  NSToIntRound(rect.x / posScale.scale));
+      PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(rect.x / scale.scale));
       sizeString.AssignWithConversion(sizeBuf);
       docShellElement->SetAttribute(SCREENX_ATTRIBUTE, sizeString, rv);
       if (shouldPersist) {
         ownerXULDoc->Persist(windowElementId, SCREENX_ATTRIBUTE);
       }
     }
     if (persistString.Find("screenY") >= 0) {
-      PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d",
-                  NSToIntRound(rect.y / posScale.scale));
+      PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(rect.y / scale.scale));
       sizeString.AssignWithConversion(sizeBuf);
       docShellElement->SetAttribute(SCREENY_ATTRIBUTE, sizeString, rv);
       if (shouldPersist) {
         ownerXULDoc->Persist(windowElementId, SCREENY_ATTRIBUTE);
       }
     }
   }
 
   if ((mPersistentAttributesDirty & PAD_SIZE) && gotRestoredBounds) {
     if (persistString.Find("width") >= 0) {
-      PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d",
-                  NSToIntRound(rect.width / sizeScale.scale));
+      PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(rect.width / scale.scale));
       sizeString.AssignWithConversion(sizeBuf);
       docShellElement->SetAttribute(WIDTH_ATTRIBUTE, sizeString, rv);
       if (shouldPersist) {
         ownerXULDoc->Persist(windowElementId, WIDTH_ATTRIBUTE);
       }
     }
     if (persistString.Find("height") >= 0) {
-      PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d",
-                  NSToIntRound(rect.height / sizeScale.scale));
+      PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(rect.height / scale.scale));
       sizeString.AssignWithConversion(sizeBuf);
       docShellElement->SetAttribute(HEIGHT_ATTRIBUTE, sizeString, rv);
       if (shouldPersist) {
         ownerXULDoc->Persist(windowElementId, HEIGHT_ATTRIBUTE);
       }
     }
   }
 
--- a/xpfe/appshell/nsXULWindow.h
+++ b/xpfe/appshell/nsXULWindow.h
@@ -13,17 +13,16 @@
 
 // Helper classes
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
 #include "nsString.h"
 #include "nsWeakReference.h"
 #include "nsCOMArray.h"
 #include "nsRect.h"
-#include "Units.h"
 
 // Interfaces needed
 #include "nsIBaseWindow.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDOMWindow.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
@@ -85,19 +84,16 @@ protected:
    virtual ~nsXULWindow();
 
    NS_IMETHOD EnsureChromeTreeOwner();
    NS_IMETHOD EnsureContentTreeOwner();
    NS_IMETHOD EnsurePrimaryContentTreeOwner();
    NS_IMETHOD EnsurePrompter();
    NS_IMETHOD EnsureAuthPrompter();
 
-   mozilla::DesktopToLayoutDeviceScale
-   GetScaleForDestinationPosition(int32_t aX, int32_t aY);
-
    void OnChromeLoaded();
    void StaggerPosition(int32_t &aRequestedX, int32_t &aRequestedY,
                         int32_t aSpecWidth, int32_t aSpecHeight);
    bool       LoadPositionFromXUL();
    bool       LoadSizeFromXUL();
    bool       LoadMiscPersistentAttributesFromXUL();
    void       SyncAttributesToWidget();
    NS_IMETHOD SavePersistentAttributes();