Bug 1370035 - Make adjusting focus during a tab switch one of the last things that occurs during any given tick. r?dao
It is possible for the async tab switcher to switch synchronously to tabs that it knows
it can switch to immediately (for example, tabs that it knows it can display as blank).
Unfortunately, the way that the async tab switcher is structured, when this occurs, the
focus adjustment occurs before the updateCurrentBrowser method is run inside
tabbrowser. This breaks focus adjustment during tab switching when the browser is
unrestored / pending, since the updateCurrentBrowser method fires the event that
causes the browser to _become_ focusable.
This patch works around this problem by putting the adjustment of focus inside a
requestAnimationFrame. This ensures that the adjustment will still happen in the
same tick, but if an updateCurrentBrowser call is going to happen, it'll happen
after that.
MozReview-Commit-ID: Fud1N8iXN4y
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -4218,17 +4218,26 @@
let tabs = this.tabbrowser.mTabBox.tabs;
let tabPanel = this.tabbrowser.mPanelContainer;
let showPanel = tabs.getRelatedElement(showTab);
let index = Array.indexOf(tabPanel.childNodes, showPanel);
if (index != -1) {
this.log(`Switch to tab ${index} - ${this.tinfo(showTab)}`);
tabPanel.setAttribute("selectedIndex", index);
if (showTab === this.requestedTab) {
- this.tabbrowser._adjustFocusAfterTabSwitch(showTab);
+ // It's possible for the tab we're switching to not be
+ // focusable until later on this tick (example: it might be
+ // pending). We ensure that the "select" event has had the
+ // opportunity to fire by making sure that the focus adjustment
+ // is one of the last things to occur.
+ window.requestAnimationFrame(() => {
+ if (this.visibleTab == showTab) {
+ this.tabbrowser._adjustFocusAfterTabSwitch(showTab);
+ }
+ });
}
}
// This doesn't necessarily exist if we're a new window and haven't switched tabs yet
if (this.lastVisibleTab)
this.lastVisibleTab._visuallySelected = false;
this.visibleTab._visuallySelected = true;