Bug 1142080 - Fix app orientation support on desktop. r=fabrice, a=bajaj
authorAlexandre Poirot <poirot.alex@gmail.com>
Tue, 24 Mar 2015 04:21:00 -0400
changeset 237890 79a8767e838e531a38dd2df1fe14a80ed083615b
parent 237889 cb4856ecd781e4c11315e6b64a2cdbb2cdc1daef
child 237896 3297c641e7e5a95f59b9c17307b268d44ee6f3b4
push id385
push userryanvm@gmail.com
push dateTue, 24 Mar 2015 21:27:55 +0000
treeherdermozilla-b2g37_v2_2@79a8767e838e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfabrice, bajaj
bugs1142080
milestone37.0
Bug 1142080 - Fix app orientation support on desktop. r=fabrice, a=bajaj
b2g/chrome/content/screen.js
--- a/b2g/chrome/content/screen.js
+++ b/b2g/chrome/content/screen.js
@@ -123,107 +123,114 @@ 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 responsive = browserWindow.gBrowser.selectedTab.__responsiveUI;
-      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)