browser/modules/NetworkPrioritizer.jsm

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 /*
michael@0 6 * This module adjusts network priority for tabs in a way that gives 'important'
michael@0 7 * tabs a higher priority. There are 3 levels of priority. Each is listed below
michael@0 8 * with the priority adjustment used.
michael@0 9 *
michael@0 10 * Highest (-10): Selected tab in the focused window.
michael@0 11 * Medium (0): Background tabs in the focused window.
michael@0 12 * Selected tab in background windows.
michael@0 13 * Lowest (+10): Background tabs in background windows.
michael@0 14 */
michael@0 15
michael@0 16 this.EXPORTED_SYMBOLS = ["trackBrowserWindow"];
michael@0 17
michael@0 18 const Ci = Components.interfaces;
michael@0 19
michael@0 20 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
michael@0 21
michael@0 22
michael@0 23 // Lazy getters
michael@0 24 XPCOMUtils.defineLazyServiceGetter(this, "_focusManager",
michael@0 25 "@mozilla.org/focus-manager;1",
michael@0 26 "nsIFocusManager");
michael@0 27
michael@0 28
michael@0 29 // Constants
michael@0 30 const TAB_EVENTS = ["TabOpen", "TabSelect"];
michael@0 31 const WINDOW_EVENTS = ["activate", "unload"];
michael@0 32 // PRIORITY DELTA is -10 because lower priority value is actually a higher priority
michael@0 33 const PRIORITY_DELTA = -10;
michael@0 34
michael@0 35
michael@0 36 // Variables
michael@0 37 let _lastFocusedWindow = null;
michael@0 38 let _windows = [];
michael@0 39
michael@0 40
michael@0 41 // Exported symbol
michael@0 42 this.trackBrowserWindow = function trackBrowserWindow(aWindow) {
michael@0 43 WindowHelper.addWindow(aWindow);
michael@0 44 }
michael@0 45
michael@0 46
michael@0 47 // Global methods
michael@0 48 function _handleEvent(aEvent) {
michael@0 49 switch (aEvent.type) {
michael@0 50 case "TabOpen":
michael@0 51 BrowserHelper.onOpen(aEvent.target.linkedBrowser);
michael@0 52 break;
michael@0 53 case "TabSelect":
michael@0 54 BrowserHelper.onSelect(aEvent.target.linkedBrowser);
michael@0 55 break;
michael@0 56 case "activate":
michael@0 57 WindowHelper.onActivate(aEvent.target);
michael@0 58 break;
michael@0 59 case "unload":
michael@0 60 WindowHelper.removeWindow(aEvent.currentTarget);
michael@0 61 break;
michael@0 62 }
michael@0 63 }
michael@0 64
michael@0 65
michael@0 66 // Methods that impact a browser. Put into single object for organization.
michael@0 67 let BrowserHelper = {
michael@0 68 onOpen: function NP_BH_onOpen(aBrowser) {
michael@0 69 // If the tab is in the focused window, leave priority as it is
michael@0 70 if (aBrowser.ownerDocument.defaultView != _lastFocusedWindow)
michael@0 71 this.decreasePriority(aBrowser);
michael@0 72 },
michael@0 73
michael@0 74 onSelect: function NP_BH_onSelect(aBrowser) {
michael@0 75 let windowEntry = WindowHelper.getEntry(aBrowser.ownerDocument.defaultView);
michael@0 76 if (windowEntry.lastSelectedBrowser)
michael@0 77 this.decreasePriority(windowEntry.lastSelectedBrowser);
michael@0 78 this.increasePriority(aBrowser);
michael@0 79
michael@0 80 windowEntry.lastSelectedBrowser = aBrowser;
michael@0 81 },
michael@0 82
michael@0 83 increasePriority: function NP_BH_increasePriority(aBrowser) {
michael@0 84 aBrowser.adjustPriority(PRIORITY_DELTA);
michael@0 85 },
michael@0 86
michael@0 87 decreasePriority: function NP_BH_decreasePriority(aBrowser) {
michael@0 88 aBrowser.adjustPriority(PRIORITY_DELTA * -1);
michael@0 89 }
michael@0 90 };
michael@0 91
michael@0 92
michael@0 93 // Methods that impact a window. Put into single object for organization.
michael@0 94 let WindowHelper = {
michael@0 95 addWindow: function NP_WH_addWindow(aWindow) {
michael@0 96 // Build internal data object
michael@0 97 _windows.push({ window: aWindow, lastSelectedBrowser: null });
michael@0 98
michael@0 99 // Add event listeners
michael@0 100 TAB_EVENTS.forEach(function(event) {
michael@0 101 aWindow.gBrowser.tabContainer.addEventListener(event, _handleEvent, false);
michael@0 102 });
michael@0 103 WINDOW_EVENTS.forEach(function(event) {
michael@0 104 aWindow.addEventListener(event, _handleEvent, false);
michael@0 105 });
michael@0 106
michael@0 107 // This gets called AFTER activate event, so if this is the focused window
michael@0 108 // we want to activate it. Otherwise, deprioritize it.
michael@0 109 if (aWindow == _focusManager.activeWindow)
michael@0 110 this.handleFocusedWindow(aWindow);
michael@0 111 else
michael@0 112 this.decreasePriority(aWindow);
michael@0 113
michael@0 114 // Select the selected tab
michael@0 115 BrowserHelper.onSelect(aWindow.gBrowser.selectedBrowser);
michael@0 116 },
michael@0 117
michael@0 118 removeWindow: function NP_WH_removeWindow(aWindow) {
michael@0 119 if (aWindow == _lastFocusedWindow)
michael@0 120 _lastFocusedWindow = null;
michael@0 121
michael@0 122 // Delete this window from our tracking
michael@0 123 _windows.splice(this.getEntryIndex(aWindow), 1);
michael@0 124
michael@0 125 // Remove the event listeners
michael@0 126 TAB_EVENTS.forEach(function(event) {
michael@0 127 aWindow.gBrowser.tabContainer.removeEventListener(event, _handleEvent, false);
michael@0 128 });
michael@0 129 WINDOW_EVENTS.forEach(function(event) {
michael@0 130 aWindow.removeEventListener(event, _handleEvent, false);
michael@0 131 });
michael@0 132 },
michael@0 133
michael@0 134 onActivate: function NP_WH_onActivate(aWindow, aHasFocus) {
michael@0 135 // If this window was the last focused window, we don't need to do anything
michael@0 136 if (aWindow == _lastFocusedWindow)
michael@0 137 return;
michael@0 138
michael@0 139 // handleFocusedWindow will deprioritize the current window
michael@0 140 this.handleFocusedWindow(aWindow);
michael@0 141
michael@0 142 // Lastly we should increase priority for this window
michael@0 143 this.increasePriority(aWindow);
michael@0 144 },
michael@0 145
michael@0 146 handleFocusedWindow: function NP_WH_handleFocusedWindow(aWindow) {
michael@0 147 // If we have a last focused window, we need to deprioritize it first
michael@0 148 if (_lastFocusedWindow)
michael@0 149 this.decreasePriority(_lastFocusedWindow);
michael@0 150
michael@0 151 // aWindow is now focused
michael@0 152 _lastFocusedWindow = aWindow;
michael@0 153 },
michael@0 154
michael@0 155 // Auxiliary methods
michael@0 156 increasePriority: function NP_WH_increasePriority(aWindow) {
michael@0 157 aWindow.gBrowser.browsers.forEach(function(aBrowser) {
michael@0 158 BrowserHelper.increasePriority(aBrowser);
michael@0 159 });
michael@0 160 },
michael@0 161
michael@0 162 decreasePriority: function NP_WH_decreasePriority(aWindow) {
michael@0 163 aWindow.gBrowser.browsers.forEach(function(aBrowser) {
michael@0 164 BrowserHelper.decreasePriority(aBrowser);
michael@0 165 });
michael@0 166 },
michael@0 167
michael@0 168 getEntry: function NP_WH_getEntry(aWindow) {
michael@0 169 return _windows[this.getEntryIndex(aWindow)];
michael@0 170 },
michael@0 171
michael@0 172 getEntryIndex: function NP_WH_getEntryAtIndex(aWindow) {
michael@0 173 // Assumes that every object has a unique window & it's in the array
michael@0 174 for (let i = 0; i < _windows.length; i++)
michael@0 175 if (_windows[i].window == aWindow)
michael@0 176 return i;
michael@0 177 }
michael@0 178 };
michael@0 179

mercurial