Bug 1194751 - Part 7. Implement ScreenHelperWin and delete old nsScreenManagerWin/nsScreenWin. r?jimm draft
authorKan-Ru Chen <kanru@kanru.info>
Thu, 09 Mar 2017 19:32:31 +0800
changeset 551546 f4a28c06839d5660ded7095ce5791de3b814f243
parent 551545 e9fcc740570b46365e7a28d79391972661f908a4
child 551547 8d1ad73ba4f2796a8a69ac28217efdf3395b9e6f
push id51077
push userkchen@mozilla.com
push dateMon, 27 Mar 2017 01:06:01 +0000
reviewersjimm
bugs1194751
milestone55.0a1
Bug 1194751 - Part 7. Implement ScreenHelperWin and delete old nsScreenManagerWin/nsScreenWin. r?jimm ScreenHelperWin is the platform dependent part of the original nsScreenManagerWin and nsScreenWin. It listens the WM_DISPLAYCHANGE message and pushes updates to ScreenManager. See patch part 4. for how ScreenManager works. MozReview-Commit-ID: 20A3ZQKmH9a
widget/windows/ScreenHelperWin.cpp
widget/windows/ScreenHelperWin.h
widget/windows/moz.build
widget/windows/nsAppShell.cpp
widget/windows/nsScreenManagerWin.cpp
widget/windows/nsScreenManagerWin.h
widget/windows/nsScreenWin.cpp
widget/windows/nsScreenWin.h
widget/windows/nsWidgetFactory.cpp
widget/windows/nsWindow.cpp
rename from widget/windows/nsScreenManagerWin.cpp
rename to widget/windows/ScreenHelperWin.cpp
--- a/widget/windows/nsScreenManagerWin.cpp
+++ b/widget/windows/ScreenHelperWin.cpp
@@ -1,132 +1,90 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "ScreenHelperWin.h"
+
+#include "mozilla/Logging.h"
+#include "nsTArray.h"
 #include "WinUtils.h"
 
-using namespace mozilla;
-
-BOOL CALLBACK CountMonitors(HMONITOR, HDC, LPRECT, LPARAM ioCount);
+static LazyLogModule sScreenLog("WidgetScreen");
 
-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
-  // has changed.
-}
-
-
-nsScreenManagerWin::~nsScreenManagerWin()
-{
-}
-
-
-// addref, release, QI
-NS_IMPL_ISUPPORTS(nsScreenManagerWin, nsIScreenManager)
-
+namespace mozilla {
+namespace widget {
 
-//
-// CreateNewScreenObject
-//
-// Utility routine. Creates a new screen object from the given device handle
-//
-// NOTE: For this "single-monitor" impl, we just always return the cached primary
-//        screen. This should change when a multi-monitor impl is done.
-//
-nsIScreen* 
-nsScreenManagerWin::CreateNewScreenObject(HMONITOR inScreen)
+BOOL CALLBACK
+CollectMonitors(HMONITOR aMon, HDC, LPRECT, LPARAM ioParam)
 {
-  nsIScreen* retScreen = nullptr;
-  
-  // look through our screen list, hoping to find it. If it's not there,
-  // add it and return the new one.
-  for (unsigned i = 0; i < mScreenList.Length(); ++i) {
-    ScreenListItem& curr = mScreenList[i];
-    if (inScreen == curr.mMon) {
-      NS_IF_ADDREF(retScreen = curr.mScreen.get());
-      return retScreen;
-    }
-  } // for each screen.
- 
-  retScreen = new nsScreenWin(inScreen);
-  mScreenList.AppendElement(ScreenListItem(inScreen, retScreen));
-
-  NS_IF_ADDREF(retScreen);
-  return retScreen;
+  auto screens = reinterpret_cast<nsTArray<RefPtr<Screen>>*>(ioParam);
+  BOOL success = FALSE;
+  MONITORINFO info;
+  info.cbSize = sizeof(MONITORINFO);
+  success = ::GetMonitorInfoW(aMon, &info);
+  if (!success) {
+    MOZ_LOG(sScreenLog, LogLevel::Error, ("GetMonitorInfoW failed"));
+    return TRUE; // continue the enumeration
+  }
+  DesktopToLayoutDeviceScale contentsScaleFactor;
+  if (WinUtils::IsPerMonitorDPIAware()) {
+    contentsScaleFactor.scale = 1.0;
+  } else {
+    contentsScaleFactor.scale = WinUtils::LogToPhysFactor(aMon);
+  }
+  CSSToLayoutDeviceScale defaultCssScaleFactor(nsIWidget::DefaultScaleOverride());
+  if (defaultCssScaleFactor.scale <= 0.0) {
+    defaultCssScaleFactor.scale = contentsScaleFactor.scale;
+  }
+  LayoutDeviceIntRect rect(info.rcMonitor.left, info.rcMonitor.top,
+                           info.rcMonitor.right - info.rcMonitor.left,
+                           info.rcMonitor.bottom - info.rcMonitor.top);
+  LayoutDeviceIntRect availRect(info.rcWork.left, info.rcWork.top,
+                                info.rcWork.right - info.rcWork.left,
+                                info.rcWork.bottom - info.rcWork.top);
+  //XXX not sure how to get this info for multiple monitors, this might be ok...
+  HDC hDCScreen = ::GetDC(nullptr);
+  NS_ASSERTION(hDCScreen,"GetDC Failure");
+  uint32_t pixelDepth = ::GetDeviceCaps(hDCScreen, BITSPIXEL);
+  ::ReleaseDC(nullptr, hDCScreen);
+  if (pixelDepth == 32) {
+    // If a device uses 32 bits per pixel, it's still only using 8 bits
+    // per color component, which is what our callers want to know.
+    // (Some devices report 32 and some devices report 24.)
+    pixelDepth = 24;
+  }
+  MOZ_LOG(sScreenLog, LogLevel::Debug, ("New screen [%d %d %d %d %d %f]",
+                                        rect.x, rect.y, rect.width, rect.height,
+                                        pixelDepth, defaultCssScaleFactor.scale));
+  screens->AppendElement(new Screen(rect, availRect,
+                                    pixelDepth, pixelDepth,
+                                    contentsScaleFactor, defaultCssScaleFactor));
+  return TRUE;
 }
 
-NS_IMETHODIMP
-nsScreenManagerWin::ScreenForId(uint32_t aId, nsIScreen **outScreen)
+float
+ScreenHelperWin::GetSystemDefaultScale()
 {
-  *outScreen = nullptr;
-
-  for (unsigned i = 0; i < mScreenList.Length(); ++i) {
-    ScreenListItem& curr = mScreenList[i];
-    uint32_t id;
-    nsresult rv = curr.mScreen->GetId(&id);
-    if (NS_SUCCEEDED(rv) && id == aId) {
-      NS_IF_ADDREF(*outScreen = curr.mScreen.get());
-      return NS_OK;
-    }
-  }
-
-  return NS_ERROR_FAILURE;
+  HMONITOR primary = widget::WinUtils::GetPrimaryMonitor();
+  return float(widget::WinUtils::LogToPhysFactor(primary));
 }
 
-//
-// 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,
-                                  nsIScreen **outScreen)
+void
+ScreenHelperWin::RefreshScreens()
 {
-  if (!(inWidth || inHeight)) {
-    NS_WARNING("trying to find screen for sizeless window, using primary monitor");
-    *outScreen = CreateNewScreenObject(nullptr);    // addrefs
-    return NS_OK;
-  }
+  MOZ_LOG(sScreenLog, LogLevel::Debug, ("Refreshing screens"));
 
-  gfx::Rect logicalBounds(inLeft, inTop, inWidth, inHeight);
-  HMONITOR genScreen = widget::WinUtils::MonitorFromRect(logicalBounds);
- 
-  *outScreen = CreateNewScreenObject(genScreen);    // addrefs
- 
-  return NS_OK;
-    
-} // ScreenForRect
-
+  AutoTArray<RefPtr<Screen>, 4> screens;
+  BOOL result = ::EnumDisplayMonitors(nullptr, nullptr,
+                                      (MONITORENUMPROC)CollectMonitors,
+                                      (LPARAM)&screens);
+  if (!result) {
+    NS_WARNING("Unable to EnumDisplayMonitors");
+  }
+  ScreenManager& screenManager = ScreenManager::GetSingleton();
+  screenManager.Refresh(Move(screens));
+}
 
-//
-// GetPrimaryScreen
-//
-// The screen with the menubar/taskbar. This shouldn't be needed very
-// often.
-//
-NS_IMETHODIMP 
-nsScreenManagerWin::GetPrimaryScreen(nsIScreen** aPrimaryScreen) 
-{
-  *aPrimaryScreen = CreateNewScreenObject(nullptr);    // addrefs  
-  return NS_OK;
-  
-} // GetPrimaryScreen
-
-NS_IMETHODIMP
-nsScreenManagerWin::GetSystemDefaultScale(float *aDefaultScale)
-{
-  HMONITOR primary = widget::WinUtils::GetPrimaryMonitor();
-  *aDefaultScale = float(widget::WinUtils::LogToPhysFactor(primary));
-  return NS_OK;
-}
+} // namespace widget
+} // namespace mozilla
rename from widget/windows/nsScreenManagerWin.h
rename to widget/windows/ScreenHelperWin.h
--- a/widget/windows/nsScreenManagerWin.h
+++ b/widget/windows/ScreenHelperWin.h
@@ -1,50 +1,28 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
-#ifndef nsScreenManagerWin_h___
-#define nsScreenManagerWin_h___
+#ifndef mozilla_widget_windows_ScreenHelperWin_h
+#define mozilla_widget_windows_ScreenHelperWin_h
 
-#include "nsIScreenManager.h"
+#include "mozilla/widget/ScreenManager.h"
 
-#include <windows.h>
-#include "nsCOMPtr.h"
-#include "nsTArray.h"
-#include "mozilla/Attributes.h"
+namespace mozilla {
+namespace widget {
 
-class nsIScreen;
-
-//------------------------------------------------------------------------
-
-class ScreenListItem
+class ScreenHelperWin final : public ScreenManager::Helper
 {
 public:
-  ScreenListItem ( HMONITOR inMon, nsIScreen* inScreen )
-    : mMon(inMon), mScreen(inScreen) { } ;
-  
-  HMONITOR mMon;
-  nsCOMPtr<nsIScreen> mScreen;
+  ScreenHelperWin() {};
+  ~ScreenHelperWin() override {}
+  float GetSystemDefaultScale() override;
+
+  static void RefreshScreens();
 };
 
-class nsScreenManagerWin final : public nsIScreenManager
-{
-public:
-  nsScreenManagerWin ( );
-
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSISCREENMANAGER
-
-private:
-  ~nsScreenManagerWin();
+} // namespace widget
+} // namespace mozilla
 
-  nsIScreen* CreateNewScreenObject ( HMONITOR inScreen ) ;
-
-  uint32_t mNumberOfScreens;
-
-    // cache the screens to avoid the memory allocations
-  AutoTArray<ScreenListItem, 8> mScreenList;
-
-};
-
-#endif  // nsScreenManagerWin_h___ 
+#endif // mozilla_widget_windows_ScreenHelperWin_h
--- a/widget/windows/moz.build
+++ b/widget/windows/moz.build
@@ -41,26 +41,25 @@ UNIFIED_SOURCES += [
     'nsDataObjCollection.cpp',
     'nsDragService.cpp',
     'nsIdleServiceWin.cpp',
     'nsImageClipboard.cpp',
     'nsLookAndFeel.cpp',
     'nsNativeDragSource.cpp',
     'nsNativeDragTarget.cpp',
     'nsNativeThemeWin.cpp',
-    'nsScreenManagerWin.cpp',
-    'nsScreenWin.cpp',
     'nsSound.cpp',
     'nsToolkit.cpp',
     'nsUXThemeData.cpp',
     'nsWindow.cpp',
     'nsWindowBase.cpp',
     'nsWindowDbg.cpp',
     'nsWindowGfx.cpp',
     'nsWinGesture.cpp',
+    'ScreenHelperWin.cpp',
     'TaskbarPreview.cpp',
     'TaskbarPreviewButton.cpp',
     'TaskbarTabPreview.cpp',
     'TaskbarWindowPreview.cpp',
     'WidgetTraceEvent.cpp',
     'WindowHook.cpp',
     'WinIMEHandler.cpp',
     'WinPointerEvents.cpp',
--- a/widget/windows/nsAppShell.cpp
+++ b/widget/windows/nsAppShell.cpp
@@ -19,16 +19,18 @@
 #include "nsIDOMWakeLockListener.h"
 #include "nsIPowerManagerService.h"
 #include "mozilla/StaticPtr.h"
 #include "nsTHashtable.h"
 #include "nsHashKeys.h"
 #include "GeckoProfiler.h"
 #include "nsComponentManagerUtils.h"
 #include "nsITimer.h"
+#include "ScreenHelperWin.h"
+#include "mozilla/widget/ScreenManager.h"
 
 // These are two messages that the code in winspool.drv on Windows 7 explicitly
 // waits for while it is pumping other Windows messages, during display of the
 // Printer Properties dialog.
 #define MOZ_WM_PRINTER_PROPERTIES_COMPLETION 0x5b7a
 #define MOZ_WM_PRINTER_PROPERTIES_FAILURE 0x5b7f
 
 using namespace mozilla;
@@ -242,16 +244,22 @@ nsAppShell::Init()
     RegisterClassW(&wc);
   }
 
   mEventWnd = CreateWindowW(kWindowClass, L"nsAppShell:EventWindow",
                             0, 0, 0, 10, 10, HWND_MESSAGE, nullptr, module,
                             nullptr);
   NS_ENSURE_STATE(mEventWnd);
 
+  if (XRE_IsParentProcess()) {
+    ScreenManager& screenManager = ScreenManager::GetSingleton();
+    screenManager.SetHelper(mozilla::MakeUnique<ScreenHelperWin>());
+    ScreenHelperWin::RefreshScreens();
+  }
+
   return nsBaseAppShell::Init();
 }
 
 NS_IMETHODIMP
 nsAppShell::Run(void)
 {
   // Content processes initialize audio later through PContent using audio
   // tray id information pulled from the browser process AudioSession. This
deleted file mode 100644
--- a/widget/windows/nsScreenWin.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-/* -*- 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 "nsIWidget.h"
-#include "WinUtils.h"
-
-using namespace mozilla;
-
-static uint32_t sScreenId;
-
-nsScreenWin::nsScreenWin(HMONITOR inScreen)
-  : mScreen(inScreen)
-  , mId(++sScreenId)
-{
-#ifdef DEBUG
-  HDC hDCScreen = ::GetDC(nullptr);
-  NS_ASSERTION(hDCScreen,"GetDC Failure");
-  NS_ASSERTION(::GetDeviceCaps(hDCScreen, TECHNOLOGY) == DT_RASDISPLAY, "Not a display screen");
-  ::ReleaseDC(nullptr,hDCScreen);
-#endif
-
-  // nothing else to do. I guess we could cache a bunch of information
-  // here, but we want to ask the device at runtime in case anything
-  // has changed.
-}
-
-
-nsScreenWin::~nsScreenWin()
-{
-  // nothing to see here.
-}
-
-
-NS_IMETHODIMP
-nsScreenWin::GetId(uint32_t *outId)
-{
-  *outId = mId;
-  return NS_OK;
-}
-
-
-NS_IMETHODIMP
-nsScreenWin::GetRect(int32_t *outLeft, int32_t *outTop, int32_t *outWidth, int32_t *outHeight)
-{
-  BOOL success = FALSE;
-  if (mScreen) {
-    MONITORINFO info;
-    info.cbSize = sizeof(MONITORINFO);
-    success = ::GetMonitorInfoW(mScreen, &info);
-    if (success) {
-      *outLeft = info.rcMonitor.left;
-      *outTop = info.rcMonitor.top;
-      *outWidth = info.rcMonitor.right - info.rcMonitor.left;
-      *outHeight = info.rcMonitor.bottom - info.rcMonitor.top;
-    }
-  }
-  if (!success) {
-     HDC hDCScreen = ::GetDC(nullptr);
-     NS_ASSERTION(hDCScreen,"GetDC Failure");
-    
-     *outTop = *outLeft = 0;
-     *outWidth = ::GetDeviceCaps(hDCScreen, HORZRES);
-     *outHeight = ::GetDeviceCaps(hDCScreen, VERTRES); 
-     
-     ::ReleaseDC(nullptr, hDCScreen);
-  }
-  return NS_OK;
-
-} // GetRect
-
-
-NS_IMETHODIMP
-nsScreenWin::GetAvailRect(int32_t *outLeft, int32_t *outTop, int32_t *outWidth, int32_t *outHeight)
-{
-  BOOL success = FALSE;
-
-  if (mScreen) {
-    MONITORINFO info;
-    info.cbSize = sizeof(MONITORINFO);
-    success = ::GetMonitorInfoW(mScreen, &info);
-    if (success) {
-      *outLeft = info.rcWork.left;
-      *outTop = info.rcWork.top;
-      *outWidth = info.rcWork.right - info.rcWork.left;
-      *outHeight = info.rcWork.bottom - info.rcWork.top;
-    }
-  }
-  if (!success) {
-    RECT workArea;
-    ::SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0);
-    *outLeft = workArea.left;
-    *outTop = workArea.top;
-    *outWidth = workArea.right - workArea.left;
-    *outHeight = workArea.bottom - workArea.top;
-  }
-
-  return NS_OK;
-  
-} // GetAvailRect
-
-NS_IMETHODIMP
-nsScreenWin::GetRectDisplayPix(int32_t *outLeft,  int32_t *outTop,
-                               int32_t *outWidth, int32_t *outHeight)
-{
-  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 / widget::WinUtils::LogToPhysFactor(mScreen);
-  *outLeft = NSToIntRound(left * scaleFactor);
-  *outTop = NSToIntRound(top * scaleFactor);
-  *outWidth = NSToIntRound(width * scaleFactor);
-  *outHeight = NSToIntRound(height * scaleFactor);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsScreenWin::GetAvailRectDisplayPix(int32_t *outLeft,  int32_t *outTop,
-                                    int32_t *outWidth, int32_t *outHeight)
-{
-  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 / widget::WinUtils::LogToPhysFactor(mScreen);
-  *outLeft = NSToIntRound(left * scaleFactor);
-  *outTop = NSToIntRound(top * scaleFactor);
-  *outWidth = NSToIntRound(width * scaleFactor);
-  *outHeight = NSToIntRound(height * scaleFactor);
-  return NS_OK;
-}
-
-
-NS_IMETHODIMP 
-nsScreenWin :: GetPixelDepth(int32_t *aPixelDepth)
-{
-  //XXX not sure how to get this info for multiple monitors, this might be ok...
-  HDC hDCScreen = ::GetDC(nullptr);
-  NS_ASSERTION(hDCScreen,"GetDC Failure");
-
-  int32_t depth = ::GetDeviceCaps(hDCScreen, BITSPIXEL);
-  if (depth == 32) {
-    // If a device uses 32 bits per pixel, it's still only using 8 bits
-    // per color component, which is what our callers want to know.
-    // (Some devices report 32 and some devices report 24.)
-    depth = 24;
-  }
-  *aPixelDepth = depth;
-
-  ::ReleaseDC(nullptr, hDCScreen);
-  return NS_OK;
-
-} // GetPixelDepth
-
-
-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;
-}
-
-NS_IMETHODIMP
-nsScreenWin::GetDefaultCSSScaleFactor(double* aScaleFactor)
-{
-  double scale = nsIWidget::DefaultScaleOverride();
-  if (scale > 0.0) {
-    *aScaleFactor = scale;
-  } else {
-    *aScaleFactor = widget::WinUtils::LogToPhysFactor(mScreen);
-  }
-  return NS_OK;
-}
deleted file mode 100644
--- a/widget/windows/nsScreenWin.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- 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/. */
-
-#ifndef nsScreenWin_h___
-#define nsScreenWin_h___
-
-#include <windows.h>
-#include "nsBaseScreen.h"
-
-//------------------------------------------------------------------------
-
-class nsScreenWin final : public nsBaseScreen
-{
-public:
-  explicit 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')
-  // 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;
-
-  NS_IMETHOD GetDefaultCSSScaleFactor(double* aScaleFactor) override;
-
-private:
-  HMONITOR mScreen;
-  uint32_t mId;
-};
-
-#endif  // nsScreenWin_h___ 
--- a/widget/windows/nsWidgetFactory.cpp
+++ b/widget/windows/nsWidgetFactory.cpp
@@ -7,20 +7,20 @@
 #include "nsIFactory.h"
 #include "nsISupports.h"
 #include "nsdefs.h"
 #include "nsWidgetsCID.h"
 #include "nsAppShell.h"
 #include "nsAppShellSingleton.h"
 #include "mozilla/ModuleUtils.h"
 #include "mozilla/WidgetUtils.h"
+#include "mozilla/widget/ScreenManager.h"
 #include "nsIServiceManager.h"
 #include "nsIdleServiceWin.h"
 #include "nsLookAndFeel.h"
-#include "nsScreenManagerWin.h"
 #include "nsSound.h"
 #include "WinMouseScrollHandler.h"
 #include "KeyboardLayout.h"
 #include "GfxInfo.h"
 #include "nsToolkit.h"
 
 // Modules that switch out based on the environment
 #include "nsXULAppAPI.h"
@@ -98,17 +98,17 @@ ColorPickerConstructor(nsISupports *aOut
   *aResult = nullptr;
   if (aOuter != nullptr) {
     return NS_ERROR_NO_AGGREGATION;
   }
   nsCOMPtr<nsIColorPicker> picker = new nsColorPicker;
   return picker->QueryInterface(aIID, aResult);
 }
 
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerWin)
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ScreenManager, ScreenManager::GetAddRefedSingleton)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIdleServiceWin, nsIdleServiceWin::GetInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound)
 NS_GENERIC_FACTORY_CONSTRUCTOR(WinTaskbar)
 NS_GENERIC_FACTORY_CONSTRUCTOR(JumpListBuilder)
 NS_GENERIC_FACTORY_CONSTRUCTOR(JumpListItem)
 NS_GENERIC_FACTORY_CONSTRUCTOR(JumpListSeparator)
@@ -167,17 +167,17 @@ NS_DEFINE_NAMED_CID(NS_DEVICE_CONTEXT_SP
 
 
 static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
   { &kNS_WINDOW_CID, false, nullptr, WindowConstructor },
   { &kNS_CHILD_CID, false, nullptr, ChildWindowConstructor },
   { &kNS_FILEPICKER_CID, false, nullptr, FilePickerConstructor, Module::MAIN_PROCESS_ONLY },
   { &kNS_COLORPICKER_CID, false, nullptr, ColorPickerConstructor, Module::MAIN_PROCESS_ONLY },
   { &kNS_APPSHELL_CID, false, nullptr, nsAppShellConstructor, Module::ALLOW_IN_GPU_PROCESS },
-  { &kNS_SCREENMANAGER_CID, false, nullptr, nsScreenManagerWinConstructor,
+  { &kNS_SCREENMANAGER_CID, false, nullptr, ScreenManagerConstructor,
     Module::MAIN_PROCESS_ONLY },
   { &kNS_GFXINFO_CID, false, nullptr, GfxInfoConstructor },
   { &kNS_THEMERENDERER_CID, false, nullptr, NS_NewNativeTheme },
   { &kNS_IDLE_SERVICE_CID, false, nullptr, nsIdleServiceWinConstructor },
   { &kNS_CLIPBOARD_CID, false, nullptr, nsClipboardConstructor, Module::MAIN_PROCESS_ONLY },
   { &kNS_CLIPBOARDHELPER_CID, false, nullptr, nsClipboardHelperConstructor },
   { &kNS_SOUND_CID, false, nullptr, nsSoundConstructor, Module::MAIN_PROCESS_ONLY },
   { &kNS_TRANSFERABLE_CID, false, nullptr, nsTransferableConstructor },
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -138,16 +138,17 @@
 #include "mozilla/widget/nsAutoRollup.h"
 #include "mozilla/widget/WinNativeEventData.h"
 #include "mozilla/widget/PlatformWidgetTypes.h"
 #include "nsThemeConstants.h"
 #include "nsBidiKeyboard.h"
 #include "nsThemeConstants.h"
 #include "gfxConfig.h"
 #include "InProcessWinCompositorWidget.h"
+#include "ScreenHelperWin.h"
 
 #include "nsIGfxInfo.h"
 #include "nsUXThemeConstants.h"
 #include "KeyboardLayout.h"
 #include "nsNativeDragTarget.h"
 #include <mmsystem.h> // needed for WIN32_LEAN_AND_MEAN
 #include <zmouse.h>
 #include <richedit.h>
@@ -5709,16 +5710,22 @@ nsWindow::ProcessMessage(UINT msg, WPARA
 
       if (!sIsInMouseCapture) {
         NotifySizeMoveDone();
       }
 
       break;
     }
 
+    case WM_DISPLAYCHANGE:
+    {
+      ScreenHelperWin::RefreshScreens();
+      break;
+    }
+
     case WM_NCLBUTTONDBLCLK:
       DispatchMouseEvent(eMouseDoubleClick, 0, lParamToClient(lParam),
                          false, WidgetMouseEvent::eLeftButton,
                          MOUSE_INPUT_SOURCE());
       result = 
         DispatchMouseEvent(eMouseUp, 0, lParamToClient(lParam),
                            false, WidgetMouseEvent::eLeftButton,
                            MOUSE_INPUT_SOURCE());