Bug 1142080 - Fix app orientation support on desktop. r=fabrice
authorAlexandre Poirot <poirot.alex@gmail.com>
Thu, 12 Mar 2015 02:12:00 -0400
changeset 233947 5747865276f1b1a658d7e8d00dcd3cac7350ce45
parent 233946 98bc690156084571595c667d7c8bb7ee972f5408
child 233948 d25cce027f28c9ed6adf9659722a66afad656693
push id57019
push usercbook@mozilla.com
push dateTue, 17 Mar 2015 10:50:22 +0000
treeherdermozilla-inbound@15e49729e473 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfabrice
bugs1142080
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1142080 - Fix app orientation support on desktop. r=fabrice
b2g/chrome/content/screen.js
--- a/b2g/chrome/content/screen.js
+++ b/b2g/chrome/content/screen.js
@@ -123,108 +123,115 @@ window.addEventListener('ContentStart', 
       ratio = parseFloat(match[4], 10);
 
     // If any of the values came out 0 or NaN or undefined, display usage
     if (!width || !height || !ratio) {
       usage();
     }
   }
 
-  function resize(width, height, ratio, shouldFlip) {
+  Services.prefs.setCharPref('layout.css.devPixelsPerPx',
+                             ratio == 1 ? -1 : ratio);
+  let defaultOrientation = width < height ? 'portrait' : 'landscape';
+  GlobalSimulatorScreen.mozOrientation = GlobalSimulatorScreen.screenOrientation = defaultOrientation;
+
+  function resize() {
     GlobalSimulatorScreen.width = width;
     GlobalSimulatorScreen.height = height;
 
-    Services.prefs.setCharPref('layout.css.devPixelsPerPx',
-                               ratio == 1 ? -1 : ratio);
-
-    // In order to do rescaling, we set the <browser> tag to the specified
-    // width and height, and then use a CSS transform to scale it so that
-    // it appears at the correct size on the host display.  We also set
-    // the size of the <window> element to that scaled target size.
-    let scale = 1.0;
-
     // Set the window width and height to desired size plus chrome
     // Include the size of the toolbox displayed under the system app
     let controls = document.getElementById('controls');
-    let controlsHeight = 0;
-    if (controls) {
-      controlsHeight = controls.getBoundingClientRect().height;
-    }
-    let chromewidth = window.outerWidth - window.innerWidth;
-    let chromeheight = window.outerHeight - window.innerHeight + controlsHeight;
+    let controlsHeight = controls ? controls.getBoundingClientRect().height : 0;
+
     if (isMulet) {
       let tab = browserWindow.gBrowser.selectedTab;
       let responsive = ResponsiveUIManager.getResponsiveUIForTab(tab);
-      responsive.setSize((Math.round(width * scale) + 16*2),
-                        (Math.round(height * scale) + controlsHeight + 61));
+      responsive.setSize(width + 16*2,
+                         height + controlsHeight + 61);
     } else {
-      window.resizeTo(Math.round(width * scale) + chromewidth,
-                      Math.round(height * scale) + chromeheight);
+      let chromewidth = window.outerWidth - window.innerWidth;
+      let chromeheight = window.outerHeight - window.innerHeight + controlsHeight;
+      window.resizeTo(width + chromewidth,
+                      height + chromeheight);
     }
 
     let frameWidth = width, frameHeight = height;
+
+    // If the current app doesn't supports the current screen orientation
+    // still resize the window, but rotate its frame so that
+    // it is displayed rotated on the side
+    let shouldFlip = GlobalSimulatorScreen.mozOrientation != GlobalSimulatorScreen.screenOrientation;
+
     if (shouldFlip) {
       frameWidth = height;
       frameHeight = width;
     }
 
     // Set the browser element to the full unscaled size of the screen
     let style = browser.style;
     style.transform = '';
     style.height = 'calc(100% - ' + controlsHeight + 'px)';
     style.bottom = controlsHeight;
 
+    style.width = frameWidth + "px";
+    style.height = frameHeight + "px";
+
     if (shouldFlip) {
       // Display the system app with a 90° clockwise rotation
-      let shift = Math.floor(Math.abs(frameWidth-frameHeight) / 2);
+      let shift = Math.floor(Math.abs(frameWidth - frameHeight) / 2);
       style.transform +=
         ' rotate(0.25turn) translate(-' + shift + 'px, -' + shift + 'px)';
     }
   }
 
   // Resize on startup
-  resize(width, height, ratio, false);
-
-  let defaultOrientation = width < height ? 'portrait' : 'landscape';
-  GlobalSimulatorScreen.mozOrientation = GlobalSimulatorScreen.screenOrientation = defaultOrientation;
+  resize();
 
   // Catch manual resizes to update the internal device size.
   window.onresize = function() {
-    width = browser.clientWidth;
-    height = browser.clientHeight;
-    if ((defaultOrientation == 'portrait' && width > height) ||
-        (defaultOrientation == 'landscape' && width < height)) {
-      let w = width;
-      width = height;
-      height = w;
-    }
+    let controls = document.getElementById('controls');
+    let controlsHeight = controls ? controls.getBoundingClientRect().height : 0;
+
+    width = window.innerWidth;
+    height = window.innerHeight - controlsHeight;
+
+    queueResize();
   };
 
   // Then resize on each rotation button click,
   // or when the system app lock/unlock the orientation
   Services.obs.addObserver(function orientationChangeListener(subject) {
     let screen = subject.wrappedJSObject;
     let { mozOrientation, screenOrientation } = screen;
 
-    let newWidth = width;
-    let newHeight = height;
-    // If we have an orientation different than the startup one,
+    // If we have an orientation different than the current one,
     // we switch the sizes
     if (screenOrientation != defaultOrientation) {
-      newWidth = height;
-      newHeight = width;
+      let w = width;
+      width = height;
+      height = w;
     }
+    defaultOrientation = screenOrientation;
+
+    queueResize();
+  }, 'simulator-adjust-window-size', false);
 
-    // If the current app doesn't supports the current screen orientation
-    // still resize the window, but rotate its frame so that
-    // it is displayed rotated on the side
-    let shouldFlip = mozOrientation != screenOrientation;
-
-    resize(newWidth, newHeight, ratio, shouldFlip);
-  }, 'simulator-adjust-window-size', false);
+  // Queue resize request in order to prevent race and slowdowns
+  // by requesting resize multiple times per loop
+  let resizeTimeout;
+  function queueResize() {
+    if (resizeTimeout) {
+      clearTimeout(resizeTimeout);
+    }
+    resizeTimeout = setTimeout(function () {
+      resizeTimeout = null;
+      resize();
+    }, 0);
+  }
 
   // A utility function like console.log() for printing to the terminal window
   // Uses dump(), but enables it first, if necessary
   function print() {
     let dump_enabled =
       Services.prefs.getBoolPref('browser.dom.window.dump.enabled');
 
     if (!dump_enabled)