Bug 1371219 - Increase margin of main menu items when accessed through touch. r=mikedeboer draft
authorJohann Hofmann <jhofmann@mozilla.com>
Thu, 20 Jul 2017 16:45:02 +0200
changeset 612962 71cec7055786687a23325ec667d59a2e630f5c57
parent 612961 c455c8ec77e439bf02c1e3e8d34a36e1fb5e3bd0
child 612963 5c69769497607e1bc9af5991ad5cebd4851e1ba4
push id69670
push userbmo:jhofmann@mozilla.com
push dateFri, 21 Jul 2017 09:38:48 +0000
reviewersmikedeboer
bugs1371219
milestone56.0a1
Bug 1371219 - Increase margin of main menu items when accessed through touch. r=mikedeboer MozReview-Commit-ID: 9gjxxc6O5YS
browser/base/content/browser-places.js
browser/base/content/browser.js
browser/base/content/browser.xul
browser/components/customizableui/CustomizableUI.jsm
browser/components/customizableui/PanelMultiView.jsm
browser/components/customizableui/content/panelUI.js
browser/themes/shared/customizableui/panelUI.inc.css
browser/themes/windows/browser.css
toolkit/content/widgets/popup.xml
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -1855,36 +1855,36 @@ var BookmarkingUI = {
       this.button.removeAttribute("notification");
 
       this.dropmarkerNotifier.style.transform = "";
       this.notifier.style.transform = "";
     }, 1000);
   },
 
   showSubView(anchor) {
-    this._showSubView(anchor);
+    this._showSubView(null, anchor);
   },
 
-  _showSubView(anchor = document.getElementById(this.BOOKMARK_BUTTON_ID)) {
+  _showSubView(event, anchor = document.getElementById(this.BOOKMARK_BUTTON_ID)) {
     let view = document.getElementById("PanelUI-bookmarks");
     view.addEventListener("ViewShowing", this);
     view.addEventListener("ViewHiding", this);
     anchor.setAttribute("closemenu", "none");
     PanelUI.showSubView("PanelUI-bookmarks", anchor,
-                        CustomizableUI.AREA_PANEL);
+                        CustomizableUI.AREA_PANEL, event);
   },
 
   onCommand: function BUI_onCommand(aEvent) {
     if (aEvent.target != aEvent.currentTarget) {
       return;
     }
 
     // Handle special case when the button is in the panel.
     if (this.button.getAttribute("cui-areatype") == CustomizableUI.TYPE_MENU_PANEL) {
-      this._showSubView();
+      this._showSubView(aEvent);
       return;
     }
     let widget = CustomizableUI.getWidget(this.BOOKMARK_BUTTON_ID)
                                .forWindow(window);
     if (widget.overflowed) {
       // Close the overflow panel because the Edit Bookmark panel will appear.
       widget.node.removeAttribute("closemenu");
     }
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1629,17 +1629,17 @@ var gBrowserInit = {
 
     if (Win7Features)
       Win7Features.onOpenWindow();
 
     FullScreen.init();
     PointerLock.init();
 
     if (AppConstants.isPlatformAndVersionAtLeast("win", "10")) {
-      ContextMenuTouchModeObserver.init();
+      MenuTouchModeObserver.init();
     }
 
     // initialize the sync UI
     requestIdleCallback(() => {
       gSync.init();
     }, {timeout: 1000 * 5});
 
     if (AppConstants.MOZ_DATA_REPORTING)
@@ -1844,17 +1844,17 @@ var gBrowserInit = {
         Cu.reportError(ex);
       }
 
       if (this.gmpInstallManager) {
         this.gmpInstallManager.uninit();
       }
 
       if (AppConstants.isPlatformAndVersionAtLeast("win", "10")) {
-        ContextMenuTouchModeObserver.uninit();
+        MenuTouchModeObserver.uninit();
       }
       BrowserOffline.uninit();
       IndexedDBPromptHelper.uninit();
       PanelUI.uninit();
       AutoShowBookmarksToolbar.uninit();
     }
 
     // Final window teardown, do this last.
@@ -7930,17 +7930,20 @@ var gPageActionButton = {
     if ((event.type == "click" && event.button != 0) ||
         (event.type == "keypress" && event.charCode != KeyEvent.DOM_VK_SPACE &&
          event.keyCode != KeyEvent.DOM_VK_RETURN)) {
       return; // Left click, space or enter only
     }
 
     this._preparePanelToBeShown();
     this.panel.hidden = false;
-    this.panel.openPopup(this.button, "bottomcenter topright");
+    this.panel.openPopup(this.button, {
+      position: "bottomcenter topright",
+      triggerEvent: event,
+    });
   },
 
   _preparePanelToBeShown() {
     // Update the bookmark item's label.
     BookmarkingUI.updateBookmarkPageMenuItem();
 
     // Update the send-to-device item's disabled state.
     let browser = gBrowser.selectedBrowser;
@@ -8298,26 +8301,27 @@ var RestoreLastSessionObserver = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
                                          Ci.nsISupportsWeakReference])
 };
 
 function restoreLastSession() {
   SessionStore.restoreLastSession();
 }
 
-/* Observes context menus and adjusts their size for better
+/* Observes menus and adjusts their size for better
  * usability when opened via a touch screen. */
-var ContextMenuTouchModeObserver = {
+var MenuTouchModeObserver = {
   init() {
     window.addEventListener("popupshowing", this, true);
   },
 
   handleEvent(event) {
     let target = event.originalTarget;
-    if (target.localName != "menupopup") {
+    // Only resize non-context menus in Photon.
+    if (target.localName != "menupopup" && !gPhotonStructure) {
       return;
     }
 
     if (event.mozInputSource == MouseEvent.MOZ_SOURCE_TOUCH) {
       target.setAttribute("touchmode", "true");
     } else {
       target.removeAttribute("touchmode");
     }
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -1213,17 +1213,17 @@
 
       <toolbarbutton id="fullscreen-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
                      observes="View:FullScreen"
                      type="checkbox"
                      label="&fullScreenCmd.label;"
                      tooltip="dynamic-shortcut-tooltip"/>
 #ifdef MOZ_PHOTON_THEME
       <toolbarbutton id="library-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
-                     oncommand="PanelUI.showSubView('appMenu-libraryView', this, null, true);"
+                     oncommand="PanelUI.showSubView('appMenu-libraryView', this, null, event);"
                      closemenu="none"
                      label="&places.library.title;"/>
 #endif
     </toolbarpalette>
   </toolbox>
 
   <hbox id="fullscr-toggler" hidden="true"/>
 
--- a/browser/components/customizableui/CustomizableUI.jsm
+++ b/browser/components/customizableui/CustomizableUI.jsm
@@ -1543,17 +1543,18 @@ var CustomizableUIInternal = {
         let wrapper = this.wrapWidget(aWidget.id).forWindow(ownerWindow);
 
         let hasMultiView = !!aNode.closest("photonpanelmultiview,panelmultiview");
         if (wrapper && !hasMultiView && wrapper.anchor) {
           this.hidePanelForNode(aNode);
           anchor = wrapper.anchor;
         }
       }
-      ownerWindow.PanelUI.showSubView(aWidget.viewId, anchor, area);
+
+      ownerWindow.PanelUI.showSubView(aWidget.viewId, anchor, area, aEvent);
     }
   },
 
   handleWidgetClick(aWidget, aNode, aEvent) {
     log.debug("handleWidgetClick");
     if (aWidget.onClick) {
       try {
         aWidget.onClick.call(null, aEvent);
--- a/browser/components/customizableui/PanelMultiView.jsm
+++ b/browser/components/customizableui/PanelMultiView.jsm
@@ -937,25 +937,35 @@ this.PanelMultiView = class {
         this.showMainView();
         if (this.panelViews) {
           if (this._transitionEndListener) {
             this._viewContainer.removeEventListener("transitionend", this._transitionEndListener);
             this._transitionEndListener = null;
           }
           for (let panelView of this._viewStack.children) {
             if (panelView.nodeName != "children") {
+              panelView.__lastKnownBoundingRect = null;
               panelView.style.removeProperty("min-width");
               panelView.style.removeProperty("max-width");
             }
           }
           this.window.removeEventListener("keydown", this);
           this._panel.removeEventListener("mousemove", this);
           this._resetKeyNavigation();
+
+          // Clear the main view size caches. The dimensions could be different
+          // when the popup is opened again, e.g. through touch mode sizing.
           this._mainViewHeight = 0;
+          this._mainViewWidth = 0;
+          this._viewContainer.style.removeProperty("min-height");
+          this._viewStack.style.removeProperty("max-height");
+          this._viewContainer.style.removeProperty("min-width");
+          this._viewContainer.style.removeProperty("max-width");
         }
+
         // Always try to layout the panel normally when reopening it. This is
         // also the layout that will be used in customize mode.
         if (this._mainView.hasAttribute("blockinboxworkaround")) {
           this._mainView.style.removeProperty("height");
           this._mainView.removeAttribute("exceeding");
         }
         break;
     }
--- a/browser/components/customizableui/content/panelUI.js
+++ b/browser/components/customizableui/content/panelUI.js
@@ -268,29 +268,31 @@ const PanelUI = {
 
         let personalBookmarksPlacement = CustomizableUI.getPlacementOfWidget("personal-bookmarks");
         if (personalBookmarksPlacement &&
             personalBookmarksPlacement.area == CustomizableUI.AREA_PANEL) {
           PlacesToolbarHelper.customizeChange();
         }
 
         let anchor;
+        let domEvent = null;
         if (!aEvent ||
             aEvent.type == "command") {
           anchor = this.menuButton;
         } else {
+          domEvent = aEvent;
           anchor = aEvent.target;
         }
 
         this.panel.addEventListener("popupshown", function() {
           resolve();
         }, {once: true});
 
         anchor = this._getPanelAnchor(anchor);
-        this.panel.openPopup(anchor);
+        this.panel.openPopup(anchor, { triggerEvent: domEvent });
       }, (reason) => {
         console.error("Error showing the PanelUI menu", reason);
       });
     });
   },
 
   /**
    * If the menu panel is being shown, hide it.
@@ -470,18 +472,32 @@ const PanelUI = {
   },
 
   /**
    * Shows a subview in the panel with a given ID.
    *
    * @param aViewId the ID of the subview to show.
    * @param aAnchor the element that spawned the subview.
    * @param aPlacementArea the CustomizableUI area that aAnchor is in.
+   * @param aEvent the event triggering the view showing.
    */
-  async showSubView(aViewId, aAnchor, aPlacementArea) {
+  async showSubView(aViewId, aAnchor, aPlacementArea, aEvent) {
+
+    let domEvent = null;
+    if (aEvent) {
+      if (aEvent.type == "command" && aEvent.inputSource != null) {
+        // Synthesize a new DOM mouse event to pass on the inputSource.
+        domEvent = document.createEvent("MouseEvent");
+        domEvent.initNSMouseEvent("click", true, true, null, 0, aEvent.screenX, aEvent.screenY,
+                                  0, 0, false, false, false, false, 0, aEvent.target, 0, aEvent.inputSource);
+      } else if (aEvent.mozInputSource != null) {
+        domEvent = aEvent;
+      }
+    }
+
     this._ensureEventListenersAdded();
     let viewNode = document.getElementById(aViewId);
     if (!viewNode) {
       Cu.reportError("Could not show panel subview with id: " + aViewId);
       return;
     }
 
     if (!aAnchor) {
@@ -579,17 +595,20 @@ const PanelUI = {
       tempPanel.addEventListener("popuphidden", panelRemover);
 
       let anchor = this._getPanelAnchor(aAnchor);
 
       if (aAnchor != anchor && aAnchor.id) {
         anchor.setAttribute("consumeanchor", aAnchor.id);
       }
 
-      tempPanel.openPopup(anchor, "bottomcenter topright");
+      tempPanel.openPopup(anchor, {
+        position: "bottomcenter topright",
+        triggerEvent: domEvent,
+      });
     }
   },
 
   /**
    * NB: The enable- and disableSingleSubviewPanelAnimations methods only
    * affect the hiding/showing animations of single-subview panels (tempPanel
    * in the showSubView method).
    */
--- a/browser/themes/shared/customizableui/panelUI.inc.css
+++ b/browser/themes/shared/customizableui/panelUI.inc.css
@@ -351,16 +351,21 @@ photonpanelmultiview panelview {
 }
 
 #appMenu-popup panelview,
 #customizationui-widget-multiview panelview:not([extension]) {
   min-width: @menuPanelWidth@;
   max-width: 30em;
 }
 
+/* Add 2 * 12px extra width for touch mode button padding. */
+#appMenu-popup[touchmode] panelview {
+  min-width: calc(@menuPanelWidth@ + 24px);
+}
+
 photonpanelmultiview .panel-subview-body {
   margin: 4px 0;
 }
 
 /* END photonpanelview adjustments */
 
 .cui-widget-panel.cui-widget-panelWithFooter > .panel-arrowcontainer > .panel-arrowcontent {
   padding-bottom: 0;
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -1956,23 +1956,30 @@ notification.pluginVulnerable > .notific
    */
   margin-left: -10px;
   margin-right: -10px;
   margin-bottom: -10px;
 }
 
 %include ../shared/contextmenu.inc.css
 
-/* Make context menu items larger when opened through touch. */
+/* Make menu items larger when opened through touch. */
+panel[touchmode] .PanelUI-subView .subviewbutton,
 menupopup[touchmode] menu,
 menupopup[touchmode] menuitem {
   padding-top: 12px;
   padding-bottom: 12px;
 }
 
+panel[touchmode] .PanelUI-subView #appMenu-edit-controls > .subviewbutton,
+panel[touchmode] .PanelUI-subView #appMenu-zoom-controls > .subviewbutton-iconic {
+  padding-inline-start: 12px;
+  padding-inline-end: 12px;
+}
+
 #contentAreaContextMenu[touchmode] > #context-navigation > menuitem {
   padding-top: 7px;
   padding-bottom: 7px;
 }
 
 #context-navigation {
   background-color: menu;
   padding-bottom: 4px;
--- a/toolkit/content/widgets/popup.xml
+++ b/toolkit/content/widgets/popup.xml
@@ -41,16 +41,29 @@
         <parameter name="aPosition"/>
         <parameter name="aX"/>
         <parameter name="aY"/>
         <parameter name="aIsContextMenu"/>
         <parameter name="aAttributesOverride"/>
         <parameter name="aTriggerEvent"/>
         <body>
         <![CDATA[
+          // Allow for passing an options object as the second argument.
+          if (arguments.length == 2 &&
+              arguments[1] != null &&
+              typeof arguments[1] == "object") {
+            let params = arguments[1];
+            aPosition = params.position;
+            aX = params.x;
+            aY = params.y;
+            aIsContextMenu = params.isContextMenu;
+            aAttributesOverride = params.attributesOverride;
+            aTriggerEvent = params.triggerEvent;
+          }
+
           try {
             var popupBox = this.popupBoxObject;
             if (popupBox)
               popupBox.openPopup(aAnchorElement, aPosition, aX, aY,
                                  aIsContextMenu, aAttributesOverride, aTriggerEvent);
           } catch (e) {}
         ]]>
         </body>