Bug 1181475 - [e10s] Shift + back/forward button opens page in a new window but renders blank
This seems to be because the docshell on the newly created browser window is inactive when it should be active. This is because with non-e10s, when we swap docshells, adding a docshell X as a child to another active docshell Y makes X be active. We don't get that automatic behaviour with e10s.
Huh… so forcing the docshell to be enabled after a remote frameloader swap doesn't appear to be enough. :( Other stuff is up.
It seems… racy…?
It just flat out doesn't seem to work, despite having the docShell be active.
What is the missing piece?
Hypothesis:
The TabStateFlusher flush Promise is not resolving before we tear the
new tab out and swap the frameloaders, and this is introducing the
non-determinism.
Test:
Add two second delay before calling replaceTabWithWindow in duplicateTabIn in browser.js.
Result:
Always won the race - content loaded every time.
This bolsters the hypothesis that it is SessionStore.duplicateTab kicking off a Promise that does not resolve in time.
Hypothesis:
When the TabStateFlusher flush Promise resolves before the new browser
window can call swapBrowsersAndCloseOther, then the race is won, and the
content is shown.
When the TabStateFlusher flush Promise resolves AFTER the new browser
window calls swapBrowsersAndCloseOther, the race is lost, and the
content is somehow not shown.
Test:
- We can delay the TabStateFlusher flush Promise resolution.
- We can delay the calling of swapBrowsersAndCloseOther
Result:
When delaying the swapBrowsersAndCloseOther, we reliably displayed the
content. When we kept that delay, but added an additional delay to the
TabStateFlusher flush Promise resolution, we reliably failed to display
the content.
CONCLUSION:
Something in the resolution handler for SessionStore.duplicateTab is
necessary in order for duplicateTabIn to work properly, and it's not
occurring fast enough.
Question?: Why is this not affecting non-e10s?
Answer: I believe this is because with non-e10s we're just winning the race more often.
Ideas for solutions:
- Add a new method to SessionStore that is like… duplicateTabAsync that returns a Promise that resolves with the newTab, then have browser.js wait for that resolution before calling replaceTabWithWindow
From Mossop:
"This code is a little inefficient. Create a new tab in the current window, create a new window, swap tab into the new window. We can make it better and fix this bug at the same time, no SessionStore changes required:
1. Create new window
2. Duplicate tab into new window
1. Create new window
2. Duplicate tab into new window
3. Close new window's initial tab"
Ah! Easy peasy! Mossop even gave me r+ before my try build came in!
Huh. Some perma orange. Wtf.
Huh… I thought opening a browser window would go
through nsXULWindow::CreateNewContentWindow, which (I believe)
spins a nested event loop until the XUL has all finished loading. That's
not the case.
This try build is better:
https://treeherder.mozilla.org/#/jobs?repo=try&revision=c27b4c9ee0fd