feat: Add native popover UI for macos, p=#12456

This commit is contained in:
mr. m
2026-02-21 23:07:30 +01:00
committed by GitHub
parent 52d03f43ef
commit e919e723c7
15 changed files with 563 additions and 209 deletions

View File

@@ -20,3 +20,10 @@
cpptype: uint32_t
mirror: always
type: static
# Enable native popovers on macOS, we've sent this patch to upstream
# but we enable it by default anyways in case they decide to not use it,
# or to disable it by default.
- name: widget.macos.native-popovers
value: true
condition: "defined(XP_MACOSX)"

View File

@@ -59,6 +59,15 @@ def main():
output_file = os.path.join(OUTPUT_DIR, "firefox", f"{name}.patch")
print(f"Processing Phabricator patch: {phab_id} -> {output_file}")
download_phab_patch(phab_id, output_file)
replaces = patch.get("replaces", {})
for replace in replaces.keys():
value = replaces[replace]
with open(output_file, 'r') as f:
content = f.read()
if replace not in content:
die(f"Replace string '{replace}' not found in {output_file}")
with open(output_file, 'w') as f:
f.write(content.replace(replace, value))
expected_files.add(output_file)
elif patch.get("type") == "local":
print(f"Local patch: {patch.get('path')}")

View File

@@ -2,7 +2,7 @@
# 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/.
<panel id="zen-folder-tabs-popup" type="arrow" orient="vertical" side="left">
<panel id="zen-folder-tabs-popup" hidepopovertail="true" type="arrow" orient="vertical" side="left">
<hbox class="tabs-list-header" flex="1">
<image class="zen-folder-tabs-list-search-icon" src="chrome://global/skin/icons/search-glass.svg"/>
<html:input id="zen-folder-tabs-list-search"

View File

@@ -2,7 +2,14 @@
# 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/.
<panel flip="side" type="arrow" popupalign="center" orient="vertical" id="PanelUI-zen-gradient-generator" position="bottomright topright" mainview="true" side="left">
<panel flip="side" type="arrow"
opupalign="center"
orient="vertical"
id="PanelUI-zen-gradient-generator"
position="bottomright topright"
mainview="true"
hidepopovertail="true"
side="left">
<panelmultiview id="PanelUI-zen-gradient-generator-multiview" mainViewId="PanelUI-zen-gradient-generator-view">
<panelview id="PanelUI-zen-gradient-generator-view" class="PanelUI-subView zen-theme-picker" role="document" mainview-with-header="true" has-custom-header="true">
<hbox class="zen-theme-picker-gradient">

View File

@@ -1,12 +0,0 @@
diff --git a/devtools/server/actors/animation-type-longhand.js b/devtools/server/actors/animation-type-longhand.js
index f6cd7b4599ab74fbdc301f316fd7ecc2e2eb841c..8279a943803ca75fe0a231606ae26a678fcc0b60 100644
--- a/devtools/server/actors/animation-type-longhand.js
+++ b/devtools/server/actors/animation-type-longhand.js
@@ -342,6 +342,7 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
"transform-origin",
"translate",
"-moz-window-transform",
+ "-zen-window-transform-origin",
"-webkit-line-clamp",
]),
],

View File

@@ -1,50 +0,0 @@
diff --git a/dom/base/use_counter_metrics.yaml b/dom/base/use_counter_metrics.yaml
index 84aa1ac40d01bc73f5039bd5c589c3fdf3a6c8ce..090f9e1eef46ed45c0a98a73013ad59faeb3414f 100644
--- a/dom/base/use_counter_metrics.yaml
+++ b/dom/base/use_counter_metrics.yaml
@@ -22106,6 +22106,22 @@ use.counter.css.page:
send_in_pings:
- use-counters
+ css_zen_window_transform_origin:
+ type: counter
+ description: >
+ Whether a page used the CSS property -zen-window-transform-origin.
+ Compare against `use.counter.top_level_content_documents_destroyed`
+ to calculate the rate.
+ bugs:
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
+ data_reviews:
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
+ notification_emails:
+ - dom-core@mozilla.com
+ expires: never
+ send_in_pings:
+ - use-counters
+
css_transform_origin:
type: counter
description: >
@@ -34076,6 +34092,22 @@ use.counter.css.doc:
send_in_pings:
- use-counters
+ css_zen_window_transform_origin:
+ type: counter
+ description: >
+ Whether a document used the CSS property -zen-window-transform-origin.
+ Compare against `use.counter.content_documents_destroyed`
+ to calculate the rate.
+ bugs:
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
+ data_reviews:
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
+ notification_emails:
+ - dom-core@mozilla.com
+ expires: never
+ send_in_pings:
+ - use-counters
+
css_transform_origin:
type: counter
description: >

View File

@@ -0,0 +1,527 @@
diff --git a/browser/components/customizableui/content/panelUI.inc.xhtml b/browser/components/customizableui/content/panelUI.inc.xhtml
--- a/browser/components/customizableui/content/panelUI.inc.xhtml
+++ b/browser/components/customizableui/content/panelUI.inc.xhtml
@@ -276,10 +276,11 @@
role="group"
type="arrow"
hidden="true"
flip="slide"
position="bottomright topright"
+ hidepopovertail="true"
noautofocus="true">
<panelmultiview id="appMenu-multiView" mainViewId="appMenu-mainView"
viewCacheId="appMenu-viewCache">
</panelmultiview>
</panel>
diff --git a/layout/xul/nsMenuPopupFrame.h b/layout/xul/nsMenuPopupFrame.h
--- a/layout/xul/nsMenuPopupFrame.h
+++ b/layout/xul/nsMenuPopupFrame.h
@@ -516,18 +516,10 @@
// Move the popup to the position specified in its |left| and |top|
// attributes.
void MoveToAttributePosition();
- // Returns true if the popup should try to remain at the same relative
- // location as the anchor while it is open. If the anchor becomes hidden
- // either directly or indirectly because a parent popup or other element
- // is no longer visible, or a parent deck page is changed, the popup hides
- // as well. The second variation also sets the anchor rectangle, relative to
- // the popup frame.
- bool ShouldFollowAnchor() const;
-
nsIFrame* GetAnchorFrame() const;
public:
/**
* Return whether the popup direction should be RTL.
@@ -536,10 +528,18 @@
*
* Return whether the popup direction should be RTL.
*/
bool IsDirectionRTL() const;
+ // Returns true if the popup should try to remain at the same relative
+ // location as the anchor while it is open. If the anchor becomes hidden
+ // either directly or indirectly because a parent popup or other element
+ // is no longer visible, or a parent deck page is changed, the popup hides
+ // as well. The second variation also sets the anchor rectangle, relative to
+ // the popup frame.
+ bool ShouldFollowAnchor() const;
+
bool ShouldFollowAnchor(nsRect& aRect);
// Returns parent menu widget for submenus that are in the same
// frame hierarchy, it's needed for Linux/Wayland which demands
// strict popup windows hierarchy.
diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml
--- a/modules/libpref/init/StaticPrefList.yaml
+++ b/modules/libpref/init/StaticPrefList.yaml
@@ -19311,10 +19311,19 @@
value: true
mirror: always
#ifdef XP_MACOSX
+# If true, use native NSPopover for arrow panel popups (type="arrow") on macOS
+# Someone like Zen browser will use this pref by default, so
+# please take this into account when you change the behavior of
+# native popover. Note: Only panels with type="arrow" will use NSPopover.
+- name: widget.macos.native-popovers
+ type: RelaxedAtomicBool
+ value: false
+ mirror: always
+
# Whether to shift by the menubar height on fullscreen mode.
# 0: never
# 1: always
# 2: auto (tries to detect when it is needed)
- name: widget.macos.shift-by-menubar-on-fullscreen
diff --git a/toolkit/themes/shared/global-shared.css b/toolkit/themes/shared/global-shared.css
--- a/toolkit/themes/shared/global-shared.css
+++ b/toolkit/themes/shared/global-shared.css
@@ -100,10 +100,19 @@
--panel-padding: var(--arrowpanel-padding);
--panel-shadow-margin: var(--arrowpanel-shadow-margin);
--menuitem-border-radius: var(--arrowpanel-menuitem-border-radius);
--menuitem-padding: var(--arrowpanel-menuitem-padding);
--menuitem-margin: var(--arrowpanel-menuitem-margin);
+
+ /* stylelint-disable-next-line media-query-no-invalid */
+ @media -moz-pref("widget.macos.native-popovers") and (-moz-platform: macos) {
+ background-color: transparent;
+ --panel-background: transparent;
+ --panel-shadow: none;
+ --panel-border-color: transparent;
+ --panel-shadow-margin: 0px;
+ }
}
/* Lightweight theme roots */
:root[lwtheme] {
diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h
--- a/widget/cocoa/nsCocoaWindow.h
+++ b/widget/cocoa/nsCocoaWindow.h
@@ -133,23 +133,38 @@
// to create its "frame view".
+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask;
@end
-@interface PopupWindow : BaseWindow {
+@interface PopupWindow : BaseWindow <NSPopoverDelegate> {
@private
BOOL mIsContextMenu;
+
+ // NSPopover support for native appearance
+ NSPopover* mPopover;
+ NSViewController* mPopoverViewController;
+ BOOL mUsePopover;
}
- (id)initWithContentRect:(NSRect)contentRect
styleMask:(NSUInteger)styleMask
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)deferCreation;
- (BOOL)isContextMenu;
- (void)setIsContextMenu:(BOOL)flag;
- (BOOL)canBecomeMainWindow;
+// NSPopover support
+- (void)setAllowPopover;
+- (BOOL)usePopover;
+- (void)showPopoverRelativeToRect:(NSRect)positioningRect
+ ofView:(NSView*)positioningView
+ preferredEdge:(NSRectEdge)preferredEdge
+ hiddenAnchor:(BOOL)hiddenAnchor;
+- (void)closePopover;
+- (void)updatePopoverContent;
+
@end
@interface BorderlessWindow : BaseWindow {
}
@@ -201,10 +216,13 @@
typedef nsIWidget Inherited;
public:
nsCocoaWindow();
+ // Check if this window should use NSPopover for popup/menu display
+ bool ShouldUseNSPopover() const;
+
[[nodiscard]] nsresult Create(nsIWidget* aParent, const DesktopIntRect& aRect,
const InitData&) override;
[[nodiscard]] nsresult Create(nsIWidget* aParent,
const LayoutDeviceIntRect& aRect,
diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -5,10 +5,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsCocoaWindow.h"
#include "nsArrayUtils.h"
+#include "nsMenuPopupFrame.h"
+#include "mozilla/dom/XULPopupElement.h"
#include "MOZDynamicCursor.h"
#include "nsIAppStartup.h"
#include "nsIDOMWindowUtils.h"
#include "nsILocalFileMac.h"
#include "CocoaCompositorWidget.h"
@@ -4958,10 +4960,15 @@
if (mWindowType == WindowType::Popup) {
SetPopupWindowLevel();
mWindow.backgroundColor = NSColor.clearColor;
mWindow.opaque = NO;
+ // Enable NSPopover for panel popup types when preference is enabled
+ if ([mWindow isKindOfClass:[PopupWindow class]] && ShouldUseNSPopover()) {
+ [(PopupWindow*)mWindow setAllowPopover];
+ }
+
// When multiple spaces are in use and the browser is assigned to a
// particular space, override the "Assign To" space and display popups on
// the active space. Does not work with multiple displays. See
// NeedsRecreateToReshow() for multi-display with multi-space workaround.
mWindow.collectionBehavior = mWindow.collectionBehavior |
@@ -5163,10 +5170,56 @@
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
bool nsCocoaWindow::IsRunningAppModal() { return [NSApp _isRunningAppModal]; }
+static NSRectEdge AlignmentPositionToNSRectEdge(int8_t aPosition) {
+ switch (aPosition) {
+ case POPUPPOSITION_BEFORESTART:
+ case POPUPPOSITION_BEFOREEND:
+ return NSRectEdgeMaxY;
+ case POPUPPOSITION_AFTERSTART:
+ case POPUPPOSITION_AFTEREND:
+ return NSRectEdgeMinY;
+ case POPUPPOSITION_STARTBEFORE:
+ case POPUPPOSITION_STARTAFTER:
+ return NSRectEdgeMaxX;
+ case POPUPPOSITION_ENDBEFORE:
+ case POPUPPOSITION_ENDAFTER:
+ return NSRectEdgeMinX;
+ default:
+ return NSRectEdgeMinY;
+ }
+}
+
+static void SyncPopoverBounds(NSPopover* aPopover,
+ nsMenuPopupFrame* aPopupFrame) {
+ if (!aPopover || !aPopover.shown) {
+ return;
+ }
+ NSWindow* popoverWindow = aPopover.contentViewController.view.window;
+ if (!popoverWindow) {
+ return;
+ }
+
+ // Synchronizing the internal bounds with the actual bounds
+ // that macOS calculated
+ NSView* contentView = popoverWindow.contentView;
+ NSRect contentFrame = [contentView convertRect:contentView.bounds toView:nil];
+ NSRect windowFrame = [popoverWindow convertRectToScreen:contentFrame];
+ NSScreen* screen = [popoverWindow screen];
+
+ if (screen) {
+ // Inverting the y axis. We convert from a cocoa point to a css point
+ CGFloat screenHeight = screen.frame.size.height;
+ mozilla::CSSPoint cssPos(
+ windowFrame.origin.x,
+ screenHeight - windowFrame.origin.y - windowFrame.size.height);
+ aPopupFrame->MoveTo(cssPos, false);
+ }
+}
+
// Hide or show this window
void nsCocoaWindow::Show(bool aState) {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
if (!mWindow) {
@@ -5227,10 +5280,58 @@
mWindow.contentView.needsDisplay = YES;
if (!nativeParentWindow || mPopupLevel != PopupLevel::Parent) {
[mWindow orderFront:nil];
}
NS_OBJC_END_TRY_IGNORE_BLOCK;
+ nsMenuPopupFrame* popupFrame = GetPopupFrame();
+ if ([mWindow isKindOfClass:[PopupWindow class]] &&
+ [(PopupWindow*)mWindow usePopover] && popupFrame &&
+ popupFrame->ShouldFollowAnchor()) {
+ if (nativeParentWindow) {
+ NSRectEdge preferredEdge =
+ AlignmentPositionToNSRectEdge(popupFrame->GetAlignmentPosition());
+ nsRect anchorRectAppUnits = popupFrame->GetUntransformedAnchorRect();
+ mozilla::CSSIntRect cssAnchorRect =
+ mozilla::CSSIntRect::FromAppUnitsRounded(anchorRectAppUnits);
+ mozilla::LayoutDeviceIntRect layoutRect =
+ mozilla::LayoutDeviceIntRect::FromUnknownRect(
+ (cssAnchorRect.ToUnknownRect()));
+ mozilla::DesktopIntRect popupAnchorRectScaled =
+ mozilla::DesktopIntRect::RoundOut(layoutRect.X(), layoutRect.Y(),
+ layoutRect.Width(),
+ layoutRect.Height());
+ // Taking the now correctly scaled anchor rect and turning it into a
+ // gecko rect this accounts for the y-axis inversion that cocoa needs,
+ // as the origin is in the bottom left. This rect is in screen space
+ NSRect cocoaScreenRect =
+ nsCocoaUtils::GeckoRectToCocoaRect(popupAnchorRectScaled);
+ // We take the screen space rect and convert it to window space
+ // coordinates, as NSPopover requires the coordinates to be in view
+ // space and inside the view. If the coordinates are outside our view,
+ // the popover will fail silently
+ NSRect windowRect =
+ [nativeParentWindow convertRectFromScreen:cocoaScreenRect];
+ NSView* parentView = [nativeParentWindow contentView];
+ // We take the window space rect and convert it to view space for the
+ // specific parent view
+ NSRect positioningRect = [parentView convertRect:windowRect
+ fromView:nil];
+ BOOL shouldHideAnchor = NO;
+ if (auto popoverElement = GetPopupFrame()) {
+ auto& element = popoverElement->PopupElement();
+ if (element.GetBoolAttr(nsGkAtoms::hidepopovertail)) {
+ shouldHideAnchor = YES;
+ }
+ }
+ [(PopupWindow*)mWindow showPopoverRelativeToRect:positioningRect
+ ofView:parentView
+ preferredEdge:preferredEdge
+ hiddenAnchor:shouldHideAnchor];
+ SyncPopoverBounds([(PopupWindow*)mWindow popover], popupFrame);
+ }
+ return;
+ }
// If our popup window is a non-native context menu, tell the OS (and
// other programs) that a menu has opened. This is how the OS knows to
// close other programs' context menus when ours open.
if ([mWindow isKindOfClass:[PopupWindow class]] &&
[(PopupWindow*)mWindow isContextMenu]) {
@@ -5301,10 +5402,15 @@
// of a window it hides the parent window.
if (mWindowType == WindowType::Popup && nativeParentWindow) {
[nativeParentWindow removeChildWindow:mWindow];
}
+ // Handle NSPopover hiding or traditional window hiding
+ if ([mWindow isKindOfClass:[PopupWindow class]] &&
+ [(PopupWindow*)mWindow usePopover]) {
+ [(PopupWindow*)mWindow closePopover];
+ }
[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]) {
@@ -5351,10 +5457,17 @@
return false;
}
return nsIWidget::ShouldUseOffMainThreadCompositing();
}
+bool nsCocoaWindow::ShouldUseNSPopover() const {
+ // Use NSPopover for panel popups when the preference is enabled
+ // But not for detached popups - they should use traditional window logic
+ return mWindowType == WindowType::Popup && mPopupType == PopupType::Panel &&
+ mozilla::StaticPrefs::widget_macos_native_popovers();
+}
+
TransparencyMode nsCocoaWindow::GetTransparencyMode() {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
return mWindow.isOpaque ? TransparencyMode::Opaque
: TransparencyMode::Transparent;
@@ -6313,10 +6426,20 @@
// We ignore aRepaint -- we have to call display:YES, otherwise the
// title bar doesn't immediately get repainted and is displayed in
// the wrong place, leading to a visual jump.
[mWindow setFrame:newFrame display:YES];
+ if (ShouldUseNSPopover() && [(PopupWindow*)mWindow usePopover]) {
+ [(PopupWindow*)mWindow updatePopoverContent];
+ // A popover won't resize by setting the frame
+ // as it's size is calculated based on the content size
+ // Therefor the content size has to be changed as well
+ NSSize contentSize = NSMakeSize(aWidth, aHeight);
+ [[(PopupWindow*)mWindow popover] setContentSize:contentSize];
+ SyncPopoverBounds([(PopupWindow*)mWindow popover], GetPopupFrame());
+ }
+
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
void nsCocoaWindow::Resize(const DesktopRect& aRect, bool aRepaint) {
DoResize(aRect.x, aRect.y, aRect.width, aRect.height, aRepaint, false);
@@ -8277,18 +8400,27 @@
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)deferCreation {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
mIsContextMenu = false;
+ mPopover = nil;
+ mPopoverViewController = nil;
+ mUsePopover = NO;
return [super initWithContentRect:contentRect
styleMask:styleMask
backing:bufferingType
defer:deferCreation];
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
}
+- (void)dealloc {
+ [mPopover release];
+ [mPopoverViewController release];
+ [super dealloc];
+}
+
// Override the private API _backdropBleedAmount. This determines how much the
// desktop wallpaper contributes to the vibrancy backdrop.
// Return 0 in order to match what the system does for sheet windows and
// _NSPopoverWindows.
- (CGFloat)_backdropBleedAmount {
@@ -8342,10 +8474,120 @@
- (void)setIsContextMenu:(BOOL)flag {
mIsContextMenu = flag;
}
+- (void)setAllowPopover {
+ mUsePopover = YES;
+
+ if (!mPopover) {
+ mPopover = [[NSPopover alloc] init];
+
+ // Use NSPopoverBehaviorApplicationDefined to prevent auto-closing
+ // when other popovers are opened, and to respect the disable_autohide
+ // preference
+ mPopover.behavior = NSPopoverBehaviorApplicationDefined;
+ mPopover.delegate = self;
+
+ // Create view controller that will contain our content view
+ mPopoverViewController = [[NSViewController alloc] init];
+
+ NSView* contentView = self.contentView;
+ if (contentView) {
+ // Ensure the content view is properly configured
+ [contentView
+ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+
+ mPopoverViewController.view = contentView;
+ mPopover.contentViewController = mPopoverViewController;
+
+ // Set popover size to match our window content size
+ NSRect contentRect = [contentView frame];
+ if (contentRect.size.width > 0 && contentRect.size.height > 0) {
+ [mPopover setContentSize:contentRect.size];
+ }
+ }
+ }
+}
+
+- (BOOL)usePopover {
+ return mUsePopover && !mIsContextMenu;
+}
+
+- (void)showPopoverRelativeToRect:(NSRect)positioningRect
+ ofView:(NSView*)positioningView
+ preferredEdge:(NSRectEdge)preferredEdge
+ hiddenAnchor:(BOOL)hiddenAnchor {
+ NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
+ if (!mPopover) {
+ return;
+ }
+
+ // Close existing popover if it's already shown
+ if (mPopover.shown) {
+ [mPopover close];
+ }
+
+ // Force content update before showing
+ [self updatePopoverContent];
+
+ if (mPopoverViewController.view) {
+ mPopover.behavior = NSPopoverBehaviorApplicationDefined;
+
+ // This is a hidden API that prevents the popover from showing its arrow
+ // pointing to the anchor.
+ [mPopover setShouldHideAnchor:hiddenAnchor];
+
+ [mPopover showRelativeToRect:positioningRect
+ ofView:positioningView
+ preferredEdge:preferredEdge];
+ }
+
+ NSWindow* popoverWindow = mPopover.contentViewController.view.window;
+ [popoverWindow setAcceptsMouseMovedEvents:YES];
+
+ NS_OBJC_END_TRY_IGNORE_BLOCK;
+}
+
+- (void)closePopover {
+ NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
+
+ if (mPopover && mPopover.shown) {
+ [mPopover close];
+ }
+
+ NS_OBJC_END_TRY_IGNORE_BLOCK;
+}
+
+- (void)updatePopoverContent {
+ NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
+
+ if (mPopover && mPopoverViewController) {
+ NSView* contentView = self.contentView;
+ if (contentView) {
+ // Ensure proper hit testing for hover events
+ [contentView setWantsLayer:YES];
+ [contentView setAcceptsTouchEvents:YES];
+
+ // Update the popover content view to match current window content
+ mPopoverViewController.view = contentView;
+
+ // Update popover size to match content
+ NSRect contentRect = [contentView frame];
+ if (contentRect.size.width > 0 && contentRect.size.height > 0) {
+ mPopover.contentSize = contentRect.size;
+ }
+ }
+ }
+
+ NS_OBJC_END_TRY_IGNORE_BLOCK;
+}
+
+- (NSPopover*)popover {
+ return mPopover;
+}
+
- (BOOL)canBecomeMainWindow {
// This is overriden because the default is 'yes' when a titlebar is present.
return NO;
}
diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py
--- a/xpcom/ds/StaticAtoms.py
+++ b/xpcom/ds/StaticAtoms.py
@@ -535,10 +535,11 @@
Atom("hgroup", "hgroup"),
Atom("hidden", "hidden"),
Atom("hidechrome", "hidechrome"),
Atom("hidecolumnpicker", "hidecolumnpicker"),
Atom("hidetitlebarseparator", "hidetitlebarseparator"),
+ Atom("hidepopovertail", "hidepopovertail"),
Atom("hide_popover", "hide-popover"),
Atom("high", "high"),
Atom("highest", "highest"),
Atom("horizontal", "horizontal"),
Atom("hover", "hover"),

View File

@@ -7,6 +7,16 @@
"id": "D279007",
"name": "Fix MacOS Crash on Shutdown Firefox 149"
},
{
"type": "phabricator",
"id": "D284084",
"name": "Native MacOS popovers",
"replaces": {
// The patch we sent was for firefox 149, but we are currently in 148, so theres
// a conflict in the patch. See https://bugzilla.mozilla.org/show_bug.cgi?id=2015354
"overridden": "overriden"
}
},
{
"type": "local",
"path": "firefox/no_liquid_glass_icon.patch"

View File

@@ -1,16 +0,0 @@
diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp
index 67ae256038fae1d61824d58f5e544f65505a1ed5..b6e70376f1d9230df9beb01216092969e9322c8f 100644
--- a/layout/generic/nsIFrame.cpp
+++ b/layout/generic/nsIFrame.cpp
@@ -11973,6 +11973,11 @@ gfx::Matrix nsIFrame::ComputeWidgetTransform() const {
gfx::Matrix4x4 matrix = nsStyleTransformMatrix::ReadTransforms(
uiReset->mMozWindowTransform, refBox, float(appUnitsPerDevPixel));
+ const StyleTransformOrigin& origin = uiReset->mWindowTransformOrigin;
+ Point transformOrigin = nsStyleTransformMatrix::Convert2DPosition(
+ origin.horizontal, origin.vertical, refBox, appUnitsPerDevPixel);
+ matrix.ChangeBasis(Point3D(transformOrigin.x, transformOrigin.y, 0));
+
gfx::Matrix result2d;
if (!matrix.CanDraw2D(&result2d)) {
// FIXME: It would be preferable to reject non-2D transforms at parse time.

View File

@@ -1,22 +0,0 @@
diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp
index e5883b377afee44626a2928a97205382e6d07e40..57ae3b0567fbd7afbcfb60a2cd662f611339e5ad 100644
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -3287,6 +3287,9 @@ nsStyleUIReset::nsStyleUIReset()
mWindowShadow(StyleWindowShadow::Auto),
mWindowOpacity(1.0),
mMozWindowInputRegionMargin(StyleLength::Zero()),
+ mWindowTransformOrigin{LengthPercentage::FromPercentage(0.5),
+ LengthPercentage::FromPercentage(0.5),
+ {0.}},
mTransitions(
nsStyleAutoArray<StyleTransition>::WITH_SINGLE_INITIAL_ELEMENT),
mTransitionTimingFunctionCount(1),
@@ -3331,6 +3334,7 @@ nsStyleUIReset::nsStyleUIReset(const nsStyleUIReset& aSource)
mWindowOpacity(aSource.mWindowOpacity),
mMozWindowInputRegionMargin(aSource.mMozWindowInputRegionMargin),
mMozWindowTransform(aSource.mMozWindowTransform),
+ mWindowTransformOrigin(aSource.mWindowTransformOrigin),
mTransitions(aSource.mTransitions.Clone()),
mTransitionTimingFunctionCount(aSource.mTransitionTimingFunctionCount),
mTransitionDurationCount(aSource.mTransitionDurationCount),

View File

@@ -1,12 +0,0 @@
diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h
index 14c24446880b7342f6c194bb068f5fd54657ec85..8a0067b2694029242a0fbe6d806b1dd0153f1715 100644
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2094,6 +2094,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset {
// The margin of the window region that should be transparent to events.
mozilla::StyleLength mMozWindowInputRegionMargin;
mozilla::StyleTransform mMozWindowTransform;
+ mozilla::StyleTransformOrigin mWindowTransformOrigin;
nsStyleAutoArray<mozilla::StyleTransition> mTransitions;
// The number of elements in mTransitions that are not from repeating

View File

@@ -1,12 +0,0 @@
diff --git a/layout/style/test/ListCSSProperties.cpp b/layout/style/test/ListCSSProperties.cpp
index 1870bfc3735255f2d41356b00dc52faf95d9d9f2..59ad4fb11c7d48d9ba84dceef09a67a42b486ed8 100644
--- a/layout/style/test/ListCSSProperties.cpp
+++ b/layout/style/test/ListCSSProperties.cpp
@@ -110,6 +110,7 @@ const char* gInaccessibleProperties[] = {
"-moz-window-opacity", // chrome-only internal properties
"-moz-window-transform", // chrome-only internal properties
"-moz-window-shadow", // chrome-only internal properties
+ "-zen-window-transform-origin", // chrome-only internal properties
};
inline int is_inaccessible(const char* aPropName) {

View File

@@ -1,23 +0,0 @@
diff --git a/servo/components/style/properties/longhands/ui.mako.rs b/servo/components/style/properties/longhands/ui.mako.rs
index 24e1e1b7e8fe4d4b70aaa4f5f022500c3dcfcbae..1176bf5d12885b4d96abb2f72288f6c631072578 100644
--- a/servo/components/style/properties/longhands/ui.mako.rs
+++ b/servo/components/style/properties/longhands/ui.mako.rs
@@ -284,6 +284,18 @@ ${helpers.predefined_type(
affects="",
)}
+${helpers.predefined_type(
+ "-zen-window-transform-origin",
+ "TransformOrigin",
+ "computed::TransformOrigin::initial_value()",
+ engines="gecko",
+ gecko_ffi_name="mWindowTransformOrigin",
+ boxed=True,
+ spec="None (Nonstandard internal property)",
+ enabled_in="chrome",
+ affects="overflow",
+)}
+
${helpers.predefined_type(
"animation-fill-mode",
"AnimationFillMode",

View File

@@ -1,5 +1,5 @@
diff --git a/toolkit/themes/shared/popup.css b/toolkit/themes/shared/popup.css
index c2618b86d7e8bb71f9f7f71ef9916c8140ca1ead..96a602f9cbfb77ee0a52151ce8ccf7ba17cf5c43 100644
index c2618b86d7e8bb71f9f7f71ef9916c8140ca1ead..9e2006015e22f1ac043c46066c4c9a85fe053a21 100644
--- a/toolkit/themes/shared/popup.css
+++ b/toolkit/themes/shared/popup.css
@@ -22,8 +22,8 @@ panel {
@@ -13,24 +13,3 @@ index c2618b86d7e8bb71f9f7f71ef9916c8140ca1ead..96a602f9cbfb77ee0a52151ce8ccf7ba
-moz-window-input-region-margin: var(--panel-shadow-margin);
margin: calc(-1 * var(--panel-shadow-margin));
@@ -143,11 +143,7 @@ panel[type="arrow"] {
-moz-window-transform,
-moz-window-opacity;
@media not (prefers-reduced-motion) {
- -moz-window-transform: translateY(-70px);
-
- &:where([side="bottom"]) {
- -moz-window-transform: translateY(70px);
- }
+ -moz-window-transform: scale(0);
}
/* Only do the fade-in animation on pre-Big Sur to avoid missing shadows on
* Big Sur+, see bug 1672091. */
@@ -161,7 +157,6 @@ panel[type="arrow"] {
}
&[animate="cancel"] {
- -moz-window-transform: none;
transform: none;
}

View File

@@ -3,38 +3,6 @@
* 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/.
*/
panel[type="arrow"] {
@media (-moz-platform: macos) and (-moz-panel-animations) {
&[side="bottom"] {
/* Animate from the bottom */
-zen-window-transform-origin: 0 100%;
}
&[side="left"] {
/* Animate from the left and center */
-zen-window-transform-origin: 0 50%;
}
&[side="right"] {
/* Animate from the right */
-zen-window-transform-origin: 100% 50%;
}
:root[zen-right-side="true"] & {
/* Animate from the right */
-zen-window-transform-origin: 100% 0;
&[side="bottom"] {
/* Animate from the bottom right */
-zen-window-transform-origin: 100% 100%;
}
&[side="left"] {
/* Animate from the right */
-zen-window-transform-origin: 100% 50%;
}
&[side="right"] {
/* Animate from the right */
-zen-window-transform-origin: 100% 50%;
}
}
}
}
menupopup,
panel[type="arrow"]:not(#feature-callout) {
@@ -62,12 +30,6 @@ panel[type="arrow"]:not(#feature-callout) {
}
@media (-moz-platform: macos) {
appearance: auto !important;
-moz-default-appearance: menupopup;
/* We set the default background here, rather than on ::part(content),
* because otherwise it'd interfere with the native look. Non-native-looking
* popups should get their background via --panel-background */
background-color: Menu;
--panel-shadow-margin: 0px !important;
--panel-background: transparent !important;
--panel-border-color: transparent;