summaryrefslogtreecommitdiffstats
path: root/widget/cocoa/nsCocoaWindow.mm
diff options
context:
space:
mode:
Diffstat (limited to 'widget/cocoa/nsCocoaWindow.mm')
-rw-r--r--widget/cocoa/nsCocoaWindow.mm119
1 files changed, 80 insertions, 39 deletions
diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
index b6d94ea94..b141e80b0 100644
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -35,6 +35,7 @@
#include "nsIWidgetListener.h"
#include "nsIPresShell.h"
#include "nsScreenCocoa.h"
+#include "VibrancyManager.h"
#include "gfxPlatform.h"
#include "qcms.h"
@@ -128,6 +129,7 @@ nsCocoaWindow::nsCocoaWindow()
, mIsAnimationSuppressed(false)
, mInReportMoveEvent(false)
, mInResize(false)
+, mAlwaysOnTop(false)
, mNumModalDescendents(0)
{
if ([NSWindow respondsToSelector:@selector(setAllowsAutomaticWindowTabbing:)]) {
@@ -302,12 +304,14 @@ nsCocoaWindow::Create(nsIWidget* aParent,
if (mWindowType == eWindowType_popup) {
if (aInitData->mMouseTransparent) {
[mWindow setIgnoresMouseEvents:YES];
+ } else {
+ [mWindow setIgnoresMouseEvents:NO];
}
// now we can convert newBounds to device pixels for the window we created,
// as the child view expects a rect expressed in the dev pix of its parent
LayoutDeviceIntRect devRect =
RoundedToInt(newBounds * GetDesktopToDeviceScale());
- return CreatePopupContentView(devRect);
+ return CreatePopupContentView(devRect, aInitData);
}
mIsAnimationSuppressed = aInitData->mIsAnimationSuppressed;
@@ -456,6 +460,11 @@ nsresult nsCocoaWindow::CreateNativeWindow(const NSRect &aRect,
mWindow = [[windowClass alloc] initWithContentRect:contentRect styleMask:features
backing:NSBackingStoreBuffered defer:YES];
+ // Make sure that window titles don't leak to disk in private browsing mode
+ // due to macOS' resume feature.
+ [mWindow setRestorable:NO];
+ [mWindow disableSnapshotRestoration];
+
// setup our notification delegate. Note that setDelegate: does NOT retain.
mDelegate = [[WindowDelegate alloc] initWithGeckoWindow:this];
[mWindow setDelegate:mDelegate];
@@ -474,7 +483,6 @@ nsresult nsCocoaWindow::CreateNativeWindow(const NSRect &aRect,
if (mWindowType == eWindowType_popup) {
SetPopupWindowLevel();
- [mWindow setHasShadow:YES];
[mWindow setBackgroundColor:[NSColor clearColor]];
[mWindow setOpaque:NO];
} else {
@@ -483,6 +491,13 @@ nsresult nsCocoaWindow::CreateNativeWindow(const NSRect &aRect,
[mWindow setOpaque:YES];
}
+ NSWindowCollectionBehavior newBehavior = [mWindow collectionBehavior];
+ if (mAlwaysOnTop) {
+ [mWindow setLevel:NSFloatingWindowLevel];
+ newBehavior |= NSWindowCollectionBehaviorCanJoinAllSpaces;
+ }
+ [mWindow setCollectionBehavior:newBehavior];
+
[mWindow setContentMinSize:NSMakeSize(60, 60)];
[mWindow disableCursorRects];
@@ -499,7 +514,8 @@ nsresult nsCocoaWindow::CreateNativeWindow(const NSRect &aRect,
}
NS_IMETHODIMP
-nsCocoaWindow::CreatePopupContentView(const LayoutDeviceIntRect &aRect)
+nsCocoaWindow::CreatePopupContentView(const LayoutDeviceIntRect &aRect,
+ nsWidgetInitData* aInitData)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
@@ -512,13 +528,16 @@ nsCocoaWindow::CreatePopupContentView(const LayoutDeviceIntRect &aRect)
nsIWidget* thisAsWidget = static_cast<nsIWidget*>(this);
nsresult rv = mPopupContentView->Create(thisAsWidget, nullptr, aRect,
- nullptr);
+ aInitData);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
- ChildView* newContentView = (ChildView*)mPopupContentView->GetNativeData(NS_NATIVE_WIDGET);
- [mWindow setContentView:newContentView];
+ NSView* contentView = [mWindow contentView];
+ ChildView* childView = (ChildView*)mPopupContentView->GetNativeData(NS_NATIVE_WIDGET);
+ [childView setFrame:NSZeroRect];
+ [childView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+ [contentView addSubview:childView];
return NS_OK;
@@ -757,6 +776,13 @@ NS_IMETHODIMP nsCocoaWindow::Show(bool bState)
(NSWindow*)parentWidget->GetNativeData(NS_NATIVE_WINDOW) : nil;
if (bState && !mBounds.IsEmpty()) {
+ // Don't try to show a popup when the parent isn't visible or is minimized.
+ if (mWindowType == eWindowType_popup && nativeParentWindow) {
+ if (![nativeParentWindow isVisible] || [nativeParentWindow isMiniaturized]) {
+ return NS_ERROR_FAILURE;
+ }
+ }
+
if (mPopupContentView) {
// Ensure our content view is visible. We never need to hide it.
mPopupContentView->Show(true);
@@ -2790,12 +2816,6 @@ static NSMutableSet *gSwizzledFrameViewClasses = nil;
- (void)_addKnownSubview:(NSView*)aView positioned:(NSWindowOrderingMode)place relativeTo:(NSView*)otherView;
@end
-// Available on 10.10
-@interface NSWindow(PrivateCornerMaskMethod)
- - (id)_cornerMask;
- - (void)_cornerMaskChanged;
-@end
-
#if !defined(MAC_OS_X_VERSION_10_10) || \
MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_10
@@ -2816,6 +2836,10 @@ static NSMutableSet *gSwizzledFrameViewClasses = nil;
#endif
+@interface NSView(NSVisualEffectViewSetMaskImage)
+- (void)setMaskImage:(NSImage*)image;
+@end
+
@interface BaseWindow(Private)
- (void)removeTrackingArea;
- (void)cursorUpdated:(NSEvent*)aEvent;
@@ -2825,25 +2849,6 @@ static NSMutableSet *gSwizzledFrameViewClasses = nil;
@implementation BaseWindow
-- (id)_cornerMask
-{
- if (!mUseMenuStyle) {
- return [super _cornerMask];
- }
-
- CGFloat radius = 4.0f;
- NSEdgeInsets insets = { 5, 5, 5, 5 };
- NSSize maskSize = { 12, 12 };
- NSImage* maskImage = [NSImage imageWithSize:maskSize flipped:YES drawingHandler:^BOOL(NSRect dstRect) {
- NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:dstRect xRadius:radius yRadius:radius];
- [[NSColor colorWithDeviceWhite:1.0 alpha:1.0] set];
- [path fill];
- return YES;
- }];
- [maskImage setCapInsets:insets];
- return maskImage;
-}
-
// The frame of a window is implemented using undocumented NSView subclasses.
// We offset the window buttons by overriding the methods _closeButtonOrigin
// and _fullScreenButtonOrigin on these frame view classes. The class which is
@@ -2916,14 +2921,54 @@ static NSMutableSet *gSwizzledFrameViewClasses = nil;
return self;
}
+// Returns an autoreleased NSImage.
+static NSImage*
+GetMenuMaskImage()
+{
+ CGFloat radius = 4.0f;
+ NSEdgeInsets insets = { 5, 5, 5, 5 };
+ NSSize maskSize = { 12, 12 };
+ NSImage* maskImage = [NSImage imageWithSize:maskSize flipped:YES drawingHandler:^BOOL(NSRect dstRect) {
+ NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:dstRect xRadius:radius yRadius:radius];
+ [[NSColor colorWithDeviceWhite:1.0 alpha:1.0] set];
+ [path fill];
+ return YES;
+ }];
+ [maskImage setCapInsets:insets];
+ return maskImage;
+}
+
+- (void)swapOutChildViewWrapper:(NSView*)aNewWrapper
+{
+ [aNewWrapper setFrame:[[self contentView] frame]];
+ NSView* childView = [[self mainChildView] retain];
+ [childView removeFromSuperview];
+ [aNewWrapper addSubview:childView];
+ [childView release];
+ [super setContentView:aNewWrapper];
+}
+
- (void)setUseMenuStyle:(BOOL)aValue
{
- if (aValue != mUseMenuStyle) {
- mUseMenuStyle = aValue;
- if ([self respondsToSelector:@selector(_cornerMaskChanged)]) {
- [self _cornerMaskChanged];
+ if (!VibrancyManager::SystemSupportsVibrancy()) {
+ return;
+ }
+
+ if (aValue && !mUseMenuStyle) {
+ // Turn on rounded corner masking.
+ NSView* effectView = VibrancyManager::CreateEffectView(VibrancyType::MENU, YES);
+ if ([effectView respondsToSelector:@selector(setMaskImage:)]) {
+ [effectView setMaskImage:GetMenuMaskImage()];
}
+ [self swapOutChildViewWrapper:effectView];
+ [effectView release];
+ } else if (mUseMenuStyle && !aValue) {
+ // Turn off rounded corner masking.
+ NSView* wrapper = [[NSView alloc] initWithFrame:NSZeroRect];
+ [self swapOutChildViewWrapper:wrapper];
+ [wrapper release];
}
+ mUseMenuStyle = aValue;
}
- (void)setBeingShown:(BOOL)aValue
@@ -3081,10 +3126,6 @@ static const NSString* kStateCollectionBehavior = @"collectionBehavior";
- (ChildView*)mainChildView
{
NSView *contentView = [self contentView];
- // A PopupWindow's contentView is a ChildView object.
- if ([contentView isKindOfClass:[ChildView class]]) {
- return (ChildView*)contentView;
- }
NSView* lastView = [[contentView subviews] lastObject];
if ([lastView isKindOfClass:[ChildView class]]) {
return (ChildView*)lastView;