Bug 1194751 - Part 8. Implement ScreenHelperCocoa and delete old nsScreenManagerCocoa/nsScreenCocoa. r?mstange draft
authorKan-Ru Chen <kanru@kanru.info>
Thu, 09 Mar 2017 19:34:49 +0800
changeset 551547 8d1ad73ba4f2796a8a69ac28217efdf3395b9e6f
parent 551546 f4a28c06839d5660ded7095ce5791de3b814f243
child 552983 4833e551618582260a233a096f1d15c95d8be635
child 553313 c86e5d54a5f20600fdfc24dd612943afeb1066fa
child 553685 4daa2218f57b86a2fcb9f6b3f582bae7dd65b4a4
child 553696 2fdc3ebdfafb209afa03a9de0a7ce12ef5de6b98
child 554485 2fb450cc9d933346cebfdbff0b32ea4130550395
push id51077
push userkchen@mozilla.com
push dateMon, 27 Mar 2017 01:06:01 +0000
reviewersmstange
bugs1194751
milestone55.0a1
Bug 1194751 - Part 8. Implement ScreenHelperCocoa and delete old nsScreenManagerCocoa/nsScreenCocoa. r?mstange ScreenHelperCocoa is the platform dependent part of the original nsScreenManagerCocoa and nsScreenCocoa. It registers NSApplicationDidChangeScreenParametersNotification and pushes updates to ScreenManager. See patch part 4. for how ScreenManager works. MozReview-Commit-ID: 1A5ha4Ys2dL
widget/cocoa/ScreenHelperCocoa.h
widget/cocoa/ScreenHelperCocoa.mm
widget/cocoa/moz.build
widget/cocoa/nsAppShell.mm
widget/cocoa/nsCocoaWindow.mm
widget/cocoa/nsPrintOptionsX.mm
widget/cocoa/nsScreenCocoa.h
widget/cocoa/nsScreenCocoa.mm
widget/cocoa/nsScreenManagerCocoa.h
widget/cocoa/nsScreenManagerCocoa.mm
widget/cocoa/nsWidgetFactory.mm
rename from widget/cocoa/nsScreenManagerCocoa.h
rename to widget/cocoa/ScreenHelperCocoa.h
--- a/widget/cocoa/nsScreenManagerCocoa.h
+++ b/widget/cocoa/ScreenHelperCocoa.h
@@ -1,33 +1,37 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- 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 nsScreenManagerCocoa_h_
-#define nsScreenManagerCocoa_h_
+#ifndef mozilla_widget_cocoa_ScreenHelperCocoa_h
+#define mozilla_widget_cocoa_ScreenHelperCocoa_h
 
-#import <Cocoa/Cocoa.h>
+#include "mozilla/widget/ScreenManager.h"
 
-#include "mozilla/RefPtr.h"
-#include "nsTArray.h"
-#include "nsIScreenManager.h"
-#include "nsScreenCocoa.h"
+@class ScreenHelperDelegate;
+@class NSScreen;
 
-class nsScreenManagerCocoa : public nsIScreenManager
+namespace mozilla {
+namespace widget {
+
+class ScreenHelperCocoa final : public ScreenManager::Helper
 {
 public:
-    nsScreenManagerCocoa();
+  ScreenHelperCocoa();
+  ~ScreenHelperCocoa() override;
 
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSISCREENMANAGER
+  float GetSystemDefaultScale() override;
 
-protected:
-    virtual ~nsScreenManagerCocoa();
+  void RefreshScreens();
+
+  static NSScreen* CocoaScreenForScreen(nsIScreen* aScreen);
 
 private:
-
-    nsScreenCocoa *ScreenForCocoaScreen(NSScreen *screen);
-    nsTArray< RefPtr<nsScreenCocoa> > mScreenList;
+  ScreenHelperDelegate* mDelegate;
 };
 
-#endif // nsScreenManagerCocoa_h_
+} // namespace widget
+} // namespace mozilla
+
+#endif // mozilla_widget_gtk_ScreenHelperGtk_h
rename from widget/cocoa/nsScreenManagerCocoa.mm
rename to widget/cocoa/ScreenHelperCocoa.mm
--- a/widget/cocoa/nsScreenManagerCocoa.mm
+++ b/widget/cocoa/ScreenHelperCocoa.mm
@@ -1,119 +1,166 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- 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 "nsScreenManagerCocoa.h"
+#include "ScreenHelperCocoa.h"
+
+#import <Cocoa/Cocoa.h>
+
+#include "mozilla/Logging.h"
+#include "nsCocoaUtils.h"
 #include "nsObjCExceptions.h"
-#include "nsCOMPtr.h"
-#include "nsCocoaUtils.h"
+
+static LazyLogModule sScreenLog("WidgetScreen");
+
+@interface ScreenHelperDelegate : NSObject
+{
+  @private
+    mozilla::widget::ScreenHelperCocoa* mHelper;
+}
 
-using namespace mozilla;
+- (id)initWithScreenHelper:(mozilla::widget::ScreenHelperCocoa*)aScreenHelper;
+- (void)didChangeScreenParameters:(NSNotification*)aNotification;
+@end
 
-NS_IMPL_ISUPPORTS(nsScreenManagerCocoa, nsIScreenManager)
+@implementation ScreenHelperDelegate
+- (id)initWithScreenHelper:(mozilla::widget::ScreenHelperCocoa*)aScreenHelper
+{
+  if ((self = [self init])) {
+    mHelper = aScreenHelper;
 
-nsScreenManagerCocoa::nsScreenManagerCocoa()
-{
+    [[NSNotificationCenter defaultCenter] addObserver:self
+                                             selector:@selector(didChangeScreenParameters:)
+                                                 name:NSApplicationDidChangeScreenParametersNotification
+                                               object:nil];
+  }
+
+  return self;
 }
 
-nsScreenManagerCocoa::~nsScreenManagerCocoa()
+- (void)dealloc
 {
+  [[NSNotificationCenter defaultCenter] removeObserver:self];
+  [super dealloc];
 }
 
-nsScreenCocoa*
-nsScreenManagerCocoa::ScreenForCocoaScreen(NSScreen *screen)
+- (void)didChangeScreenParameters:(NSNotification*)aNotification
+{
+  MOZ_LOG(sScreenLog, LogLevel::Debug,
+          ("Received NSApplicationDidChangeScreenParametersNotification"));
+
+  mHelper->RefreshScreens();
+}
+@end
+
+namespace mozilla {
+namespace widget {
+
+ScreenHelperCocoa::ScreenHelperCocoa()
 {
-    for (uint32_t i = 0; i < mScreenList.Length(); ++i) {
-        nsScreenCocoa* sc = mScreenList[i];
-        if (sc->CocoaScreen() == screen) {
-            // doesn't addref
-            return sc;
-        }
-    }
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
+  MOZ_LOG(sScreenLog, LogLevel::Debug, ("ScreenHelperCocoa created"));
+
+  mDelegate = [[ScreenHelperDelegate alloc] initWithScreenHelper:this];
+
+  RefreshScreens();
 
-    // didn't find it; create and insert
-    RefPtr<nsScreenCocoa> sc = new nsScreenCocoa(screen);
-    mScreenList.AppendElement(sc);
-    return sc.get();
+  NS_OBJC_END_TRY_ABORT_BLOCK;
+}
+
+ScreenHelperCocoa::~ScreenHelperCocoa()
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
+  [mDelegate release];
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
-NS_IMETHODIMP
-nsScreenManagerCocoa::ScreenForId (uint32_t aId, nsIScreen **outScreen)
+static already_AddRefed<Screen>
+MakeScreen(NSScreen* aScreen)
 {
-    NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
 
-    *outScreen = nullptr;
+  DesktopToLayoutDeviceScale contentsScaleFactor(nsCocoaUtils::GetBackingScaleFactor(aScreen));
+  CSSToLayoutDeviceScale defaultCssScaleFactor(contentsScaleFactor.scale);
+  NSRect frame = [aScreen frame];
+  LayoutDeviceIntRect rect =
+    nsCocoaUtils::CocoaRectToGeckoRectDevPix(frame, contentsScaleFactor.scale);
+  frame = [aScreen visibleFrame];
+  LayoutDeviceIntRect availRect =
+    nsCocoaUtils::CocoaRectToGeckoRectDevPix(frame, contentsScaleFactor.scale);
+  NSWindowDepth depth = [aScreen depth];
+  uint32_t pixelDepth = NSBitsPerPixelFromDepth(depth);
 
-    for (uint32_t i = 0; i < mScreenList.Length(); ++i) {
-        nsScreenCocoa* sc = mScreenList[i];
-        uint32_t id;
-        nsresult rv = sc->GetId(&id);
+  MOZ_LOG(sScreenLog, LogLevel::Debug, ("New screen [%d %d %d %d %d %f]",
+                                        rect.x, rect.y, rect.width, rect.height,
+                                        pixelDepth, contentsScaleFactor.scale));
 
-        if (NS_SUCCEEDED(rv) && id == aId) {
-            *outScreen = sc;
-            NS_ADDREF(*outScreen);
-            return NS_OK;
-        }
-    }
+  RefPtr<Screen> screen = new Screen(rect, availRect,
+                                     pixelDepth, pixelDepth,
+                                     contentsScaleFactor, defaultCssScaleFactor);
+  return screen.forget();
 
-    return NS_ERROR_FAILURE;
+  NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(nullptr);
+}
 
-    NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+float
+ScreenHelperCocoa::GetSystemDefaultScale()
+{
+  return 1.0f;
 }
 
-NS_IMETHODIMP
-nsScreenManagerCocoa::ScreenForRect (int32_t aX, int32_t aY,
-                                     int32_t aWidth, int32_t aHeight,
-                                     nsIScreen **outScreen)
+void
+ScreenHelperCocoa::RefreshScreens()
 {
-    NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
-    NSEnumerator *screenEnum = [[NSScreen screens] objectEnumerator];
-    NSRect inRect =
-      nsCocoaUtils::GeckoRectToCocoaRect(DesktopIntRect(aX, aY,
-                                                        aWidth, aHeight));
-    NSScreen *screenWindowIsOn = [NSScreen mainScreen];
-    float greatestArea = 0;
+  MOZ_LOG(sScreenLog, LogLevel::Debug, ("Refreshing screens"));
+
+  AutoTArray<RefPtr<Screen>, 4> screens;
 
-    while (NSScreen *screen = [screenEnum nextObject]) {
-        NSDictionary *desc = [screen deviceDescription];
-        if ([desc objectForKey:NSDeviceIsScreen] == nil)
-            continue;
+  for (NSScreen* screen in [NSScreen screens]) {
+    NSDictionary *desc = [screen deviceDescription];
+    if ([desc objectForKey:NSDeviceIsScreen] == nil) {
+      continue;
+    }
+    screens.AppendElement(MakeScreen(screen));
+  }
 
-        NSRect r = NSIntersectionRect([screen frame], inRect);
-        float area = r.size.width * r.size.height;
-        if (area > greatestArea) {
-            greatestArea = area;
-            screenWindowIsOn = screen;
-        }
-    }
+  ScreenManager& screenManager = ScreenManager::GetSingleton();
+  screenManager.Refresh(Move(screens));
 
-    *outScreen = ScreenForCocoaScreen(screenWindowIsOn);
-    NS_ADDREF(*outScreen);
-    return NS_OK;
-
-    NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+  NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
-NS_IMETHODIMP
-nsScreenManagerCocoa::GetPrimaryScreen (nsIScreen **outScreen)
+NSScreen*
+ScreenHelperCocoa::CocoaScreenForScreen(nsIScreen* aScreen)
 {
-    NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
-    // the mainScreen is the screen with the "key window" (focus, I assume?)
-    NSScreen *sc = [[NSScreen screens] objectAtIndex:0];
+  for (NSScreen* screen in [NSScreen screens]) {
+    NSDictionary *desc = [screen deviceDescription];
+    if ([desc objectForKey:NSDeviceIsScreen] == nil) {
+      continue;
+    }
+    LayoutDeviceIntRect rect;
+    double scale;
+    aScreen->GetRect(&rect.x, &rect.y, &rect.width, &rect.height);
+    aScreen->GetContentsScaleFactor(&scale);
+    NSRect frame = [screen frame];
+    LayoutDeviceIntRect frameRect =
+      nsCocoaUtils::CocoaRectToGeckoRectDevPix(frame, scale);
+    if (rect == frameRect) {
+      return screen;
+    }
+  }
+  return [NSScreen mainScreen];
 
-    *outScreen = ScreenForCocoaScreen(sc);
-    NS_ADDREF(*outScreen);
-
-    return NS_OK;
-
-    NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+  NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
-NS_IMETHODIMP
-nsScreenManagerCocoa::GetSystemDefaultScale(float *aDefaultScale)
-{
-    *aDefaultScale = 1.0f;
-    return NS_OK;
-}
+} // namespace widget
+} // namespace mozilla
--- a/widget/cocoa/moz.build
+++ b/widget/cocoa/moz.build
@@ -41,26 +41,25 @@ UNIFIED_SOURCES += [
     'nsMenuGroupOwnerX.mm',
     'nsMenuItemIconX.mm',
     'nsMenuItemX.mm',
     'nsMenuUtilsX.mm',
     'nsMenuX.mm',
     'nsPrintDialogX.mm',
     'nsPrintOptionsX.mm',
     'nsPrintSettingsX.mm',
-    'nsScreenCocoa.mm',
-    'nsScreenManagerCocoa.mm',
     'nsSound.mm',
     'nsStandaloneNativeMenu.mm',
     'nsSystemStatusBarCocoa.mm',
     'nsToolkit.mm',
     'nsWidgetFactory.mm',
     'nsWindowMap.mm',
     'OSXNotificationCenter.mm',
     'RectTextureImage.mm',
+    'ScreenHelperCocoa.mm',
     'SwipeTracker.mm',
     'TextInputHandler.mm',
     'VibrancyManager.mm',
     'ViewRegion.mm',
     'WidgetTraceEvent.mm',
 ]
 
 # These files cannot be built in unified mode because they cause symbol conflicts
--- a/widget/cocoa/nsAppShell.mm
+++ b/widget/cocoa/nsAppShell.mm
@@ -27,16 +27,18 @@
 #include "nsObjCExceptions.h"
 #include "nsCocoaFeatures.h"
 #include "nsCocoaUtils.h"
 #include "nsChildView.h"
 #include "nsToolkit.h"
 #include "TextInputHandler.h"
 #include "mozilla/HangMonitor.h"
 #include "GeckoProfiler.h"
+#include "ScreenHelperCocoa.h"
+#include "mozilla/widget/ScreenManager.h"
 #include "pratom.h"
 #if !defined(RELEASE_OR_BETA) || defined(DEBUG)
 #include "nsSandboxViolationSink.h"
 #endif
 
 #include <IOKit/pwr_mgt/IOPMLib.h>
 #include "nsIDOMWakeLockListener.h"
 #include "nsIPowerManagerService.h"
@@ -301,16 +303,21 @@ nsAppShell::Init()
   context.info = this;
   context.perform = ProcessGeckoEvents;
   
   mCFRunLoopSource = ::CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
   NS_ENSURE_STATE(mCFRunLoopSource);
 
   ::CFRunLoopAddSource(mCFRunLoop, mCFRunLoopSource, kCFRunLoopCommonModes);
 
+  if (XRE_IsParentProcess()) {
+    ScreenManager& screenManager = ScreenManager::GetSingleton();
+    screenManager.SetHelper(mozilla::MakeUnique<ScreenHelperCocoa>());
+  }
+
   rv = nsBaseAppShell::Init();
 
   if (!gAppShellMethodsSwizzled) {
     // We should only replace the original terminate: method if we're not
     // running in a Cocoa embedder. See bug 604901.
     if (!mRunningCocoaEmbedded) {
       nsToolkit::SwizzleMethods([NSApplication class], @selector(terminate:),
                                 @selector(nsAppShell_NSApplication_terminate:));
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -29,17 +29,16 @@
 #include "nsStyleConsts.h"
 #include "nsNativeThemeColors.h"
 #include "nsNativeThemeCocoa.h"
 #include "nsChildView.h"
 #include "nsCocoaFeatures.h"
 #include "nsIScreenManager.h"
 #include "nsIWidgetListener.h"
 #include "nsIPresShell.h"
-#include "nsScreenCocoa.h"
 
 #include "gfxPlatform.h"
 #include "qcms.h"
 
 #include "mozilla/AutoRestore.h"
 #include "mozilla/BasicEvents.h"
 #include "mozilla/Preferences.h"
 #include <algorithm>
@@ -1393,18 +1392,17 @@ NS_IMPL_ISUPPORTS0(FullscreenTransitionD
   [self cleanupAndDispatch:animation];
 }
 @end
 
 /* virtual */ bool
 nsCocoaWindow::PrepareForFullscreenTransition(nsISupports** aData)
 {
   nsCOMPtr<nsIScreen> widgetScreen = GetWidgetScreen();
-  nsScreenCocoa* screen = static_cast<nsScreenCocoa*>(widgetScreen.get());
-  NSScreen* cocoaScreen = screen->CocoaScreen();
+  NSScreen* cocoaScreen = ScreenHelperCocoa::CocoaScreenForScreen(widgetScreen);
 
   NSWindow* win =
     [[NSWindow alloc] initWithContentRect:[cocoaScreen frame]
                                 styleMask:NSBorderlessWindowMask
                                   backing:NSBackingStoreBuffered
                                     defer:YES];
   [win setBackgroundColor:[NSColor blackColor]];
   [win setAlphaValue:0];
--- a/widget/cocoa/nsPrintOptionsX.mm
+++ b/widget/cocoa/nsPrintOptionsX.mm
@@ -3,16 +3,18 @@
  * 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 "nsCOMPtr.h"
 #include "nsQueryObject.h"
 #include "nsIServiceManager.h"
 #include "nsPrintOptionsX.h"
 #include "nsPrintSettingsX.h"
+#include "nsIWebBrowserPrint.h"
+#include "nsCocoaUtils.h"
 
 using namespace mozilla::embedding;
 
 nsPrintOptionsX::nsPrintOptionsX()
 {
 }
 
 nsPrintOptionsX::~nsPrintOptionsX()
deleted file mode 100644
--- a/widget/cocoa/nsScreenCocoa.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* 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 nsScreenCocoa_h_
-#define nsScreenCocoa_h_
-
-#import <Cocoa/Cocoa.h>
-
-#include "nsBaseScreen.h"
-
-class nsScreenCocoa : public nsBaseScreen
-{
-public:
-    explicit nsScreenCocoa (NSScreen *screen);
-    ~nsScreenCocoa ();
-
-    NS_IMETHOD GetId(uint32_t* outId);
-    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);
-    NS_IMETHOD GetRectDisplayPix(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
-    NS_IMETHOD GetAvailRectDisplayPix(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
-    NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth);
-    NS_IMETHOD GetColorDepth(int32_t* aColorDepth);
-    NS_IMETHOD GetContentsScaleFactor(double* aContentsScaleFactor);
-    NS_IMETHOD GetDefaultCSSScaleFactor(double* aScaleFactor)
-    {
-      return GetContentsScaleFactor(aScaleFactor);
-    }
-
-    NSScreen *CocoaScreen() { return mScreen; }
-
-private:
-    CGFloat BackingScaleFactor();
-
-    NSScreen *mScreen;
-    uint32_t mId;
-};
-
-#endif // nsScreenCocoa_h_
deleted file mode 100644
--- a/widget/cocoa/nsScreenCocoa.mm
+++ /dev/null
@@ -1,147 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* 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 "nsScreenCocoa.h"
-#include "nsObjCExceptions.h"
-#include "nsCocoaUtils.h"
-
-static uint32_t sScreenId = 0;
-
-nsScreenCocoa::nsScreenCocoa (NSScreen *screen)
-{
-  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
-  mScreen = [screen retain];
-  mId = ++sScreenId;
-
-  NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-nsScreenCocoa::~nsScreenCocoa ()
-{
-  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
-  [mScreen release];
-
-  NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-NS_IMETHODIMP
-nsScreenCocoa::GetId(uint32_t *outId)
-{
-  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
-
-  *outId = mId;
-  return NS_OK;
-
-  NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-NS_IMETHODIMP
-nsScreenCocoa::GetRect(int32_t *outX, int32_t *outY, int32_t *outWidth, int32_t *outHeight)
-{
-  NSRect frame = [mScreen frame];
-
-  mozilla::LayoutDeviceIntRect r =
-    nsCocoaUtils::CocoaRectToGeckoRectDevPix(frame, BackingScaleFactor());
-
-  *outX = r.x;
-  *outY = r.y;
-  *outWidth = r.width;
-  *outHeight = r.height;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsScreenCocoa::GetAvailRect(int32_t *outX, int32_t *outY, int32_t *outWidth, int32_t *outHeight)
-{
-  NSRect frame = [mScreen visibleFrame];
-
-  mozilla::LayoutDeviceIntRect r =
-    nsCocoaUtils::CocoaRectToGeckoRectDevPix(frame, BackingScaleFactor());
-
-  *outX = r.x;
-  *outY = r.y;
-  *outWidth = r.width;
-  *outHeight = r.height;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsScreenCocoa::GetRectDisplayPix(int32_t *outX, int32_t *outY, int32_t *outWidth, int32_t *outHeight)
-{
-  NSRect frame = [mScreen frame];
-
-  mozilla::DesktopIntRect r = nsCocoaUtils::CocoaRectToGeckoRect(frame);
-
-  *outX = r.x;
-  *outY = r.y;
-  *outWidth = r.width;
-  *outHeight = r.height;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsScreenCocoa::GetAvailRectDisplayPix(int32_t *outX, int32_t *outY, int32_t *outWidth, int32_t *outHeight)
-{
-  NSRect frame = [mScreen visibleFrame];
-
-  mozilla::DesktopIntRect r = nsCocoaUtils::CocoaRectToGeckoRect(frame);
-
-  *outX = r.x;
-  *outY = r.y;
-  *outWidth = r.width;
-  *outHeight = r.height;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsScreenCocoa::GetPixelDepth(int32_t *aPixelDepth)
-{
-  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
-
-  NSWindowDepth depth = [mScreen depth];
-  int bpp = NSBitsPerPixelFromDepth(depth);
-
-  *aPixelDepth = bpp;
-  return NS_OK;
-
-  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
-}
-
-NS_IMETHODIMP
-nsScreenCocoa::GetColorDepth(int32_t *aColorDepth)
-{
-  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
-
-  NSWindowDepth depth = [mScreen depth];
-  int bpp = NSBitsPerPixelFromDepth (depth);
-
-  *aColorDepth = bpp;
-  return NS_OK;
-
-  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
-}
-
-NS_IMETHODIMP
-nsScreenCocoa::GetContentsScaleFactor(double *aContentsScaleFactor)
-{
-  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
-
-  *aContentsScaleFactor = (double) BackingScaleFactor();
-  return NS_OK;
-
-  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
-}
-
-CGFloat
-nsScreenCocoa::BackingScaleFactor()
-{
-  return nsCocoaUtils::GetBackingScaleFactor(mScreen);
-}
--- a/widget/cocoa/nsWidgetFactory.mm
+++ b/widget/cocoa/nsWidgetFactory.mm
@@ -27,42 +27,43 @@
 
 #include "nsLookAndFeel.h"
 
 #include "nsSound.h"
 #include "nsIdleServiceX.h"
 #include "NativeKeyBindings.h"
 #include "OSXNotificationCenter.h"
 
-#include "nsScreenManagerCocoa.h"
 #include "nsDeviceContextSpecX.h"
 #include "nsPrintOptionsX.h"
 #include "nsPrintDialogX.h"
 #include "nsPrintSession.h"
 #include "nsToolkitCompsCID.h"
 
+#include "mozilla/widget/ScreenManager.h"
+
 using namespace mozilla;
 using namespace mozilla::widget;
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsCocoaWindow)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsChildView)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePicker)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsColorPicker)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDragService)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerCocoa)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceContextSpecX)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintOptionsX, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintDialogServiceX, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSession, Init)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIdleServiceX, nsIdleServiceX::GetInstance)
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ScreenManager, ScreenManager::GetAddRefedSingleton)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(OSXNotificationCenter, Init)
 
 #include "nsMenuBarX.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsNativeMenuServiceX)
 
 #include "nsBidiKeyboard.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard)
 
@@ -133,17 +134,17 @@ static const mozilla::Module::CIDEntry k
   { &kNS_CLIPBOARD_CID, false, NULL, nsClipboardConstructor,
     mozilla::Module::MAIN_PROCESS_ONLY },
   { &kNS_CLIPBOARDHELPER_CID, false, NULL, nsClipboardHelperConstructor },
   { &kNS_DRAGSERVICE_CID, false, NULL, nsDragServiceConstructor,
     mozilla::Module::MAIN_PROCESS_ONLY },
   { &kNS_BIDIKEYBOARD_CID, false, NULL, nsBidiKeyboardConstructor,
     mozilla::Module::MAIN_PROCESS_ONLY },
   { &kNS_THEMERENDERER_CID, false, NULL, nsNativeThemeCocoaConstructor },
-  { &kNS_SCREENMANAGER_CID, false, NULL, nsScreenManagerCocoaConstructor,
+  { &kNS_SCREENMANAGER_CID, false, NULL, ScreenManagerConstructor,
     mozilla::Module::MAIN_PROCESS_ONLY },
   { &kNS_DEVICE_CONTEXT_SPEC_CID, false, NULL, nsDeviceContextSpecXConstructor },
   { &kNS_PRINTSESSION_CID, false, NULL, nsPrintSessionConstructor },
   { &kNS_PRINTSETTINGSSERVICE_CID, false, NULL, nsPrintOptionsXConstructor },
   { &kNS_PRINTDIALOGSERVICE_CID, false, NULL, nsPrintDialogServiceXConstructor },
   { &kNS_IDLE_SERVICE_CID, false, NULL, nsIdleServiceXConstructor },
   { &kNS_SYSTEMALERTSSERVICE_CID, false, NULL, OSXNotificationCenterConstructor },
   { &kNS_NATIVEMENUSERVICE_CID, false, NULL, nsNativeMenuServiceXConstructor },