diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 991e95970171..462c8ae110f2 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -257,6 +257,9 @@ pref("browser.startup.homepage", "chrome://branding/locale/browsercon // Whether we should skip the homepage when opening the first-run page pref("browser.startup.firstrunSkipsHomepage", true); +// Show an about:blank window as early as possible for quick startup feedback. +pref("browser.startup.blankWindow", false); + pref("browser.slowStartup.notificationDisabled", false); pref("browser.slowStartup.timeThreshold", 20000); pref("browser.slowStartup.maxSamples", 5); diff --git a/browser/components/nsBrowserContentHandler.js b/browser/components/nsBrowserContentHandler.js index 353a3438f4ec..05fe1b82add2 100644 --- a/browser/components/nsBrowserContentHandler.js +++ b/browser/components/nsBrowserContentHandler.js @@ -797,10 +797,27 @@ nsDefaultCommandLineHandler.prototype = { return; } } + if (cmdLine.state == nsICommandLine.STATE_INITIAL_LAUNCH) { + let win = Services.wm.getMostRecentWindow("navigator:blank"); + if (win) { + win.location = gBrowserContentHandler.chromeURL; + win.arguments = [gBrowserContentHandler.defaultArgs]; + return; + } + } + // Passing defaultArgs, so use NO_EXTERNAL_URIS openWindow(null, gBrowserContentHandler.chromeURL, "_blank", "chrome,dialog=no,all" + gBrowserContentHandler.getFeatures(cmdLine), gBrowserContentHandler.defaultArgs, NO_EXTERNAL_URIS); + } else { + // Need a better solution in the future to avoid opening the blank window + // when command line parameters say we are not going to show a browser + // window, but for now the blank window getting closed quickly (and + // causing only a slight flicker) is better than leaving it open. + let win = Services.wm.getMostRecentWindow("navigator:blank"); + if (win) + win.close(); } }, diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index fe46bcb8bf99..36ba40f8aeca 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -8,6 +8,69 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); +(function earlyBlankFirstPaint() { + if (!Services.prefs.getBoolPref("browser.startup.blankWindow", false)) + return; + + let store = Cc["@mozilla.org/xul/xulstore;1"].getService(Ci.nsIXULStore); + let getValue = attr => + store.getValue("chrome://browser/content/browser.xul", "main-window", attr); + let width = getValue("width"); + let height = getValue("height"); + + // The clean profile case isn't handled yet. Return early for now. + if (!width || !height) + return; + + let screenX = getValue("screenX"); + let screenY = getValue("screenY"); + let browserWindowFeatures = + "chrome,all,dialog=no,extrachrome,menubar,resizable,scrollbars,status," + + "location,toolbar,personalbar," + + `left=${screenX},top=${screenY}`; + + if (Services.prefs.getBoolPref("browser.suppress_first_window_animation")) + browserWindowFeatures += ",suppressanimation"; + + let win = Services.ww.openWindow(null, "about:blank", null, + browserWindowFeatures, null); + + // Hide the titlebar if the actual browser window will draw in it. + if (Services.prefs.getBoolPref("browser.tabs.drawInTitlebar")) { + win.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils) + .setChromeMargin(0, 2, 2, 2); + } + + if (AppConstants.platform != "macosx") { + // On Windows/Linux the position is in device pixels rather than CSS pixels. + let scale = win.devicePixelRatio; + if (scale > 1) + win.moveTo(screenX / scale, screenY / scale); + } + + // The sizemode="maximized" attribute needs to be set before first paint. + let docElt = win.document.documentElement; + let sizemode = getValue("sizemode"); + if (sizemode == "maximized") { + docElt.setAttribute("sizemode", sizemode); + + // Needed for when the user leaves the maximized mode. + docElt.setAttribute("height", height); + docElt.setAttribute("width", width); + } else { + // Setting the size of the window in the features string instead of here + // causes the window to grow by the size of the titlebar. + win.resizeTo(width, height); + } + + // The window becomes visible after OnStopRequest, so make this happen now. + win.stop(); + + // Used in nsBrowserContentHandler.js to close unwanted blank windows. + docElt.setAttribute("windowtype", "navigator:blank"); +})(); + Cu.importGlobalProperties(["fetch"]); XPCOMUtils.defineLazyServiceGetter(this, "WindowsUIUtils", "@mozilla.org/windows-ui-utils;1", "nsIWindowsUIUtils");