Merge mozilla-central to mozilla-inbound r=merge a=merge on a CLOSED TREE
authorANDREEA PAVEL <apavel@mozilla.com>
Thu, 02 Nov 2017 15:38:39 +0200
changeset 443094 91e6ad83776b015b3f8726fde7c4dbdf7bb3c4a0
parent 443091 def80dfc06543c1fe60518bbb8d21a456bef9f01 (current diff)
parent 443063 40a14ca1cf04499f398e4cb8ba359b39eae4e216 (diff)
child 443095 c1576d8e9cb791665849c94dcfb9d833f90da9a4
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge, merge
milestone58.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
Merge mozilla-central to mozilla-inbound r=merge a=merge on a CLOSED TREE
--- a/accessible/ipc/win/handler/AccessibleTextTearoff.cpp
+++ b/accessible/ipc/win/handler/AccessibleTextTearoff.cpp
@@ -22,32 +22,16 @@ namespace a11y {
 
 AccessibleTextTearoff::AccessibleTextTearoff(AccessibleHandler* aHandler)
   : mHandler(aHandler)
 {
   MOZ_ASSERT(aHandler);
 }
 
 HRESULT
-AccessibleTextTearoff::ResolveAccText()
-{
-  if (mAccTextProxy) {
-    return S_OK;
-  }
-
-  RefPtr<IUnknown> proxy(mHandler->GetProxy());
-  if (!proxy) {
-    return E_UNEXPECTED;
-  }
-
-  return proxy->QueryInterface(IID_IAccessibleText,
-                               getter_AddRefs(mAccTextProxy));
-}
-
-HRESULT
 AccessibleTextTearoff::ResolveAccHypertext()
 {
   if (mAccHypertextProxy) {
     return S_OK;
   }
 
   RefPtr<IUnknown> proxy(mHandler->GetProxy());
   if (!proxy) {
@@ -61,223 +45,223 @@ AccessibleTextTearoff::ResolveAccHyperte
 IMPL_IUNKNOWN_QUERY_HEAD(AccessibleTextTearoff)
 IMPL_IUNKNOWN_QUERY_IFACE(IAccessibleText)
 IMPL_IUNKNOWN_QUERY_IFACE(IAccessibleHypertext)
 IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(mHandler)
 
 HRESULT
 AccessibleTextTearoff::addSelection(long startOffset, long endOffset)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->addSelection(startOffset, endOffset);
+  return mAccHypertextProxy->addSelection(startOffset, endOffset);
 }
 
 HRESULT
 AccessibleTextTearoff::get_attributes(long offset, long *startOffset,
                                       long *endOffset, BSTR *textAttributes)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->get_attributes(offset, startOffset, endOffset,
+  return mAccHypertextProxy->get_attributes(offset, startOffset, endOffset,
                                        textAttributes);
 }
 
 HRESULT
 AccessibleTextTearoff::get_caretOffset(long *offset)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->get_caretOffset(offset);
+  return mAccHypertextProxy->get_caretOffset(offset);
 }
 
 HRESULT
 AccessibleTextTearoff::get_characterExtents(long offset,
                                             enum IA2CoordinateType coordType,
                                             long *x, long *y, long *width,
                                             long *height)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->get_characterExtents(offset, coordType, x, y, width,
+  return mAccHypertextProxy->get_characterExtents(offset, coordType, x, y, width,
                                              height);
 }
 
 HRESULT
 AccessibleTextTearoff::get_nSelections(long *nSelections)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->get_nSelections(nSelections);
+  return mAccHypertextProxy->get_nSelections(nSelections);
 }
 
 HRESULT
 AccessibleTextTearoff::get_offsetAtPoint(long x, long y,
                                          enum IA2CoordinateType coordType,
                                          long *offset)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->get_offsetAtPoint(x, y, coordType, offset);
+  return mAccHypertextProxy->get_offsetAtPoint(x, y, coordType, offset);
 }
 
 HRESULT
 AccessibleTextTearoff::get_selection(long selectionIndex, long *startOffset,
                                      long *endOffset)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->get_selection(selectionIndex, startOffset, endOffset);
+  return mAccHypertextProxy->get_selection(selectionIndex, startOffset, endOffset);
 }
 
 HRESULT
 AccessibleTextTearoff::get_text(long startOffset, long endOffset, BSTR *text)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->get_text(startOffset, endOffset, text);
+  return mAccHypertextProxy->get_text(startOffset, endOffset, text);
 }
 
 HRESULT
 AccessibleTextTearoff::get_textBeforeOffset(long offset,
                                             enum IA2TextBoundaryType boundaryType,
                                             long *startOffset, long *endOffset,
                                             BSTR *text)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->get_textBeforeOffset(offset, boundaryType, startOffset,
+  return mAccHypertextProxy->get_textBeforeOffset(offset, boundaryType, startOffset,
                                              endOffset, text);
 }
 
 HRESULT
 AccessibleTextTearoff::get_textAfterOffset(long offset,
                                            enum IA2TextBoundaryType boundaryType,
                                            long *startOffset, long *endOffset,
                                            BSTR *text)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->get_textAfterOffset(offset, boundaryType,
+  return mAccHypertextProxy->get_textAfterOffset(offset, boundaryType,
                                             startOffset, endOffset, text);
 }
 
 HRESULT
 AccessibleTextTearoff::get_textAtOffset(long offset,
                                         enum IA2TextBoundaryType boundaryType,
                                         long *startOffset, long *endOffset,
                                         BSTR *text)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->get_textAtOffset(offset, boundaryType, startOffset,
+  return mAccHypertextProxy->get_textAtOffset(offset, boundaryType, startOffset,
                                          endOffset, text);
 }
 
 HRESULT
 AccessibleTextTearoff::removeSelection(long selectionIndex)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->removeSelection(selectionIndex);
+  return mAccHypertextProxy->removeSelection(selectionIndex);
 }
 
 HRESULT
 AccessibleTextTearoff::setCaretOffset(long offset)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->setCaretOffset(offset);
+  return mAccHypertextProxy->setCaretOffset(offset);
 }
 
 HRESULT
 AccessibleTextTearoff::setSelection(long selectionIndex, long startOffset,
                                     long endOffset)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->setSelection(selectionIndex, startOffset, endOffset);
+  return mAccHypertextProxy->setSelection(selectionIndex, startOffset, endOffset);
 }
 
 HRESULT
 AccessibleTextTearoff::get_nCharacters(long *nCharacters)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->get_nCharacters(nCharacters);
+  return mAccHypertextProxy->get_nCharacters(nCharacters);
 }
 
 HRESULT
 AccessibleTextTearoff::scrollSubstringTo(long startIndex, long endIndex,
                                          enum IA2ScrollType scrollType)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->scrollSubstringTo(startIndex, endIndex, scrollType);
+  return mAccHypertextProxy->scrollSubstringTo(startIndex, endIndex, scrollType);
 }
 
 HRESULT
 AccessibleTextTearoff::scrollSubstringToPoint(long startIndex, long endIndex,
                                               enum IA2CoordinateType coordinateType,
                                               long x, long y)
 {
-  HRESULT hr = ResolveAccText();
+  HRESULT hr = ResolveAccHypertext();
   if (FAILED(hr)) {
     return hr;
   }
 
-  return mAccTextProxy->scrollSubstringToPoint(startIndex, endIndex,
+  return mAccHypertextProxy->scrollSubstringToPoint(startIndex, endIndex,
                                                coordinateType, x, y);
 }
 
 HRESULT
 AccessibleTextTearoff::get_newText(IA2TextSegment *newText)
 {
   if (!newText) {
     return E_INVALIDARG;
--- a/accessible/ipc/win/handler/AccessibleTextTearoff.h
+++ b/accessible/ipc/win/handler/AccessibleTextTearoff.h
@@ -69,20 +69,18 @@ public:
   // IAccessibleHypertext
   STDMETHODIMP get_nHyperlinks(long *hyperlinkCount) override;
   STDMETHODIMP get_hyperlink(long index,
                              IAccessibleHyperlink **hyperlink) override;
   STDMETHODIMP get_hyperlinkIndex(long charIndex, long *hyperlinkIndex) override;
 
 private:
   ~AccessibleTextTearoff() = default;
-  HRESULT ResolveAccText();
   HRESULT ResolveAccHypertext();
 
   RefPtr<AccessibleHandler>     mHandler;
-  RefPtr<IAccessibleText>       mAccTextProxy;
   RefPtr<IAccessibleHypertext>  mAccHypertextProxy;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif // mozilla_a11y_AccessibleTextTearoff_h
--- a/devtools/client/netmonitor/src/assets/styles/netmonitor.css
+++ b/devtools/client/netmonitor/src/assets/styles/netmonitor.css
@@ -158,22 +158,27 @@ body,
 .status-bar-label.load {
   color: var(--theme-highlight-red);
 }
 
 /* Request list empty panel */
 
 .request-list-empty-notice {
   margin: 0;
-  padding: 12px;
-  font-size: 120%;
   flex: 1;
   overflow: auto;
 }
 
+.empty-notice-element {
+  padding-top: 12px;
+  padding-left: 12px;
+  padding-right: 12px;
+  font-size: 1.2rem;
+}
+
 .notice-perf-message {
   margin-top: 2px;
   display: flex;
   align-items: center;
 }
 
 .requests-list-perf-notice-button {
   min-width: 30px;
@@ -244,20 +249,29 @@ body,
 }
 
 .theme-firebug .requests-list-column {
   padding: 1px;
 }
 
 /* Requests list headers */
 
+.requests-list-headers-wrapper {
+  position: sticky;
+  top: 0;
+  z-index: 1000;
+  width: 100%;
+  padding: 0;
+}
+
 .requests-list-headers {
   display: table-header-group;
   height: 24px;
   padding: 0;
+  width: 100%;
 }
 
 .requests-list-headers .requests-list-column:first-child .requests-list-header-button {
   border-width: 0;
 }
 
 .requests-list-header-button {
   background-color: transparent;
@@ -737,16 +751,17 @@ body,
 
 .requests-list-timings-total:dir(rtl) {
   transform-origin: right center;
 }
 
 /* Request list item */
 
 .request-list-item {
+  position: relative;
   display: table-row;
   height: 24px;
 }
 
 .request-list-item.selected {
   background-color: var(--theme-selection-background);
   color: var(--theme-selection-color);
 }
--- a/devtools/client/netmonitor/src/components/RequestList.js
+++ b/devtools/client/netmonitor/src/components/RequestList.js
@@ -8,37 +8,34 @@ const {
   createFactory,
   DOM,
   PropTypes,
 } = require("devtools/client/shared/vendor/react");
 
 // Components
 const RequestListContent = createFactory(require("./RequestListContent"));
 const RequestListEmptyNotice = createFactory(require("./RequestListEmptyNotice"));
-const RequestListHeader = createFactory(require("./RequestListHeader"));
 const StatusBar = createFactory(require("./StatusBar"));
 
 const { div } = DOM;
 
 /**
  * Request panel component
  */
 function RequestList({
   connector,
   isEmpty,
 }) {
   return (
     div({ className: "request-list-container" },
-      RequestListHeader(),
       isEmpty ? RequestListEmptyNotice({connector}) : RequestListContent({connector}),
-      StatusBar({connector}),
+      StatusBar(),
     )
   );
 }
 
 RequestList.displayName = "RequestList";
 
 RequestList.propTypes = {
-  connector: PropTypes.object.isRequired,
   isEmpty: PropTypes.bool.isRequired,
 };
 
 module.exports = RequestList;
--- a/devtools/client/netmonitor/src/components/RequestListContent.js
+++ b/devtools/client/netmonitor/src/components/RequestListContent.js
@@ -15,16 +15,17 @@ const { HTMLTooltip } = require("devtool
 const Actions = require("../actions/index");
 const { setTooltipImageContent } = require("../request-list-tooltip");
 const {
   getDisplayedRequests,
   getWaterfallScale,
 } = require("../selectors/index");
 
 // Components
+const RequestListHeader = createFactory(require("./RequestListHeader"));
 const RequestListItem = createFactory(require("./RequestListItem"));
 const RequestListContextMenu = require("../request-list-context-menu");
 
 const { div } = DOM;
 
 // tooltip show/hide delay in ms
 const REQUESTS_TOOLTIP_TOGGLE_DELAY = 500;
 
@@ -253,16 +254,17 @@ class RequestListContent extends Compone
       div({ className: "requests-list-wrapper"},
         div({ className: "requests-list-table"},
           div({
             ref: "contentEl",
             className: "requests-list-contents",
             tabIndex: 0,
             onKeyDown: this.onKeyDown,
           },
+            RequestListHeader(),
             displayedRequests.map((item, index) => RequestListItem({
               firstRequestStartedMillis,
               fromCache: item.status === "304" || item.fromCache,
               columns,
               item,
               index,
               isSelected: item.id === selectedRequestId,
               key: item.id,
--- a/devtools/client/netmonitor/src/components/RequestListEmptyNotice.js
+++ b/devtools/client/netmonitor/src/components/RequestListEmptyNotice.js
@@ -13,16 +13,17 @@ const {
 const { connect } = require("devtools/client/shared/vendor/react-redux");
 const Actions = require("../actions/index");
 const { ACTIVITY_TYPE } = require("../constants");
 const { L10N } = require("../utils/l10n");
 const { getPerformanceAnalysisURL } = require("../utils/mdn-utils");
 
 // Components
 const MDNLink = createFactory(require("./MdnLink"));
+const RequestListHeader = createFactory(require("./RequestListHeader"));
 
 const { button, div, span } = DOM;
 
 const RELOAD_NOTICE_1 = L10N.getStr("netmonitor.reloadNotice1");
 const RELOAD_NOTICE_2 = L10N.getStr("netmonitor.reloadNotice2");
 const RELOAD_NOTICE_3 = L10N.getStr("netmonitor.reloadNotice3");
 const PERFORMANCE_NOTICE_1 = L10N.getStr("netmonitor.perfNotice1");
 const PERFORMANCE_NOTICE_2 = L10N.getStr("netmonitor.perfNotice2");
@@ -41,17 +42,18 @@ class RequestListEmptyNotice extends Com
     };
   }
 
   render() {
     return div(
       {
         className: "request-list-empty-notice",
       },
-      div({ className: "notice-reload-message" },
+      RequestListHeader(),
+      div({ className: "notice-reload-message empty-notice-element" },
         span(null, RELOAD_NOTICE_1),
         button(
           {
             className: "devtools-button requests-list-reload-notice-button",
             "data-standalone": true,
             onClick: this.props.onReloadClick,
           },
           RELOAD_NOTICE_2
--- a/devtools/client/netmonitor/src/components/RequestListHeader.js
+++ b/devtools/client/netmonitor/src/components/RequestListHeader.js
@@ -99,57 +99,59 @@ class RequestListHeader extends Componen
         this.props.resizeWaterfall(waterfallHeader.getBoundingClientRect().width));
     }
   }
 
   render() {
     let { columns, scale, sort, sortBy, waterfallWidth } = this.props;
 
     return (
-      div({ className: "devtools-toolbar requests-list-headers" },
-        HEADERS.filter((header) => columns.get(header.name)).map((header) => {
-          let name = header.name;
-          let boxName = header.boxName || name;
-          let label = header.noLocalization
-            ? name : L10N.getStr(`netmonitor.toolbar.${header.label || name}`);
-          let sorted, sortedTitle;
-          let active = sort.type == name ? true : undefined;
+      div({ className: "devtools-toolbar requests-list-headers-wrapper" },
+        div({ className: "devtools-toolbar requests-list-headers" },
+          HEADERS.filter((header) => columns.get(header.name)).map((header) => {
+            let name = header.name;
+            let boxName = header.boxName || name;
+            let label = header.noLocalization
+              ? name : L10N.getStr(`netmonitor.toolbar.${header.label || name}`);
+            let sorted, sortedTitle;
+            let active = sort.type == name ? true : undefined;
 
-          if (active) {
-            sorted = sort.ascending ? "ascending" : "descending";
-            sortedTitle = L10N.getStr(sort.ascending
-              ? "networkMenu.sortedAsc"
-              : "networkMenu.sortedDesc");
-          }
+            if (active) {
+              sorted = sort.ascending ? "ascending" : "descending";
+              sortedTitle = L10N.getStr(sort.ascending
+                ? "networkMenu.sortedAsc"
+                : "networkMenu.sortedDesc");
+            }
 
-          return (
-            div({
-              id: `requests-list-${boxName}-header-box`,
-              className: `requests-list-column requests-list-${boxName}`,
-              key: name,
-              ref: `${name}Header`,
-              // Used to style the next column.
-              "data-active": active,
-              onContextMenu: this.onContextMenu,
-            },
-              button({
-                id: `requests-list-${name}-button`,
-                className: `requests-list-header-button`,
-                "data-sorted": sorted,
-                title: sortedTitle ? `${label} (${sortedTitle})` : label,
-                onClick: () => sortBy(name),
+            return (
+              div({
+                id: `requests-list-${boxName}-header-box`,
+                className: `requests-list-column requests-list-${boxName}`,
+                key: name,
+                ref: `${name}Header`,
+                // Used to style the next column.
+                "data-active": active,
+                onContextMenu: this.onContextMenu,
               },
-                name === "waterfall"
-                  ? WaterfallLabel(waterfallWidth, scale, label)
-                  : div({ className: "button-text" }, label),
-                div({ className: "button-icon" })
+                button({
+                  id: `requests-list-${name}-button`,
+                  className: `requests-list-header-button`,
+                  "data-sorted": sorted,
+                  title: sortedTitle ? `${label} (${sortedTitle})` : label,
+                  onClick: () => sortBy(name),
+                },
+                  name === "waterfall"
+                    ? WaterfallLabel(waterfallWidth, scale, label)
+                    : div({ className: "button-text" }, label),
+                  div({ className: "button-icon" })
+                )
               )
-            )
-          );
-        })
+            );
+          })
+        )
       )
     );
   }
 }
 
 /**
  * Build the waterfall header - timing tick marks with the right spacing
  */
--- a/devtools/client/netmonitor/test/browser.ini
+++ b/devtools/client/netmonitor/test/browser.ini
@@ -114,16 +114,17 @@ skip-if = (os == 'linux' && debug && bit
 [browser_net_filter-01.js]
 skip-if = (os == 'linux' && debug && bits == 32) # Bug 1303439
 [browser_net_filter-02.js]
 [browser_net_filter-03.js]
 [browser_net_filter-04.js]
 [browser_net_filter-autocomplete.js]
 [browser_net_filter-flags.js]
 [browser_net_footer-summary.js]
+[browser_net_headers-alignment.js]
 [browser_net_headers_sorted.js]
 [browser_net_icon-preview.js]
 [browser_net_image-tooltip.js]
 [browser_net_json-b64.js]
 [browser_net_json-null.js]
 [browser_net_json-long.js]
 [browser_net_json-malformed.js]
 [browser_net_json_custom_mime.js]
--- a/devtools/client/netmonitor/test/browser_net_autoscroll.js
+++ b/devtools/client/netmonitor/test/browser_net_autoscroll.js
@@ -1,15 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 /**
  * Bug 863102 - Automatically scroll down upon new network requests.
+ * edited to account for changes made to fix Bug 1360457
  */
 add_task(function* () {
   requestLongerTimeout(4);
 
   let { monitor } = yield initNetMonitor(INFINITE_GET_URL, true);
   let { document, windowRequire, store } = monitor.panelWin;
   let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
 
@@ -22,42 +23,44 @@ add_task(function* () {
   ok(requestsContainer, "Container element exists as expected.");
 
   // (1) Check that the scroll position is maintained at the bottom
   // when the requests overflow the vertical size of the container.
   yield waitForRequestsToOverflowContainer();
   yield waitForScroll();
   ok(true, "Scrolled to bottom on overflow.");
 
-  // (2) Now set the scroll position to the first item and check
-  // that additional requests do not change the scroll position.
-  let firstNode = requestsContainer.firstChild;
-  firstNode.scrollIntoView();
+  // (2) Now scroll to the top and check that additional requests
+  // do not change the scroll position.
+  requestsContainer.scrollTop = 0;
   yield waitSomeTime();
   ok(!scrolledToBottom(requestsContainer), "Not scrolled to bottom.");
   // save for comparison later
   let scrollTop = requestsContainer.scrollTop;
   yield waitForNetworkEvents(monitor, 8);
   yield waitSomeTime();
   is(requestsContainer.scrollTop, scrollTop, "Did not scroll.");
 
   // (3) Now set the scroll position back at the bottom and check that
   // additional requests *do* cause the container to scroll down.
   requestsContainer.scrollTop = requestsContainer.scrollHeight;
   ok(scrolledToBottom(requestsContainer), "Set scroll position to bottom.");
   yield waitForNetworkEvents(monitor, 8);
   yield waitForScroll();
   ok(true, "Still scrolled to bottom.");
 
-  // (4) Now select an item in the list and check that additional requests
-  // do not change the scroll position.
+  // (4) Now select the first item in the list
+  // and check that additional requests do not change the scroll position
+  // from just below the headers.
   store.dispatch(Actions.selectRequestByIndex(0));
   yield waitForNetworkEvents(monitor, 8);
   yield waitSomeTime();
-  is(requestsContainer.scrollTop, 0, "Did not scroll.");
+  let requestsContainerHeaders = requestsContainer.firstChild;
+  let headersHeight = requestsContainerHeaders.offsetHeight;
+  is(requestsContainer.scrollTop, headersHeight, "Did not scroll.");
 
   // Done: clean up.
   return teardown(monitor);
 
   function waitForRequestListToAppear() {
     info("Waiting until the empty notice disappears and is replaced with the list");
     return waitUntil(() => !!document.querySelector(".requests-list-contents"));
   }
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/test/browser_net_headers-alignment.js
@@ -0,0 +1,64 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/**
+ * Bug 1360457 - Mis-alignment between headers and columns on overflow
+ */
+
+add_task(function* () {
+  requestLongerTimeout(4);
+
+  let { monitor } = yield initNetMonitor(INFINITE_GET_URL, true);
+  let { document, windowRequire, store } = monitor.panelWin;
+  let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
+
+  store.dispatch(Actions.batchEnable(false));
+
+  // Wait until the first request makes the empty notice disappear
+  yield waitForRequestListToAppear();
+
+  let requestsContainer = document.querySelector(".requests-list-contents");
+  ok(requestsContainer, "Container element exists as expected.");
+  let headers = document.querySelector(".requests-list-headers");
+  ok(headers, "Headers element exists as expected.");
+
+  yield waitForRequestsToOverflowContainer();
+
+  // Get first request line, not child 0 as this is the headers
+  let firstRequestLine = requestsContainer.childNodes[1];
+
+  // Find number of columns
+  let numberOfColumns = headers.childElementCount;
+  for (let columnNumber = 0; columnNumber < numberOfColumns; columnNumber++) {
+    let aHeaderColumn = headers.childNodes[columnNumber];
+    let aRequestColumn = firstRequestLine.childNodes[columnNumber];
+    is(aHeaderColumn.getBoundingClientRect().left,
+       aRequestColumn.getBoundingClientRect().left,
+       "Headers for columns number " + columnNumber + " are aligned."
+    );
+  }
+
+  // Done: clean up.
+  return teardown(monitor);
+
+  function waitForRequestListToAppear() {
+    info("Waiting until the empty notice disappears and is replaced with the list");
+    return waitUntil(() => !!document.querySelector(".requests-list-contents"));
+  }
+
+  function* waitForRequestsToOverflowContainer() {
+    info("Waiting for enough requests to overflow the container");
+    while (true) {
+      info("Waiting for one network request");
+      yield waitForNetworkEvents(monitor, 1);
+      console.log(requestsContainer.scrollHeight);
+      console.log(requestsContainer.clientHeight);
+      if (requestsContainer.scrollHeight > requestsContainer.clientHeight) {
+        info("The list is long enough, returning");
+        return;
+      }
+    }
+  }
+});
--- a/taskcluster/ci/test/talos.yml
+++ b/taskcluster/ci/test/talos.yml
@@ -173,35 +173,27 @@ talos-g5:
     description: "Talos g5"
     try-name: g5
     treeherder-symbol: tc-T(g5)
     run-on-projects:
         by-test-platform:
             linux64-qr/.*: ['mozilla-central', 'try']
             default: ['mozilla-beta', 'mozilla-central', 'mozilla-inbound', 'autoland', 'try']
     mozharness:
-        config:
-            by-test-platform:
-                default:
-                    - remove_executables.py
         extra-options:
             - --suite=g5
             - --add-option
             - --webServer,localhost
 
 talos-g5-stylo-disabled:
     description: "Talos Stylo disabled g5"
     try-name: g5-stylo-disabled
     treeherder-symbol: tc-Tsd(g5)
     run-on-projects: ['mozilla-beta', 'mozilla-central', 'try']
     mozharness:
-        config:
-            by-test-platform:
-                default:
-                    - remove_executables.py
         extra-options:
             - --suite=g5-stylo-disabled
             - --add-option
             - --webServer,localhost
 
 talos-h1:
     description: "Talos h1"
     try-name: h1
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_capabilities.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_capabilities.py
@@ -63,23 +63,23 @@ class TestCapabilities(MarionetteTestCas
             else:
                 current_profile = convert_path(self.marionette.instance.runner.profile.profile)
             self.assertEqual(convert_path(str(self.caps["moz:profile"])), current_profile)
             self.assertEqual(convert_path(str(self.marionette.profile)), current_profile)
 
         self.assertIn("moz:accessibilityChecks", self.caps)
         self.assertFalse(self.caps["moz:accessibilityChecks"])
         self.assertIn("moz:webdriverClick", self.caps)
-        self.assertEqual(self.caps["moz:webdriverClick"], False)
+        self.assertEqual(self.caps["moz:webdriverClick"], True)
 
-    def test_set_webdriver_click(self):
+    def test_disable_webdriver_click(self):
         self.marionette.delete_session()
-        self.marionette.start_session({"moz:webdriverClick": True})
+        self.marionette.start_session({"moz:webdriverClick": False})
         caps = self.marionette.session_capabilities
-        self.assertEqual(True, caps["moz:webdriverClick"])
+        self.assertEqual(False, caps["moz:webdriverClick"])
 
     def test_we_get_valid_uuid4_when_creating_a_session(self):
         self.assertNotIn("{", self.marionette.session_id,
                          "Session ID has {{}} in it: {}".format(
                              self.marionette.session_id))
 
 
 class TestCapabilityMatching(MarionetteTestCase):
--- a/testing/marionette/session.js
+++ b/testing/marionette/session.js
@@ -361,17 +361,17 @@ session.Capabilities = class extends Map
       // features
       ["rotatable", appinfo.name == "B2G"],
 
       // proprietary
       ["moz:accessibilityChecks", false],
       ["moz:headless", Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo).isHeadless],
       ["moz:processID", Services.appinfo.processID],
       ["moz:profile", maybeProfile()],
-      ["moz:webdriverClick", false],
+      ["moz:webdriverClick", true],
     ]);
   }
 
   /**
    * @param {string} key
    *     Capability key.
    * @param {(string|number|boolean)} value
    *     JSON-safe capability value.
--- a/testing/marionette/test_session.js
+++ b/testing/marionette/test_session.js
@@ -374,17 +374,17 @@ add_test(function test_Capabilities_ctor
   ok(caps.get("timeouts") instanceof session.Timeouts);
   ok(caps.get("proxy") instanceof session.Proxy);
 
   ok(caps.has("rotatable"));
 
   equal(false, caps.get("moz:accessibilityChecks"));
   ok(caps.has("moz:processID"));
   ok(caps.has("moz:profile"));
-  equal(false, caps.get("moz:webdriverClick"));
+  equal(true, caps.get("moz:webdriverClick"));
 
   run_next_test();
 });
 
 add_test(function test_Capabilities_toString() {
   equal("[object session.Capabilities]", new session.Capabilities().toString());
 
   run_next_test();
@@ -442,17 +442,17 @@ add_test(function test_Capabilities_from
   let proxyConfig = {proxyType: "manual"};
   caps = fromJSON({proxy: proxyConfig});
   equal("manual", caps.get("proxy").proxyType);
 
   let timeoutsConfig = {implicit: 123};
   caps = fromJSON({timeouts: timeoutsConfig});
   equal(123, caps.get("timeouts").implicit);
 
-  equal(false, caps.get("moz:webdriverClick"));
+  equal(true, caps.get("moz:webdriverClick"));
   caps = fromJSON({"moz:webdriverClick": true});
   equal(true, caps.get("moz:webdriverClick"));
   Assert.throws(() => fromJSON({"moz:webdriverClick": "foo"}));
   Assert.throws(() => fromJSON({"moz:webdriverClick": 1}));
 
   caps = fromJSON({"moz:accessibilityChecks": true});
   equal(true, caps.get("moz:accessibilityChecks"));
   caps = fromJSON({"moz:accessibilityChecks": false});
--- a/widget/WidgetUtils.cpp
+++ b/widget/WidgetUtils.cpp
@@ -2,19 +2,21 @@
  * vim: sw=2 ts=8 et :
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/WidgetUtils.h"
 #include "mozilla/dom/ContentParent.h"
+#include "mozilla/Services.h"
 #include "mozilla/Unused.h"
 #include "nsContentUtils.h"
 #include "nsIBidiKeyboard.h"
+#include "nsIStringBundle.h"
 #include "nsTArray.h"
 #ifdef XP_WIN
 #include "WinUtils.h"
 #endif
 #if MOZ_WIDGET_GTK == 3
 #include "mozilla/WidgetUtilsGtk.h"
 #endif
 
@@ -132,10 +134,31 @@ WidgetUtils::SendBidiKeyboardInfoToConte
 
   nsTArray<dom::ContentParent*> children;
   dom::ContentParent::GetAll(children);
   for (uint32_t i = 0; i < children.Length(); i++) {
     Unused << children[i]->SendBidiKeyboardNotify(rtl, bidiKeyboards);
   }
 }
 
+// static
+void
+WidgetUtils::GetBrandShortName(nsAString& aBrandName)
+{
+    aBrandName.Truncate();
+
+    nsCOMPtr<nsIStringBundleService> bundleService =
+        mozilla::services::GetStringBundleService();
+
+    nsCOMPtr<nsIStringBundle> bundle;
+    if (bundleService) {
+        bundleService->CreateBundle(
+            "chrome://branding/locale/brand.properties",
+            getter_AddRefs(bundle));
+    }
+
+    if (bundle) {
+        bundle->GetStringFromName("brandShortName", aBrandName);
+    }
+}
+
 } // namespace widget
 } // namespace mozilla
--- a/widget/WidgetUtils.h
+++ b/widget/WidgetUtils.h
@@ -86,14 +86,20 @@ public:
   * Does device have touch support
   */
   static uint32_t IsTouchDeviceSupportPresent();
 
   /**
    * Send bidi keyboard information to content process
    */
   static void SendBidiKeyboardInfoToContent();
+
+  /**
+   * Get branchShortName from string bundle
+   */
+  static void GetBrandShortName(nsAString& aBrandName);
+
 };
 
 } // namespace widget
 } // namespace mozilla
 
 #endif // mozilla_WidgetUtils_h
--- a/widget/gtk/mozgtk/mozgtk.c
+++ b/widget/gtk/mozgtk/mozgtk.c
@@ -66,16 +66,17 @@ STUB(gdk_screen_get_number)
 STUB(gdk_screen_get_resolution)
 STUB(gdk_screen_get_rgba_visual)
 STUB(gdk_screen_get_root_window)
 STUB(gdk_screen_get_system_visual)
 STUB(gdk_screen_get_width)
 STUB(gdk_screen_height)
 STUB(gdk_screen_is_composited)
 STUB(gdk_screen_width)
+STUB(gdk_set_program_class)
 STUB(gdk_unicode_to_keyval)
 STUB(gdk_visual_get_depth)
 STUB(gdk_visual_get_system)
 STUB(gdk_window_add_filter)
 STUB(gdk_window_begin_move_drag)
 STUB(gdk_window_begin_resize_drag)
 STUB(gdk_window_destroy)
 STUB(gdk_window_focus)
--- a/widget/gtk/nsAppShell.cpp
+++ b/widget/gtk/nsAppShell.cpp
@@ -11,16 +11,17 @@
 #include <errno.h>
 #include <gdk/gdk.h>
 #include "nsAppShell.h"
 #include "nsWindow.h"
 #include "mozilla/Logging.h"
 #include "prenv.h"
 #include "mozilla/HangMonitor.h"
 #include "mozilla/Unused.h"
+#include "mozilla/WidgetUtils.h"
 #include "GeckoProfiler.h"
 #include "nsIPowerManagerService.h"
 #ifdef MOZ_ENABLE_DBUS
 #include "WakeLockListener.h"
 #endif
 #include "gfxPlatform.h"
 #include "ScreenHelperGTK.h"
 #include "HeadlessScreenHelper.h"
@@ -171,16 +172,28 @@ nsAppShell::Init()
         ScreenManager& screenManager = ScreenManager::GetSingleton();
         if (gfxPlatform::IsHeadless()) {
             screenManager.SetHelper(mozilla::MakeUnique<HeadlessScreenHelper>());
         } else {
             screenManager.SetHelper(mozilla::MakeUnique<ScreenHelperGTK>());
         }
     }
 
+    if (gtk_check_version(3, 16, 3) == nullptr) {
+        // Before 3.16.3, GDK cannot override classname by --class command line
+        // option when program uses gdk_set_program_class().
+        //
+        // See https://bugzilla.gnome.org/show_bug.cgi?id=747634
+        nsAutoString brandName;
+        mozilla::widget::WidgetUtils::GetBrandShortName(brandName);
+        if (!brandName.IsEmpty()) {
+            gdk_set_program_class(NS_ConvertUTF16toUTF8(brandName).get());
+        }
+    }
+
 #if MOZ_WIDGET_GTK == 3
     if (!sReal_gtk_window_check_resize &&
         gtk_check_version(3,8,0) != nullptr) { // GTK 3.0 to GTK 3.6.
         // GtkWindow is a static class and so will leak anyway but this ref
         // makes sure it isn't recreated.
         gpointer gtk_plug_class = g_type_class_ref(GTK_TYPE_WINDOW);
         auto check_resize = &GTK_CONTAINER_CLASS(gtk_plug_class)->check_resize;
         sReal_gtk_window_check_resize = *check_resize;
--- a/widget/gtk/nsSound.cpp
+++ b/widget/gtk/nsSound.cpp
@@ -20,17 +20,17 @@
 #include "nsIChannel.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsDirectoryService.h"
 #include "nsDirectoryServiceDefs.h"
 #include "mozilla/FileUtils.h"
 #include "mozilla/Services.h"
 #include "mozilla/Unused.h"
-#include "nsIStringBundle.h"
+#include "mozilla/WidgetUtils.h"
 #include "nsIXULAppInfo.h"
 #include "nsContentUtils.h"
 #include "gfxPlatform.h"
 #include "mozilla/ClearOnShutdown.h"
 
 #include <stdio.h>
 #include <unistd.h>
 
@@ -120,31 +120,21 @@ ca_context_get_default()
 
         if (sound_theme_name) {
             ca_context_change_props(ctx, "canberra.xdg-theme.name",
                                     sound_theme_name, nullptr);
             g_free(sound_theme_name);
         }
     }
 
-    nsCOMPtr<nsIStringBundleService> bundleService =
-        mozilla::services::GetStringBundleService();
-    if (bundleService) {
-        nsCOMPtr<nsIStringBundle> brandingBundle;
-        bundleService->CreateBundle("chrome://branding/locale/brand.properties",
-                                    getter_AddRefs(brandingBundle));
-        if (brandingBundle) {
-            nsAutoString wbrand;
-            brandingBundle->GetStringFromName("brandShortName", wbrand);
-            NS_ConvertUTF16toUTF8 brand(wbrand);
-
-            ca_context_change_props(ctx, "application.name", brand.get(),
-                                    nullptr);
-        }
-    }
+    nsAutoString wbrand;
+    WidgetUtils::GetBrandShortName(wbrand);
+    ca_context_change_props(ctx, "application.name",
+                            NS_ConvertUTF16toUTF8(wbrand).get(),
+                            nullptr);
 
     nsCOMPtr<nsIXULAppInfo> appInfo = do_GetService("@mozilla.org/xre/app-info;1");
     if (appInfo) {
         nsAutoCString version;
         appInfo->GetVersion(version);
 
         ca_context_change_props(ctx, "application.version", version.get(),
                                 nullptr);
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -12,16 +12,17 @@
 #include "mozilla/MiscEvents.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/TextEventDispatcher.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/TouchEvents.h"
 #include "mozilla/UniquePtrExtensions.h"
+#include "mozilla/WidgetUtils.h"
 #include <algorithm>
 
 #include "GeckoProfiler.h"
 
 #include "prlink.h"
 #include "nsGTKToolkit.h"
 #include "nsIRollupListener.h"
 #include "nsIDOMNode.h"
@@ -71,17 +72,16 @@
 #endif
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Likely.h"
 #include "mozilla/Preferences.h"
 #include "nsIPrefService.h"
 #include "nsIGConfService.h"
 #include "nsIServiceManager.h"
-#include "nsIStringBundle.h"
 #include "nsGfxCIID.h"
 #include "nsGtkUtils.h"
 #include "nsIObserverService.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "nsIIdleServiceInternal.h"
 #include "nsIPropertyBag2.h"
 #include "GLContext.h"
 #include "gfx2DGlue.h"
@@ -171,18 +171,16 @@ static GdkCursor *get_gtk_cursor(nsCurso
 
 static GdkWindow *get_inner_gdk_window (GdkWindow *aWindow,
                                         gint x, gint y,
                                         gint *retx, gint *rety);
 
 static int    is_parent_ungrab_enter(GdkEventCrossing *aEvent);
 static int    is_parent_grab_leave(GdkEventCrossing *aEvent);
 
-static void GetBrandName(nsAString& brandName);
-
 /* callbacks from widgets */
 #if (MOZ_WIDGET_GTK == 2)
 static gboolean expose_event_cb           (GtkWidget *widget,
                                            GdkEventExpose *event);
 #else
 static gboolean expose_event_cb           (GtkWidget *widget,
                                            cairo_t *rect);
 #endif
@@ -1772,17 +1770,20 @@ nsWindow::SetIcon(const nsAString& aIcon
 {
     if (!mShell)
         return;
 
     nsAutoCString iconName;
 
     if (aIconSpec.EqualsLiteral("default")) {
         nsAutoString brandName;
-        GetBrandName(brandName);
+        WidgetUtils::GetBrandShortName(brandName);
+        if (brandName.IsEmpty()) {
+            brandName.AssignLiteral(u"Mozilla");
+        }
         AppendUTF16toUTF8(brandName, iconName);
         ToLowerCase(iconName);
     } else {
         AppendUTF16toUTF8(aIconSpec, iconName);
     }
 
     nsCOMPtr<nsIFile> iconFile;
     nsAutoCString path;
@@ -3516,35 +3517,16 @@ nsWindow::OnTouchEvent(GdkEventTouch* aE
         *event.mTouches.AppendElement() = touch.forget();
     }
 
     DispatchInputEvent(&event);
     return TRUE;
 }
 #endif
 
-static void
-GetBrandName(nsAString& aBrandName)
-{
-    nsCOMPtr<nsIStringBundleService> bundleService =
-        do_GetService(NS_STRINGBUNDLE_CONTRACTID);
-
-    nsCOMPtr<nsIStringBundle> bundle;
-    if (bundleService)
-        bundleService->CreateBundle(
-            "chrome://branding/locale/brand.properties",
-            getter_AddRefs(bundle));
-
-    if (bundle)
-        bundle->GetStringFromName("brandShortName", aBrandName);
-
-    if (aBrandName.IsEmpty())
-        aBrandName.AssignLiteral(u"Mozilla");
-}
-
 static GdkWindow *
 CreateGdkWindow(GdkWindow *parent, GtkWidget *widget)
 {
     GdkWindowAttr attributes;
     gint          attributes_mask = GDK_WA_VISUAL;
 
     attributes.event_mask = kEvents;