summaryrefslogtreecommitdiffstats
path: root/widget/cocoa
diff options
context:
space:
mode:
Diffstat (limited to 'widget/cocoa')
-rw-r--r--widget/cocoa/MacThemeGeometryType.h4
-rw-r--r--widget/cocoa/ScreenHelperCocoa.mm28
-rw-r--r--widget/cocoa/TextInputHandler.mm68
-rw-r--r--widget/cocoa/VibrancyManager.h1
-rw-r--r--widget/cocoa/VibrancyManager.mm33
-rw-r--r--widget/cocoa/ViewRegion.mm53
-rw-r--r--widget/cocoa/moz.build6
-rw-r--r--widget/cocoa/nsChildView.mm162
-rw-r--r--widget/cocoa/nsCocoaWindow.h241
-rw-r--r--widget/cocoa/nsCocoaWindow.mm809
-rw-r--r--widget/cocoa/nsLookAndFeel.h14
-rw-r--r--widget/cocoa/nsLookAndFeel.mm103
-rw-r--r--widget/cocoa/nsNativeThemeCocoa.h4
-rw-r--r--widget/cocoa/nsNativeThemeCocoa.mm70
-rw-r--r--widget/cocoa/nsNativeThemeColors.h37
-rw-r--r--widget/cocoa/nsPIWidgetCocoa.idl37
-rw-r--r--widget/cocoa/nsWindowMap.mm54
17 files changed, 485 insertions, 1239 deletions
diff --git a/widget/cocoa/MacThemeGeometryType.h b/widget/cocoa/MacThemeGeometryType.h
index 4691dbdec2..91879503e1 100644
--- a/widget/cocoa/MacThemeGeometryType.h
+++ b/widget/cocoa/MacThemeGeometryType.h
@@ -7,11 +7,7 @@
enum MacThemeGeometryType {
eThemeGeometryTypeTitlebar = 1,
- eThemeGeometryTypeToolbar,
- eThemeGeometryTypeToolbox,
eThemeGeometryTypeWindowButtons,
- eThemeGeometryTypeMenu,
- eThemeGeometryTypeTooltip,
};
#endif
diff --git a/widget/cocoa/ScreenHelperCocoa.mm b/widget/cocoa/ScreenHelperCocoa.mm
index 57e1313320..2f1408e345 100644
--- a/widget/cocoa/ScreenHelperCocoa.mm
+++ b/widget/cocoa/ScreenHelperCocoa.mm
@@ -9,6 +9,7 @@
#import <Cocoa/Cocoa.h>
#include "mozilla/Logging.h"
+#include "nsCocoaFeatures.h"
#include "nsCocoaUtils.h"
#include "nsObjCExceptions.h"
@@ -109,6 +110,26 @@ static already_AddRefed<Screen> MakeScreen(NSScreen* aScreen) {
pixelDepth = MAX_REPORTED_PIXEL_DEPTH;
}
+ // What's the maximum color component value this screen can display? This
+ // is a reasonable stand-in for measuring peak brightness.
+ CGFloat componentValueMax =
+ aScreen.maximumPotentialExtendedDynamicRangeColorComponentValue;
+
+ // Should we treat this as HDR? Based on spec at
+ // https://drafts.csswg.org/mediaqueries-5/#dynamic-range, we'll consider it
+ // HDR if it has pixel depth greater than 24, and if has high peak brightness,
+ // which we measure by checking if it can represent component values greater
+ // than 1.0.
+ //
+ // Also, on HDR screens, users may want to force SDR by setting a different
+ // colorspace, for example by using the "Photography (P3 D65)" preset. In that
+ // case, componentValueMax will be 1.0 and we want to treat the display as
+ // SDR.
+ bool isHDR = pixelDepth > 24 && componentValueMax > 1.0;
+
+ // Double-check HDR against the platform capabilities.
+ isHDR &= nsCocoaFeatures::OnBigSurOrLater();
+
float dpi = 96.0f;
CGDirectDisplayID displayID =
[[[aScreen deviceDescription] objectForKey:@"NSScreenNumber"] intValue];
@@ -125,9 +146,10 @@ static already_AddRefed<Screen> MakeScreen(NSScreen* aScreen) {
// Getting the refresh rate is a little hard on OS X. We could use
// CVDisplayLinkGetNominalOutputVideoRefreshPeriod, but that's a little
// involved. Ideally we could query it from vsync. For now, we leave it out.
- RefPtr<Screen> screen = new Screen(rect, availRect, pixelDepth, pixelDepth, 0,
- contentsScaleFactor, defaultCssScaleFactor,
- dpi, Screen::IsPseudoDisplay::No);
+ RefPtr<Screen> screen =
+ new Screen(rect, availRect, pixelDepth, pixelDepth, 0,
+ contentsScaleFactor, defaultCssScaleFactor, dpi,
+ Screen::IsPseudoDisplay::No, Screen::IsHDR(isHDR));
return screen.forget();
NS_OBJC_END_TRY_BLOCK_RETURN(nullptr);
diff --git a/widget/cocoa/TextInputHandler.mm b/widget/cocoa/TextInputHandler.mm
index 1d96a3ce82..046f1c46be 100644
--- a/widget/cocoa/TextInputHandler.mm
+++ b/widget/cocoa/TextInputHandler.mm
@@ -10,6 +10,7 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/AutoRestore.h"
+#include "mozilla/MacStringHelpers.h"
#include "mozilla/MiscEvents.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/StaticPrefs_intl.h"
@@ -321,13 +322,13 @@ static const char* GetCharacters(const nsAString& aString) {
}
// the result will be freed automatically by cocoa.
- NSString* result = nsCocoaUtils::ToNSString(escapedStr);
+ NSString* result = XPCOMStringToNSString(escapedStr);
return [result UTF8String];
}
static const char* GetCharacters(const NSString* aString) {
nsAutoString str;
- nsCocoaUtils::GetStringForNSString(aString, str);
+ CopyNSStringToXPCOMString(aString, str);
return GetCharacters(str);
}
@@ -835,7 +836,7 @@ bool TISInputSourceWrapper::GetStringProperty(const CFStringRef aKey,
nsAString& aStr) {
CFStringRef str;
GetStringProperty(aKey, str);
- nsCocoaUtils::GetStringForNSString((const NSString*)str, aStr);
+ CopyNSStringToXPCOMString((const NSString*)str, aStr);
return !aStr.IsEmpty();
}
@@ -883,8 +884,7 @@ bool TISInputSourceWrapper::GetPrimaryLanguage(nsAString& aPrimaryLanguage) {
NS_ENSURE_TRUE(mInputSource, false);
CFStringRef primaryLanguage;
NS_ENSURE_TRUE(GetPrimaryLanguage(primaryLanguage), false);
- nsCocoaUtils::GetStringForNSString((const NSString*)primaryLanguage,
- aPrimaryLanguage);
+ CopyNSStringToXPCOMString((const NSString*)primaryLanguage, aPrimaryLanguage);
return !aPrimaryLanguage.IsEmpty();
}
@@ -985,7 +985,7 @@ void TISInputSourceWrapper::ComputeInsertStringForCharCode(
} else {
// If the caller isn't sure what string will be input, let's use
// characters of NSEvent.
- nsCocoaUtils::GetStringForNSString([aNativeKeyEvent characters], aResult);
+ CopyNSStringToXPCOMString([aNativeKeyEvent characters], aResult);
}
// If control key is pressed and the eventChars is a non-printable control
@@ -1156,8 +1156,8 @@ void TISInputSourceWrapper::InitKeyEvent(NSEvent* aNativeKeyEvent,
// non-ASCII capable layout to ASCII capable, or from Dvorak to QWERTY.
// KeyboardEvent.key value should be the switched layout's character.
else if (aKeyEvent.IsMeta()) {
- nsCocoaUtils::GetStringForNSString([aNativeKeyEvent characters],
- aKeyEvent.mKeyValue);
+ CopyNSStringToXPCOMString([aNativeKeyEvent characters],
+ aKeyEvent.mKeyValue);
}
// If control key is pressed, some keys may produce printable character via
// [aNativeKeyEvent characters]. Otherwise, translate input character of
@@ -1188,8 +1188,8 @@ void TISInputSourceWrapper::InitKeyEvent(NSEvent* aNativeKeyEvent,
[aNativeKeyEvent modifierFlags]);
aKeyEvent.mKeyValue = TranslateToChar(nativeKeyCode, state, kbType);
} else {
- nsCocoaUtils::GetStringForNSString([aNativeKeyEvent characters],
- aKeyEvent.mKeyValue);
+ CopyNSStringToXPCOMString([aNativeKeyEvent characters],
+ aKeyEvent.mKeyValue);
// If the key value is empty, the event may be a dead key event.
// If TranslateToChar() returns non-zero value, that means that
// the key may input a character with different dead key state.
@@ -1207,8 +1207,8 @@ void TISInputSourceWrapper::InitKeyEvent(NSEvent* aNativeKeyEvent,
if (aKeyEvent.mKeyNameIndex == KEY_NAME_INDEX_USE_STRING &&
(aKeyEvent.mKeyValue.IsEmpty() ||
IsControlChar(aKeyEvent.mKeyValue[0]))) {
- nsCocoaUtils::GetStringForNSString(
- [aNativeKeyEvent charactersIgnoringModifiers], aKeyEvent.mKeyValue);
+ CopyNSStringToXPCOMString([aNativeKeyEvent charactersIgnoringModifiers],
+ aKeyEvent.mKeyValue);
// But don't expose it if it's a control character.
if (!aKeyEvent.mKeyValue.IsEmpty() &&
IsControlChar(aKeyEvent.mKeyValue[0])) {
@@ -1243,7 +1243,7 @@ void TISInputSourceWrapper::WillDispatchKeyboardEvent(
if (MOZ_LOG_TEST(gKeyLog, LogLevel::Info)) {
nsAutoString chars;
- nsCocoaUtils::GetStringForNSString([aNativeKeyEvent characters], chars);
+ CopyNSStringToXPCOMString([aNativeKeyEvent characters], chars);
NS_ConvertUTF16toUTF8 utf8Chars(chars);
char16_t uniChar = static_cast<char16_t>(aKeyEvent.mCharCode);
MOZ_LOG(
@@ -2428,7 +2428,7 @@ void TextInputHandler::InsertText(NSString* aString,
NSRange selectedRange = SelectedRange();
nsAutoString str;
- nsCocoaUtils::GetStringForNSString(aString, str);
+ CopyNSStringToXPCOMString(aString, str);
AutoInsertStringClearer clearer(currentKeyEvent);
if (currentKeyEvent) {
@@ -3849,7 +3849,7 @@ bool IMEInputHandler::DispatchCompositionCommitEvent(
mSelectedRange.location += aCommitString->Length();
} else if (mIMECompositionString) {
nsAutoString commitString;
- nsCocoaUtils::GetStringForNSString(mIMECompositionString, commitString);
+ CopyNSStringToXPCOMString(mIMECompositionString, commitString);
mSelectedRange.location += commitString.Length();
}
mSelectedRange.length = 0;
@@ -4037,7 +4037,7 @@ void IMEInputHandler::InsertTextAsCommittingComposition(
}
nsString str;
- nsCocoaUtils::GetStringForNSString(aString, str);
+ CopyNSStringToXPCOMString(aString, str);
if (!IsIMEComposing()) {
MOZ_DIAGNOSTIC_ASSERT(!str.IsEmpty());
@@ -4171,7 +4171,7 @@ void IMEInputHandler::SetMarkedText(NSAttributedString* aAttrString,
}
nsString str;
- nsCocoaUtils::GetStringForNSString([aAttrString string], str);
+ CopyNSStringToXPCOMString([aAttrString string], str);
mMarkedRange.length = str.Length();
@@ -4272,7 +4272,7 @@ NSAttributedString* IMEInputHandler::GetAttributedSubstringFromRange(
if (MOZ_LOG_TEST(gIMELog, LogLevel::Info)) {
nsAutoString str;
- nsCocoaUtils::GetStringForNSString(nsstr, str);
+ CopyNSStringToXPCOMString(nsstr, str);
MOZ_LOG(gIMELog, LogLevel::Info,
("%p IMEInputHandler::GetAttributedSubstringFromRange, "
"computed with mIMECompositionString (result string=\"%s\")",
@@ -5051,18 +5051,17 @@ nsresult TextInputHandlerBase::SynthesizeNativeKeyEvent(
bool sendFlagsChangedEvent = IsModifierKey(aNativeKeyCode);
NSEventType eventType =
sendFlagsChangedEvent ? NSEventTypeFlagsChanged : NSEventTypeKeyDown;
- NSEvent* downEvent =
- [NSEvent keyEventWithType:eventType
- location:NSMakePoint(0, 0)
- modifierFlags:modifierFlags
- timestamp:0
- windowNumber:windowNumber
- context:nil
- characters:nsCocoaUtils::ToNSString(aCharacters)
- charactersIgnoringModifiers:nsCocoaUtils::ToNSString(
- aUnmodifiedCharacters)
- isARepeat:NO
- keyCode:aNativeKeyCode];
+ NSEvent* downEvent = [NSEvent
+ keyEventWithType:eventType
+ location:NSMakePoint(0, 0)
+ modifierFlags:modifierFlags
+ timestamp:0
+ windowNumber:windowNumber
+ context:nil
+ characters:XPCOMStringToNSString(aCharacters)
+ charactersIgnoringModifiers:XPCOMStringToNSString(aUnmodifiedCharacters)
+ isARepeat:NO
+ keyCode:aNativeKeyCode];
NSEvent* upEvent = sendFlagsChangedEvent
? nil
@@ -5232,7 +5231,7 @@ bool TextInputHandlerBase::SetSelection(NSRange& aRange) {
return false;
}
nsAutoString nativeChars;
- nsCocoaUtils::GetStringForNSString([aNativeEvent characters], nativeChars);
+ CopyNSStringToXPCOMString([aNativeEvent characters], nativeChars);
// this is not character inputting event, simply.
if (nativeChars.IsEmpty() ||
@@ -5314,7 +5313,7 @@ void TextInputHandlerBase::KeyEventState::InitKeyEvent(
if (!mInsertedString.IsEmpty()) {
nsAutoString unhandledString;
GetUnhandledString(unhandledString);
- NSString* unhandledNSString = nsCocoaUtils::ToNSString(unhandledString);
+ NSString* unhandledNSString = XPCOMStringToNSString(unhandledString);
// If the key event's some characters were already handled by
// InsertString() calls, we need to create a dummy event which doesn't
// include the handled characters.
@@ -5345,7 +5344,7 @@ void TextInputHandlerBase::KeyEventState::GetUnhandledString(
return;
}
nsAutoString characters;
- nsCocoaUtils::GetStringForNSString([mKeyEvent characters], characters);
+ CopyNSStringToXPCOMString([mKeyEvent characters], characters);
if (characters.IsEmpty()) {
return;
}
@@ -5373,8 +5372,7 @@ TextInputHandlerBase::AutoInsertStringClearer::~AutoInsertStringClearer() {
// If inserting string is a part of characters of the event,
// we should record it as inserted string.
nsAutoString characters;
- nsCocoaUtils::GetStringForNSString([mState->mKeyEvent characters],
- characters);
+ CopyNSStringToXPCOMString([mState->mKeyEvent characters], characters);
nsAutoString insertedString(mState->mInsertedString);
insertedString += *mState->mInsertString;
if (StringBeginsWith(characters, insertedString)) {
diff --git a/widget/cocoa/VibrancyManager.h b/widget/cocoa/VibrancyManager.h
index d431540830..c70ec60a3b 100644
--- a/widget/cocoa/VibrancyManager.h
+++ b/widget/cocoa/VibrancyManager.h
@@ -24,6 +24,7 @@ namespace mozilla {
enum class VibrancyType {
TOOLTIP,
MENU,
+ TITLEBAR,
};
/**
diff --git a/widget/cocoa/VibrancyManager.mm b/widget/cocoa/VibrancyManager.mm
index e9cfcc3be0..6062acb931 100644
--- a/widget/cocoa/VibrancyManager.mm
+++ b/widget/cocoa/VibrancyManager.mm
@@ -9,6 +9,7 @@
#import <objc/message.h>
#include "nsChildView.h"
+#include "mozilla/StaticPrefs_widget.h"
using namespace mozilla;
@@ -30,18 +31,34 @@ static NSVisualEffectState VisualEffectStateForVibrancyType(
// Tooltip and menu windows are never "key", so we need to tell the
// vibrancy effect to look active regardless of window state.
return NSVisualEffectStateActive;
- default:
- return NSVisualEffectStateFollowsWindowActiveState;
+ case VibrancyType::TITLEBAR:
+ break;
}
+ return NSVisualEffectStateFollowsWindowActiveState;
}
static NSVisualEffectMaterial VisualEffectMaterialForVibrancyType(
- VibrancyType aType, BOOL* aOutIsEmphasized) {
+ VibrancyType aType) {
switch (aType) {
case VibrancyType::TOOLTIP:
return (NSVisualEffectMaterial)NSVisualEffectMaterialToolTip;
case VibrancyType::MENU:
return NSVisualEffectMaterialMenu;
+ case VibrancyType::TITLEBAR:
+ return NSVisualEffectMaterialTitlebar;
+ }
+}
+
+static NSVisualEffectBlendingMode VisualEffectBlendingModeForVibrancyType(
+ VibrancyType aType) {
+ switch (aType) {
+ case VibrancyType::TOOLTIP:
+ case VibrancyType::MENU:
+ return NSVisualEffectBlendingModeBehindWindow;
+ case VibrancyType::TITLEBAR:
+ return StaticPrefs::widget_macos_titlebar_blend_mode_behind_window()
+ ? NSVisualEffectBlendingModeBehindWindow
+ : NSVisualEffectBlendingModeWithinWindow;
}
}
@@ -53,11 +70,9 @@ static NSVisualEffectMaterial VisualEffectMaterialForVibrancyType(
self.appearance = nil;
self.state = VisualEffectStateForVibrancyType(mType);
-
- BOOL isEmphasized = NO;
- self.material = VisualEffectMaterialForVibrancyType(mType, &isEmphasized);
- self.emphasized = isEmphasized;
-
+ self.material = VisualEffectMaterialForVibrancyType(mType);
+ self.blendingMode = VisualEffectBlendingModeForVibrancyType(mType);
+ self.emphasized = NO;
return self;
}
@@ -89,7 +104,7 @@ bool VibrancyManager::UpdateVibrantRegion(
}
auto& vr = *mVibrantRegions.GetOrInsertNew(uint32_t(aType));
return vr.UpdateRegion(aRegion, mCoordinateConverter, mContainerView, ^() {
- return this->CreateEffectView(aType);
+ return CreateEffectView(aType);
});
}
diff --git a/widget/cocoa/ViewRegion.mm b/widget/cocoa/ViewRegion.mm
index 62e76d2df8..5b275a18a3 100644
--- a/widget/cocoa/ViewRegion.mm
+++ b/widget/cocoa/ViewRegion.mm
@@ -12,8 +12,8 @@
using namespace mozilla;
ViewRegion::~ViewRegion() {
- for (size_t i = 0; i < mViews.Length(); i++) {
- [mViews[i] removeFromSuperview];
+ for (NSView* view : mViews) {
+ [view removeFromSuperview];
}
}
@@ -33,34 +33,31 @@ bool ViewRegion::UpdateRegion(const LayoutDeviceIntRegion& aRegion,
nsTArray<NSView*> viewsToRecycle = std::move(mViews);
// The mViews array is now empty.
- size_t i = 0;
- for (auto iter = aRegion.RectIter();
- !iter.Done() || i < viewsToRecycle.Length(); i++) {
- if (!iter.Done()) {
- NSView* view = nil;
- NSRect rect = aCoordinateConverter.DevPixelsToCocoaPoints(iter.Get());
- if (i < viewsToRecycle.Length()) {
- view = viewsToRecycle[i];
- } else {
- view = aViewCreationCallback();
- [aContainerView addSubview:view];
-
- // Now that the view is in the view hierarchy, it'll be kept alive by
- // its superview, so we can drop our reference.
- [view release];
- }
- if (!NSEqualRects(rect, [view frame])) {
- [view setFrame:rect];
- }
- [view setNeedsDisplay:YES];
- mViews.AppendElement(view);
- iter.Next();
+ size_t viewsRecycled = 0;
+ for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) {
+ NSRect rect = aCoordinateConverter.DevPixelsToCocoaPoints(iter.Get());
+ NSView* view = nil;
+ if (viewsRecycled < viewsToRecycle.Length()) {
+ view = viewsToRecycle[viewsRecycled++];
} else {
- // Our new region is made of fewer rects than the old region, so we can
- // remove this view. We only have a weak reference to it, so removing it
- // from the view hierarchy will release it.
- [viewsToRecycle[i] removeFromSuperview];
+ view = aViewCreationCallback();
+ [aContainerView addSubview:view];
+
+ // Now that the view is in the view hierarchy, it'll be kept alive by
+ // its superview, so we can drop our reference.
+ [view release];
}
+ if (!NSEqualRects(rect, view.frame)) {
+ view.frame = rect;
+ }
+ view.needsDisplay = YES;
+ mViews.AppendElement(view);
+ }
+ for (NSView* view : Span(viewsToRecycle).From(viewsRecycled)) {
+ // Our new region is made of fewer rects than the old region, so we can
+ // remove this view. We only have a weak reference to it, so removing it
+ // from the view hierarchy will release it.
+ [view removeFromSuperview];
}
mRegion = aRegion;
diff --git a/widget/cocoa/moz.build b/widget/cocoa/moz.build
index ddb402e2cc..d0939d34c7 100644
--- a/widget/cocoa/moz.build
+++ b/widget/cocoa/moz.build
@@ -11,12 +11,6 @@ with Files("**"):
with Files("*TextInput*"):
BUG_COMPONENT = ("Core", "DOM: UI Events & Focus Handling")
-XPIDL_SOURCES += [
- "nsPIWidgetCocoa.idl",
-]
-
-XPIDL_MODULE = "widget_cocoa"
-
EXPORTS += [
"DesktopBackgroundImage.h",
"MediaHardwareKeysEventSourceMac.h",
diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm
index 79919ba69a..d3241a983f 100644
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -473,17 +473,20 @@ void* nsChildView::GetNativeData(uint32_t aDataType) {
#pragma mark -
void nsChildView::SuppressAnimation(bool aSuppress) {
- GetAppWindowWidget()->SuppressAnimation(aSuppress);
+ if (nsCocoaWindow* widget = GetAppWindowWidget()) {
+ widget->SuppressAnimation(aSuppress);
+ }
}
bool nsChildView::IsVisible() const {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
if (!mVisible) {
- return mVisible;
+ return false;
}
- if (!GetAppWindowWidget()->IsVisible()) {
+ nsCocoaWindow* widget = GetAppWindowWidget();
+ if (NS_WARN_IF(!widget) || !widget->IsVisible()) {
return false;
}
@@ -739,11 +742,11 @@ void nsChildView::Resize(double aWidth, double aHeight, bool aRepaint) {
mBounds.height = height;
ManipulateViewWithoutNeedingDisplay(mView, ^{
- [mView setFrame:DevPixelsToCocoaPoints(mBounds)];
+ mView.frame = DevPixelsToCocoaPoints(mBounds);
});
if (mVisible && aRepaint) {
- [[mView pixelHostingView] setNeedsDisplay:YES];
+ mView.pixelHostingView.needsDisplay = YES;
}
ReportSizeEvent();
@@ -779,11 +782,11 @@ void nsChildView::Resize(double aX, double aY, double aWidth, double aHeight,
}
ManipulateViewWithoutNeedingDisplay(mView, ^{
- [mView setFrame:DevPixelsToCocoaPoints(mBounds)];
+ mView.frame = DevPixelsToCocoaPoints(mBounds);
});
if (mVisible && aRepaint) {
- [[mView pixelHostingView] setNeedsDisplay:YES];
+ mView.pixelHostingView.needsDisplay = YES;
}
if (isMoving) {
@@ -1070,10 +1073,8 @@ nsresult nsChildView::SynthesizeNativeTouchpadDoubleTap(
bool nsChildView::SendEventToNativeMenuSystem(NSEvent* aEvent) {
bool handled = false;
- nsCocoaWindow* widget = GetAppWindowWidget();
- if (widget) {
- nsMenuBarX* mb = widget->GetMenuBar();
- if (mb) {
+ if (nsCocoaWindow* widget = GetAppWindowWidget()) {
+ if (nsMenuBarX* mb = widget->GetMenuBar()) {
// Check if main menu wants to handle the event.
handled = mb->PerformKeyEquivalent(aEvent);
}
@@ -1157,10 +1158,8 @@ nsresult nsChildView::ActivateNativeMenuItemAt(const nsAString& indexString) {
nsresult nsChildView::ForceUpdateNativeMenuAt(const nsAString& indexString) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
- nsCocoaWindow* widget = GetAppWindowWidget();
- if (widget) {
- nsMenuBarX* mb = widget->GetMenuBar();
- if (mb) {
+ if (nsCocoaWindow* widget = GetAppWindowWidget()) {
+ if (nsMenuBarX* mb = widget->GetMenuBar()) {
if (indexString.IsEmpty())
mb->ForceNativeMenuReload();
else
@@ -1689,33 +1688,6 @@ RefPtr<layers::NativeLayerRoot> nsChildView::GetNativeLayerRoot() {
return mNativeLayerRoot;
}
-static int32_t FindTitlebarBottom(
- const nsTArray<nsIWidget::ThemeGeometry>& aThemeGeometries,
- int32_t aWindowWidth) {
- int32_t titlebarBottom = 0;
- for (auto& g : aThemeGeometries) {
- if (g.mType == eThemeGeometryTypeTitlebar && g.mRect.X() <= 0 &&
- g.mRect.XMost() >= aWindowWidth && g.mRect.Y() <= 0) {
- titlebarBottom = std::max(titlebarBottom, g.mRect.YMost());
- }
- }
- return titlebarBottom;
-}
-
-static int32_t FindUnifiedToolbarBottom(
- const nsTArray<nsIWidget::ThemeGeometry>& aThemeGeometries,
- int32_t aWindowWidth, int32_t aTitlebarBottom) {
- int32_t unifiedToolbarBottom = aTitlebarBottom;
- for (uint32_t i = 0; i < aThemeGeometries.Length(); ++i) {
- const nsIWidget::ThemeGeometry& g = aThemeGeometries[i];
- if ((g.mType == eThemeGeometryTypeToolbar) && g.mRect.X() <= 0 &&
- g.mRect.XMost() >= aWindowWidth && g.mRect.Y() <= aTitlebarBottom) {
- unifiedToolbarBottom = std::max(unifiedToolbarBottom, g.mRect.YMost());
- }
- }
- return unifiedToolbarBottom;
-}
-
static LayoutDeviceIntRect FindFirstRectOfType(
const nsTArray<nsIWidget::ThemeGeometry>& aThemeGeometries,
nsITheme::ThemeGeometryType aThemeGeometryType) {
@@ -1730,32 +1702,17 @@ static LayoutDeviceIntRect FindFirstRectOfType(
void nsChildView::UpdateThemeGeometries(
const nsTArray<ThemeGeometry>& aThemeGeometries) {
- if (![mView window]) return;
+ if (!mView.window) {
+ return;
+ }
UpdateVibrancy(aThemeGeometries);
- 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();
+ if (![mView.window isKindOfClass:[ToolbarWindow class]]) {
+ return;
+ }
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 =
@@ -1768,10 +1725,8 @@ void nsChildView::UpdateThemeGeometries(
static Maybe<VibrancyType> ThemeGeometryTypeToVibrancyType(
nsITheme::ThemeGeometryType aThemeGeometryType) {
switch (aThemeGeometryType) {
- case eThemeGeometryTypeTooltip:
- return Some(VibrancyType::TOOLTIP);
- case eThemeGeometryTypeMenu:
- return Some(VibrancyType::MENU);
+ case eThemeGeometryTypeTitlebar:
+ return Some(VibrancyType::TITLEBAR);
default:
return Nothing();
}
@@ -1781,7 +1736,7 @@ static LayoutDeviceIntRegion GatherVibrantRegion(
const nsTArray<nsIWidget::ThemeGeometry>& aThemeGeometries,
VibrancyType aVibrancyType) {
LayoutDeviceIntRegion region;
- for (auto& geometry : aThemeGeometries) {
+ for (const auto& geometry : aThemeGeometries) {
if (ThemeGeometryTypeToVibrancyType(geometry.mType) ==
Some(aVibrancyType)) {
region.OrWith(geometry.mRect);
@@ -1790,40 +1745,13 @@ static LayoutDeviceIntRegion GatherVibrantRegion(
return region;
}
-template <typename Region>
-static void MakeRegionsNonOverlappingImpl(Region& aOutUnion) {}
-
-template <typename Region, typename... Regions>
-static void MakeRegionsNonOverlappingImpl(Region& aOutUnion, Region& aFirst,
- Regions&... aRest) {
- MakeRegionsNonOverlappingImpl(aOutUnion, aRest...);
- aFirst.SubOut(aOutUnion);
- aOutUnion.OrWith(aFirst);
-}
-
-// Subtracts parts from regions in such a way that they don't have any overlap.
-// Each region in the argument list will have the union of all the regions
-// *following* it subtracted from itself. In other words, the arguments are
-// sorted low priority to high priority.
-template <typename Region, typename... Regions>
-static void MakeRegionsNonOverlapping(Region& aFirst, Regions&... aRest) {
- Region unionOfAll;
- MakeRegionsNonOverlappingImpl(unionOfAll, aFirst, aRest...);
-}
-
void nsChildView::UpdateVibrancy(
const nsTArray<ThemeGeometry>& aThemeGeometries) {
- LayoutDeviceIntRegion menuRegion =
- GatherVibrantRegion(aThemeGeometries, VibrancyType::MENU);
- LayoutDeviceIntRegion tooltipRegion =
- GatherVibrantRegion(aThemeGeometries, VibrancyType::TOOLTIP);
-
- MakeRegionsNonOverlapping(menuRegion, tooltipRegion);
+ LayoutDeviceIntRegion titlebarRegion =
+ GatherVibrantRegion(aThemeGeometries, VibrancyType::TITLEBAR);
auto& vm = EnsureVibrancyManager();
- bool changed = false;
- changed |= vm.UpdateVibrantRegion(VibrancyType::MENU, menuRegion);
- changed |= vm.UpdateVibrantRegion(VibrancyType::TOOLTIP, tooltipRegion);
+ bool changed = vm.UpdateVibrantRegion(VibrancyType::TITLEBAR, titlebarRegion);
if (changed) {
SuspendAsyncCATransactions();
@@ -1834,7 +1762,7 @@ mozilla::VibrancyManager& nsChildView::EnsureVibrancyManager() {
MOZ_ASSERT(mView, "Only call this once we have a view!");
if (!mVibrancyManager) {
mVibrancyManager =
- MakeUnique<VibrancyManager>(*this, [mView vibrancyViewsContainer]);
+ MakeUnique<VibrancyManager>(*this, mView.vibrancyViewsContainer);
}
return *mVibrancyManager;
}
@@ -1897,7 +1825,7 @@ void nsChildView::UpdateWindowDraggingRegion(
// Suppress calls to setNeedsDisplay during NSView geometry changes.
ManipulateViewWithoutNeedingDisplay(mView, ^() {
changed = mNonDraggableRegion.UpdateRegion(
- nonDraggable, *this, [mView nonDraggableViewsContainer], ^() {
+ nonDraggable, *this, mView.nonDraggableViewsContainer, ^() {
return [[NonDraggableView alloc] initWithFrame:NSZeroRect];
});
});
@@ -2198,22 +2126,22 @@ NSEvent* gLastDragMouseDownEvent = nil; // [strong]
mCancelSwipeAnimation = nil;
#endif
+ auto bounds = self.bounds;
mNonDraggableViewsContainer =
- [[ViewRegionContainerView alloc] initWithFrame:[self bounds]];
+ [[ViewRegionContainerView alloc] initWithFrame:bounds];
mVibrancyViewsContainer =
- [[ViewRegionContainerView alloc] initWithFrame:[self bounds]];
+ [[ViewRegionContainerView alloc] initWithFrame:bounds];
- [mNonDraggableViewsContainer
- setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
- [mVibrancyViewsContainer
- setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+ mNonDraggableViewsContainer.autoresizingMask =
+ mVibrancyViewsContainer.autoresizingMask =
+ NSViewWidthSizable | NSViewHeightSizable;
[self addSubview:mNonDraggableViewsContainer];
[self addSubview:mVibrancyViewsContainer];
- mPixelHostingView = [[PixelHostingView alloc] initWithFrame:[self bounds]];
- [mPixelHostingView
- setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+ mPixelHostingView = [[PixelHostingView alloc] initWithFrame:bounds];
+ mPixelHostingView.autoresizingMask =
+ NSViewWidthSizable | NSViewHeightSizable;
[self addSubview:mPixelHostingView];
@@ -2222,7 +2150,7 @@ NSEvent* gLastDragMouseDownEvent = nil; // [strong]
mRootCALayer.bounds = NSZeroRect;
mRootCALayer.anchorPoint = NSZeroPoint;
mRootCALayer.contentsGravity = kCAGravityTopLeft;
- [[mPixelHostingView layer] addSublayer:mRootCALayer];
+ [mPixelHostingView.layer addSublayer:mRootCALayer];
mLastPressureStage = 0;
}
@@ -2398,7 +2326,7 @@ NSEvent* gLastDragMouseDownEvent = nil; // [strong]
// This call will cause updateRootCALayer to be called during the upcoming
// main thread CoreAnimation transaction. It will also trigger a transaction
// if no transaction is currently pending.
- [[mPixelHostingView layer] setNeedsDisplay];
+ [mPixelHostingView.layer setNeedsDisplay];
}
}
@@ -5129,18 +5057,12 @@ BOOL ChildViewMouseTracker::WindowAcceptsEvent(NSWindow* aWindow,
case WindowType::TopLevel:
case WindowType::Dialog:
- if ([aWindow attachedSheet]) return NO;
+ 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;
}
diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h
index 621c32eb44..96e117ba26 100644
--- a/widget/cocoa/nsCocoaWindow.h
+++ b/widget/cocoa/nsCocoaWindow.h
@@ -12,7 +12,6 @@
#include "mozilla/RefPtr.h"
#include "nsBaseWidget.h"
-#include "nsPIWidgetCocoa.h"
#include "nsCocoaUtils.h"
#include "nsTouchBar.h"
#include <dlfcn.h>
@@ -27,12 +26,6 @@ namespace mozilla {
enum class NativeKeyBindingsType : uint8_t;
} // namespace mozilla
-typedef struct _nsCocoaWindowList {
- _nsCocoaWindowList() : prev(nullptr), window(nullptr) {}
- struct _nsCocoaWindowList* prev;
- nsCocoaWindow* window; // Weak
-} nsCocoaWindowList;
-
// NSWindow subclass that is the base class for all of our own window classes.
// Among other things, this class handles the storage of those settings that
// need to be persisted across window destruction and reconstruction, i.e. when
@@ -169,102 +162,75 @@ typedef struct _nsCocoaWindowList {
- (void)sendToplevelDeactivateEvents;
@end
-@interface MOZTitlebarView : NSVisualEffectView
-@end
-
@interface FullscreenTitlebarTracker : NSTitlebarAccessoryViewController
- (FullscreenTitlebarTracker*)init;
@end
// NSWindow subclass for handling windows with toolbars.
@interface ToolbarWindow : BaseWindow {
- // This window's titlebar view, if present.
- // Will be nil if the window has neither a titlebar nor a unified toolbar.
- // This view is a subview of the window's content view and gets created and
- // 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;
- virtual LayoutDeviceIntPoint GetClientOffset() override;
- virtual LayoutDeviceIntMargin ClientToWindowMargin() override;
-
- virtual void* GetNativeData(uint32_t aDataType) override;
-
- virtual void ConstrainPosition(DesktopIntPoint&) override;
- virtual void SetSizeConstraints(const SizeConstraints& aConstraints) override;
- virtual void Move(double aX, double aY) override;
- virtual nsSizeMode SizeMode() override { return mSizeMode; }
- virtual void SetSizeMode(nsSizeMode aMode) override;
- virtual void GetWorkspaceID(nsAString& workspaceID) override;
- virtual void MoveToWorkspace(const nsAString& workspaceID) override;
- virtual void SuppressAnimation(bool aSuppress) override;
- virtual void HideWindowChrome(bool aShouldHide) override;
-
- virtual bool PrepareForFullscreenTransition(nsISupports** aData) override;
- virtual void PerformFullscreenTransition(FullscreenTransitionStage aStage,
- uint16_t aDuration,
- nsISupports* aData,
- nsIRunnable* aCallback) override;
- virtual void CleanupFullscreenTransition() override;
+ [[nodiscard]] nsresult Create(nsIWidget* aParent,
+ nsNativeWidget aNativeParent,
+ const DesktopIntRect& aRect,
+ InitData* = nullptr) override;
+
+ [[nodiscard]] nsresult Create(nsIWidget* aParent,
+ nsNativeWidget aNativeParent,
+ const LayoutDeviceIntRect& aRect,
+ InitData* = nullptr) override;
+
+ void Destroy() override;
+
+ void Show(bool aState) override;
+ bool NeedsRecreateToReshow() override;
+
+ void Enable(bool aState) override;
+ bool IsEnabled() const override;
+ void SetModal(bool aState) override;
+ bool IsRunningAppModal() override;
+ bool IsVisible() const override;
+ void SetFocus(Raise, mozilla::dom::CallerType aCallerType) override;
+ LayoutDeviceIntPoint WidgetToScreenOffset() override;
+ LayoutDeviceIntPoint GetClientOffset() override;
+ LayoutDeviceIntMargin ClientToWindowMargin() override;
+
+ void* GetNativeData(uint32_t aDataType) override;
+
+ void ConstrainPosition(DesktopIntPoint&) override;
+ void SetSizeConstraints(const SizeConstraints& aConstraints) override;
+ void Move(double aX, double aY) override;
+ nsSizeMode SizeMode() override { return mSizeMode; }
+ void SetSizeMode(nsSizeMode aMode) override;
+ void GetWorkspaceID(nsAString& workspaceID) override;
+ void MoveToWorkspace(const nsAString& workspaceID) override;
+ void SuppressAnimation(bool aSuppress) override;
+ void HideWindowChrome(bool aShouldHide) override;
+
+ bool PrepareForFullscreenTransition(nsISupports** aData) override;
+ void PerformFullscreenTransition(FullscreenTransitionStage aStage,
+ uint16_t aDuration, nsISupports* aData,
+ nsIRunnable* aCallback) override;
+ void CleanupFullscreenTransition() override;
nsresult MakeFullScreen(bool aFullScreen) final;
nsresult MakeFullScreenWithNativeTransition(bool aFullScreen) final;
NSAnimation* FullscreenTransitionAnimation() const {
@@ -277,79 +243,79 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
mFullscreenTransitionAnimation = nil;
}
- virtual void Resize(double aWidth, double aHeight, bool aRepaint) override;
- virtual void Resize(double aX, double aY, double aWidth, double aHeight,
- bool aRepaint) override;
+ void Resize(double aWidth, double aHeight, bool aRepaint) override;
+ void Resize(double aX, double aY, double aWidth, double aHeight,
+ bool aRepaint) override;
NSRect GetClientCocoaRect();
- virtual LayoutDeviceIntRect GetClientBounds() override;
- virtual LayoutDeviceIntRect GetScreenBounds() override;
+ LayoutDeviceIntRect GetClientBounds() override;
+ LayoutDeviceIntRect GetScreenBounds() override;
void ReportMoveEvent();
void ReportSizeEvent();
- virtual void SetCursor(const Cursor&) override;
+ void SetCursor(const Cursor&) override;
CGFloat BackingScaleFactor();
void BackingScaleFactorChanged();
- virtual double GetDefaultScaleInternal() override;
- virtual int32_t RoundsWidgetCoordinatesTo() override;
+ double GetDefaultScaleInternal() override;
+ int32_t RoundsWidgetCoordinatesTo() override;
mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() final {
return mozilla::DesktopToLayoutDeviceScale(BackingScaleFactor());
}
- virtual nsresult SetTitle(const nsAString& aTitle) override;
-
- virtual void Invalidate(const LayoutDeviceIntRect& aRect) override;
- virtual WindowRenderer* GetWindowRenderer() override;
- virtual nsresult DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
- nsEventStatus& aStatus) override;
- virtual void CaptureRollupEvents(bool aDoCapture) override;
- [[nodiscard]] virtual nsresult GetAttention(int32_t aCycleCount) override;
- virtual bool HasPendingInputEvent() override;
- virtual TransparencyMode GetTransparencyMode() override;
- virtual void SetTransparencyMode(TransparencyMode aMode) override;
- virtual void SetWindowShadowStyle(mozilla::WindowShadow aStyle) override;
- virtual void SetWindowOpacity(float aOpacity) override;
- virtual void SetWindowTransform(
- const mozilla::gfx::Matrix& aTransform) override;
- virtual void SetInputRegion(const InputRegion&) override;
- virtual void SetColorScheme(
- const mozilla::Maybe<mozilla::ColorScheme>&) override;
- virtual void SetShowsToolbarButton(bool aShow) override;
- virtual void SetSupportsNativeFullscreen(bool aShow) override;
- virtual void SetWindowAnimationType(WindowAnimationType aType) override;
- virtual void SetDrawsTitle(bool aDrawTitle) override;
- virtual nsresult SetNonClientMargins(const LayoutDeviceIntMargin&) override;
+ nsresult SetTitle(const nsAString& aTitle) override;
+
+ void Invalidate(const LayoutDeviceIntRect& aRect) override;
+ WindowRenderer* GetWindowRenderer() override;
+ nsresult DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
+ nsEventStatus& aStatus) override;
+ void CaptureRollupEvents(bool aDoCapture) override;
+ [[nodiscard]] nsresult GetAttention(int32_t aCycleCount) override;
+ bool HasPendingInputEvent() override;
+ TransparencyMode GetTransparencyMode() override;
+ void SetTransparencyMode(TransparencyMode aMode) override;
+ void SetWindowShadowStyle(mozilla::WindowShadow aStyle) override;
+ void SetWindowOpacity(float aOpacity) override;
+ void SetWindowTransform(const mozilla::gfx::Matrix& aTransform) override;
+ void SetInputRegion(const InputRegion&) override;
+ void SetColorScheme(const mozilla::Maybe<mozilla::ColorScheme>&) override;
+ void SetShowsToolbarButton(bool aShow) override;
+ void SetSupportsNativeFullscreen(bool aShow) override;
+ void SetWindowAnimationType(WindowAnimationType aType) override;
+ void SetDrawsTitle(bool aDrawTitle) override;
+ nsresult SetNonClientMargins(const LayoutDeviceIntMargin&) override;
void SetDrawsInTitlebar(bool aState);
- virtual void UpdateThemeGeometries(
+ void UpdateThemeGeometries(
const nsTArray<ThemeGeometry>& aThemeGeometries) override;
- virtual nsresult SynthesizeNativeMouseEvent(
- LayoutDeviceIntPoint aPoint, NativeMouseMessage aNativeMessage,
- mozilla::MouseButton aButton, nsIWidget::Modifiers aModifierFlags,
- nsIObserver* aObserver) override;
- virtual nsresult SynthesizeNativeMouseScrollEvent(
+ nsresult SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint,
+ NativeMouseMessage aNativeMessage,
+ mozilla::MouseButton aButton,
+ nsIWidget::Modifiers aModifierFlags,
+ nsIObserver* aObserver) override;
+ nsresult SynthesizeNativeMouseScrollEvent(
LayoutDeviceIntPoint aPoint, uint32_t aNativeMessage, double aDeltaX,
double aDeltaY, double aDeltaZ, uint32_t aModifierFlags,
uint32_t aAdditionalFlags, nsIObserver* aObserver) override;
- virtual void LockAspectRatio(bool aShouldLock) override;
+ void LockAspectRatio(bool aShouldLock) override;
void DispatchSizeModeEvent();
void DispatchOcclusionEvent();
// be notified that a some form of drag event needs to go into Gecko
- virtual bool DragEvent(unsigned int aMessage,
- mozilla::gfx::Point aMouseGlobal,
- UInt16 aKeyModifiers);
+ bool DragEvent(unsigned int aMessage, mozilla::gfx::Point aMouseGlobal,
+ UInt16 aKeyModifiers);
+
+ bool HasModalDescendants() const { return mNumModalDescendants > 0; }
+ bool IsModal() const { return mModal; }
- bool HasModalDescendents() { return mNumModalDescendents > 0; }
NSWindow* GetCocoaWindow() { return mWindow; }
void SetMenuBar(RefPtr<nsMenuBarX>&& aMenuBar);
nsMenuBarX* GetMenuBar();
- virtual void SetInputContext(const InputContext& aContext,
- const InputContextAction& aAction) override;
- virtual InputContext GetInputContext() override { return mInputContext; }
- MOZ_CAN_RUN_SCRIPT virtual bool GetEditCommands(
+ void SetInputContext(const InputContext& aContext,
+ const InputContextAction& aAction) override;
+ InputContext GetInputContext() override { return mInputContext; }
+ MOZ_CAN_RUN_SCRIPT bool GetEditCommands(
mozilla::NativeKeyBindingsType aType,
const mozilla::WidgetKeyboardEvent& aEvent,
nsTArray<mozilla::CommandInt>& aCommands) override;
@@ -400,6 +366,7 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
void DestroyNativeWindow();
void UpdateBounds();
int32_t GetWorkspaceID();
+ void SendSetZLevelEvent();
void DoResize(double aX, double aY, double aWidth, double aHeight,
bool aRepaint, bool aConstrainToCurrentScreen);
@@ -407,7 +374,7 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
void UpdateFullscreenState(bool aFullScreen, bool aNativeMode);
nsresult DoMakeFullScreen(bool aFullScreen, bool aUseSystemTransition);
- virtual already_AddRefed<nsIWidget> AllocateChildPopupWidget() override {
+ already_AddRefed<nsIWidget> AllocateChildPopupWidget() override {
return nsIWidget::CreateTopLevelWindow();
}
@@ -417,8 +384,6 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
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
@@ -432,8 +397,6 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
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
@@ -482,19 +445,18 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
// unnecessary OcclusionStateChanged events.
bool mHasStartedNativeFullscreen;
- bool mModal;
- bool mFakeModal;
-
- bool mIsAnimationSuppressed;
+ bool mModal = false;
+ bool mIsAnimationSuppressed = false;
- bool mInReportMoveEvent; // true if in a call to ReportMoveEvent().
- bool mInResize; // true if in a call to DoResize().
- bool mWindowTransformIsIdentity;
- bool mAlwaysOnTop;
- bool mAspectRatioLocked;
+ bool mInReportMoveEvent = false; // true if in a call to ReportMoveEvent().
+ bool mInResize = false; // true if in a call to DoResize().
+ bool mWindowTransformIsIdentity = true;
+ bool mAlwaysOnTop = false;
+ bool mAspectRatioLocked = false;
bool mIsAlert = false; // True if this is an non-native alert window.
+ bool mWasShown = false;
- int32_t mNumModalDescendents;
+ int32_t mNumModalDescendants = 0;
InputContext mInputContext;
NSWindowAnimationBehavior mWindowAnimationBehavior;
@@ -508,9 +470,6 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
// to EndOurNativeTransition() when the native transition is complete.
bool CanStartNativeTransition();
void EndOurNativeTransition();
-
- // true if Show() has been called.
- bool mWasShown;
};
#endif // nsCocoaWindow_h_
diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
index 4b135e7565..8e54d9e7fd 100644
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -66,15 +66,6 @@ using namespace mozilla::layers;
using namespace mozilla::widget;
using namespace mozilla;
-int32_t gXULModalLevel = 0;
-
-// In principle there should be only one app-modal window at any given time.
-// But sometimes, despite our best efforts, another window appears above the
-// current app-modal window. So we need to keep a linked list of app-modal
-// windows. (A non-sheet window that appears above an app-modal window is
-// also made app-modal.) See nsCocoaWindow::SetModal().
-nsCocoaWindowList* gGeckoAppModalWindowList = NULL;
-
BOOL sTouchBarIsInitialized = NO;
// defined in nsMenuBarX.mm
@@ -83,6 +74,8 @@ extern NSMenu* sApplicationMenu; // Application menu shared by all menubars
// defined in nsChildView.mm
extern BOOL gSomeMenuBarPainted;
+static uint32_t sModalWindowCount = 0;
+
extern "C" {
// CGSPrivate.h
typedef NSInteger CGSConnection;
@@ -105,13 +98,6 @@ extern CGError CGSSetWindowTransform(CGSConnection cid, CGSWindow wid,
#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()) {
@@ -139,33 +125,21 @@ nsCocoaWindow::nsCocoaWindow()
mAncestorLink(nullptr),
mWindow(nil),
mDelegate(nil),
- mSheetWindowParent(nil),
mPopupContentView(nil),
mFullscreenTransitionAnimation(nil),
mShadowStyle(WindowShadow::None),
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),
- mInReportMoveEvent(false),
- mInResize(false),
- mWindowTransformIsIdentity(true),
- mAlwaysOnTop(false),
- mAspectRatioLocked(false),
- mNumModalDescendents(0),
- mWindowAnimationBehavior(NSWindowAnimationBehaviorDefault),
- mWasShown(false) {
+ mWindowAnimationBehavior(NSWindowAnimationBehaviorDefault) {
// Disable automatic tabbing. We need to do this before we
// orderFront any of our windows.
- [NSWindow setAllowsAutomaticWindowTabbing:NO];
+ NSWindow.allowsAutomaticWindowTabbing = NO;
}
void nsCocoaWindow::DestroyNativeWindow() {
@@ -223,14 +197,6 @@ nsCocoaWindow::~nsCocoaWindow() {
}
NS_IF_RELEASE(mPopupContentView);
-
- // Deal with the possiblity that we're being destroyed while running modal.
- if (mModal) {
- NS_WARNING("Widget destroyed while running modal!");
- --gXULModalLevel;
- NS_ASSERTION(gXULModalLevel >= 0, "Weirdness setting modality!");
- }
-
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
@@ -432,15 +398,6 @@ nsresult nsCocoaWindow::CreateNativeWindow(const NSRect& aRect,
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;
@@ -607,14 +564,14 @@ nsresult nsCocoaWindow::CreatePopupContentView(const LayoutDeviceIntRect& aRect,
}
void nsCocoaWindow::Destroy() {
- if (mOnDestroyCalled) return;
+ if (mOnDestroyCalled) {
+ return;
+ }
mOnDestroyCalled = true;
- // SetFakeModal(true) is called for non-modal window opened by modal window.
- // On Cocoa, it needs corresponding SetFakeModal(false) on destroy to restore
- // ancestor windows' state.
- if (mFakeModal) {
- SetFakeModal(false);
+ // Deal with the possiblity that we're being destroyed while running modal.
+ if (mModal) {
+ SetModal(false);
}
// If we don't hide here we run into problems with panels, this is not ideal.
@@ -651,14 +608,6 @@ void nsCocoaWindow::Destroy() {
}
}
-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;
@@ -708,14 +657,18 @@ void* nsCocoaWindow::GetNativeData(uint32_t aDataType) {
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) {
+void nsCocoaWindow::SetModal(bool aModal) {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
+ if (mModal == aModal) {
+ return;
+ }
+
// Unlike many functions here, we explicitly *do not check* for the
// existence of mWindow. This is to ensure that calls to SetModal have
// no early exits and always update state. That way, if the calls are
@@ -732,80 +685,47 @@ void nsCocoaWindow::SetModal(bool aState) {
// objects leaking.
nsAutoreleasePool localPool;
- mModal = aState;
- nsCocoaWindow* ancestor = static_cast<nsCocoaWindow*>(mAncestorLink);
- if (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];
- }
- }
- 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;
- }
- }
+ mModal = aModal;
+
+ if (aModal) {
+ sModalWindowCount++;
} 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];
- }
- }
- 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.level = NSNormalWindowLevel;
- }
+ MOZ_ASSERT(sModalWindowCount);
+ sModalWindowCount--;
+ }
+
+ // When a 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).
+ for (auto* ancestor = static_cast<nsCocoaWindow*>(mAncestorLink); ancestor;
+ ancestor = static_cast<nsCocoaWindow*>(ancestor->mParent)) {
+ const bool changed = aModal ? ancestor->mNumModalDescendants++ == 0
+ : --ancestor->mNumModalDescendants == 0;
+ NS_ASSERTION(ancestor->mNumModalDescendants >= 0,
+ "Widget hierarchy changed while modal!");
+ if (!changed || ancestor->mWindowType == WindowType::Invisible) {
+ continue;
}
+ NSWindow* win = ancestor->GetCocoaWindow();
+ [[win standardWindowButton:NSWindowCloseButton] setEnabled:!aModal];
+ [[win standardWindowButton:NSWindowMiniaturizeButton] setEnabled:!aModal];
+ [[win standardWindowButton:NSWindowZoomButton] setEnabled:!aModal];
+ }
+ if (aModal) {
+ mWindow.level = NSModalPanelWindowLevel;
+ } else if (mWindowType == WindowType::Popup) {
+ SetPopupWindowLevel();
+ } else {
+ mWindow.level = NSNormalWindowLevel;
}
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
-void nsCocoaWindow::SetFakeModal(bool aState) {
- mFakeModal = aState;
- SetModal(aState);
-}
-
bool nsCocoaWindow::IsRunningAppModal() { return [NSApp _isRunningAppModal]; }
// Hide or show this window
@@ -816,12 +736,10 @@ void nsCocoaWindow::Show(bool aState) {
return;
}
- if (!mSheetNeedsShow) {
- // Early exit if our current visibility state is already the requested
- // state.
- if (aState == mWindow.isVisibleOrBeingShown) {
- return;
- }
+ // Early exit if our current visibility state is already the requested
+ // state.
+ if (aState == mWindow.isVisibleOrBeingShown) {
+ return;
}
[mWindow setBeingShown:aState];
@@ -829,11 +747,8 @@ void nsCocoaWindow::Show(bool aState) {
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 (aState && !mBounds.IsEmpty()) {
// If we had set the activationPolicy to accessory, then right now we won't
@@ -856,82 +771,7 @@ void nsCocoaWindow::Show(bool aState) {
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
@@ -939,7 +779,9 @@ void nsCocoaWindow::Show(bool aState) {
// calls to ...orderFront: in TRY blocks. See bmo bug 470864.
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
[[mWindow contentView] setNeedsDisplay:YES];
- [mWindow orderFront:nil];
+ if (!nativeParentWindow || mPopupLevel != PopupLevel::Parent) {
+ [mWindow orderFront:nil];
+ }
NS_OBJC_END_TRY_IGNORE_BLOCK;
SendSetZLevelEvent();
// If our popup window is a non-native context menu, tell the OS (and
@@ -955,9 +797,7 @@ void nsCocoaWindow::Show(bool aState) {
// If a parent window was supplied and this is a popup at the parent
// level, set its child window. This will cause the child window to
- // appear above the parent and move when the parent does. Setting this
- // needs to happen after the _setWindowNumber calls above, otherwise the
- // window doesn't focus properly.
+ // appear above the parent and move when the parent does.
if (nativeParentWindow && mPopupLevel == PopupLevel::Parent) {
[nativeParentWindow addChildWindow:mWindow ordered:NSWindowAbove];
}
@@ -1001,120 +841,22 @@ void nsCocoaWindow::Show(bool aState) {
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 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];
+ }
- // 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 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"];
}
}
@@ -2287,53 +2029,13 @@ bool nsCocoaWindow::DragEvent(unsigned int aMessage,
return false;
}
-NS_IMETHODIMP nsCocoaWindow::SendSetZLevelEvent() {
- nsWindowZ placement = nsWindowZTop;
- nsCOMPtr<nsIWidget> actualBelow;
+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
@@ -3184,9 +2886,7 @@ void nsCocoaWindow::CocoaWindowDidResize() {
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()) {
@@ -3205,13 +2905,6 @@ void nsCocoaWindow::CocoaWindowDidResize() {
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;
@@ -3264,36 +2957,6 @@ void nsCocoaWindow::CocoaWindowDidResize() {
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;
@@ -3354,7 +3017,7 @@ void nsCocoaWindow::CocoaWindowDidResize() {
return self.FrameView__closeButtonOrigin;
}
auto* win = static_cast<ToolbarWindow*>(self.window);
- if (win.drawsContentsIntoWindowFrame &&
+ if (win.drawsContentsIntoWindowFrame && !win.wantsTitleDrawn &&
!(win.styleMask & NSWindowStyleMaskFullScreen) &&
(win.styleMask & NSWindowStyleMaskTitled)) {
const NSRect buttonsRect = win.windowButtonsRect;
@@ -3624,7 +3287,7 @@ static const NSString* kStateWantsTitleDrawn = @"wantsTitleDrawn";
}
- (void)setDrawsContentsIntoWindowFrame:(BOOL)aState {
- bool changed = (aState != mDrawsIntoWindowFrame);
+ bool changed = aState != mDrawsIntoWindowFrame;
mDrawsIntoWindowFrame = aState;
if (changed) {
[self reflowTitlebarElements];
@@ -3826,53 +3489,6 @@ static const NSString* kStateWantsTitleDrawn = @"wantsTitleDrawn";
@end
-@interface NSView (NSThemeFrame)
-- (void)_drawTitleStringInClip:(NSRect)aRect;
-- (void)_maskCorners:(NSUInteger)aFlags clipRect:(NSRect)aRect;
-@end
-
-@implementation MOZTitlebarView
-
-- (instancetype)initWithFrame:(NSRect)aFrame {
- self = [super initWithFrame:aFrame];
-
- self.material = NSVisualEffectMaterialTitlebar;
- self.blendingMode = NSVisualEffectBlendingModeWithinWindow;
-
- // Add a separator line at the bottom of the titlebar. NSBoxSeparator isn't a
- // perfect match for a native titlebar separator, but it's better than
- // nothing. We really want the appearance that _NSTitlebarDecorationView
- // creates with the help of CoreUI, but there's no public API for that.
- NSBox* separatorLine =
- [[NSBox alloc] initWithFrame:NSMakeRect(0, 0, aFrame.size.width, 1)];
- separatorLine.autoresizingMask = NSViewWidthSizable | NSViewMaxYMargin;
- separatorLine.boxType = NSBoxSeparator;
- [self addSubview:separatorLine];
- [separatorLine release];
-
- return self;
-}
-
-- (BOOL)mouseDownCanMoveWindow {
- return YES;
-}
-
-- (void)mouseUp:(NSEvent*)event {
- if (event.clickCount == 2) {
- // Handle titlebar double click. We don't get the window's default behavior
- // here because the window uses NSWindowStyleMaskFullSizeContentView, and
- // this view (the titlebar gradient view) is technically part of the window
- // "contents" (it's a subview of the content view).
- if (nsCocoaUtils::ShouldZoomOnTitlebarDoubleClick()) {
- [self.window performZoom:nil];
- } else if (nsCocoaUtils::ShouldMinimizeOnTitlebarDoubleClick()) {
- [self.window performMiniaturize:nil];
- }
- }
-}
-
-@end
-
@interface MOZTitlebarAccessoryView : NSView
@end
@@ -3896,44 +3512,51 @@ static const NSString* kStateWantsTitleDrawn = @"wantsTitleDrawn";
@implementation FullscreenTitlebarTracker
- (FullscreenTitlebarTracker*)init {
[super init];
- self.view =
- [[[MOZTitlebarAccessoryView alloc] initWithFrame:NSZeroRect] autorelease];
self.hidden = YES;
return self;
}
+- (void)loadView {
+ self.view =
+ [[[MOZTitlebarAccessoryView alloc] initWithFrame:NSZeroRect] autorelease];
+}
@end
-// This class allows us to exercise control over the window's title bar. It is
-// used for all windows with titlebars.
-//
-// ToolbarWindow supports two modes:
-// - drawsContentsIntoWindowFrame mode: In this mode, the Gecko ChildView is
-// sized to cover the entire window frame and manages titlebar drawing.
-// - separate titlebar mode, with support for unified toolbars: In this mode,
-// the Gecko ChildView does not extend into the titlebar. However, this
-// window's content view (which is the ChildView's superview) *does* extend
-// into the titlebar. Moreover, in this mode, we place a MOZTitlebarView
-// in the content view, as a sibling of the ChildView.
-//
-// The "separate titlebar mode" supports the "unified toolbar" look:
-// If there's a toolbar right below the titlebar, the two can "connect" and
-// form a single gradient without a separator line in between.
-//
-// The following mechanism communicates the height of the unified toolbar to
-// the ToolbarWindow:
-//
-// 1) In the style sheet we set the toolbar's -moz-appearance to toolbar.
-// 2) When the toolbar is visible and we paint the application chrome
-// window, the array that Gecko passes nsChildView::UpdateThemeGeometries
-// will contain an entry for the widget type StyleAppearance::Toolbar.
-// 3) nsChildView::UpdateThemeGeometries passes the toolbar's height, plus the
-// titlebar height, to -[ToolbarWindow setUnifiedToolbarHeight:].
-//
-// The actual drawing of the gradient happens in two parts: The titlebar part
-// (i.e. the top 22 pixels of the gradient) is drawn by the MOZTitlebarView,
-// which is a subview of the window's content view and a sibling of the
-// ChildView. The rest of the gradient is drawn by Gecko into the ChildView, as
-// part of the -moz-appearance rendering of the toolbar.
+// Drop all mouse events if a modal window has appeared above us.
+// This helps make us behave as if the OS were running a "real" modal event
+// loop.
+static bool MaybeDropEventForModalWindow(NSEvent* aEvent, id aDelegate) {
+ if (!sModalWindowCount) {
+ return false;
+ }
+
+ NSEventType type = [aEvent type];
+ switch (type) {
+ case NSEventTypeScrollWheel:
+ case NSEventTypeLeftMouseDown:
+ case NSEventTypeLeftMouseUp:
+ case NSEventTypeRightMouseDown:
+ case NSEventTypeRightMouseUp:
+ case NSEventTypeOtherMouseDown:
+ case NSEventTypeOtherMouseUp:
+ case NSEventTypeMouseMoved:
+ case NSEventTypeLeftMouseDragged:
+ case NSEventTypeRightMouseDragged:
+ case NSEventTypeOtherMouseDragged:
+ break;
+ default:
+ return false;
+ }
+
+ if (aDelegate && [aDelegate isKindOfClass:[WindowDelegate class]]) {
+ if (nsCocoaWindow* widget = [(WindowDelegate*)aDelegate geckoWidget]) {
+ if (!widget->IsModal() || widget->HasModalDescendants()) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
@implementation ToolbarWindow
- (id)initWithContentRect:(NSRect)aChildViewRect
@@ -3972,17 +3595,12 @@ static const NSString* kStateWantsTitleDrawn = @"wantsTitleDrawn";
styleMask:aStyle
backing:aBufferingType
defer:aFlag])) {
- mTitlebarView = nil;
- mUnifiedToolbarHeight = 22.0f;
- mSheetAttachmentPosition = aChildViewRect.size.height;
mWindowButtonsRect = NSZeroRect;
- mInitialTitlebarHeight = [self titlebarHeight];
- [self setTitlebarAppearsTransparent:YES];
+ self.titlebarAppearsTransparent = YES;
if (@available(macOS 11.0, *)) {
self.titlebarSeparatorStyle = NSTitlebarSeparatorStyleNone;
}
- [self updateTitlebarView];
mFullscreenTitlebarTracker = [[FullscreenTitlebarTracker alloc] init];
// revealAmount is an undocumented property of
@@ -4048,8 +3666,7 @@ static bool ShouldShiftByMenubarHeightInFullscreen(nsCocoaWindow* aWindow) {
}
- (void)updateTitlebarShownAmount:(CGFloat)aShownAmount {
- NSInteger styleMask = [self styleMask];
- if (!(styleMask & NSWindowStyleMaskFullScreen)) {
+ if (!(self.styleMask & NSWindowStyleMaskFullScreen)) {
// We are not interested in the size of the titlebar unless we are in
// fullscreen.
return;
@@ -4071,27 +3688,24 @@ static bool ShouldShiftByMenubarHeightInFullscreen(nsCocoaWindow* aWindow) {
}
if (nsIWidgetListener* listener = geckoWindow->GetWidgetListener()) {
- // Use the titlebar height cached in our frame rather than
- // [ToolbarWindow titlebarHeight]. titlebarHeight returns 0 when we're in
- // fullscreen.
- CGFloat shiftByPixels = mInitialTitlebarHeight * aShownAmount;
+ // titlebarHeight returns 0 when we're in fullscreen, return the default
+ // titlebar height.
+ CGFloat shiftByPixels =
+ LookAndFeel::GetInt(LookAndFeel::IntID::MacTitlebarHeight) *
+ aShownAmount;
if (ShouldShiftByMenubarHeightInFullscreen(geckoWindow)) {
shiftByPixels += mMenuBarHeight * aShownAmount;
}
- // Use mozilla::DesktopToLayoutDeviceScale rather than the
- // DesktopToLayoutDeviceScale in nsCocoaWindow. The latter accounts for
- // screen DPI. We don't want that because the revealAmount property
- // already accounts for it, so we'd be compounding DPI scales > 1.
- mozilla::DesktopCoord coord = LayoutDeviceCoord(shiftByPixels) /
- mozilla::DesktopToLayoutDeviceScale();
-
- listener->MacFullscreenMenubarOverlapChanged(coord);
+ // Use desktop pixels rather than the DesktopToLayoutDeviceScale in
+ // nsCocoaWindow. The latter accounts for screen DPI. We don't want that
+ // because the revealAmount property already accounts for it, so we'd be
+ // compounding DPI scales > 1.
+ listener->MacFullscreenMenubarOverlapChanged(DesktopCoord(shiftByPixels));
}
}
}
- (void)dealloc {
- [mTitlebarView release];
[mFullscreenTitlebarTracker removeObserver:self forKeyPath:@"revealAmount"];
[mFullscreenTitlebarTracker removeFromParentViewController];
[mFullscreenTitlebarTracker release];
@@ -4100,80 +3714,13 @@ static bool ShouldShiftByMenubarHeightInFullscreen(nsCocoaWindow* aWindow) {
}
- (NSArray<NSView*>*)contentViewContents {
- NSMutableArray<NSView*>* contents = [[self.contentView subviews] mutableCopy];
- if (mTitlebarView) {
- // Do not include the titlebar gradient view in the returned array.
- [contents removeObject:mTitlebarView];
- }
- return [contents autorelease];
-}
-
-- (void)updateTitlebarView {
- BOOL needTitlebarView =
- !self.drawsContentsIntoWindowFrame || mUnifiedToolbarHeight > 0;
- if (needTitlebarView && !mTitlebarView) {
- mTitlebarView =
- [[MOZTitlebarView alloc] initWithFrame:self.unifiedToolbarRect];
- mTitlebarView.autoresizingMask = NSViewWidthSizable | NSViewMinYMargin;
- [self.contentView addSubview:mTitlebarView
- positioned:NSWindowBelow
- relativeTo:nil];
- } else if (needTitlebarView && mTitlebarView) {
- mTitlebarView.frame = self.unifiedToolbarRect;
- } else if (!needTitlebarView && mTitlebarView) {
- [mTitlebarView removeFromSuperview];
- [mTitlebarView release];
- mTitlebarView = nil;
- }
+ return [[self.contentView.subviews copy] autorelease];
}
- (void)windowMainStateChanged {
- [self setTitlebarNeedsDisplay];
[[self mainChildView] ensureNextCompositeIsAtomicWithMainThreadPaint];
}
-- (void)setTitlebarNeedsDisplay {
- [mTitlebarView setNeedsDisplay:YES];
-}
-
-- (NSRect)titlebarRect {
- CGFloat titlebarHeight = self.titlebarHeight;
- return NSMakeRect(0, self.frame.size.height - titlebarHeight,
- self.frame.size.width, titlebarHeight);
-}
-
-// In window contentView coordinates (origin bottom left)
-- (NSRect)unifiedToolbarRect {
- return NSMakeRect(0, self.frame.size.height - mUnifiedToolbarHeight,
- self.frame.size.width, mUnifiedToolbarHeight);
-}
-
-// Returns the unified height of titlebar + toolbar.
-- (CGFloat)unifiedToolbarHeight {
- return mUnifiedToolbarHeight;
-}
-
-- (CGFloat)titlebarHeight {
- // We use the original content rect here, not what we return from
- // [self contentRectForFrameRect:], because that would give us a
- // titlebarHeight of zero.
- NSRect frameRect = self.frame;
- NSUInteger styleMask = self.styleMask;
- styleMask &= ~NSWindowStyleMaskFullSizeContentView;
- NSRect originalContentRect = [NSWindow contentRectForFrameRect:frameRect
- styleMask:styleMask];
- return NSMaxY(frameRect) - NSMaxY(originalContentRect);
-}
-
-// Stores the complete height of titlebar + toolbar.
-- (void)setUnifiedToolbarHeight:(CGFloat)aHeight {
- if (aHeight == mUnifiedToolbarHeight) return;
-
- mUnifiedToolbarHeight = aHeight;
-
- [self updateTitlebarView];
-}
-
// Extending the content area into the title bar works by resizing the
// mainChildView so that it covers the titlebar.
- (void)setDrawsContentsIntoWindowFrame:(BOOL)aState {
@@ -4197,21 +3744,6 @@ static bool ShouldShiftByMenubarHeightInFullscreen(nsCocoaWindow* aWindow) {
// we'll send a mouse move event with the correct new position.
ChildViewMouseTracker::ResendLastMouseMoveEvent();
}
-
- [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 {
@@ -4268,42 +3800,9 @@ static bool ShouldShiftByMenubarHeightInFullscreen(nsCocoaWindow* aWindow) {
}
- (void)sendEvent:(NSEvent*)anEvent {
- NSEventType type = [anEvent type];
-
- switch (type) {
- case NSEventTypeScrollWheel:
- case NSEventTypeLeftMouseDown:
- case NSEventTypeLeftMouseUp:
- case NSEventTypeRightMouseDown:
- case NSEventTypeRightMouseUp:
- case NSEventTypeOtherMouseDown:
- case NSEventTypeOtherMouseUp:
- case NSEventTypeMouseMoved:
- case NSEventTypeLeftMouseDragged:
- case NSEventTypeRightMouseDragged:
- case NSEventTypeOtherMouseDragged: {
- // Drop all mouse events if a modal window has appeared above us.
- // This helps make us behave as if the OS were running a "real" modal
- // event loop.
- id delegate = self.delegate;
- if (delegate && [delegate isKindOfClass:[WindowDelegate class]]) {
- nsCocoaWindow* widget = [(WindowDelegate*)delegate geckoWidget];
- if (widget) {
- if (gGeckoAppModalWindowList &&
- widget != gGeckoAppModalWindowList->window) {
- return;
- }
- if (widget->HasModalDescendents()) {
- return;
- }
- }
- }
- break;
- }
- default:
- break;
+ if (MaybeDropEventForModalWindow(anEvent, self.delegate)) {
+ return;
}
-
[super sendEvent:anEvent];
}
@@ -4403,40 +3902,8 @@ static const NSUInteger kWindowShadowOptionsTooltip = 4;
}
- (void)sendEvent:(NSEvent*)anEvent {
- NSEventType type = [anEvent type];
-
- switch (type) {
- case NSEventTypeScrollWheel:
- case NSEventTypeLeftMouseDown:
- case NSEventTypeLeftMouseUp:
- case NSEventTypeRightMouseDown:
- case NSEventTypeRightMouseUp:
- case NSEventTypeOtherMouseDown:
- case NSEventTypeOtherMouseUp:
- case NSEventTypeMouseMoved:
- case NSEventTypeLeftMouseDragged:
- case NSEventTypeRightMouseDragged:
- case NSEventTypeOtherMouseDragged: {
- // Drop all mouse events if a modal window has appeared above us.
- // This helps make us behave as if the OS were running a "real" modal
- // event loop.
- id delegate = self.delegate;
- if (delegate && [delegate isKindOfClass:[WindowDelegate class]]) {
- nsCocoaWindow* widget = [(WindowDelegate*)delegate geckoWidget];
- if (widget) {
- if (gGeckoAppModalWindowList &&
- widget != gGeckoAppModalWindowList->window) {
- return;
- }
- if (widget->HasModalDescendents()) {
- return;
- }
- }
- }
- break;
- }
- default:
- break;
+ if (MaybeDropEventForModalWindow(anEvent, self.delegate)) {
+ return;
}
[super sendEvent:anEvent];
diff --git a/widget/cocoa/nsLookAndFeel.h b/widget/cocoa/nsLookAndFeel.h
index adce685a4e..89e4c93713 100644
--- a/widget/cocoa/nsLookAndFeel.h
+++ b/widget/cocoa/nsLookAndFeel.h
@@ -12,14 +12,17 @@ class nsLookAndFeel final : public nsXPLookAndFeel {
nsLookAndFeel();
virtual ~nsLookAndFeel();
- void NativeInit() final;
+ void NativeInit() final { EnsureInit(); }
+ void RefreshImpl() final;
+ void EnsureInit();
+
nsresult NativeGetColor(ColorID, ColorScheme, nscolor& aColor) override;
nsresult NativeGetInt(IntID, int32_t& aResult) override;
nsresult NativeGetFloat(FloatID, float& aResult) override;
bool NativeGetFont(FontID aID, nsString& aFontName,
gfxFontStyle& aFontStyle) override;
- virtual char16_t GetPasswordCharacterImpl() override {
+ char16_t GetPasswordCharacterImpl() override {
// unicode value for the bullet character, used for password textfields.
return 0x2022;
}
@@ -34,10 +37,9 @@ class nsLookAndFeel final : public nsXPLookAndFeel {
static void RecordAccessibilityTelemetry();
protected:
- static bool SystemWantsDarkTheme();
- static bool IsSystemOrientationRTL();
- static nscolor ProcessSelectionBackground(nscolor aColor,
- ColorScheme aScheme);
+ bool mInitialized = false;
+ bool mRtl = false;
+ int32_t mTitlebarHeight = 0;
};
#endif // nsLookAndFeel_h_
diff --git a/widget/cocoa/nsLookAndFeel.mm b/widget/cocoa/nsLookAndFeel.mm
index 5675198ff2..779984be0c 100644
--- a/widget/cocoa/nsLookAndFeel.mm
+++ b/widget/cocoa/nsLookAndFeel.mm
@@ -32,22 +32,44 @@ using namespace mozilla;
+ (void)startObserving;
@end
-nsLookAndFeel::nsLookAndFeel() = default;
+nsLookAndFeel::nsLookAndFeel() {
+ [MOZLookAndFeelDynamicChangeObserver startObserving];
+}
nsLookAndFeel::~nsLookAndFeel() = default;
-void nsLookAndFeel::NativeInit() {
+void nsLookAndFeel::EnsureInit() {
+ if (mInitialized) {
+ return;
+ }
+
NS_OBJC_BEGIN_TRY_ABORT_BLOCK
- [MOZLookAndFeelDynamicChangeObserver startObserving];
+ mInitialized = true;
+ NSWindow* window =
+ [[NSWindow alloc] initWithContentRect:NSZeroRect
+ styleMask:NSWindowStyleMaskTitled
+ backing:NSBackingStoreBuffered
+ defer:NO];
+ auto release = MakeScopeExit([&] { [window release]; });
+
+ mRtl = window.windowTitlebarLayoutDirection ==
+ NSUserInterfaceLayoutDirectionRightToLeft;
+ mTitlebarHeight = std::ceil(window.frame.size.height);
+
RecordTelemetry();
NS_OBJC_END_TRY_ABORT_BLOCK
}
+void nsLookAndFeel::RefreshImpl() {
+ mInitialized = false;
+ nsXPLookAndFeel::RefreshImpl();
+}
+
static nscolor GetColorFromNSColor(NSColor* aColor) {
NSColor* deviceColor =
- [aColor colorUsingColorSpace:[NSColorSpace deviceRGBColorSpace]];
+ [aColor colorUsingColorSpace:NSColorSpace.deviceRGBColorSpace];
return NS_RGBA((unsigned int)(deviceColor.redComponent * 255.0),
(unsigned int)(deviceColor.greenComponent * 255.0),
(unsigned int)(deviceColor.blueComponent * 255.0),
@@ -77,8 +99,7 @@ static nscolor GetColorFromNSColorWithCustomAlpha(NSColor* aColor,
// whereas white text on dark blue (which what you get if you mix
// partially-transparent light blue with the black textbox background) has much
// better contrast.
-nscolor nsLookAndFeel::ProcessSelectionBackground(nscolor aColor,
- ColorScheme aScheme) {
+static nscolor ProcessSelectionBackground(nscolor aColor, ColorScheme aScheme) {
if (aScheme == ColorScheme::Dark) {
// When we use a dark selection color, we do not change alpha because we do
// not use dark selection in content. The dark system color is appropriate
@@ -136,6 +157,14 @@ nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme,
case ColorID::MozMenuhover:
case ColorID::Selecteditem:
color = GetColorFromNSColor(NSColor.selectedContentBackgroundColor);
+ if (aID == ColorID::MozMenuhover &&
+ !LookAndFeel::GetInt(IntID::PrefersReducedTransparency)) {
+ // Wash the color a little bit with semi-transparent white to match a
+ // bit closer the native NSVisualEffectSelection on menus.
+ color = NS_ComposeColors(
+ color,
+ NS_RGBA(255, 255, 255, aScheme == ColorScheme::Light ? 51 : 25));
+ }
break;
case ColorID::Accentcolortext:
case ColorID::MozMenuhovertext:
@@ -197,6 +226,7 @@ nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme,
: NS_RGB(0xFF, 0xFF, 0xFF);
break;
case ColorID::Windowtext:
+ case ColorID::MozDialogtext:
color = GetColorFromNSColor(NSColor.windowFrameTextColor);
break;
case ColorID::Appworkspace:
@@ -254,13 +284,14 @@ nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme,
case ColorID::Windowframe:
color = GetColorFromNSColor(NSColor.windowFrameColor);
break;
- case ColorID::Window: {
- color = GetColorFromNSColor(NSColor.windowBackgroundColor);
+ case ColorID::MozDialog:
+ case ColorID::Window:
+ color = GetColorFromNSColor(aScheme == ColorScheme::Light
+ ? NSColor.windowBackgroundColor
+ : NSColor.underPageBackgroundColor);
break;
- }
case ColorID::Field:
case ColorID::MozCombobox:
- case ColorID::MozDialog:
color = GetColorFromNSColor(NSColor.controlBackgroundColor);
break;
case ColorID::Fieldtext:
@@ -269,7 +300,6 @@ nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme,
case ColorID::MozButtonhovertext:
case ColorID::Menutext:
case ColorID::Infotext:
- case ColorID::MozDialogtext:
case ColorID::MozCellhighlighttext:
case ColorID::MozColheadertext:
case ColorID::MozColheaderhovertext:
@@ -323,6 +353,7 @@ nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme,
case ColorID::SpellCheckerUnderline:
case ColorID::Activeborder:
case ColorID::Inactiveborder:
+ case ColorID::MozAutofillBackground:
aColor = GetStandinForNativeColor(aID, aScheme);
return NS_OK;
default:
@@ -336,6 +367,16 @@ nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme,
NS_OBJC_END_TRY_ABORT_BLOCK
}
+static bool SystemWantsDarkTheme() {
+ // This returns true if the macOS system appearance is set to dark mode,
+ // false otherwise.
+ NSAppearanceName aquaOrDarkAqua =
+ [NSApp.effectiveAppearance bestMatchFromAppearancesWithNames:@[
+ NSAppearanceNameAqua, NSAppearanceNameDarkAqua
+ ]];
+ return [aquaOrDarkAqua isEqualToString:NSAppearanceNameDarkAqua];
+}
+
nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
@@ -355,9 +396,6 @@ nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) {
case IntID::CaretWidth:
aResult = 1;
break;
- case IntID::ShowCaretDuringSelection:
- aResult = 0;
- break;
case IntID::SelectTextfieldsOnKeyFocus:
// Select textfield content when focused by kbd
// used by EventStateManager::sTextfieldSelectModel
@@ -412,7 +450,12 @@ nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) {
aResult = nsCocoaFeatures::OnBigSurOrLater();
break;
case IntID::MacRTL:
- aResult = IsSystemOrientationRTL();
+ EnsureInit();
+ aResult = mRtl;
+ break;
+ case IntID::MacTitlebarHeight:
+ EnsureInit();
+ aResult = mTitlebarHeight;
break;
case IntID::AlertNotificationOrigin:
aResult = NS_ALERT_TOP;
@@ -469,14 +512,6 @@ nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) {
aResult = NSWorkspace.sharedWorkspace
.accessibilityDisplayShouldIncreaseContrast;
break;
- case IntID::VideoDynamicRange: {
- // If the platform says it supports HDR, then we claim to support
- // video-dynamic-range.
- gfxPlatform* platform = gfxPlatform::GetPlatform();
- MOZ_ASSERT(platform);
- aResult = platform->SupportsHDR();
- break;
- }
case IntID::PanelAnimations:
aResult = 1;
break;
@@ -519,28 +554,6 @@ nsresult nsLookAndFeel::NativeGetFloat(FloatID aID, float& aResult) {
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
-bool nsLookAndFeel::SystemWantsDarkTheme() {
- // This returns true if the macOS system appearance is set to dark mode, false
- // otherwise.
- NSAppearanceName aquaOrDarkAqua =
- [NSApp.effectiveAppearance bestMatchFromAppearancesWithNames:@[
- NSAppearanceNameAqua, NSAppearanceNameDarkAqua
- ]];
- return [aquaOrDarkAqua isEqualToString:NSAppearanceNameDarkAqua];
-}
-
-/*static*/
-bool nsLookAndFeel::IsSystemOrientationRTL() {
- NSWindow* window =
- [[NSWindow alloc] initWithContentRect:NSZeroRect
- styleMask:NSWindowStyleMaskBorderless
- backing:NSBackingStoreBuffered
- defer:NO];
- auto direction = window.windowTitlebarLayoutDirection;
- [window release];
- return direction == NSUserInterfaceLayoutDirectionRightToLeft;
-}
-
bool nsLookAndFeel::NativeGetFont(FontID aID, nsString& aFontName,
gfxFontStyle& aFontStyle) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
diff --git a/widget/cocoa/nsNativeThemeCocoa.h b/widget/cocoa/nsNativeThemeCocoa.h
index 9488e50e1e..ebbf782264 100644
--- a/widget/cocoa/nsNativeThemeCocoa.h
+++ b/widget/cocoa/nsNativeThemeCocoa.h
@@ -159,7 +159,6 @@ class nsNativeThemeCocoa : public mozilla::widget::ThemeCocoa {
eSpinButtonDown, // SpinButtonParams
eSegment, // SegmentParams
eSeparator,
- eToolbar, // bool
eStatusBar, // bool
eGroupBox,
eTextField, // TextFieldParams
@@ -204,9 +203,6 @@ class nsNativeThemeCocoa : public mozilla::widget::ThemeCocoa {
static WidgetInfo Separator() {
return WidgetInfo(Widget::eSeparator, false);
}
- static WidgetInfo Toolbar(bool aParams) {
- return WidgetInfo(Widget::eToolbar, aParams);
- }
static WidgetInfo StatusBar(bool aParams) {
return WidgetInfo(Widget::eStatusBar, aParams);
}
diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm
index ff715ac57c..18913facea 100644
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -399,9 +399,8 @@ static BOOL FrameIsInActiveWindow(nsIFrame* aFrame) {
// 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;
}
NS_IMPL_ISUPPORTS_INHERITED(nsNativeThemeCocoa, nsNativeTheme, nsITheme)
@@ -1021,7 +1020,6 @@ static bool IsToolbarStyleContainer(nsIFrame* aFrame) {
}
switch (aFrame->StyleDisplay()->EffectiveAppearance()) {
- case StyleAppearance::Toolbar:
case StyleAppearance::Statusbar:
return true;
default:
@@ -2078,35 +2076,6 @@ void nsNativeThemeCocoa::DrawSegment(CGContextRef cgContext,
RenderWithCoreUI(drawRect, cgContext, dict);
}
-void nsNativeThemeCocoa::DrawToolbar(CGContextRef cgContext,
- const CGRect& inBoxRect, bool aIsMain) {
- CGRect drawRect = inBoxRect;
-
- // top border
- drawRect.size.height = 1.0f;
- DrawNativeGreyColorInRect(cgContext, toolbarTopBorderGrey, drawRect, aIsMain);
-
- // background
- drawRect.origin.y += drawRect.size.height;
- drawRect.size.height = inBoxRect.size.height - 2.0f;
- DrawNativeGreyColorInRect(cgContext, toolbarFillGrey, drawRect, aIsMain);
-
- // bottom border
- drawRect.origin.y += drawRect.size.height;
- drawRect.size.height = 1.0f;
- DrawNativeGreyColorInRect(cgContext, toolbarBottomBorderGrey, drawRect,
- aIsMain);
-}
-
-static bool ToolbarCanBeUnified(const gfx::Rect& aRect, NSWindow* aWindow) {
- if (![aWindow isKindOfClass:[ToolbarWindow class]]) return false;
-
- ToolbarWindow* win = (ToolbarWindow*)aWindow;
- float unifiedToolbarHeight = [win unifiedToolbarHeight];
- return aRect.X() == 0 && aRect.Width() >= [win frame].size.width &&
- aRect.YMost() <= unifiedToolbarHeight;
-}
-
void nsNativeThemeCocoa::DrawStatusBar(CGContextRef cgContext,
const HIRect& inBoxRect, bool aIsMain) {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
@@ -2329,25 +2298,12 @@ Maybe<nsNativeThemeCocoa::WidgetInfo> nsNativeThemeCocoa::ComputeWidgetInfo(
case StyleAppearance::Separator:
return Some(WidgetInfo::Separator());
- case StyleAppearance::Toolbar: {
- NSWindow* win = NativeWindowForFrame(aFrame);
- bool isMain = [win isMainWindow];
- if (ToolbarCanBeUnified(nativeWidgetRect, win)) {
- // Unified toolbars are drawn similar to vibrancy; we communicate their
- // extents via the theme geometry mechanism and then place native views
- // under Gecko's rendering. So Gecko just needs to be transparent in the
- // place where the toolbar should be visible.
- return Nothing();
- }
- 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: {
@@ -2594,11 +2550,6 @@ void nsNativeThemeCocoa::RenderWidget(const WidgetInfo& aWidgetInfo,
HIThemeDrawSeparator(&macRect, &sdi, cgContext, HITHEME_ORIENTATION);
break;
}
- case Widget::eToolbar: {
- bool isMain = aWidgetInfo.Params<bool>();
- DrawToolbar(cgContext, macRect, isMain);
- break;
- }
case Widget::eStatusBar: {
bool isMain = aWidgetInfo.Params<bool>();
DrawStatusBar(cgContext, macRect, isMain);
@@ -2710,7 +2661,6 @@ bool nsNativeThemeCocoa::CreateWebRenderCommandsForWidget(
case StyleAppearance::SpinnerDownbutton:
case StyleAppearance::Toolbarbutton:
case StyleAppearance::Separator:
- case StyleAppearance::Toolbar:
case StyleAppearance::MozWindowTitlebar:
case StyleAppearance::Statusbar:
case StyleAppearance::Menulist:
@@ -3091,8 +3041,6 @@ nsNativeThemeCocoa::WidgetStateChanged(nsIFrame* aFrame,
// Some widget types just never change state.
switch (aAppearance) {
case StyleAppearance::MozWindowTitlebar:
- case StyleAppearance::Toolbox:
- case StyleAppearance::Toolbar:
case StyleAppearance::Statusbar:
case StyleAppearance::Tooltip:
case StyleAppearance::Tabpanels:
@@ -3178,13 +3126,11 @@ bool nsNativeThemeCocoa::ThemeSupportsWidget(nsPresContext* aPresContext,
case StyleAppearance::Spinner:
case StyleAppearance::SpinnerUpbutton:
case StyleAppearance::SpinnerDownbutton:
- case StyleAppearance::Toolbar:
case StyleAppearance::Statusbar:
case StyleAppearance::NumberInput:
case StyleAppearance::Textfield:
case StyleAppearance::Textarea:
case StyleAppearance::Searchfield:
- case StyleAppearance::Toolbox:
case StyleAppearance::ProgressBar:
case StyleAppearance::Progresschunk:
case StyleAppearance::Meter:
@@ -3265,7 +3211,6 @@ bool nsNativeThemeCocoa::WidgetAppearanceDependsOnWindowFocus(
case StyleAppearance::SpinnerUpbutton:
case StyleAppearance::SpinnerDownbutton:
case StyleAppearance::Separator:
- case StyleAppearance::Toolbox:
case StyleAppearance::NumberInput:
case StyleAppearance::Textfield:
case StyleAppearance::Treeview:
@@ -3283,16 +3228,8 @@ nsITheme::ThemeGeometryType nsNativeThemeCocoa::ThemeGeometryTypeForWidget(
switch (aAppearance) {
case StyleAppearance::MozWindowTitlebar:
return eThemeGeometryTypeTitlebar;
- case StyleAppearance::Toolbar:
- return eThemeGeometryTypeToolbar;
- case StyleAppearance::Toolbox:
- return eThemeGeometryTypeToolbox;
case StyleAppearance::MozWindowButtonBox:
return eThemeGeometryTypeWindowButtons;
- case StyleAppearance::Tooltip:
- return eThemeGeometryTypeTooltip;
- case StyleAppearance::Menupopup:
- return eThemeGeometryTypeMenu;
default:
return eThemeGeometryTypeUnknown;
}
@@ -3307,7 +3244,6 @@ nsITheme::Transparency nsNativeThemeCocoa::GetWidgetTransparency(
switch (aAppearance) {
case StyleAppearance::Menupopup:
case StyleAppearance::Tooltip:
- case StyleAppearance::Toolbar:
return eTransparent;
case StyleAppearance::MozMacUnifiedToolbarWindow:
// We want these to be treated as opaque by Gecko. We ensure there's an
diff --git a/widget/cocoa/nsNativeThemeColors.h b/widget/cocoa/nsNativeThemeColors.h
index 02ec96f51a..051335e9bc 100644
--- a/widget/cocoa/nsNativeThemeColors.h
+++ b/widget/cocoa/nsNativeThemeColors.h
@@ -10,43 +10,6 @@
#include "mozilla/ColorScheme.h"
-enum ColorName {
- toolbarTopBorderGrey,
- toolbarFillGrey,
- toolbarBottomBorderGrey,
-};
-
-static const int sLionThemeColors[][2] = {
- /* { active window, inactive window } */
- // toolbar:
- {0xD0, 0xF0}, // top separator line
- {0xB2, 0xE1}, // fill color
- {0x59, 0x87}, // bottom separator line
-};
-
-static const int sYosemiteThemeColors[][2] = {
- /* { active window, inactive window } */
- // toolbar:
- {0xBD, 0xDF}, // top separator line
- {0xD3, 0xF6}, // fill color
- {0xB3, 0xD1}, // bottom separator line
-};
-
-inline int NativeGreyColorAsInt(ColorName name, BOOL isMain) {
- return sYosemiteThemeColors[name][isMain ? 0 : 1];
-}
-
-inline float NativeGreyColorAsFloat(ColorName name, BOOL isMain) {
- return NativeGreyColorAsInt(name, isMain) / 255.0f;
-}
-
-inline void DrawNativeGreyColorInRect(CGContextRef context, ColorName name,
- CGRect rect, BOOL isMain) {
- float grey = NativeGreyColorAsFloat(name, isMain);
- CGContextSetRGBFillColor(context, grey, grey, grey, 1.0f);
- CGContextFillRect(context, rect);
-}
-
inline NSAppearance* NSAppearanceForColorScheme(mozilla::ColorScheme aScheme) {
NSAppearanceName appearanceName = aScheme == mozilla::ColorScheme::Light
? NSAppearanceNameAqua
diff --git a/widget/cocoa/nsPIWidgetCocoa.idl b/widget/cocoa/nsPIWidgetCocoa.idl
deleted file mode 100644
index 54aa0d5113..0000000000
--- a/widget/cocoa/nsPIWidgetCocoa.idl
+++ /dev/null
@@ -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
index d93f89cb58..6f92adceaf 100644
--- a/widget/cocoa/nsWindowMap.mm
+++ b/widget/cocoa/nsWindowMap.mm
@@ -115,31 +115,31 @@
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
if ((self = [super init])) {
- [[NSNotificationCenter defaultCenter]
+ [NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(windowBecameKey:)
name:NSWindowDidBecomeKeyNotification
object:inWindow];
- [[NSNotificationCenter defaultCenter]
+ [NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(windowResignedKey:)
name:NSWindowDidResignKeyNotification
object:inWindow];
- [[NSNotificationCenter defaultCenter]
+ [NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(windowBecameMain:)
name:NSWindowDidBecomeMainNotification
object:inWindow];
- [[NSNotificationCenter defaultCenter]
+ [NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(windowResignedMain:)
name:NSWindowDidResignMainNotification
object:inWindow];
- [[NSNotificationCenter defaultCenter]
+ [NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(windowWillClose:)
name:NSWindowWillCloseNotification
@@ -153,7 +153,7 @@
- (void)dealloc {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
- [[NSNotificationCenter defaultCenter] removeObserver:self];
+ [NSNotificationCenter.defaultCenter removeObserver:self];
[super dealloc];
NS_OBJC_END_TRY_IGNORE_BLOCK;
@@ -171,7 +171,7 @@
+ (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;
@@ -191,7 +191,7 @@
+ (void)deactivateInWindow:(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;
@@ -205,9 +205,10 @@
+ (void)activateInWindowViews:(NSWindow*)aWindow {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
- id firstResponder = [aWindow firstResponder];
- if ([firstResponder isKindOfClass:[ChildView class]])
+ id firstResponder = aWindow.firstResponder;
+ if ([firstResponder isKindOfClass:[ChildView class]]) {
[firstResponder viewsWindowDidBecomeKey];
+ }
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
@@ -217,9 +218,10 @@
+ (void)deactivateInWindowViews:(NSWindow*)aWindow {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
- id firstResponder = [aWindow firstResponder];
- if ([firstResponder isKindOfClass:[ChildView class]])
+ id firstResponder = aWindow.firstResponder;
+ if ([firstResponder isKindOfClass:[ChildView class]]) {
[firstResponder viewsWindowDidResignKey];
+ }
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
@@ -230,23 +232,23 @@
// should be sent when a native window becomes key, and the NS_DEACTIVATE
// event should be sent when it resignes key.
- (void)windowBecameKey:(NSNotification*)inNotification {
- NSWindow* window = (NSWindow*)[inNotification object];
+ NSWindow* window = inNotification.object;
- id delegate = [window delegate];
+ id delegate = window.delegate;
if (!delegate || ![delegate isKindOfClass:[WindowDelegate class]]) {
[TopLevelWindowData activateInWindowViews:window];
- } else if ([window isSheet] || [NSApp modalWindow]) {
+ } else if (window.isSheet || NSApp.modalWindow) {
[TopLevelWindowData activateInWindow:window];
}
}
- (void)windowResignedKey:(NSNotification*)inNotification {
- NSWindow* window = (NSWindow*)[inNotification object];
+ NSWindow* window = inNotification.object;
- id delegate = [window delegate];
+ id delegate = window.delegate;
if (!delegate || ![delegate isKindOfClass:[WindowDelegate class]]) {
[TopLevelWindowData deactivateInWindowViews:window];
- } else if ([window isSheet] || [NSApp modalWindow]) {
+ } else if (window.isSheet || NSApp.modalWindow) {
[TopLevelWindowData deactivateInWindow:window];
}
}
@@ -255,24 +257,24 @@
// state). So (for non-embedders) we need to ensure that a top-level window
// is main when an NS_ACTIVATE event is sent to Gecko for it.
- (void)windowBecameMain:(NSNotification*)inNotification {
- NSWindow* window = (NSWindow*)[inNotification object];
-
- id delegate = [window delegate];
+ NSWindow* window = inNotification.object;
+ id delegate = window.delegate;
// Don't send events to a top-level window that has a sheet/modal-window open
// above it -- as far as Gecko is concerned, it's inactive, and stays so until
// the sheet/modal-window closes.
if (delegate && [delegate isKindOfClass:[WindowDelegate class]] &&
- ![window attachedSheet] && ![NSApp modalWindow])
+ !window.attachedSheet && !NSApp.modalWindow) {
[TopLevelWindowData activateInWindow:window];
+ }
}
- (void)windowResignedMain:(NSNotification*)inNotification {
- NSWindow* window = (NSWindow*)[inNotification object];
-
- id delegate = [window delegate];
+ NSWindow* window = inNotification.object;
+ id delegate = window.delegate;
if (delegate && [delegate isKindOfClass:[WindowDelegate class]] &&
- ![window attachedSheet] && ![NSApp modalWindow])
+ ![window attachedSheet] && ![NSApp modalWindow]) {
[TopLevelWindowData deactivateInWindow:window];
+ }
}
- (void)windowWillClose:(NSNotification*)inNotification {