Bug 1710507 - Make native menus respect the XUL element's directionality. r=emilio a=pascalc
authorMarkus Stange <mstange.moz@gmail.com>
Tue, 11 May 2021 20:34:17 +0000
changeset 644588 74c1ada52f543cdf67e9bb3b4f4572757dc502f9
parent 644587 43465b5e3c62c30a698a2f13b5399d16d45b5b30
child 644589 00a12bb94d11fe62c5e0d0827d8196022d5de699
push id15460
push userpchevrel@mozilla.com
push dateTue, 18 May 2021 07:12:13 +0000
treeherdermozilla-beta@a60b24466ab7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio, pascalc
bugs1710507
milestone89.0
Bug 1710507 - Make native menus respect the XUL element's directionality. r=emilio a=pascalc This affects both native context menus and menubar menus. Doing a flush here is fine, the nsMenuX constructor already flushes via SetupIcon() (which also uses nsComputedDOMStyle, in nsMenuItemIconX::GetIconURI). Differential Revision: https://phabricator.services.mozilla.com/D114785
widget/cocoa/nsMenuX.mm
--- a/widget/cocoa/nsMenuX.mm
+++ b/widget/cocoa/nsMenuX.mm
@@ -15,16 +15,17 @@
 
 #include "MOZMenuOpeningCoordinator.h"
 #include "nsMenuItemX.h"
 #include "nsMenuUtilsX.h"
 #include "nsMenuItemIconX.h"
 
 #include "nsObjCExceptions.h"
 
+#include "nsComputedDOMStyle.h"
 #include "nsThreadUtils.h"
 #include "nsToolkit.h"
 #include "nsCocoaUtils.h"
 #include "nsCOMPtr.h"
 #include "prinrval.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsUnicharUtils.h"
@@ -699,27 +700,48 @@ void nsMenuX::OnWillActivateItem(NSMenuI
       RefPtr<dom::Element> itemElement = item->Content()->AsElement();
       if (nsCOMPtr<nsIContent> popupContent = GetMenuPopupContent()) {
         mObserver->OnMenuWillActivateItem(popupContent->AsElement(), itemElement);
       }
     }
   }
 }
 
+// Flushes style.
+static NSUserInterfaceLayoutDirection DirectionForElement(dom::Element* aElement) {
+  // Get the direction from the computed style so that inheritance into submenus is respected.
+  // aElement may not have a frame.
+  RefPtr<ComputedStyle> sc = nsComputedDOMStyle::GetComputedStyle(aElement, nullptr);
+  if (!sc) {
+    return NSApp.userInterfaceLayoutDirection;
+  }
+
+  switch (sc->StyleVisibility()->mDirection) {
+    case StyleDirection::Ltr:
+      return NSUserInterfaceLayoutDirectionLeftToRight;
+    case StyleDirection::Rtl:
+      return NSUserInterfaceLayoutDirectionRightToLeft;
+  }
+}
+
 void nsMenuX::RebuildMenu() {
   MOZ_RELEASE_ASSERT(mNeedsRebuild);
   gConstructingMenu = true;
 
   // Retrieve our menupopup.
   nsCOMPtr<nsIContent> menuPopup = GetMenuPopupContent();
   if (!menuPopup) {
     gConstructingMenu = false;
     return;
   }
 
+  if (menuPopup->IsElement()) {
+    mNativeMenu.userInterfaceLayoutDirection = DirectionForElement(menuPopup->AsElement());
+  }
+
   // Iterate over the kids
   for (nsIContent* child = menuPopup->GetFirstChild(); child; child = child->GetNextSibling()) {
     if (Maybe<MenuChild> menuChild = CreateMenuChild(child)) {
       AddMenuChild(std::move(*menuChild));
     }
   }  // for each menu item
 
   InsertPlaceholderIfNeeded();