bug 851520 - add systemDefaultScale attribute to nsIScreenManager, and use it to decide when to remove browser.content.full-zoom prefs during UI migration if running on windows/hi-dpi. r=roc,adw a=lsblakk
authorJonathan Kew <jkew@mozilla.com>
Tue, 09 Apr 2013 22:07:02 +0100
changeset 137388 22ca02c5f23ab875488fc4e544060e08116af7f6
parent 137387 e3aefe042287ae61106854ea96431d9255c312a4
child 137389 1f59b22c764fadc6ff3c3e2144bac774049d12aa
push id2452
push userlsblakk@mozilla.com
push dateMon, 13 May 2013 16:59:38 +0000
treeherdermozilla-beta@d4b152d29d8d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, adw, lsblakk
bugs851520
milestone22.0a2
bug 851520 - add systemDefaultScale attribute to nsIScreenManager, and use it to decide when to remove browser.content.full-zoom prefs during UI migration if running on windows/hi-dpi. r=roc,adw a=lsblakk
browser/components/nsBrowserGlue.js
widget/android/nsScreenManagerAndroid.cpp
widget/cocoa/nsScreenManagerCocoa.mm
widget/gonk/nsWindow.cpp
widget/gtk2/nsScreenManagerGtk.cpp
widget/nsIScreenManager.idl
widget/os2/nsScreenManagerOS2.cpp
widget/qt/nsScreenManagerQt.cpp
widget/windows/nsScreenManagerWin.cpp
widget/xpwidgets/PuppetWidget.cpp
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1218,17 +1218,17 @@ BrowserGlue.prototype = {
     var notifyBox = win.gBrowser.getNotificationBox();
     var notification = notifyBox.appendNotification(text, title, null,
                                                     notifyBox.PRIORITY_CRITICAL_MEDIUM,
                                                     buttons);
     notification.persistence = -1; // Until user closes it
   },
 
   _migrateUI: function BG__migrateUI() {
-    const UI_VERSION = 9;
+    const UI_VERSION = 10;
     const BROWSER_DOCURL = "chrome://browser/content/browser.xul#";
     let currentUIVersion = 0;
     try {
       currentUIVersion = Services.prefs.getIntPref("browser.migration.version");
     } catch(ex) {}
     if (currentUIVersion >= UI_VERSION)
       return;
 
@@ -1361,16 +1361,31 @@ BrowserGlue.prototype = {
         }
         this._setPersist(toolbarResource, currentsetResource, currentset);
       }
 
       Services.prefs.clearUserPref("browser.download.useToolkitUI");
       Services.prefs.clearUserPref("browser.library.useNewDownloadsView");
     }
 
+#ifdef XP_WIN
+    if (currentUIVersion < 10) {
+      // For Windows systems with display set to > 96dpi (i.e. systemDefaultScale
+      // will return a value > 1.0), we want to discard any saved full-zoom settings,
+      // as we'll now be scaling the content according to the system resolution
+      // scale factor (Windows "logical DPI" setting)
+      let sm = Cc["@mozilla.org/gfx/screenmanager;1"].getService(Ci.nsIScreenManager);
+      if (sm.systemDefaultScale > 1.0) {
+        let cps2 = Cc["@mozilla.org/content-pref/service;1"].
+                   getService(Ci.nsIContentPrefService2);
+        cps2.removeByName("browser.content.full-zoom", null);
+      }
+    }
+#endif
+
     if (this._dirty)
       this._dataSource.QueryInterface(Ci.nsIRDFRemoteDataSource).Flush();
 
     delete this._rdf;
     delete this._dataSource;
 
     // Update the migration version.
     Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
--- a/widget/android/nsScreenManagerAndroid.cpp
+++ b/widget/android/nsScreenManagerAndroid.cpp
@@ -100,8 +100,14 @@ nsScreenManagerAndroid::ScreenForNativeW
 
 NS_IMETHODIMP
 nsScreenManagerAndroid::GetNumberOfScreens(uint32_t *aNumberOfScreens)
 {
     *aNumberOfScreens = 1;
     return NS_OK;
 }
 
+NS_IMETHODIMP
+nsScreenManagerAndroid::GetSystemDefaultScale(float *aDefaultScale)
+{
+    *aDefaultScale = 1.0f;
+    return NS_OK;
+}
--- a/widget/cocoa/nsScreenManagerCocoa.mm
+++ b/widget/cocoa/nsScreenManagerCocoa.mm
@@ -92,16 +92,23 @@ nsScreenManagerCocoa::GetNumberOfScreens
     *aNumberOfScreens = [ss count];
 
     return NS_OK;
 
     NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 NS_IMETHODIMP
+nsScreenManagerCocoa::GetSystemDefaultScale(float *aDefaultScale)
+{
+    *aDefaultScale = 1.0f;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
 nsScreenManagerCocoa::ScreenForNativeWidget (void *nativeWidget, nsIScreen **outScreen)
 {
     NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
     NSWindow *window = static_cast<NSWindow*>(nativeWidget);
     if (window) {
         nsIScreen *screen = ScreenForCocoaScreen([window screen]);
         *outScreen = screen;
--- a/widget/gonk/nsWindow.cpp
+++ b/widget/gonk/nsWindow.cpp
@@ -867,8 +867,15 @@ nsScreenManagerGonk::ScreenForNativeWidg
 }
 
 NS_IMETHODIMP
 nsScreenManagerGonk::GetNumberOfScreens(uint32_t *aNumberOfScreens)
 {
     *aNumberOfScreens = 1;
     return NS_OK;
 }
+
+NS_IMETHODIMP
+nsScreenManagerGonk::GetSystemDefaultScale(float *aDefaultScale)
+{
+    *aDefaultScale = 1.0f;
+    return NS_OK;
+}
--- a/widget/gtk2/nsScreenManagerGtk.cpp
+++ b/widget/gtk2/nsScreenManagerGtk.cpp
@@ -280,16 +280,23 @@ nsScreenManagerGtk :: GetNumberOfScreens
     return rv;
   }
   *aNumberOfScreens = mCachedScreenArray.Count();
   return NS_OK;
   
 } // GetNumberOfScreens
 
 NS_IMETHODIMP
+nsScreenManagerGtk::GetSystemDefaultScale(float *aDefaultScale)
+{
+  *aDefaultScale = 1.0f;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsScreenManagerGtk :: ScreenForNativeWidget (void *aWidget, nsIScreen **outScreen)
 {
   nsresult rv;
   rv = EnsureInit();
   if (NS_FAILED(rv)) {
     NS_ERROR("nsScreenManagerGtk::EnsureInit() failed from ScreenForNativeWidget");
     return rv;
   }
--- a/widget/nsIScreenManager.idl
+++ b/widget/nsIScreenManager.idl
@@ -2,17 +2,17 @@
  *
  * 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 "nsISupports.idl"
 #include "nsIScreen.idl"
 
-[scriptable, uuid(B92319E6-9A84-4ca7-A2CC-EEC22EA9854E)]
+[scriptable, uuid(1C195990-FF9E-412B-AFE7-67D1C660BB27)]
 interface nsIScreenManager : nsISupports
 {
     //
     // 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 screen coordinates.
     //
@@ -20,16 +20,36 @@ interface nsIScreenManager : nsISupports
   
     // The screen with the menubar/taskbar. This shouldn't be needed very
     // often.
   readonly attribute nsIScreen primaryScreen;
   
     // Holds the number of screens that are available
   readonly attribute unsigned long numberOfScreens;
 
+    // The default DPI scaling factor of the screen environment (number of
+    // screen pixels corresponding to 1 CSS px, at the default zoom level).
+    //
+    // This is currently fixed at 1.0 on most platforms, but varies on Windows
+    // if the "logical DPI" scaling option in the Display control panel is set
+    // to a value other than 100% (e.g. 125% or 150% are increasingly common
+    // defaults on laptops with high-dpi screens). See bug 851520.
+    //
+    // NOTE that on OS X, this does -not- reflect the "backing scale factor"
+    // used to support Retina displays, which is a per-display property,
+    // not a system-wide scaling factor. The default ratio of CSS pixels to
+    // Cocoa points remains 1:1, even on a Retina screen where one Cocoa point
+    // corresponds to two device pixels. (This is exposed via other APIs:
+    // see window.devicePixelRatio).
+    //
+    // NOTE also that on Linux, this does -not- currently reflect changes
+    // to the system-wide (X11 or Gtk2) DPI value, as Firefox does not yet
+    // honor these settings. See bug 798362 and bug 712898.
+  readonly attribute float systemDefaultScale;
+
     // Returns the nsIScreen instance for the given native widget pointer;
     // the pointer is specific to the particular widget implementation,
     // and is generally of the same type that NS_NATIVE_WINDOW is.
   [noscript] nsIScreen screenForNativeWidget ( in voidPtr nativeWidget );
 };
 
 
 %{ C++
--- a/widget/os2/nsScreenManagerOS2.cpp
+++ b/widget/os2/nsScreenManagerOS2.cpp
@@ -87,13 +87,20 @@ NS_IMETHODIMP
 nsScreenManagerOS2 :: GetNumberOfScreens(uint32_t *aNumberOfScreens)
 {
   *aNumberOfScreens = 1;
   return NS_OK;
   
 } // GetNumberOfScreens
 
 NS_IMETHODIMP
+nsScreenManagerOS2::GetSystemDefaultScale(float *aDefaultScale)
+{
+  *aDefaultScale = 1.0f;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsScreenManagerOS2 :: ScreenForNativeWidget(void *nativeWidget, nsIScreen **aScreen)
 {
   *aScreen = CreateNewScreenObject();    // addrefs
   return NS_OK;
 }
--- a/widget/qt/nsScreenManagerQt.cpp
+++ b/widget/qt/nsScreenManagerQt.cpp
@@ -95,15 +95,22 @@ nsScreenManagerQt::GetNumberOfScreens(ui
     if (!desktop)
         init();
 
     *aNumberOfScreens = desktop->numScreens();
     return NS_OK;
 }
 
 NS_IMETHODIMP
+nsScreenManagerQt::GetSystemDefaultScale(float *aDefaultScale)
+{
+    *aDefaultScale = 1.0f;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
 nsScreenManagerQt :: ScreenForNativeWidget (void *aWidget, nsIScreen **outScreen)
 {
     // I don't know how to go from GtkWindow to nsIScreen, especially
     // given xinerama and stuff, so let's just do this
     QRect rect = static_cast<QWidget*>(aWidget)->geometry();
     return ScreenForRect(rect.x(), rect.y(), rect.width(), rect.height(), outScreen);
 }
--- a/widget/windows/nsScreenManagerWin.cpp
+++ b/widget/windows/nsScreenManagerWin.cpp
@@ -150,14 +150,21 @@ nsScreenManagerWin :: GetNumberOfScreens
     *aNumberOfScreens = mNumberOfScreens = count;
   }
 
   return NS_OK;
   
 } // GetNumberOfScreens
 
 NS_IMETHODIMP
+nsScreenManagerWin::GetSystemDefaultScale(float *aDefaultScale)
+{
+  *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);
   return NS_OK;
 }
--- a/widget/xpwidgets/PuppetWidget.cpp
+++ b/widget/xpwidgets/PuppetWidget.cpp
@@ -749,10 +749,17 @@ PuppetScreenManager::ScreenForNativeWidg
 
 NS_IMETHODIMP
 PuppetScreenManager::GetNumberOfScreens(uint32_t* aNumberOfScreens)
 {
   *aNumberOfScreens = 1;
   return NS_OK;
 }
 
+NS_IMETHODIMP
+PuppetScreenManager::GetSystemDefaultScale(float *aDefaultScale)
+{
+  *aDefaultScale = 1.0f;
+  return NS_OK;
+}
+
 }  // namespace widget
 }  // namespace mozilla