1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
|
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "components/remote_cocoa/app_shim/browser_native_widget_window_mac.h"
#import <AppKit/AppKit.h>
#include "base/mac/mac_util.h"
#include "components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h"
#include "components/remote_cocoa/common/native_widget_ns_window_host.mojom.h"
namespace {
// Workaround for https://crbug.com/1369643
const double kThinControllerHeight = 0.5;
} // namespace
@interface NSWindow (PrivateBrowserNativeWidgetAPI)
+ (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle;
@end
@interface NSThemeFrame (PrivateBrowserNativeWidgetAPI)
- (CGFloat)_titlebarHeight;
- (void)setStyleMask:(NSUInteger)styleMask;
- (void)setButtonRevealAmount:(double)amount;
@end
@interface BrowserWindowFrame : NativeWidgetMacNSWindowTitledFrame
@end
@implementation BrowserWindowFrame {
BOOL _inFullScreen;
BOOL _alwaysShowTrafficLights;
}
// NSThemeFrame overrides.
- (CGFloat)_titlebarHeight {
bool overrideTitlebarHeight = false;
float titlebarHeight = 0;
auto* window = base::apple::ObjCCast<NativeWidgetMacNSWindow>([self window]);
remote_cocoa::NativeWidgetNSWindowBridge* bridge = [window bridge];
if (!bridge) {
return [super _titlebarHeight];
}
// Ignore the overridden titlebar height when in fullscreen unless
// kImmersiveFullscreenTabs is enabled and the toolbar is visible. The
// toolbar is hidden during content fullscreen.
// In short the titlebar will be the same size during non-fullscreen and
// kImmersiveFullscreenTabs fullscreen. During content fullscreen the toolbar
// is hidden and the titlebar will be smaller default height.
if (!_inFullScreen || bridge->ShouldUseCustomTitlebarHeightForFullscreen()) {
bridge->host()->GetWindowFrameTitlebarHeight(&overrideTitlebarHeight,
&titlebarHeight);
}
if (overrideTitlebarHeight) {
return titlebarHeight;
}
return [super _titlebarHeight];
}
- (void)setStyleMask:(NSUInteger)styleMask {
_inFullScreen = (styleMask & NSWindowStyleMaskFullScreen) != 0;
[super setStyleMask:styleMask];
}
- (BOOL)_shouldCenterTrafficLights {
return YES;
}
- (void)setButtonRevealAmount:(double)amount {
// Don't override the reveal amount sent to `super`. `-[NSThemeFrame
// setButtonRevealAmount:]` performs layout operations in addition to
// adjusting the visibility of the traffic lights. The layout changes are
// desired and should be left intact.
[super setButtonRevealAmount:amount];
if (amount == 1.0) {
return;
}
[self maybeShowTrafficLights];
}
- (void)setAlwaysShowTrafficLights:(BOOL)alwaysShow {
_alwaysShowTrafficLights = alwaysShow;
[self maybeShowTrafficLights];
}
- (void)maybeShowTrafficLights {
if (!_alwaysShowTrafficLights) {
return;
}
NSWindow* window = [self window];
[[window standardWindowButton:NSWindowCloseButton] setAlphaValue:1.0];
[[window standardWindowButton:NSWindowMiniaturizeButton] setAlphaValue:1.0];
[[window standardWindowButton:NSWindowZoomButton] setAlphaValue:1.0];
}
@end
@implementation BrowserNativeWidgetWindow
@synthesize thinTitlebarViewController = _thinTitlebarViewController;
// NSWindow (PrivateAPI) overrides.
+ (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle {
// - NSThemeFrame and its subclasses will be nil if it's missing at runtime.
if ([BrowserWindowFrame class])
return [BrowserWindowFrame class];
return [super frameViewClassForStyleMask:windowStyle];
}
- (instancetype)initWithContentRect:(NSRect)contentRect
styleMask:(NSUInteger)windowStyle
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)deferCreation {
if ((self = [super initWithContentRect:contentRect
styleMask:windowStyle
backing:bufferingType
defer:deferCreation])) {
[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(windowDidBecomeKey:)
name:NSWindowDidBecomeKeyNotification
object:nil];
if (base::mac::MacOSMajorVersion() >= 13) {
_thinTitlebarViewController =
[[NSTitlebarAccessoryViewController alloc] init];
NSView* thinView = [[NSView alloc] init];
thinView.wantsLayer = YES;
thinView.layer.backgroundColor = NSColor.blackColor.CGColor;
_thinTitlebarViewController.view = thinView;
_thinTitlebarViewController.layoutAttribute = NSLayoutAttributeBottom;
_thinTitlebarViewController.fullScreenMinHeight = kThinControllerHeight;
_thinTitlebarViewController.hidden = YES;
[self addTitlebarAccessoryViewController:_thinTitlebarViewController];
}
}
return self;
}
- (void)dealloc {
[NSNotificationCenter.defaultCenter removeObserver:self];
}
- (void)windowDidBecomeKey:(NSNotification*)notify {
// NSToolbarFullScreenWindow should never become the key window, otherwise
// the browser window will appear inactive. Activate the browser window
// when this happens.
NSWindow* toolbarWindow = notify.object;
if (toolbarWindow.parentWindow == self &&
remote_cocoa::IsNSToolbarFullScreenWindow(toolbarWindow)) {
[self makeKeyAndOrderFront:nil];
}
}
// The base implementation returns YES if the window's frame view is a custom
// class, which causes undesirable changes in behavior. AppKit NSWindow
// subclasses are known to override it and return NO.
- (BOOL)_usesCustomDrawing {
return NO;
}
// Handle "Move focus to the window toolbar" configured in System Preferences ->
// Keyboard -> Shortcuts -> Keyboard. Usually Ctrl+F5. The argument (|unknown|)
// tends to just be nil.
- (void)_handleFocusToolbarHotKey:(id)unknown {
remote_cocoa::NativeWidgetNSWindowBridge* bridge = [self bridge];
if (bridge)
bridge->host()->OnFocusWindowToolbar();
}
- (void)setAlwaysShowTrafficLights:(BOOL)alwaysShow {
[base::apple::ObjCCastStrict<BrowserWindowFrame>(self.contentView.superview)
setAlwaysShowTrafficLights:alwaysShow];
}
@end
|