Bug 1397447 - add UI and automatic toggles to make the auto-hide functionality more seamless, r?mak draft
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Mon, 11 Sep 2017 18:54:48 +0100
changeset 663082 83827656291a3a43711c2dcdff72ce08e3ef252f
parent 663081 10f163485600bb7c8e002b34cbfda16fd75635db
child 731082 b60c469feb5998703c60d1aecfbd6dbe3a958ccb
push id79307
push userbmo:gijskruitbosch+bugs@gmail.com
push dateTue, 12 Sep 2017 15:18:02 +0000
reviewersmak
bugs1397447
milestone57.0a1
Bug 1397447 - add UI and automatic toggles to make the auto-hide functionality more seamless, r?mak MozReview-Commit-ID: 9xN3N4aLwfv
browser/components/customizableui/CustomizeMode.jsm
browser/components/customizableui/content/panelUI.inc.xul
browser/components/downloads/test/browser/browser_downloads_autohide.js
browser/locales/en-US/chrome/browser/browser.dtd
browser/themes/shared/customizableui/customizeMode.inc.css
--- a/browser/components/customizableui/CustomizeMode.jsm
+++ b/browser/components/customizableui/CustomizeMode.jsm
@@ -16,16 +16,20 @@ const kSkipSourceNodePref = "browser.uiC
 const kToolbarVisibilityBtn = "customization-toolbar-visibility-button";
 const kDrawInTitlebarPref = "browser.tabs.drawInTitlebar";
 const kMaxTransitionDurationMs = 2000;
 const kKeepBroadcastAttributes = "keepbroadcastattributeswhencustomizing";
 
 const kPanelItemContextMenu = "customizationPanelItemContextMenu";
 const kPaletteItemContextMenu = "customizationPaletteItemContextMenu";
 
+const kDownloadAutohideCheckboxId = "downloads-button-autohide-checkbox";
+const kDownloadAutohidePanelId = "downloads-button-autohide-panel";
+const kDownloadAutoHidePref = "browser.download.autohideButton";
+
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource:///modules/CustomizableUI.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/AddonManager.jsm");
 Cu.import("resource://gre/modules/AppConstants.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "DragPositionManager",
                                   "resource:///modules/DragPositionManager.jsm");
@@ -349,16 +353,18 @@ CustomizeMode.prototype = {
         // and make it async so it doesn't affect the timing.
         this.visiblePalette.clientTop;
         this.visiblePalette.setAttribute("showing", "true");
       }, 0);
       this._updateEmptyPaletteNotice();
 
       this._updateLWThemeButtonIcon();
 
+      this._setupDownloadAutoHideToggle();
+
       this._handler.isEnteringCustomizeMode = false;
 
       CustomizableUI.dispatchToolboxEvent("customizationready", {}, window);
 
       if (!this._wantToBeInCustomizeMode) {
         this.exit();
       }
     })().catch(e => {
@@ -390,16 +396,18 @@ CustomizeMode.prototype = {
     }
 
     this.hideTip();
 
     this._handler.isExitingCustomizeMode = true;
 
     this._removeExtraToolbarsIfEmpty();
 
+    this._teardownDownloadAutoHideToggle();
+
     CustomizableUI.removeListener(this);
 
     this.document.removeEventListener("keypress", this);
 
     let window = this.window;
     let document = this.document;
 
     // Hide the palette before starting the transition for increased perf.
@@ -467,16 +475,18 @@ CustomizeMode.prototype = {
       // or the TabSelect event handler will think that we are exiting
       // customization mode for a second time.
       this._customizing = false;
 
       let customizableToolbars = document.querySelectorAll("toolbar[customizable=true]:not([autohide=true])");
       for (let toolbar of customizableToolbars)
         toolbar.removeAttribute("customizing");
 
+      this._maybeMoveDownloadsButtonToNavBar();
+
       delete this._lastLightweightTheme;
       this._changed = false;
       this._transitioning = false;
       this._handler.isExitingCustomizeMode = false;
       CustomizableUI.dispatchToolboxEvent("aftercustomization", {}, window);
       CustomizableUI.notifyEndCustomizing(window);
 
       if (this._wantToBeInCustomizeMode) {
@@ -611,27 +621,39 @@ CustomizeMode.prototype = {
     return null;
   },
 
   addToToolbar(aNode) {
     aNode = this._getCustomizableChildForNode(aNode);
     if (aNode.localName == "toolbarpaletteitem" && aNode.firstChild) {
       aNode = aNode.firstChild;
     }
+
+    // If the user explicitly moves this item, turn off autohide.
+    if (aNode.id == "downloads-button") {
+      Services.prefs.setBoolPref(kDownloadAutoHidePref, false);
+    }
+
     CustomizableUI.addWidgetToArea(aNode.id, CustomizableUI.AREA_NAVBAR);
     if (!this._customizing) {
       CustomizableUI.dispatchToolboxEvent("customizationchange");
     }
   },
 
   addToPanel(aNode) {
     aNode = this._getCustomizableChildForNode(aNode);
     if (aNode.localName == "toolbarpaletteitem" && aNode.firstChild) {
       aNode = aNode.firstChild;
     }
+
+    // If the user explicitly moves this item, turn off autohide.
+    if (aNode.id == "downloads-button") {
+      Services.prefs.setBoolPref(kDownloadAutoHidePref, false);
+    }
+
     let panel = CustomizableUI.AREA_FIXED_OVERFLOW_PANEL;
     CustomizableUI.addWidgetToArea(aNode.id, panel);
     if (!this._customizing) {
       CustomizableUI.dispatchToolboxEvent("customizationchange");
     }
 
     if (Services.prefs.getBoolPref("toolkit.cosmeticAnimations.enabled")) {
       let overflowButton = this.document.getElementById("nav-bar-overflow-button");
@@ -650,16 +672,20 @@ CustomizeMode.prototype = {
     }
   },
 
   removeFromArea(aNode) {
     aNode = this._getCustomizableChildForNode(aNode);
     if (aNode.localName == "toolbarpaletteitem" && aNode.firstChild) {
       aNode = aNode.firstChild;
     }
+    // If the user explicitly removes this item, turn off autohide.
+    if (aNode.id == "downloads-button") {
+      Services.prefs.setBoolPref(kDownloadAutoHidePref, false);
+    }
     CustomizableUI.removeWidgetFromArea(aNode.id);
     if (!this._customizing) {
       CustomizableUI.dispatchToolboxEvent("customizationchange");
     }
   },
 
   populatePalette() {
     let fragment = this.document.createDocumentFragment();
@@ -1076,16 +1102,17 @@ CustomizeMode.prototype = {
       await this._wrapToolbarItems();
       this.populatePalette();
 
       this.persistCurrentSets(true);
 
       this._updateResetButton();
       this._updateUndoResetButton();
       this._updateEmptyPaletteNotice();
+      this._moveDownloadsButtonToNavBar = false;
       this.resetting = false;
       if (!this._wantToBeInCustomizeMode) {
         this.exit();
       }
     })().catch(log.error);
   },
 
   undoReset() {
@@ -1102,16 +1129,17 @@ CustomizeMode.prototype = {
       await this._wrapToolbarItems();
       this.populatePalette();
 
       this.persistCurrentSets(true);
 
       this._updateResetButton();
       this._updateUndoResetButton();
       this._updateEmptyPaletteNotice();
+      this._moveDownloadsButtonToNavBar = false;
       this.resetting = false;
     })().catch(log.error);
   },
 
   _onToolbarVisibilityChange(aEvent) {
     let toolbar = aEvent.target;
     if (aEvent.detail.visible && toolbar.getAttribute("customizable") == "true") {
       toolbar.setAttribute("customizing", "true");
@@ -1168,16 +1196,19 @@ CustomizeMode.prototype = {
       // API also does the right thing (and adds it to the palette)
       let widgetId = aNodeToChange.id;
       let widget = CustomizableUI.getWidget(widgetId);
       if (widget.provider == CustomizableUI.PROVIDER_API) {
         let paletteItem = this.makePaletteItem(widget, "palette");
         this.visiblePalette.appendChild(paletteItem);
       }
     }
+    if (aNodeToChange.id == "downloads-button") {
+      this._showDownloadsAutoHidePanel();
+    }
   },
 
   onWidgetDestroyed(aWidgetId) {
     let wrapper = this.document.getElementById("wrapper-" + aWidgetId);
     if (wrapper) {
       wrapper.remove();
     }
   },
@@ -1752,16 +1783,21 @@ CustomizeMode.prototype = {
 
     this._cancelDragActive(this._dragOverItem, null, true);
 
     try {
       this._applyDrop(aEvent, targetArea, originArea, draggedItemId, targetNode);
     } catch (ex) {
       log.error(ex, ex.stack);
     }
+
+    // If the user explicitly moves this item, turn off autohide.
+    if (draggedItemId == "downloads-button") {
+      Services.prefs.setBoolPref(kDownloadAutoHidePref, false);
+    }
   },
 
   _applyDrop(aEvent, aTargetArea, aOriginArea, aDraggedItemId, aTargetNode) {
     let document = aEvent.target.ownerDocument;
     let draggedItem = document.getElementById(aDraggedItemId);
     draggedItem.hidden = false;
     draggedItem.removeAttribute("mousedown");
 
@@ -2241,16 +2277,104 @@ CustomizeMode.prototype = {
   },
 
   onPanelContextMenuShowing(event) {
     let inPermanentArea = !!event.target.triggerNode.closest("#widget-overflow-fixed-list");
     let doc = event.target.ownerDocument;
     doc.getElementById("customizationPanelItemContextMenuUnpin").hidden = !inPermanentArea;
     doc.getElementById("customizationPanelItemContextMenuPin").hidden = inPermanentArea;
   },
+
+  _checkForDownloadsClick(event) {
+    if (event.target.closest("#wrapper-downloads-button") && event.button == 0) {
+      event.view.gCustomizeMode._showDownloadsAutoHidePanel();
+    }
+  },
+
+  _setupDownloadAutoHideToggle() {
+    this.document.getElementById(kDownloadAutohidePanelId).removeAttribute("hidden");
+    this.window.addEventListener("click", this._checkForDownloadsClick, true);
+  },
+
+  _teardownDownloadAutoHideToggle() {
+    this.window.removeEventListener("click", this._checkForDownloadsClick, true);
+    this.document.getElementById(kDownloadAutohidePanelId).hidePopup();
+  },
+
+  _maybeMoveDownloadsButtonToNavBar() {
+    // If the user toggled the autohide checkbox while the item was in the
+    // palette, and hasn't moved it since, move the item to the default
+    // location in the navbar for them.
+    if (!CustomizableUI.getPlacementOfWidget("downloads-button") &&
+        this._moveDownloadsButtonToNavBar &&
+        this.window.DownloadsButton.autoHideDownloadsButton) {
+      let navbarPlacements = CustomizableUI.getWidgetIdsInArea("nav-bar");
+      let insertionPoint = navbarPlacements.indexOf("urlbar-container");
+      while (++insertionPoint < navbarPlacements.length) {
+        let widget = navbarPlacements[insertionPoint];
+        // If we find a non-searchbar, non-spacer node, break out of the loop:
+        if (widget != "search-container" &&
+             !(CustomizableUI.isSpecialWidget(widget) && widget.includes("spring"))) {
+          break;
+        }
+      }
+      CustomizableUI.addWidgetToArea("downloads-button", "nav-bar", insertionPoint);
+    }
+  },
+
+  _showDownloadsAutoHidePanel() {
+    let doc = this.document;
+    let panel = doc.getElementById(kDownloadAutohidePanelId);
+    panel.hidePopup();
+    let button = doc.getElementById("downloads-button");
+    // We don't show the tooltip if the button is in the panel.
+    if (button.closest("#widget-overflow-fixed-list")) {
+      return;
+    }
+
+    let checkbox = doc.getElementById(kDownloadAutohideCheckboxId);
+    if (this.window.DownloadsButton.autoHideDownloadsButton) {
+      checkbox.setAttribute("checked", "true");
+    } else {
+      checkbox.removeAttribute("checked");
+    }
+
+    let offsetX = 0, offsetY = 0;
+    let position;
+    if (button.closest("#nav-bar")) {
+      let navbarWidgets = CustomizableUI.getWidgetIdsInArea("nav-bar");
+      if (navbarWidgets.indexOf("urlbar-container") > navbarWidgets.indexOf("downloads-button")) {
+        // Tested in RTL, these get inverted automatically, so this does the
+        // right thing without taking RTL into account explicitly.
+        position = "rightcenter topleft";
+        offsetX = -8;
+      } else {
+        position = "leftcenter topright";
+        offsetX = 8;
+      }
+    } else if (button.closest("#customization-palette")) {
+      position = "topcenter bottomleft";
+      offsetY = 10;
+    } else {
+      // For non-navbar toolbars, this works better than guessing whether
+      // left or right is a better place to position:
+      position = "bottomcenter topleft";
+      offsetY = -5;
+    }
+    // We don't use the icon to anchor because it might be resizing because of
+    // the animations for drag/drop. Hence the use of offsets.
+    panel.openPopup(button, position, offsetX, offsetY);
+  },
+
+  onDownloadsAutoHideChange(event) {
+    let checkbox = event.target.ownerDocument.getElementById(kDownloadAutohideCheckboxId);
+    Services.prefs.setBoolPref(kDownloadAutoHidePref, checkbox.checked);
+    // Ensure we move the button (back) after the user leaves customize mode.
+    event.view.gCustomizeMode._moveDownloadsButtonToNavBar = checkbox.checked;
+  },
 };
 
 function __dumpDragData(aEvent, caller) {
   if (!gDebug) {
     return;
   }
   let str = "Dumping drag data (" + (caller ? caller + " in " : "") + "CustomizeMode.jsm) {\n";
   str += "  type: " + aEvent.type + "\n";
--- a/browser/components/customizableui/content/panelUI.inc.xul
+++ b/browser/components/customizableui/content/panelUI.inc.xul
@@ -748,8 +748,22 @@
                        type="checkbox"
                        oncommand="onViewToolbarCommand(event)"
                        label="&viewBookmarksToolbar.label;"
                        label-checked="&hideBookmarksToolbar.label;"/>
       </vbox>
     </panelview>
   </photonpanelmultiview>
 </panel>
+
+<panel id="downloads-button-autohide-panel"
+       role="group"
+       type="arrow"
+       hidden="true"
+       onpopupshown="gCustomizeMode._downloadPanelAutoHideTimeout = setTimeout(() => event.target.hidePopup(), 4000);"
+       onmouseover="clearTimeout(gCustomizeMode._downloadPanelAutoHideTimeout);"
+       onmouseout="gCustomizeMode._downloadPanelAutoHideTimeout = setTimeout(() => event.target.hidePopup(), 2000);"
+       onpopuphidden="clearTimeout(gCustomizeMode._downloadPanelAutoHideTimeout);"
+       >
+  <checkbox id="downloads-button-autohide-checkbox"
+            label="&customizeMode.autoHideDownloadsButton.label;" checked="true"
+            oncommand="gCustomizeMode.onDownloadsAutoHideChange(event)"/>
+</panel>
--- a/browser/components/downloads/test/browser/browser_downloads_autohide.js
+++ b/browser/components/downloads/test/browser/browser_downloads_autohide.js
@@ -23,36 +23,44 @@ add_task(async function checkStateDuring
   ok(!DownloadsIndicatorView.hasDownloads,
      "Should be no downloads when starting the test");
   let downloadsButton = document.getElementById("downloads-button");
   ok(downloadsButton.hasAttribute("hidden"),
      "Button should be hidden in the toolbar");
   gCustomizeMode.addToPanel(downloadsButton);
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button shouldn't be hidden in the panel");
+  ok(!Services.prefs.getBoolPref(kDownloadAutoHidePref),
+     "Pref got set to false when the user moved the button");
   gCustomizeMode.addToToolbar(downloadsButton);
+  ok(!Services.prefs.getBoolPref(kDownloadAutoHidePref),
+     "Pref remains false when the user moved the button");
+  Services.prefs.setBoolPref(kDownloadAutoHidePref, true);
   ok(downloadsButton.hasAttribute("hidden"),
-     "Button should be hidden again in the toolbar");
+     "Button should be hidden again in the toolbar " +
+     "now that we flipped the pref");
   Services.prefs.setBoolPref(kDownloadAutoHidePref, false);
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button shouldn't be hidden with autohide turned off");
   gCustomizeMode.addToPanel(downloadsButton);
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button shouldn't be hidden with autohide turned off " +
      "after moving it to the panel");
   gCustomizeMode.addToToolbar(downloadsButton);
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button shouldn't be hidden with autohide turned off " +
      "after moving it back to the toolbar");
   gCustomizeMode.addToPanel(downloadsButton);
   Services.prefs.setBoolPref(kDownloadAutoHidePref, true);
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button should still not be hidden with autohide turned back on " +
      "because it's in the panel");
-  gCustomizeMode.addToToolbar(downloadsButton);
+  // Use CUI directly instead of the customize mode APIs,
+  // to avoid tripping the "automatically turn off autohide" code.
+  CustomizableUI.addWidgetToArea("downloads-button", "nav-bar");
   ok(downloadsButton.hasAttribute("hidden"),
      "Button should be hidden again in the toolbar");
   gCustomizeMode.removeFromArea(downloadsButton);
   Services.prefs.setBoolPref(kDownloadAutoHidePref, false);
   // Can't use gCustomizeMode.addToToolbar here because it doesn't work for
   // palette items if the window isn't in customize mode:
   CustomizableUI.addWidgetToArea(downloadsButton.id, CustomizableUI.AREA_NAVBAR);
   ok(!downloadsButton.hasAttribute("hidden"),
@@ -63,16 +71,21 @@ add_task(async function checkStateDuring
 
 add_task(async function checkStateInCustomizeMode() {
   ok(Services.prefs.getBoolPref("browser.download.autohideButton"),
      "Should be autohiding the button");
   let downloadsButton = document.getElementById("downloads-button");
   await promiseCustomizeStart();
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button should be shown in customize mode.");
+  await promiseCustomizeEnd();
+  ok(downloadsButton.hasAttribute("hidden"),
+     "Button should be hidden if it's in the toolbar " +
+     "after customize mode without any moves.");
+  await promiseCustomizeStart();
   gCustomizeMode.addToPanel(downloadsButton);
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button should be shown in customize mode when moved to the panel");
   gCustomizeMode.addToToolbar(downloadsButton);
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button should be shown in customize mode when moved back to the toolbar");
   gCustomizeMode.removeFromArea(downloadsButton);
   ok(!downloadsButton.hasAttribute("hidden"),
@@ -84,18 +97,19 @@ add_task(async function checkStateInCust
      "even when flipping the autohide pref");
   gCustomizeMode.addToPanel(downloadsButton);
   await promiseCustomizeEnd();
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button should be shown after customize mode when moved to the panel");
   await promiseCustomizeStart();
   gCustomizeMode.addToToolbar(downloadsButton);
   await promiseCustomizeEnd();
-  ok(downloadsButton.hasAttribute("hidden"),
-     "Button should be hidden if it's in the toolbar after customize mode.");
+  ok(!downloadsButton.hasAttribute("hidden"),
+     "Button should be shown in the toolbar after " +
+     "customize mode because we moved it.");
   await promiseCustomizeStart();
   await gCustomizeMode.reset();
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button should be shown in the toolbar in customize mode after a reset.");
   await gCustomizeMode.undoReset();
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button should be shown in the toolbar in customize mode " +
      "when undoing the reset.");
@@ -119,23 +133,26 @@ add_task(async function checkStateInCust
   await promiseCustomizeStart();
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button should be shown in customize mode.");
   let otherWin = await BrowserTestUtils.openNewBrowserWindow();
   let otherDownloadsButton = otherWin.document.getElementById("downloads-button");
   ok(otherDownloadsButton.hasAttribute("hidden"),
      "Button should be hidden in the other window.");
 
-  gCustomizeMode.addToPanel(downloadsButton);
+  // Use CUI directly instead of the customize mode APIs,
+  // to avoid tripping the "automatically turn off autohide" code.
+  CustomizableUI.addWidgetToArea("downloads-button",
+                                 CustomizableUI.AREA_FIXED_OVERFLOW_PANEL);
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button should still be shown in customize mode.");
   ok(!otherDownloadsButton.hasAttribute("hidden"),
      "Button should be shown in the other window too because it's in a panel.");
 
-  gCustomizeMode.addToToolbar(downloadsButton);
+  CustomizableUI.addWidgetToArea("downloads-button", CustomizableUI.AREA_NAVBAR);
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button should still be shown in customize mode.");
   ok(otherDownloadsButton.hasAttribute("hidden"),
      "Button should be hidden again in the other window.");
 
   Services.prefs.setBoolPref(kDownloadAutoHidePref, false);
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button should be shown in customize mode");
@@ -151,16 +168,18 @@ add_task(async function checkStateInCust
 
   gCustomizeMode.addToPanel(downloadsButton);
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button should still be shown in customize mode.");
   ok(!otherDownloadsButton.hasAttribute("hidden"),
      "Button should be shown in the other window too because it's in a panel.");
 
   gCustomizeMode.removeFromArea(downloadsButton);
+  ok(!Services.prefs.getBoolPref(kDownloadAutoHidePref),
+     "Autohide pref turned off by moving the button");
   ok(!downloadsButton.hasAttribute("hidden"),
      "Button should still be shown in customize mode.");
   // Don't need to assert in the other window - button is gone there.
 
   await gCustomizeMode.reset();
   ok(Services.prefs.getBoolPref(kDownloadAutoHidePref),
      "Autohide pref reset by reset()");
   ok(!downloadsButton.hasAttribute("hidden"),
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -861,16 +861,18 @@ you can use these alternative items. Oth
      “Touch” is displayed in the Customize screen, under the Density menu.
      It’s an adjective (Density -> Touch), and it means that control layout is
      optimized for touch devices. -->
 <!ENTITY customizeMode.uidensity.menuTouch.label "Touch">
 <!ENTITY customizeMode.uidensity.menuTouch.tooltip "Touch">
 <!ENTITY customizeMode.uidensity.menuTouch.accessKey "T">
 <!ENTITY customizeMode.uidensity.autoTouchMode.checkbox.label "Use Touch for Tablet Mode">
 
+<!ENTITY customizeMode.autoHideDownloadsButton.label "Auto-hide">
+
 <!ENTITY getUserMedia.selectCamera.label "Camera to share:">
 <!ENTITY getUserMedia.selectCamera.accesskey "C">
 <!ENTITY getUserMedia.selectMicrophone.label "Microphone to share:">
 <!ENTITY getUserMedia.selectMicrophone.accesskey "M">
 <!ENTITY getUserMedia.audioCapture.label "Audio from the tab will be shared.">
 <!ENTITY getUserMedia.allWindowsShared.message "All visible windows on your screen will be shared.">
 
 <!ENTITY trackingProtection.title "Tracking Protection">
--- a/browser/themes/shared/customizableui/customizeMode.inc.css
+++ b/browser/themes/shared/customizableui/customizeMode.inc.css
@@ -492,8 +492,17 @@ toolbarpaletteitem[place=toolbar] > tool
   display: block;
 }
 
 @media (min-resolution: 1.1dppx) {
   #customization-panelHolder > #widget-overflow-fixed-list:empty {
     background-image: url("chrome://browser/skin/customizableui/empty-overflow-panel@2x.png");
   }
 }
+
+#downloads-button-autohide-panel > .panel-arrowcontainer > .panel-arrowcontent {
+  padding: 5px 12px;
+}
+
+#downloads-button-autohide-checkbox {
+  margin: 0;
+  padding: 0;
+}