summaryrefslogtreecommitdiff
path: root/widget/cocoa/VibrancyManager.mm
diff options
context:
space:
mode:
Diffstat (limited to 'widget/cocoa/VibrancyManager.mm')
-rw-r--r--widget/cocoa/VibrancyManager.mm244
1 files changed, 0 insertions, 244 deletions
diff --git a/widget/cocoa/VibrancyManager.mm b/widget/cocoa/VibrancyManager.mm
deleted file mode 100644
index d02338eb6b..0000000000
--- a/widget/cocoa/VibrancyManager.mm
+++ /dev/null
@@ -1,244 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; 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 "VibrancyManager.h"
-#include "nsChildView.h"
-#import <objc/message.h>
-
-using namespace mozilla;
-
-void
-VibrancyManager::UpdateVibrantRegion(VibrancyType aType,
- const LayoutDeviceIntRegion& aRegion)
-{
- if (aRegion.IsEmpty()) {
- mVibrantRegions.Remove(uint32_t(aType));
- return;
- }
- auto& vr = *mVibrantRegions.LookupOrAdd(uint32_t(aType));
- vr.UpdateRegion(aRegion, mCoordinateConverter, mContainerView, ^() {
- return this->CreateEffectView(aType);
- });
-}
-
-@interface NSView(CurrentFillColor)
-- (NSColor*)_currentFillColor;
-@end
-
-static NSColor*
-AdjustedColor(NSColor* aFillColor, VibrancyType aType)
-{
- if (aType == VibrancyType::MENU && [aFillColor alphaComponent] == 1.0) {
- // The opaque fill color that's used for the menu background when "Reduce
- // vibrancy" is checked in the system accessibility prefs is too dark.
- // This is probably because we're not using the right material for menus,
- // see VibrancyManager::CreateEffectView.
- return [NSColor colorWithDeviceWhite:0.96 alpha:1.0];
- }
- return aFillColor;
-}
-
-NSColor*
-VibrancyManager::VibrancyFillColorForType(VibrancyType aType)
-{
- NSView* view = mVibrantRegions.LookupOrAdd(uint32_t(aType))->GetAnyView();
-
- if (view && [view respondsToSelector:@selector(_currentFillColor)]) {
- // -[NSVisualEffectView _currentFillColor] is the color that the view
- // draws in its drawRect implementation.
- return AdjustedColor([view _currentFillColor], aType);
- }
- return [NSColor whiteColor];
-}
-
-@interface NSView(FontSmoothingBackgroundColor)
-- (NSColor*)fontSmoothingBackgroundColor;
-@end
-
-NSColor*
-VibrancyManager::VibrancyFontSmoothingBackgroundColorForType(VibrancyType aType)
-{
- NSView* view = mVibrantRegions.LookupOrAdd(uint32_t(aType))->GetAnyView();
-
- if (view && [view respondsToSelector:@selector(fontSmoothingBackgroundColor)]) {
- return [view fontSmoothingBackgroundColor];
- }
- return [NSColor clearColor];
-}
-
-static NSView*
-HitTestNil(id self, SEL _cmd, NSPoint aPoint)
-{
- // This view must be transparent to mouse events.
- return nil;
-}
-
-static BOOL
-AllowsVibrancyYes(id self, SEL _cmd)
-{
- // Means that the foreground is blended using a vibrant blend mode.
- return YES;
-}
-
-static Class
-CreateEffectViewClass(BOOL aForegroundVibrancy, BOOL aIsContainer)
-{
- // Create a class that inherits from NSVisualEffectView and overrides the
- // methods -[NSView hitTest:] and -[NSVisualEffectView allowsVibrancy].
- Class NSVisualEffectViewClass = NSClassFromString(@"NSVisualEffectView");
- const char* className = aForegroundVibrancy
- ? "EffectViewWithForegroundVibrancy" : "EffectViewWithoutForegroundVibrancy";
- Class EffectViewClass = objc_allocateClassPair(NSVisualEffectViewClass, className, 0);
- if (!aIsContainer) {
- class_addMethod(EffectViewClass, @selector(hitTest:), (IMP)HitTestNil,
- "@@:{CGPoint=dd}");
- }
- if (aForegroundVibrancy) {
- // Override the -[NSView allowsVibrancy] method to return YES.
- class_addMethod(EffectViewClass, @selector(allowsVibrancy), (IMP)AllowsVibrancyYes, "I@:");
- }
- return EffectViewClass;
-}
-
-static id
-AppearanceForVibrancyType(VibrancyType aType)
-{
- Class NSAppearanceClass = NSClassFromString(@"NSAppearance");
- switch (aType) {
- case VibrancyType::LIGHT:
- case VibrancyType::TOOLTIP:
- case VibrancyType::MENU:
- case VibrancyType::HIGHLIGHTED_MENUITEM:
- case VibrancyType::SHEET:
- case VibrancyType::SOURCE_LIST:
- case VibrancyType::SOURCE_LIST_SELECTION:
- case VibrancyType::ACTIVE_SOURCE_LIST_SELECTION:
- return [NSAppearanceClass performSelector:@selector(appearanceNamed:)
- withObject:@"NSAppearanceNameVibrantLight"];
- case VibrancyType::DARK:
- return [NSAppearanceClass performSelector:@selector(appearanceNamed:)
- withObject:@"NSAppearanceNameVibrantDark"];
- }
-}
-
-#if !defined(MAC_OS_X_VERSION_10_10) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_10
-enum {
- NSVisualEffectStateFollowsWindowActiveState,
- NSVisualEffectStateActive,
- NSVisualEffectStateInactive
-};
-
-enum {
- NSVisualEffectMaterialTitlebar = 3
-};
-#endif
-
-#if !defined(MAC_OS_X_VERSION_10_11) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_11
-enum {
- NSVisualEffectMaterialMenu = 5,
- NSVisualEffectMaterialSidebar = 7
-};
-#endif
-
-static NSUInteger
-VisualEffectStateForVibrancyType(VibrancyType aType)
-{
- switch (aType) {
- case VibrancyType::TOOLTIP:
- case VibrancyType::MENU:
- case VibrancyType::HIGHLIGHTED_MENUITEM:
- case VibrancyType::SHEET:
- // Tooltip and menu windows are never "key" and sheets always looks
- // active, so we need to tell the vibrancy effect to look active
- // regardless of window state.
- return NSVisualEffectStateActive;
- default:
- return NSVisualEffectStateFollowsWindowActiveState;
- }
-}
-
-static BOOL
-HasVibrantForeground(VibrancyType aType)
-{
- switch (aType) {
- case VibrancyType::MENU:
- return YES;
- default:
- return NO;
- }
-}
-
-#if !defined(MAC_OS_X_VERSION_10_12) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12
-enum {
- NSVisualEffectMaterialSelection = 4
-};
-#endif
-
-@interface NSView(NSVisualEffectViewMethods)
-- (void)setState:(NSUInteger)state;
-- (void)setMaterial:(NSUInteger)material;
-- (void)setEmphasized:(BOOL)emphasized;
-@end
-
-NSView*
-VibrancyManager::CreateEffectView(VibrancyType aType, BOOL aIsContainer)
-{
- static Class EffectViewWithoutForegroundVibrancy = CreateEffectViewClass(NO, NO);
- static Class EffectViewWithForegroundVibrancy = CreateEffectViewClass(YES, NO);
- static Class EffectViewContainer = CreateEffectViewClass(NO, YES);
-
- // Pick the right NSVisualEffectView subclass for the desired vibrancy mode.
- // For "container" views, never use foreground vibrancy, because returning
- // YES from allowsVibrancy forces on foreground vibrancy for all descendant
- // views which can have unintended effects.
- Class EffectViewClass = aIsContainer
- ? EffectViewContainer
- : (HasVibrantForeground(aType) ? EffectViewWithForegroundVibrancy
- : EffectViewWithoutForegroundVibrancy);
- NSView* effectView = [[EffectViewClass alloc] initWithFrame:NSZeroRect];
- [effectView performSelector:@selector(setAppearance:)
- withObject:AppearanceForVibrancyType(aType)];
- [effectView setState:VisualEffectStateForVibrancyType(aType)];
-
- BOOL canUseElCapitanMaterials = nsCocoaFeatures::OnElCapitanOrLater();
- if (aType == VibrancyType::MENU) {
- // Before 10.11 there is no material that perfectly matches the menu
- // look. Of all available material types, NSVisualEffectMaterialTitlebar
- // is the one that comes closest.
- [effectView setMaterial:canUseElCapitanMaterials ? NSVisualEffectMaterialMenu
- : NSVisualEffectMaterialTitlebar];
- } else if (aType == VibrancyType::SOURCE_LIST && canUseElCapitanMaterials) {
- [effectView setMaterial:NSVisualEffectMaterialSidebar];
- } else if (aType == VibrancyType::HIGHLIGHTED_MENUITEM ||
- aType == VibrancyType::SOURCE_LIST_SELECTION ||
- aType == VibrancyType::ACTIVE_SOURCE_LIST_SELECTION) {
- [effectView setMaterial:NSVisualEffectMaterialSelection];
- if ([effectView respondsToSelector:@selector(setEmphasized:)] &&
- aType != VibrancyType::SOURCE_LIST_SELECTION) {
- [effectView setEmphasized:YES];
- }
- }
-
- return effectView;
-}
-
-static bool
-ComputeSystemSupportsVibrancy()
-{
-#ifdef __x86_64__
- return NSClassFromString(@"NSAppearance") &&
- NSClassFromString(@"NSVisualEffectView");
-#else
- // objc_allocateClassPair doesn't work in 32 bit mode, so turn off vibrancy.
- return false;
-#endif
-}
-
-/* static */ bool
-VibrancyManager::SystemSupportsVibrancy()
-{
- static bool supportsVibrancy = ComputeSystemSupportsVibrancy();
- return supportsVibrancy;
-}