diff --git a/browser/app/nsBrowserApp.cpp b/browser/app/nsBrowserApp.cpp
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -154,19 +154,31 @@ static bool IsArg(const char* arg, const
 #endif
 
   return false;
 }
 
 Bootstrap::UniquePtr gBootstrap;
 
 static int do_main(int argc, char* argv[], char* envp[]) {
+  // Allow profile downgrade for Zotero
+  setenv("MOZ_ALLOW_DOWNGRADE", "1", 1);
+  // Don't create dedicated profile (default-esr)
+  setenv("MOZ_LEGACY_PROFILES", "1", 1);
+
   // Allow firefox.exe to launch XULRunner apps via -app <application.ini>
   // Note that -app must be the *first* argument.
-  const char* appDataFile = getenv("XUL_APP_FILE");
+  UniqueFreePtr<char> iniPath = BinaryPath::GetApplicationIni();
+  if (!iniPath) {
+    Output("Couldn't find application.ini.\n");
+    return 255;
+  }
+  char *appDataFile = iniPath.get();
+
+
   if ((!appDataFile || !*appDataFile) && (argc > 1 && IsArg(argv[1], "app"))) {
     if (argc == 2) {
       Output("Incorrect number of arguments passed to -app");
       return 255;
     }
     appDataFile = argv[2];
 
     char appEnv[MAXPATHLEN];
diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -11529,18 +11529,17 @@ static nsIWidget* GetPresContextContaine
   return mainWidget;
 }
 
 static bool IsTopLevelWidget(nsIWidget* aWidget) {
   using WindowType = mozilla::widget::WindowType;
 
   auto windowType = aWidget->GetWindowType();
   return windowType == WindowType::TopLevel ||
-         windowType == WindowType::Dialog || windowType == WindowType::Popup ||
-         windowType == WindowType::Sheet;
+         windowType == WindowType::Dialog || windowType == WindowType::Popup;
 }
 
 PresShell::WindowSizeConstraints PresShell::GetWindowSizeConstraints() {
   nsSize minSize(0, 0);
   nsSize maxSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
   nsIFrame* rootFrame = FrameConstructor()->GetRootElementStyleFrame();
   if (!rootFrame || !mPresContext) {
     return {minSize, maxSize};
diff --git a/layout/xul/nsXULTooltipListener.cpp b/layout/xul/nsXULTooltipListener.cpp
--- a/layout/xul/nsXULTooltipListener.cpp
+++ b/layout/xul/nsXULTooltipListener.cpp
@@ -365,53 +365,56 @@ nsresult nsXULTooltipListener::ShowToolt
 
   // get the tooltip content designated for the target node
   nsCOMPtr<nsIContent> tooltipNode;
   GetTooltipFor(sourceNode, getter_AddRefs(tooltipNode));
   if (!tooltipNode || sourceNode == tooltipNode)
     return NS_ERROR_FAILURE;  // the target node doesn't need a tooltip
 
   // set the node in the document that triggered the tooltip and show it
-  if (tooltipNode->GetComposedDoc() &&
-      nsContentUtils::IsChromeDoc(tooltipNode->GetComposedDoc())) {
-    // Make sure the target node is still attached to some document.
-    // It might have been deleted.
-    if (sourceNode->IsInComposedDoc()) {
-      if (!mIsSourceTree) {
-        mLastTreeRow = -1;
-        mLastTreeCol = nullptr;
-      }
+  // Make sure the document still has focus.
+  auto* doc = tooltipNode->GetComposedDoc();
+  if (!doc || !nsContentUtils::IsChromeDoc(doc) ||
+      !doc->HasFocus(IgnoreErrors())) {
+    return NS_OK;
+  }
+  // Make sure the target node is still attached to some document.
+  // It might have been deleted.
+  if (sourceNode->IsInComposedDoc()) {
+    if (!mIsSourceTree) {
+      mLastTreeRow = -1;
+      mLastTreeCol = nullptr;
+    }
 
-      mCurrentTooltip = do_GetWeakReference(tooltipNode);
-      LaunchTooltip();
-      mTargetNode = nullptr;
-
-      nsCOMPtr<nsIContent> currentTooltip = do_QueryReferent(mCurrentTooltip);
-      if (!currentTooltip) return NS_OK;
+    mCurrentTooltip = do_GetWeakReference(tooltipNode);
+    LaunchTooltip();
+    mTargetNode = nullptr;
 
-      // listen for popuphidden on the tooltip node, so that we can
-      // be sure DestroyPopup is called even if someone else closes the tooltip
-      currentTooltip->AddSystemEventListener(u"popuphiding"_ns, this, false,
-                                             false);
+    nsCOMPtr<nsIContent> currentTooltip = do_QueryReferent(mCurrentTooltip);
+    if (!currentTooltip) return NS_OK;
+
+    // listen for popuphidden on the tooltip node, so that we can
+    // be sure DestroyPopup is called even if someone else closes the tooltip
+    currentTooltip->AddSystemEventListener(u"popuphiding"_ns, this, false,
+                                           false);
 
-      // listen for mousedown, mouseup, keydown, and mouse events at
-      // document level
-      if (Document* doc = sourceNode->GetComposedDoc()) {
-        // Probably, we should listen to untrusted events for hiding tooltips
-        // on content since tooltips might disturb something of web
-        // applications.  If we don't specify the aWantsUntrusted of
-        // AddSystemEventListener(), the event target sets it to TRUE if the
-        // target is in content.
-        doc->AddSystemEventListener(u"wheel"_ns, this, true);
-        doc->AddSystemEventListener(u"mousedown"_ns, this, true);
-        doc->AddSystemEventListener(u"mouseup"_ns, this, true);
-        doc->AddSystemEventListener(u"keydown"_ns, this, true);
-      }
-      mSourceNode = nullptr;
+    // listen for mousedown, mouseup, keydown, and mouse events at
+    // document level
+    if (Document* doc = sourceNode->GetComposedDoc()) {
+      // Probably, we should listen to untrusted events for hiding tooltips
+      // on content since tooltips might disturb something of web
+      // applications.  If we don't specify the aWantsUntrusted of
+      // AddSystemEventListener(), the event target sets it to TRUE if the
+      // target is in content.
+      doc->AddSystemEventListener(u"wheel"_ns, this, true);
+      doc->AddSystemEventListener(u"mousedown"_ns, this, true);
+      doc->AddSystemEventListener(u"mouseup"_ns, this, true);
+      doc->AddSystemEventListener(u"keydown"_ns, this, true);
     }
+    mSourceNode = nullptr;
   }
 
   return NS_OK;
 }
 
 static void SetTitletipLabel(XULTreeElement* aTree, Element* aTooltip,
                              int32_t aRow, nsTreeColumn* aCol) {
   nsCOMPtr<nsITreeView> view = aTree->GetView();
diff --git a/python/mozbuild/mozbuild/action/unpack_dmg.py b/python/mozbuild/mozbuild/action/unpack_dmg.py
--- a/python/mozbuild/mozbuild/action/unpack_dmg.py
+++ b/python/mozbuild/mozbuild/action/unpack_dmg.py
@@ -34,18 +34,18 @@ def main(args):
     options = parser.parse_args(args)
 
     dmg_tool = bootstrap_toolchain("dmg/dmg")
     hfs_tool = bootstrap_toolchain("dmg/hfsplus")
 
     dmg.extract_dmg(
         dmgfile=Path(options.dmgfile),
         output=Path(options.outpath),
-        dmg_tool=Path(dmg_tool),
-        hfs_tool=Path(hfs_tool),
+        dmg_tool=_path_or_none(dmg_tool),
+        hfs_tool=_path_or_none(hfs_tool),
         dsstore=_path_or_none(options.dsstore),
         background=_path_or_none(options.background),
         icon=_path_or_none(options.icon),
     )
     return 0
 
 
 if __name__ == "__main__":
diff --git a/widget/InitData.h b/widget/InitData.h
--- a/widget/InitData.h
+++ b/widget/InitData.h
@@ -12,17 +12,16 @@
 
 namespace mozilla::widget {
 
 // Window types
 enum class WindowType : uint8_t {
   TopLevel,   // default top level window
   Dialog,     // top level window but usually handled differently
               // by the OS
-  Sheet,      // MacOSX sheet (special dialog class)
   Popup,      // used for combo boxes, etc
   Child,      // child windows (contained inside a window on the
               // desktop (has no border))
   Invisible,  // windows that are invisible or offscreen
 };
 
 // Popup types for WindowType::Popup
 enum class PopupType : uint8_t {
diff --git a/widget/cocoa/moz.build b/widget/cocoa/moz.build
--- a/widget/cocoa/moz.build
+++ b/widget/cocoa/moz.build
@@ -6,22 +6,16 @@
 
 with Files("**"):
     BUG_COMPONENT = ("Core", "Widget: Cocoa")
     SCHEDULES.exclusive = ["macosx"]
 
 with Files("*TextInput*"):
     BUG_COMPONENT = ("Core", "DOM: UI Events & Focus Handling")
 
-XPIDL_SOURCES += [
-    "nsPIWidgetCocoa.idl",
-]
-
-XPIDL_MODULE = "widget_cocoa"
-
 EXPORTS += [
     "CFTypeRefPtr.h",
     "DesktopBackgroundImage.h",
     "MediaHardwareKeysEventSourceMac.h",
     "MediaHardwareKeysEventSourceMacMediaCenter.h",
     "mozView.h",
     "nsBidiKeyboard.h",
     "nsChangeObserver.h",
diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -1678,29 +1678,23 @@ void nsChildView::UpdateThemeGeometries(
 
   if (![[mView window] isKindOfClass:[ToolbarWindow class]]) return;
 
   // Update unified toolbar height and sheet attachment position.
   int32_t windowWidth = mBounds.width;
   int32_t titlebarBottom = FindTitlebarBottom(aThemeGeometries, windowWidth);
   int32_t unifiedToolbarBottom =
       FindUnifiedToolbarBottom(aThemeGeometries, windowWidth, titlebarBottom);
-  int32_t toolboxBottom = FindFirstRectOfType(aThemeGeometries, eThemeGeometryTypeToolbox).YMost();
 
   ToolbarWindow* win = (ToolbarWindow*)[mView window];
   int32_t titlebarHeight =
       [win drawsContentsIntoWindowFrame] ? 0 : CocoaPointsToDevPixels([win titlebarHeight]);
   int32_t devUnifiedHeight = titlebarHeight + unifiedToolbarBottom;
   [win setUnifiedToolbarHeight:DevPixelsToCocoaPoints(devUnifiedHeight)];
 
-  int32_t sheetPositionDevPx = std::max(toolboxBottom, unifiedToolbarBottom);
-  NSPoint sheetPositionView = {0, DevPixelsToCocoaPoints(sheetPositionDevPx)};
-  NSPoint sheetPositionWindow = [mView convertPoint:sheetPositionView toView:nil];
-  [win setSheetAttachmentPosition:sheetPositionWindow.y];
-
   // Update titlebar control offsets.
   LayoutDeviceIntRect windowButtonRect =
       FindFirstRectOfType(aThemeGeometries, eThemeGeometryTypeWindowButtons);
   [win placeWindowButtons:[mView convertRect:DevPixelsToCocoaPoints(windowButtonRect) toView:nil]];
 }
 
 static Maybe<VibrancyType> ThemeGeometryTypeToVibrancyType(
     nsITheme::ThemeGeometryType aThemeGeometryType) {
@@ -4899,24 +4893,16 @@ BOOL ChildViewMouseTracker::WindowAccept
       return WindowAcceptsEvent([aWindow parentWindow], aEvent, aView, aIsClickThrough);
 
     case WindowType::TopLevel:
     case WindowType::Dialog:
       if ([aWindow attachedSheet]) return NO;
 
       topLevelWindow = aWindow;
       break;
-    case WindowType::Sheet: {
-      nsIWidget* parentWidget = windowWidget->GetSheetWindowParent();
-      if (!parentWidget) return YES;
-
-      topLevelWindow = (NSWindow*)parentWidget->GetNativeData(NS_NATIVE_WINDOW);
-      break;
-    }
-
     default:
       return YES;
   }
 
   if (!topLevelWindow || ([topLevelWindow isMainWindow] && !aIsClickThrough) ||
       [aEvent type] == NSEventTypeOtherMouseDown ||
       (([aEvent modifierFlags] & NSEventModifierFlagCommand) != 0 &&
        [aEvent type] != NSEventTypeMouseMoved))
diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h
--- a/widget/cocoa/nsCocoaWindow.h
+++ b/widget/cocoa/nsCocoaWindow.h
@@ -7,17 +7,16 @@
 #define nsCocoaWindow_h_
 
 #undef DARWIN
 
 #import <Cocoa/Cocoa.h>
 
 #include "mozilla/RefPtr.h"
 #include "nsBaseWidget.h"
-#include "nsPIWidgetCocoa.h"
 #include "nsCocoaUtils.h"
 #include "nsTouchBar.h"
 #include <dlfcn.h>
 #include <queue>
 
 class nsCocoaWindow;
 class nsChildView;
 class nsMenuBarX;
@@ -191,60 +190,53 @@ typedef struct _nsCocoaWindowList {
   // destroyed by updateTitlebarView.
   MOZTitlebarView* mTitlebarView;  // [STRONG]
   // mFullscreenTitlebarTracker attaches an invisible rectangle to the system
   // title bar. This allows us to detect when the title bar is showing in
   // fullscreen.
   FullscreenTitlebarTracker* mFullscreenTitlebarTracker;
 
   CGFloat mUnifiedToolbarHeight;
-  CGFloat mSheetAttachmentPosition;
   CGFloat mMenuBarHeight;
   /* Store the height of the titlebar when this window is initialized. The
      titlebarHeight getter returns 0 when in fullscreen, which is not useful in
      some cases. */
   CGFloat mInitialTitlebarHeight;
   NSRect mWindowButtonsRect;
 }
 - (void)setUnifiedToolbarHeight:(CGFloat)aHeight;
 - (CGFloat)unifiedToolbarHeight;
 - (CGFloat)titlebarHeight;
 - (NSRect)titlebarRect;
 - (void)setTitlebarNeedsDisplay;
 - (void)setDrawsContentsIntoWindowFrame:(BOOL)aState;
-- (void)setSheetAttachmentPosition:(CGFloat)aY;
-- (CGFloat)sheetAttachmentPosition;
 - (void)placeWindowButtons:(NSRect)aRect;
 - (NSRect)windowButtonsRect;
 - (void)windowMainStateChanged;
 @end
 
-class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
+class nsCocoaWindow final : public nsBaseWidget {
  private:
   typedef nsBaseWidget Inherited;
 
  public:
   nsCocoaWindow();
 
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSPIWIDGETCOCOA;  // semicolon for clang-format bug 1629756
-
   [[nodiscard]] virtual nsresult Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
                                         const DesktopIntRect& aRect, InitData* = nullptr) override;
 
   [[nodiscard]] virtual nsresult Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
                                         const LayoutDeviceIntRect& aRect,
                                         InitData* = nullptr) override;
 
   virtual void Destroy() override;
 
   virtual void Show(bool aState) override;
   virtual bool NeedsRecreateToReshow() override;
 
-  virtual nsIWidget* GetSheetWindowParent(void) override;
   virtual void Enable(bool aState) override;
   virtual bool IsEnabled() const override;
   virtual void SetModal(bool aState) override;
   virtual void SetFakeModal(bool aState) override;
   virtual bool IsRunningAppModal() override;
   virtual bool IsVisible() const override;
   virtual void SetFocus(Raise, mozilla::dom::CallerType aCallerType) override;
   virtual LayoutDeviceIntPoint WidgetToScreenOffset() override;
@@ -393,47 +385,45 @@ class nsCocoaWindow final : public nsBas
   virtual ~nsCocoaWindow();
 
   nsresult CreateNativeWindow(const NSRect& aRect, BorderStyle aBorderStyle, bool aRectIsFrameRect,
                               bool aIsPrivateBrowsing);
   nsresult CreatePopupContentView(const LayoutDeviceIntRect& aRect, InitData*);
   void DestroyNativeWindow();
   void UpdateBounds();
   int32_t GetWorkspaceID();
+  void SendSetZLevelEvent();
 
   void DoResize(double aX, double aY, double aWidth, double aHeight, bool aRepaint,
                 bool aConstrainToCurrentScreen);
 
   void UpdateFullscreenState(bool aFullScreen, bool aNativeMode);
   nsresult DoMakeFullScreen(bool aFullScreen, bool aUseSystemTransition);
 
   virtual already_AddRefed<nsIWidget> AllocateChildPopupWidget() override {
     return nsIWidget::CreateTopLevelWindow();
   }
 
   nsIWidget* mParent;         // if we're a popup, this is our parent [WEAK]
   nsIWidget* mAncestorLink;   // link to traverse ancestors [WEAK]
   BaseWindow* mWindow;        // our cocoa window [STRONG]
   WindowDelegate* mDelegate;  // our delegate for processing window msgs [STRONG]
   RefPtr<nsMenuBarX> mMenuBar;
-  NSWindow* mSheetWindowParent;    // if this is a sheet, this is the NSWindow it's attached to
   nsChildView* mPopupContentView;  // if this is a popup, this is its content widget
   // if this is a toplevel window, and there is any ongoing fullscreen
   // transition, it is the animation object.
   NSAnimation* mFullscreenTransitionAnimation;
   mozilla::StyleWindowShadow mShadowStyle;
 
   CGFloat mBackingScaleFactor;
   CGFloat mAspectRatio;
 
   WindowAnimationType mAnimationType;
 
   bool mWindowMadeHere;  // true if we created the window, false for embedding
-  bool mSheetNeedsShow;  // if this is a sheet, are we waiting to be shown?
-                         // this is used for sibling sheet contention only
   nsSizeMode mSizeMode;
   bool mInFullScreenMode;
   // Whether we are currently using native fullscreen. It could be false because
   // we are in the emulated fullscreen where we do not use the native fullscreen.
   bool mInNativeFullScreenMode;
 
   mozilla::Maybe<TransitionType> mTransitionCurrent;
   std::queue<TransitionType> mTransitionsPending;
diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -30,16 +30,17 @@
 #include "nsMenuUtilsX.h"
 #include "nsStyleConsts.h"
 #include "nsNativeThemeColors.h"
 #include "nsNativeThemeCocoa.h"
 #include "nsChildView.h"
 #include "nsCocoaFeatures.h"
 #include "nsIScreenManager.h"
 #include "nsIWidgetListener.h"
+#include "nsXULPopupManager.h"
 #include "SDKDeclarations.h"
 #include "VibrancyManager.h"
 #include "nsPresContext.h"
 #include "nsDocShell.h"
 
 #include "gfxPlatform.h"
 #include "qcms.h"
 
@@ -99,28 +100,27 @@ typedef enum {
 static NSString* const CGSSpaceIDKey = @"ManagedSpaceID";
 static NSString* const CGSSpacesKey = @"Spaces";
 extern CGSConnection _CGSDefaultConnection(void);
 extern CGError CGSSetWindowTransform(CGSConnection cid, CGSWindow wid, CGAffineTransform transform);
 }
 
 #define NS_APPSHELLSERVICE_CONTRACTID "@mozilla.org/appshell/appShellService;1"
 
-NS_IMPL_ISUPPORTS_INHERITED(nsCocoaWindow, Inherited, nsPIWidgetCocoa)
-
-// A note on testing to see if your object is a sheet...
-// |mWindowType == WindowType::Sheet| is true if your gecko nsIWidget is a sheet
-// widget - whether or not the sheet is showing. |[mWindow isSheet]| will return
-// true *only when the sheet is actually showing*. Choose your test wisely.
-
 static void RollUpPopups(
     nsIRollupListener::AllowAnimations aAllowAnimations = nsIRollupListener::AllowAnimations::Yes) {
+  if (RefPtr pm = nsXULPopupManager::GetInstance()) {
+    pm->RollupTooltips();
+  }
+
   nsIRollupListener* rollupListener = nsBaseWidget::GetActiveRollupListener();
-  NS_ENSURE_TRUE_VOID(rollupListener);
-
+
+  if (!rollupListener) {
+    return;
+  }
   if (rollupListener->RollupNativeMenu()) {
     return;
   }
 
   nsCOMPtr<nsIWidget> rollupWidget = rollupListener->GetRollupWidget();
   if (!rollupWidget) {
     return;
   }
@@ -129,24 +129,22 @@ static void RollUpPopups(
   rollupListener->Rollup(options);
 }
 
 nsCocoaWindow::nsCocoaWindow()
     : mParent(nullptr),
       mAncestorLink(nullptr),
       mWindow(nil),
       mDelegate(nil),
-      mSheetWindowParent(nil),
       mPopupContentView(nil),
       mFullscreenTransitionAnimation(nil),
       mShadowStyle(StyleWindowShadow::Default),
       mBackingScaleFactor(0.0),
       mAnimationType(nsIWidget::eGenericWindowAnimation),
       mWindowMadeHere(false),
-      mSheetNeedsShow(false),
       mSizeMode(nsSizeMode_Normal),
       mInFullScreenMode(false),
       mInNativeFullScreenMode(false),
       mIgnoreOcclusionCount(0),
       mHasStartedNativeFullscreen(false),
       mModal(false),
       mFakeModal(false),
       mIsAnimationSuppressed(false),
@@ -431,25 +429,16 @@ nsresult nsCocoaWindow::CreateNativeWind
           features |= NSWindowStyleMaskClosable;
         }
       }
       break;
     case WindowType::TopLevel:
     case WindowType::Dialog:
       features = WindowMaskForBorderStyle(aBorderStyle);
       break;
-    case WindowType::Sheet:
-      if (mParent->GetWindowType() != WindowType::Invisible &&
-          aBorderStyle & BorderStyle::ResizeH) {
-        features = NSWindowStyleMaskResizable;
-      } else {
-        features = NSWindowStyleMaskMiniaturizable;
-      }
-      features |= NSWindowStyleMaskTitled;
-      break;
     default:
       NS_ERROR("Unhandled window type!");
       return NS_ERROR_FAILURE;
   }
 
   NSRect contentRect;
 
   if (aRectIsFrameRect) {
@@ -650,24 +639,16 @@ void nsCocoaWindow::Destroy() {
     if (mInNativeFullScreenMode) {
       DestroyNativeWindow();
     } else if (mWindow) {
       nsCocoaUtils::HideOSChromeOnScreen(false);
     }
   }
 }
 
-nsIWidget* nsCocoaWindow::GetSheetWindowParent(void) {
-  if (mWindowType != WindowType::Sheet) return nullptr;
-  nsCocoaWindow* parent = static_cast<nsCocoaWindow*>(mParent);
-  while (parent && (parent->mWindowType == WindowType::Sheet))
-    parent = static_cast<nsCocoaWindow*>(parent->mParent);
-  return parent;
-}
-
 void* nsCocoaWindow::GetNativeData(uint32_t aDataType) {
   NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
 
   void* retVal = nullptr;
 
   switch (aDataType) {
     // to emulate how windows works, we always have to return a NSView
     // for NS_NATIVE_WIDGET
@@ -707,17 +688,17 @@ void* nsCocoaWindow::GetNativeData(uint3
   return retVal;
 
   NS_OBJC_END_TRY_BLOCK_RETURN(nullptr);
 }
 
 bool nsCocoaWindow::IsVisible() const {
   NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
 
-  return (mWindow && ([mWindow isVisibleOrBeingShown] || mSheetNeedsShow));
+  return mWindow && mWindow.isVisibleOrBeingShown;
 
   NS_OBJC_END_TRY_BLOCK_RETURN(false);
 }
 
 void nsCocoaWindow::SetModal(bool aState) {
   NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
 
   if (!mWindow) return;
@@ -734,64 +715,60 @@ void nsCocoaWindow::SetModal(bool aState
     ++gXULModalLevel;
     // When a non-sheet window gets "set modal", make the window(s) that it
     // appears over behave as they should.  We can't rely on native methods to
     // do this, for the following reason:  The OS runs modal non-sheet windows
     // in an event loop (using [NSApplication runModalForWindow:] or similar
     // methods) that's incompatible with the modal event loop in AppWindow::
     // ShowModal() (each of these event loops is "exclusive", and can't run at
     // the same time as other (similar) event loops).
-    if (mWindowType != WindowType::Sheet) {
-      while (ancestor) {
-        if (ancestor->mNumModalDescendents++ == 0) {
-          NSWindow* aWindow = ancestor->GetCocoaWindow();
-          if (ancestor->mWindowType != WindowType::Invisible) {
-            [[aWindow standardWindowButton:NSWindowCloseButton] setEnabled:NO];
-            [[aWindow standardWindowButton:NSWindowMiniaturizeButton] setEnabled:NO];
-            [[aWindow standardWindowButton:NSWindowZoomButton] setEnabled:NO];
-          }
+    while (ancestor) {
+      if (ancestor->mNumModalDescendents++ == 0) {
+        NSWindow* aWindow = ancestor->GetCocoaWindow();
+        if (ancestor->mWindowType != WindowType::Invisible) {
+          [[aWindow standardWindowButton:NSWindowCloseButton] setEnabled:NO];
+          [[aWindow standardWindowButton:NSWindowMiniaturizeButton] setEnabled:NO];
+          [[aWindow standardWindowButton:NSWindowZoomButton] setEnabled:NO];
         }
-        ancestor = static_cast<nsCocoaWindow*>(ancestor->mParent);
       }
-      [mWindow setLevel:NSModalPanelWindowLevel];
-      nsCocoaWindowList* windowList = new nsCocoaWindowList;
-      if (windowList) {
-        windowList->window = this;  // Don't ADDREF
-        windowList->prev = gGeckoAppModalWindowList;
-        gGeckoAppModalWindowList = windowList;
-      }
+      ancestor = static_cast<nsCocoaWindow*>(ancestor->mParent);
+    }
+    [mWindow setLevel:NSModalPanelWindowLevel];
+    nsCocoaWindowList* windowList = new nsCocoaWindowList;
+    if (windowList) {
+      windowList->window = this;  // Don't ADDREF
+      windowList->prev = gGeckoAppModalWindowList;
+      gGeckoAppModalWindowList = windowList;
     }
   } else {
     --gXULModalLevel;
     NS_ASSERTION(gXULModalLevel >= 0, "Mismatched call to nsCocoaWindow::SetModal(false)!");
-    if (mWindowType != WindowType::Sheet) {
-      while (ancestor) {
-        if (--ancestor->mNumModalDescendents == 0) {
-          NSWindow* aWindow = ancestor->GetCocoaWindow();
-          if (ancestor->mWindowType != WindowType::Invisible) {
-            [[aWindow standardWindowButton:NSWindowCloseButton] setEnabled:YES];
-            [[aWindow standardWindowButton:NSWindowMiniaturizeButton] setEnabled:YES];
-            [[aWindow standardWindowButton:NSWindowZoomButton] setEnabled:YES];
-          }
+    while (ancestor) {
+      if (--ancestor->mNumModalDescendents == 0) {
+        NSWindow* aWindow = ancestor->GetCocoaWindow();
+        if (ancestor->mWindowType != WindowType::Invisible) {
+          [[aWindow standardWindowButton:NSWindowCloseButton] setEnabled:YES];
+          [[aWindow standardWindowButton:NSWindowMiniaturizeButton] setEnabled:YES];
+          [[aWindow standardWindowButton:NSWindowZoomButton] setEnabled:YES];
         }
-        NS_ASSERTION(ancestor->mNumModalDescendents >= 0, "Widget hierarchy changed while modal!");
-        ancestor = static_cast<nsCocoaWindow*>(ancestor->mParent);
       }
-      if (gGeckoAppModalWindowList) {
-        NS_ASSERTION(gGeckoAppModalWindowList->window == this,
-                     "Widget hierarchy changed while modal!");
-        nsCocoaWindowList* saved = gGeckoAppModalWindowList;
-        gGeckoAppModalWindowList = gGeckoAppModalWindowList->prev;
-        delete saved;  // "window" not ADDREFed
-      }
-      if (mWindowType == WindowType::Popup)
-        SetPopupWindowLevel();
-      else
-        [mWindow setLevel:NSNormalWindowLevel];
+      NS_ASSERTION(ancestor->mNumModalDescendents >= 0, "Widget hierarchy changed while modal!");
+      ancestor = static_cast<nsCocoaWindow*>(ancestor->mParent);
     }
+    if (gGeckoAppModalWindowList) {
+      NS_ASSERTION(gGeckoAppModalWindowList->window == this,
+                   "Widget hierarchy changed while modal!");
+      nsCocoaWindowList* saved = gGeckoAppModalWindowList;
+      gGeckoAppModalWindowList = gGeckoAppModalWindowList->prev;
+      delete saved;  // "window" not ADDREFed
+    }
+    if (mWindowType == WindowType::Popup)
+      SetPopupWindowLevel();
+    else
+      [mWindow setLevel:NSNormalWindowLevel];
   }
 
   NS_OBJC_END_TRY_IGNORE_BLOCK;
 }
 
 void nsCocoaWindow::SetFakeModal(bool aState) {
   mFakeModal = aState;
   SetModal(aState);
@@ -800,32 +777,28 @@ void nsCocoaWindow::SetFakeModal(bool aS
 bool nsCocoaWindow::IsRunningAppModal() { return [NSApp _isRunningAppModal]; }
 
 // Hide or show this window
 void nsCocoaWindow::Show(bool bState) {
   NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
 
   if (!mWindow) return;
 
-  if (!mSheetNeedsShow) {
-    // Early exit if our current visibility state is already the requested state.
-    if (bState == ([mWindow isVisible] || [mWindow isBeingShown])) {
-      return;
-    }
+  // Early exit if our current visibility state is already the requested state.
+  if (bState == ([mWindow isVisible] || [mWindow isBeingShown])) {
+    return;
   }
 
   [mWindow setBeingShown:bState];
   if (bState && !mWasShown) {
     mWasShown = true;
   }
 
-  nsIWidget* parentWidget = mParent;
-  nsCOMPtr<nsPIWidgetCocoa> piParentWidget(do_QueryInterface(parentWidget));
   NSWindow* nativeParentWindow =
-      (parentWidget) ? (NSWindow*)parentWidget->GetNativeData(NS_NATIVE_WINDOW) : nil;
+      mParent ? (NSWindow*)mParent->GetNativeData(NS_NATIVE_WINDOW) : nil;
 
   if (bState && !mBounds.IsEmpty()) {
     // If we had set the activationPolicy to accessory, then right now we won't
     // have a dock icon. Make sure that we undo that and show a dock icon now that
     // we're going to show a window.
     if ([NSApp activationPolicy] != NSApplicationActivationPolicyRegular) {
       [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
       PR_SetEnv("MOZ_APP_NO_DOCK=");
@@ -838,87 +811,17 @@ void nsCocoaWindow::Show(bool bState) {
       }
     }
 
     if (mPopupContentView) {
       // Ensure our content view is visible. We never need to hide it.
       mPopupContentView->Show(true);
     }
 
-    if (mWindowType == WindowType::Sheet) {
-      // bail if no parent window (its basically what we do in Carbon)
-      if (!nativeParentWindow || !piParentWidget) return;
-
-      NSWindow* topNonSheetWindow = nativeParentWindow;
-
-      // If this sheet is the child of another sheet, hide the parent so that
-      // this sheet can be displayed. Leave the parent mSheetNeedsShow alone,
-      // that is only used to handle sibling sheet contention. The parent will
-      // return once there are no more child sheets.
-      bool parentIsSheet = false;
-      if (NS_SUCCEEDED(piParentWidget->GetIsSheet(&parentIsSheet)) && parentIsSheet) {
-        piParentWidget->GetSheetWindowParent(&topNonSheetWindow);
-#ifdef MOZ_THUNDERBIRD
-        [NSApp endSheet:nativeParentWindow];
-#else
-        [nativeParentWindow.sheetParent endSheet:nativeParentWindow];
-#endif
-      }
-
-      nsCOMPtr<nsIWidget> sheetShown;
-      if (NS_SUCCEEDED(piParentWidget->GetChildSheet(true, getter_AddRefs(sheetShown))) &&
-          (!sheetShown || sheetShown == this)) {
-        // If this sheet is already the sheet actually being shown, don't
-        // tell it to show again. Otherwise the number of calls to
-#ifdef MOZ_THUNDERBIRD
-        // [NSApp beginSheet...] won't match up with [NSApp endSheet...].
-#else
-        // [NSWindow beginSheet...] won't match up with [NSWindow endSheet...].
-#endif
-        if (![mWindow isVisible]) {
-          mSheetNeedsShow = false;
-          mSheetWindowParent = topNonSheetWindow;
-#ifdef MOZ_THUNDERBIRD
-          // Only set contextInfo if our parent isn't a sheet.
-          NSWindow* contextInfo = parentIsSheet ? nil : mSheetWindowParent;
-          [TopLevelWindowData deactivateInWindow:mSheetWindowParent];
-          [NSApp beginSheet:mWindow
-              modalForWindow:mSheetWindowParent
-               modalDelegate:mDelegate
-              didEndSelector:@selector(didEndSheet:returnCode:contextInfo:)
-                 contextInfo:contextInfo];
-#else
-          NSWindow* sheet = mWindow;
-          NSWindow* nonSheetParent = parentIsSheet ? nil : mSheetWindowParent;
-          [TopLevelWindowData deactivateInWindow:mSheetWindowParent];
-          [mSheetWindowParent beginSheet:sheet
-                       completionHandler:^(NSModalResponse returnCode) {
-                         // Note: 'nonSheetParent' (if it is set) is the window that is the parent
-                         // of the sheet. If it's set, 'nonSheetParent' is always the top- level
-                         // window, not another sheet itself.  But 'nonSheetParent' is nil if our
-                         // parent window is also a sheet -- in that case we shouldn't send the
-                         // top-level window any activate events (because it's our parent window
-                         // that needs to get these events, not the top-level window).
-                         [TopLevelWindowData deactivateInWindow:sheet];
-                         [sheet orderOut:nil];
-                         if (nonSheetParent) {
-                           [TopLevelWindowData activateInWindow:nonSheetParent];
-                         }
-                       }];
-#endif
-          [TopLevelWindowData activateInWindow:mWindow];
-          SendSetZLevelEvent();
-        }
-      } else {
-        // A sibling of this sheet is active, don't show this sheet yet.
-        // When the active sheet hides, its brothers and sisters that have
-        // mSheetNeedsShow set will have their opportunities to display.
-        mSheetNeedsShow = true;
-      }
-    } else if (mWindowType == WindowType::Popup) {
+    if (mWindowType == WindowType::Popup) {
       // For reasons that aren't yet clear, calls to [NSWindow orderFront:] or
       // [NSWindow makeKeyAndOrderFront:] can sometimes trigger "Error (1000)
       // creating CGSWindow", which in turn triggers an internal inconsistency
       // NSException.  These errors shouldn't be fatal.  So we need to wrap
       // calls to ...orderFront: in TRY blocks.  See bmo bug 470864.
       NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
       [[mWindow contentView] setNeedsDisplay:YES];
       [mWindow orderFront:nil];
@@ -974,120 +877,30 @@ void nsCocoaWindow::Show(bool bState) {
       SendSetZLevelEvent();
     }
   } else {
     // roll up any popups if a top-level window is going away
     if (mWindowType == WindowType::TopLevel || mWindowType == WindowType::Dialog) {
       RollUpPopups();
     }
 
-    // now get rid of the window/sheet
-    if (mWindowType == WindowType::Sheet) {
-      if (mSheetNeedsShow) {
-        // This is an attempt to hide a sheet that never had a chance to
-        // be shown. There's nothing to do other than make sure that it
-        // won't show.
-        mSheetNeedsShow = false;
-      } else {
-        // get sheet's parent *before* hiding the sheet (which breaks the linkage)
-        NSWindow* sheetParent = mSheetWindowParent;
-
-        // hide the sheet
-#ifdef MOZ_THUNDERBIRD
-        [NSApp endSheet:mWindow];
-#else
-        [mSheetWindowParent endSheet:mWindow];
-#endif
-        [TopLevelWindowData deactivateInWindow:mWindow];
-
-        nsCOMPtr<nsIWidget> siblingSheetToShow;
-        bool parentIsSheet = false;
-
-        if (nativeParentWindow && piParentWidget &&
-            NS_SUCCEEDED(
-                piParentWidget->GetChildSheet(false, getter_AddRefs(siblingSheetToShow))) &&
-            siblingSheetToShow) {
-          // First, give sibling sheets an opportunity to show.
-          siblingSheetToShow->Show(true);
-        } else if (nativeParentWindow && piParentWidget &&
-                   NS_SUCCEEDED(piParentWidget->GetIsSheet(&parentIsSheet)) && parentIsSheet) {
-#ifdef MOZ_THUNDERBIRD
-          // Only set contextInfo if the parent of the parent sheet we're about
-          // to restore isn't itself a sheet.
-          NSWindow* contextInfo = sheetParent;
-#else
-          // Only set nonSheetGrandparent if the parent of the parent sheet we're about
-          // to restore isn't itself a sheet.
-          NSWindow* nonSheetGrandparent = sheetParent;
-#endif
-          nsIWidget* grandparentWidget = nil;
-          if (NS_SUCCEEDED(piParentWidget->GetRealParent(&grandparentWidget)) &&
-              grandparentWidget) {
-            nsCOMPtr<nsPIWidgetCocoa> piGrandparentWidget(do_QueryInterface(grandparentWidget));
-            bool grandparentIsSheet = false;
-            if (piGrandparentWidget &&
-                NS_SUCCEEDED(piGrandparentWidget->GetIsSheet(&grandparentIsSheet)) &&
-                grandparentIsSheet) {
-#ifdef MOZ_THUNDERBIRD
-              contextInfo = nil;
-#else
-              nonSheetGrandparent = nil;
-#endif
-            }
-          }
-          // If there are no sibling sheets, but the parent is a sheet, restore
-          // it.  It wasn't sent any deactivate events when it was hidden, so
-          // don't call through Show, just let the OS put it back up.
-#ifdef MOZ_THUNDERBIRD
-          [NSApp beginSheet:nativeParentWindow
-              modalForWindow:sheetParent
-               modalDelegate:[nativeParentWindow delegate]
-              didEndSelector:@selector(didEndSheet:returnCode:contextInfo:)
-                 contextInfo:contextInfo];
-#else
-          [nativeParentWindow beginSheet:sheetParent
-                       completionHandler:^(NSModalResponse returnCode) {
-                         // Note: 'nonSheetGrandparent' (if it is set) is the window that is the
-                         // parent of sheetParent. If it's set, 'nonSheetGrandparent' is always the
-                         // top-level window, not another sheet itself.  But 'nonSheetGrandparent'
-                         // is nil if our parent window is also a sheet -- in that case we shouldn't
-                         // send the top-level window any activate events (because it's our parent
-                         // window that needs to get these events, not the top-level window).
-                         [TopLevelWindowData deactivateInWindow:sheetParent];
-                         [sheetParent orderOut:nil];
-                         if (nonSheetGrandparent) {
-                           [TopLevelWindowData activateInWindow:nonSheetGrandparent];
-                         }
-                       }];
-#endif
-        } else {
-          // Sheet, that was hard.  No more siblings or parents, going back
-          // to a real window.
-          NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
-          [sheetParent makeKeyAndOrderFront:nil];
-          NS_OBJC_END_TRY_IGNORE_BLOCK;
-        }
-        SendSetZLevelEvent();
-      }
-    } else {
-      // If the window is a popup window with a parent window we need to
-      // unhook it here before ordering it out. When you order out the child
-      // of a window it hides the parent window.
-      if (mWindowType == WindowType::Popup && nativeParentWindow)
-        [nativeParentWindow removeChildWindow:mWindow];
-
-      [mWindow orderOut:nil];
-
-      // If our popup window is a non-native context menu, tell the OS (and
-      // other programs) that a menu has closed.
-      if ([mWindow isKindOfClass:[PopupWindow class]] && [(PopupWindow*)mWindow isContextMenu]) {
-        [[NSDistributedNotificationCenter defaultCenter]
-            postNotificationName:@"com.apple.HIToolbox.endMenuTrackingNotification"
-                          object:@"org.mozilla.gecko.PopupWindow"];
-      }
+    // If the window is a popup window with a parent window we need to
+    // unhook it here before ordering it out. When you order out the child
+    // of a window it hides the parent window.
+    if (mWindowType == WindowType::Popup && nativeParentWindow)
+      [nativeParentWindow removeChildWindow:mWindow];
+
+    [mWindow orderOut:nil];
+
+    // If our popup window is a non-native context menu, tell the OS (and
+    // other programs) that a menu has closed.
+    if ([mWindow isKindOfClass:[PopupWindow class]] && [(PopupWindow*)mWindow isContextMenu]) {
+      [[NSDistributedNotificationCenter defaultCenter]
+          postNotificationName:@"com.apple.HIToolbox.endMenuTrackingNotification"
+                        object:@"org.mozilla.gecko.PopupWindow"];
     }
   }
 
   [mWindow setBeingShown:NO];
 
   NS_OBJC_END_TRY_IGNORE_BLOCK;
 }
 
@@ -2136,59 +1949,22 @@ void nsCocoaWindow::Invalidate(const Lay
 // a drop, to a drag enter/leave, or a drag over event. The actual event
 // is passed in |aMessage| and is passed along to our event hanlder so Gecko
 // knows about it.
 bool nsCocoaWindow::DragEvent(unsigned int aMessage, mozilla::gfx::Point aMouseGlobal,
                               UInt16 aKeyModifiers) {
   return false;
 }
 
-NS_IMETHODIMP nsCocoaWindow::SendSetZLevelEvent() {
-  nsWindowZ placement = nsWindowZTop;
-  nsCOMPtr<nsIWidget> actualBelow;
-  if (mWidgetListener)
+void nsCocoaWindow::SendSetZLevelEvent() {
+  if (mWidgetListener) {
+    nsWindowZ placement = nsWindowZTop;
+    nsCOMPtr<nsIWidget> actualBelow;
     mWidgetListener->ZLevelChanged(true, &placement, nullptr, getter_AddRefs(actualBelow));
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsCocoaWindow::GetChildSheet(bool aShown, nsIWidget** _retval) {
-  nsIWidget* child = GetFirstChild();
-
-  while (child) {
-    if (child->GetWindowType() == WindowType::Sheet) {
-      // if it's a sheet, it must be an nsCocoaWindow
-      nsCocoaWindow* cocoaWindow = static_cast<nsCocoaWindow*>(child);
-      if (cocoaWindow->mWindow && ((aShown && [cocoaWindow->mWindow isVisible]) ||
-                                   (!aShown && cocoaWindow->mSheetNeedsShow))) {
-        nsCOMPtr<nsIWidget> widget = cocoaWindow;
-        widget.forget(_retval);
-        return NS_OK;
-      }
-    }
-    child = child->GetNextSibling();
   }
-
-  *_retval = nullptr;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsCocoaWindow::GetRealParent(nsIWidget** parent) {
-  *parent = mParent;
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsCocoaWindow::GetIsSheet(bool* isSheet) {
-  mWindowType == WindowType::Sheet ? * isSheet = true : * isSheet = false;
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsCocoaWindow::GetSheetWindowParent(NSWindow** sheetWindowParent) {
-  *sheetWindowParent = mSheetWindowParent;
-  return NS_OK;
 }
 
 // Invokes callback and ProcessEvent methods on Event Listener object
 nsresult nsCocoaWindow::DispatchEvent(WidgetGUIEvent* event, nsEventStatus& aStatus) {
   aStatus = nsEventStatus_eIgnore;
 
   nsCOMPtr<nsIWidget> kungFuDeathGrip(event->mWidget);
   mozilla::Unused << kungFuDeathGrip;  // Not used within this function
@@ -3030,19 +2806,17 @@ void nsCocoaWindow::CocoaWindowDidResize
 
 - (void)windowDidBecomeKey:(NSNotification*)aNotification {
   NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
 
   RollUpPopups();
   ChildViewMouseTracker::ReEvaluateMouseEnterState();
 
   NSWindow* window = [aNotification object];
-  if ([window isSheet]) [WindowDelegate paintMenubarForWindow:window];
-
-  nsChildView* mainChildView =
+  auto* mainChildView =
       static_cast<nsChildView*>([[(BaseWindow*)window mainChildView] widget]);
   if (mainChildView) {
     if (mainChildView->GetInputContext().IsPasswordEditor()) {
       TextInputHandler::EnableSecureEventInput();
     } else {
       TextInputHandler::EnsureSecureEventInputDisabled();
     }
   }
@@ -3051,22 +2825,16 @@ void nsCocoaWindow::CocoaWindowDidResize
 }
 
 - (void)windowDidResignKey:(NSNotification*)aNotification {
   NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
 
   RollUpPopups(nsIRollupListener::AllowAnimations::No);
 
   ChildViewMouseTracker::ReEvaluateMouseEnterState();
-
-  // If a sheet just resigned key then we should paint the menu bar
-  // for whatever window is now main.
-  NSWindow* window = [aNotification object];
-  if ([window isSheet]) [WindowDelegate paintMenubarForWindow:[NSApp mainWindow]];
-
   TextInputHandler::EnsureSecureEventInputDisabled();
 
   NS_OBJC_END_TRY_IGNORE_BLOCK;
 }
 
 - (void)windowWillMove:(NSNotification*)aNotification {
   RollUpPopups();
 }
@@ -3105,42 +2873,16 @@ void nsCocoaWindow::CocoaWindowDidResize
 
 - (BOOL)windowShouldZoom:(NSWindow*)window toFrame:(NSRect)proposedFrame {
   if (!mHasEverBeenZoomed && [window isZoomed]) return NO;  // See bug 429954.
 
   mHasEverBeenZoomed = YES;
   return YES;
 }
 
-- (NSRect)window:(NSWindow*)window willPositionSheet:(NSWindow*)sheet usingRect:(NSRect)rect {
-  if ([window isKindOfClass:[ToolbarWindow class]]) {
-    rect.origin.y = [(ToolbarWindow*)window sheetAttachmentPosition];
-  }
-  return rect;
-}
-
-#ifdef MOZ_THUNDERBIRD
-- (void)didEndSheet:(NSWindow*)sheet returnCode:(int)returnCode contextInfo:(void*)contextInfo {
-  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
-  // Note: 'contextInfo' (if it is set) is the window that is the parent of
-  // the sheet.  The value of contextInfo is determined in
-  // nsCocoaWindow::Show().  If it's set, 'contextInfo' is always the top-
-  // level window, not another sheet itself.  But 'contextInfo' is nil if
-  // our parent window is also a sheet -- in that case we shouldn't send
-  // the top-level window any activate events (because it's our parent
-  // window that needs to get these events, not the top-level window).
-  [TopLevelWindowData deactivateInWindow:sheet];
-  [sheet orderOut:self];
-  if (contextInfo) [TopLevelWindowData activateInWindow:(NSWindow*)contextInfo];
-
-  NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-#endif
-
 - (void)windowDidChangeBackingProperties:(NSNotification*)aNotification {
   NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
 
   NSWindow* window = (NSWindow*)[aNotification object];
 
   if ([window respondsToSelector:@selector(backingScaleFactor)]) {
     CGFloat oldFactor =
         [[[aNotification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue];
@@ -3787,17 +3529,16 @@ static const NSString* kStateWantsTitleD
   NSRect contentRect = frameRect;
 
   if ((self = [super initWithContentRect:contentRect
                                styleMask:aStyle
                                  backing:aBufferingType
                                    defer:aFlag])) {
     mTitlebarView = nil;
     mUnifiedToolbarHeight = 22.0f;
-    mSheetAttachmentPosition = aChildViewRect.size.height;
     mWindowButtonsRect = NSZeroRect;
     mInitialTitlebarHeight = [self titlebarHeight];
 
     [self setTitlebarAppearsTransparent:YES];
 #if !defined(MAC_OS_VERSION_11_0) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_VERSION_11_0
     if (nsCocoaFeatures::OnBigSurOrLater()) {
 #else
     if (@available(macOS 11.0, *)) {
@@ -4014,24 +3755,16 @@ static bool ShouldShiftByMenubarHeightIn
   [self updateTitlebarView];
 }
 
 - (void)setWantsTitleDrawn:(BOOL)aDrawTitle {
   [super setWantsTitleDrawn:aDrawTitle];
   [self setTitlebarNeedsDisplay];
 }
 
-- (void)setSheetAttachmentPosition:(CGFloat)aY {
-  mSheetAttachmentPosition = aY;
-}
-
-- (CGFloat)sheetAttachmentPosition {
-  return mSheetAttachmentPosition;
-}
-
 - (void)placeWindowButtons:(NSRect)aRect {
   if (!NSEqualRects(mWindowButtonsRect, aRect)) {
     mWindowButtonsRect = aRect;
     [self reflowTitlebarElements];
   }
 }
 
 - (NSRect)windowButtonsRect {
diff --git a/widget/cocoa/nsMenuX.h b/widget/cocoa/nsMenuX.h
--- a/widget/cocoa/nsMenuX.h
+++ b/widget/cocoa/nsMenuX.h
@@ -181,17 +181,18 @@ class nsMenuX final : public nsMenuParen
   already_AddRefed<nsIContent> GetMenuPopupContent();
   void WillInsertChild(const MenuChild& aChild);
   void WillRemoveChild(const MenuChild& aChild);
   void AddMenuChild(MenuChild&& aChild);
   void InsertMenuChild(MenuChild&& aChild);
   void RemoveMenuChild(const MenuChild& aChild);
   mozilla::Maybe<MenuChild> CreateMenuChild(nsIContent* aContent);
   RefPtr<nsMenuItemX> CreateMenuItem(nsIContent* aMenuItemContent);
-  GeckoNSMenu* CreateMenuWithGeckoString(nsString& aMenuTitle);
+  GeckoNSMenu* CreateMenuWithGeckoString(nsString& aMenuTitle,
+                                         bool aShowServices);
   void DidFirePopupShowing();
 
   // Find the index at which aChild needs to be inserted into mMenuChildren such that mMenuChildren
   // remains in correct content order, i.e. the order in mMenuChildren is the same as the order of
   // the DOM children of our <menupopup>.
   size_t FindInsertionIndex(const MenuChild& aChild);
 
   // Calculates the index at which aChild's NSMenuItem should be inserted into our NSMenu.
diff --git a/widget/cocoa/nsMenuX.mm b/widget/cocoa/nsMenuX.mm
--- a/widget/cocoa/nsMenuX.mm
+++ b/widget/cocoa/nsMenuX.mm
@@ -89,20 +89,24 @@ nsMenuX::nsMenuX(nsMenuParentX* aParent,
 
   mMenuDelegate = [[MenuDelegate alloc] initWithGeckoMenu:this];
   mMenuDelegate.menuIsInMenubar = mMenuGroupOwner->GetMenuBar() != nullptr;
 
   if (!nsMenuBarX::sNativeEventTarget) {
     nsMenuBarX::sNativeEventTarget = [[NativeMenuItemTarget alloc] init];
   }
 
+  bool shouldShowServices = false;
   if (mContent->IsElement()) {
     mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::label, mLabel);
+
+    shouldShowServices =
+        mContent->AsElement()->HasAttr(nsGkAtoms::showservicesmenu);
   }
-  mNativeMenu = CreateMenuWithGeckoString(mLabel);
+  mNativeMenu = CreateMenuWithGeckoString(mLabel, shouldShowServices);
 
   // register this menu to be notified when changes are made to our content object
   NS_ASSERTION(mMenuGroupOwner, "No menu owner given, must have one");
   mMenuGroupOwner->RegisterForContentChanges(mContent, this);
 
   mVisible = !nsMenuUtilsX::NodeIsHiddenOrCollapsed(mContent);
 
   NSString* newCocoaLabelString = nsMenuUtilsX::GetTruncatedCocoaLabel(mLabel);
@@ -773,28 +777,33 @@ nsresult nsMenuX::SetEnabled(bool aIsEna
 }
 
 nsresult nsMenuX::GetEnabled(bool* aIsEnabled) {
   NS_ENSURE_ARG_POINTER(aIsEnabled);
   *aIsEnabled = mIsEnabled;
   return NS_OK;
 }
 
-GeckoNSMenu* nsMenuX::CreateMenuWithGeckoString(nsString& aMenuTitle) {
+GeckoNSMenu* nsMenuX::CreateMenuWithGeckoString(nsString& aMenuTitle,
+                                                bool aShowServices) {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   NSString* title = [NSString stringWithCharacters:(UniChar*)aMenuTitle.get()
                                             length:aMenuTitle.Length()];
   GeckoNSMenu* myMenu = [[GeckoNSMenu alloc] initWithTitle:title];
   myMenu.delegate = mMenuDelegate;
 
   // We don't want this menu to auto-enable menu items because then Cocoa
   // overrides our decisions and things get incorrectly enabled/disabled.
   myMenu.autoenablesItems = NO;
 
+  // Only show "Services", "Autofill" and similar entries provided by macOS
+  // if our caller wants them:
+  myMenu.allowsContextMenuPlugIns = aShowServices;
+
   // we used to install Carbon event handlers here, but since NSMenu* doesn't
   // create its underlying MenuRef until just before display, we delay until
   // that happens. Now we install the event handlers when Cocoa notifies
   // us that a menu is about to display - see the Cocoa MenuDelegate class.
 
   return myMenu;
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -387,19 +387,18 @@ static BOOL FrameIsInActiveWindow(nsIFra
   if ([win isSheet]) {
     return [win isKeyWindow];
   }
   return [win isMainWindow] && ![win attachedSheet];
 }
 
 // Toolbar controls and content controls respond to different window
 // activeness states.
-static BOOL IsActive(nsIFrame* aFrame, BOOL aIsToolbarControl) {
-  if (aIsToolbarControl) return [NativeWindowForFrame(aFrame) isMainWindow];
-  return FrameIsInActiveWindow(aFrame);
+static BOOL IsActiveToolbarControl(nsIFrame* aFrame) {
+  return NativeWindowForFrame(aFrame).isMainWindow;
 }
 
 static bool IsInSourceList(nsIFrame* aFrame) {
   for (nsIFrame* frame = aFrame->GetParent(); frame;
        frame = nsLayoutUtils::GetCrossDocParentFrameInProcess(frame)) {
     if (frame->StyleDisplay()->EffectiveAppearance() == StyleAppearance::MozMacSourceList) {
       return true;
     }
@@ -2397,17 +2396,17 @@ Maybe<nsNativeThemeCocoa::WidgetInfo> ns
       return Some(WidgetInfo::Toolbar(isMain));
     }
 
     case StyleAppearance::MozWindowTitlebar: {
       return Nothing();
     }
 
     case StyleAppearance::Statusbar:
-      return Some(WidgetInfo::StatusBar(IsActive(aFrame, YES)));
+      return Some(WidgetInfo::StatusBar(IsActiveToolbarControl(aFrame)));
 
     case StyleAppearance::MenulistButton:
     case StyleAppearance::Menulist: {
       ControlParams controlParams = ComputeControlParams(aFrame, elementState);
       controlParams.pressed = IsOpenButton(aFrame);
       DropdownParams params;
       params.controlParams = controlParams;
       params.pullsDown = false;
diff --git a/widget/cocoa/nsPIWidgetCocoa.idl b/widget/cocoa/nsPIWidgetCocoa.idl
--- a/widget/cocoa/nsPIWidgetCocoa.idl
+++ b/widget/cocoa/nsPIWidgetCocoa.idl
@@ -1,37 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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 "nsISupports.idl"
-
-interface nsIWidget;
-
-[ptr] native NSWindowPtr(NSWindow);
-
-//
-// nsPIWidgetCocoa
-//
-// A private interface (unfrozen, private to the widget implementation) that
-// gives us access to some extra features on a widget/window.
-//
-[uuid(f75ff69e-3a51-419e-bd29-042f804bc2ed)]
-interface nsPIWidgetCocoa : nsISupports
-{
-  void SendSetZLevelEvent();
-
-  // Find the displayed child sheet (if aShown) or a child sheet that
-  // wants to be displayed (if !aShown)
-  nsIWidget GetChildSheet(in boolean aShown);
-
-  // Get the parent widget (if any) StandardCreate() was called with.
-  nsIWidget GetRealParent();
-
-  // If the object implementing this interface is a sheet, this will return the
-  // native NSWindow it is attached to
-  readonly attribute NSWindowPtr sheetWindowParent;
-
-  // True if window is a sheet
-  readonly attribute boolean isSheet;
-
-}; // nsPIWidgetCocoa
diff --git a/widget/cocoa/nsWindowMap.mm b/widget/cocoa/nsWindowMap.mm
--- a/widget/cocoa/nsWindowMap.mm
+++ b/widget/cocoa/nsWindowMap.mm
@@ -160,17 +160,17 @@
 // only child widgets (nsChildView objects)).  (The notification is sent
 // to windowBecameKey: or windowBecameMain: below.)
 //
 // For use with clients that (like Firefox) do use top-level widgets (and
 // have NSWindow delegates of class WindowDelegate).
 + (void)activateInWindow:(NSWindow*)aWindow {
   NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
 
-  WindowDelegate* delegate = (WindowDelegate*)[aWindow delegate];
+  WindowDelegate* delegate = (WindowDelegate*)aWindow.delegate;
   if (!delegate || ![delegate isKindOfClass:[WindowDelegate class]]) return;
 
   if ([delegate toplevelActiveState]) return;
   [delegate sendToplevelActivateEvents];
 
   NS_OBJC_END_TRY_IGNORE_BLOCK;
 }
 
diff --git a/widget/headless/HeadlessWidget.cpp b/widget/headless/HeadlessWidget.cpp
--- a/widget/headless/HeadlessWidget.cpp
+++ b/widget/headless/HeadlessWidget.cpp
@@ -155,20 +155,19 @@ void HeadlessWidget::GetCompositorWidget
     mozilla::widget::CompositorWidgetInitData* aInitData) {
   *aInitData =
       mozilla::widget::HeadlessCompositorWidgetInitData(GetClientSize());
 }
 
 nsIWidget* HeadlessWidget::GetTopLevelWidget() { return mTopLevel; }
 
 void HeadlessWidget::RaiseWindow() {
-  MOZ_ASSERT(mWindowType == WindowType::TopLevel ||
-                 mWindowType == WindowType::Dialog ||
-                 mWindowType == WindowType::Sheet,
-             "Raising a non-toplevel window.");
+  MOZ_ASSERT(
+      mWindowType == WindowType::TopLevel || mWindowType == WindowType::Dialog,
+      "Raising a non-toplevel window.");
 
   // Do nothing if this is the currently active window.
   RefPtr<HeadlessWidget> activeWindow = GetActiveWindow();
   if (activeWindow == this) {
     return;
   }
 
   // Raise the window to the top of the stack.
@@ -199,17 +198,17 @@ void HeadlessWidget::Show(bool aState) {
 
   LOG(("HeadlessWidget::Show [%p] state %d\n", (void*)this, aState));
 
   // Top-level window and dialogs are activated/raised when shown.
   // NB: alwaysontop windows are generally used for peripheral indicators,
   //     so we don't focus them by default.
   if (aState && !mAlwaysOnTop &&
       (mWindowType == WindowType::TopLevel ||
-       mWindowType == WindowType::Dialog || mWindowType == WindowType::Sheet)) {
+       mWindowType == WindowType::Dialog)) {
     RaiseWindow();
   }
 
   ApplySizeModeSideEffects();
 }
 
 bool HeadlessWidget::IsVisible() const { return mVisible; }
 
diff --git a/xpcom/build/BinaryPath.h b/xpcom/build/BinaryPath.h
--- a/xpcom/build/BinaryPath.h
+++ b/xpcom/build/BinaryPath.h
@@ -128,16 +128,56 @@ class BinaryPath {
     } else {
       rv = NS_ERROR_FAILURE;
     }
 
     CFRelease(executableURL);
     return rv;
   }
 
+  static nsresult GetApplicationIni(char aResult[MAXPATHLEN])
+  {
+    // Works even if we're not bundled.
+    CFBundleRef appBundle = CFBundleGetMainBundle();
+    if (!appBundle) {
+      return NS_ERROR_FAILURE;
+    }
+
+    CFURLRef iniURL = CFBundleCopyResourceURL(appBundle, CFSTR("application.ini"),
+                                              NULL, CFSTR("app"));
+    if (!iniURL) {
+      return NS_ERROR_FAILURE;
+    }
+
+    nsresult rv;
+    if (CFURLGetFileSystemRepresentation(iniURL, false, (UInt8*)aResult,
+                                         MAXPATHLEN)) {
+      // Sanitize path in case the app was launched from Terminal via
+      // './firefox' for example.
+      size_t readPos = 0;
+      size_t writePos = 0;
+      while (aResult[readPos] != '\0') {
+        if (aResult[readPos] == '.' && aResult[readPos + 1] == '/') {
+          readPos += 2;
+        } else {
+          aResult[writePos] = aResult[readPos];
+          readPos++;
+          writePos++;
+        }
+      }
+      aResult[writePos] = '\0';
+      rv = NS_OK;
+    } else {
+      rv = NS_ERROR_FAILURE;
+    }
+
+    CFRelease(iniURL);
+    return rv;
+  }
+
 #elif defined(ANDROID)
   static nsresult Get(char aResult[MAXPATHLEN]) {
     // On Android, we use the MOZ_ANDROID_LIBDIR variable that is set by the
     // Java bootstrap code.
     const char* libDir = getenv("MOZ_ANDROID_LIBDIR");
     if (!libDir) {
       return NS_ERROR_FAILURE;
     }
@@ -283,16 +323,29 @@ class BinaryPath {
     if (NS_FAILED(Get(path))) {
       return nullptr;
     }
     UniqueFreePtr<char> result;
     result.reset(strdup(path));
     return result;
   }
 
+#if defined(XP_MACOSX)
+  static UniqueFreePtr<char> GetApplicationIni()
+  {
+    char path[MAXPATHLEN];
+    if (NS_FAILED(GetApplicationIni(path))) {
+      return nullptr;
+    }
+    UniqueFreePtr<char> result;
+    result.reset(strdup(path));
+    return result;
+  }
+#endif
+
 #ifdef MOZILLA_INTERNAL_API
   static nsresult GetFile(nsIFile** aResult) {
     nsCOMPtr<nsIFile> lf;
 #  ifdef XP_WIN
     wchar_t exePath[MAXPATHLEN];
     nsresult rv = GetW(exePath);
 #  else
     char exePath[MAXPATHLEN];
diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py
--- a/xpcom/ds/StaticAtoms.py
+++ b/xpcom/ds/StaticAtoms.py
@@ -1141,16 +1141,17 @@ STATIC_ATOMS = [
     Atom("self", "self"),
     Atom("seltype", "seltype"),
     Atom("setcookie", "set-cookie"),
     Atom("setter", "setter"),
     Atom("shadow", "shadow"),
     Atom("shape", "shape"),
     Atom("show", "show"),
     Atom("showcaret", "showcaret"),
+    Atom("showservicesmenu", "showservicesmenu"),
     Atom("sibling", "sibling"),
     Atom("simple", "simple"),
     Atom("simp_chinese_formal", "simp-chinese-formal"),
     Atom("simp_chinese_informal", "simp-chinese-informal"),
     Atom("single", "single"),
     Atom("size", "size"),
     Atom("sizes", "sizes"),
     Atom("sizemode", "sizemode"),
diff --git a/xpfe/appshell/nsAppShellService.cpp b/xpfe/appshell/nsAppShellService.cpp
--- a/xpfe/appshell/nsAppShellService.cpp
+++ b/xpfe/appshell/nsAppShellService.cpp
@@ -590,32 +590,16 @@ nsresult nsAppShellService::JustCreateTo
                      nsIWebBrowserChrome::CHROME_TITLEBAR |
                      nsIWebBrowserChrome::CHROME_STATUSBAR;
   if (widgetInitData.mWindowType == widget::WindowType::Dialog &&
       ((aChromeMask & pipMask) == pipMask) && !(aChromeMask & barMask)) {
     widgetInitData.mPIPWindow = true;
   }
 #endif
 
-#ifdef XP_MACOSX
-  // Mac OS X sheet support
-  // Adding CHROME_OPENAS_CHROME to sheetMask makes modal windows opened from
-  // nsGlobalWindow::ShowModalDialog() be dialogs (not sheets), while modal
-  // windows opened from nsPromptService::DoDialog() still are sheets.  This
-  // fixes bmo bug 395465 (see nsCocoaWindow::StandardCreate() and
-  // nsCocoaWindow::SetModal()).
-  uint32_t sheetMask = nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
-                       nsIWebBrowserChrome::CHROME_MODAL |
-                       nsIWebBrowserChrome::CHROME_OPENAS_CHROME;
-  if (parent && (parent != mHiddenWindow) &&
-      ((aChromeMask & sheetMask) == sheetMask)) {
-    widgetInitData.mWindowType = widget::WindowType::Sheet;
-  }
-#endif
-
 #if defined(XP_WIN)
   if (widgetInitData.mWindowType == widget::WindowType::TopLevel ||
       widgetInitData.mWindowType == widget::WindowType::Dialog)
     widgetInitData.mClipChildren = true;
 #endif
 
   // note default chrome overrides other OS chrome settings, but
   // not internal chrome
