Bug 1602757: Work around LookAndFeel not propagating to processes without tabs r=emilio
☠☠ backed out by 7aaac87105b7 ☠ ☠
authorRandell Jesup <rjesup@wgate.com>
Wed, 20 May 2020 22:37:15 +0000
changeset 531342 2c7bf6206bb4e6572785f5b33f02024bf2ec249d
parent 531341 a0142f6bb65f3ff91c76a3e4634ef337e069d6d3
child 531343 1c98ac1c42836e9c4c0791baaa761e9b8f5ee7b7
push id37438
push userabutkovits@mozilla.com
push dateThu, 21 May 2020 09:36:57 +0000
treeherdermozilla-central@2d00a1a6495c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1602757, 1638618
milestone78.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 1602757: Work around LookAndFeel not propagating to processes without tabs r=emilio This is a workaround for bug 1638618 Differential Revision: https://phabricator.services.mozilla.com/D76187
layout/style/test/mq_changes_child.html
layout/style/test/test_mq_changes_in_iframe.html
--- a/layout/style/test/mq_changes_child.html
+++ b/layout/style/test/mq_changes_child.html
@@ -1,8 +1,11 @@
 <script>
 const mql = matchMedia("(prefers-reduced-motion: reduce)");
+
 mql.addEventListener("change", event => {
-  parent.postMessage({ "matches": event.matches }, "*");
+  if (event.matches) {
+    parent.postMessage({ "matches": event.matches }, "*");
+  }
 });
 
 window.onload = () => { parent.postMessage("ready", "*"); };
 </script>
--- a/layout/style/test/test_mq_changes_in_iframe.html
+++ b/layout/style/test/test_mq_changes_in_iframe.html
@@ -10,40 +10,59 @@
 <p id="display"></p>
 <div id="content" style="display: none"></div>
 <iframe id="iframe"></iframe>
 <pre id="test"></pre>
 <script>
 add_task(async () => {
   const mqString = "(prefers-reduced-motion: reduce)";
 
-  SpecialPowers.DOMWindowUtils.setPrefersReducedMotionOverrideForTest(false);
+// Bug 1638618: Theme changes (and thus LookAndFeel, including reduced-motion)
+// aren't propagated to processes that don't have PresContexts in them
+// (i.e. only to processes with open tabs), and so preallocated processes
+// have the Theme/LookAndFeel values current when they were prestarted.
+// It can also affect e10s processes that are recycled via Provide/Take.
+// Add an extra level of handshake to ensure we change reduced-motion
+// after the iframe's process is loaded.   When that is fixed we could
+// restore the pre-iframe-creation setting to false here.
 
   iframe.src = SimpleTest.getTestFileURL("mq_changes_child.html")
                          .replace("mochi.test:8888", "example.com");
   await new Promise(resolve => window.addEventListener("message", event => {
     if (event.data == "ready") {
       resolve();
     }
   }, { once: true } ));
+  // Must be after loading the iframe (bug 1638618).
+  // This may or make not trigger a 'change' event in the iframe, depending
+  // on the initial value of reduced-motion the frame's process has.
+
+  SpecialPowers.DOMWindowUtils.setPrefersReducedMotionOverrideForTest(false);
 
   const mql = matchMedia(mqString);
-  ok(!mql.matches, `Doesn't matches ${mqString}`);
+  // Wait if needed for the value to propagate
+  if (mql.matches) {
+    await new Promise(resolve => mql.addEventListener("change", resolve,
+                                                      { once: true }));
+  }
+  ok(!mql.matches, `Doesn't match ${mqString}`);
 
   const changedInThisDocument = new Promise(resolve => {
     mql.addEventListener("change", event => { resolve(event.matches); });
   });
   const changedInIFrame = new Promise(resolve => {
     window.addEventListener("message", event => {
       if ("matches" in event.data) {
         resolve(event.data.matches);
       }
     }, { once: true });
   });
 
+  // This will trigger a change event in the iframe always, and will send a
+  // match event back to us
   SpecialPowers.DOMWindowUtils.setPrefersReducedMotionOverrideForTest(true);
 
   const results =
       await Promise.allSettled([ changedInThisDocument, changedInIFrame ]);
 
   results.forEach(result => {
     is(result.status, "fulfilled");
     ok(result.value, `Matches ${mqString}`);