Bug 1396618 - Throttle window minimize and restore draft
authorAndreas Tolfsen <ato@sny.no>
Mon, 04 Sep 2017 16:55:34 +0100
changeset 658724 01dee786cafcde44e70fbb147fc326d4a28e8155
parent 658578 632e42dca494ec3d90b70325d9c359f80cb3f38a
child 729732 a360a9d749688be7eb218191019734561acbc80f
push id77851
push userbmo:ato@sny.no
push dateMon, 04 Sep 2017 15:56:14 +0000
bugs1396618
milestone57.0a1
Bug 1396618 - Throttle window minimize and restore MozReview-Commit-ID: 5LUWYwURQgs
testing/marionette/driver.js
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -1476,44 +1476,36 @@ GeckoDriver.prototype.getWindowRect = fu
 GeckoDriver.prototype.setWindowRect = async function(cmd, resp) {
   assert.firefox();
   const win = assert.window(this.getCurrentWindow());
   assert.noUserPrompt(this.dialog);
 
   let {x, y, width, height} = cmd.parameters;
   let origRect = this.curBrowser.rect;
 
-  // Throttle resize event by forcing the event queue to flush and delay
-  // until the main thread is idle.
-  function optimisedResize(resolve) {
-    return () => Services.tm.idleDispatchToMainThread(() => {
-      win.requestAnimationFrame(resolve);
-    });
-  }
-
   // Exit fullscreen and wait for window to resize.
   async function exitFullscreen() {
     return new Promise(resolve => {
-      win.addEventListener("sizemodechange", optimisedResize(resolve), {once: true});
+      win.addEventListener("sizemodechange", whenIdle(win, resolve), {once: true});
       win.fullScreen = false;
     });
   }
 
   // Restore window and wait for the window state to change.
   async function restoreWindow() {
     return new Promise(resolve => {
-      win.addEventListener("sizemodechange", resolve, {once: true});
+      win.addEventListener("sizemodechange", whenIdle(win, resolve), {once: true});
       win.restore();
     });
   }
 
   // Synchronous resize to |width| and |height| dimensions.
   async function resizeWindow(width, height) {
     return new Promise(resolve => {
-      win.addEventListener("resize", optimisedResize(resolve), {once: true});
+      win.addEventListener("resize", whenIdle(win, resolve), {once: true});
       win.resizeTo(width, height);
     });
   }
 
   // Wait until window size has changed.  We can't wait for the
   // user-requested window size as this may not be achievable on the
   // current system.
   const windowResizeChange = async () => {
@@ -3022,17 +3014,17 @@ GeckoDriver.prototype.setScreenOrientati
 GeckoDriver.prototype.minimizeWindow = async function(cmd, resp) {
   assert.firefox();
   const win = assert.window(this.getCurrentWindow());
   assert.noUserPrompt(this.dialog);
 
   let state = WindowState.from(win.windowState);
   if (state != WindowState.Minimized) {
     await new Promise(resolve => {
-      win.addEventListener("sizemodechange", resolve, {once: true});
+      win.addEventListener("sizemodechange", whenIdle(win, resolve), {once: true});
       win.minimize();
     });
   }
 
   return this.curBrowser.rect;
 };
 
 /**
@@ -3701,8 +3693,28 @@ function copy(obj) {
   return obj;
 }
 
 function getOuterWindowId(win) {
   return win.QueryInterface(Ci.nsIInterfaceRequestor)
       .getInterface(Ci.nsIDOMWindowUtils)
       .outerWindowID;
 }
+
+/**
+ * Throttle <var>callback</var> until the main thread is idle and
+ * <var>window</var> has performed an animation frame.
+ *
+ * @param {ChromeWindow} window
+ *     Window to request the animation frame from.
+ * @param {function()} callback
+ *     Called when done.
+ *
+ * @return {function()}
+ *     Anonymous function that when invoked will wait for the main
+ *     thread to clear up and request an animation frame before calling
+ *     <var>callback</var>.
+ */
+function whenIdle(window, callback) {
+  return () => Services.tm.idleDispatchToMainThread(() => {
+    window.requestAnimationFrame(callback);
+  });
+}