chore: put NativeWindowMac's methods in order (#27040)

This commit is contained in:
Cheng Zhao 2020-12-18 09:50:51 +09:00 committed by GitHub
parent a55e028b12
commit f99ea7c0ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 222 additions and 228 deletions

View file

@ -236,7 +236,7 @@ class NativeWindow : public base::SupportsUserData,
const std::string& display_name);
virtual void CloseFilePreview();
virtual void SetGTKDarkThemeEnabled(bool use_dark_theme) = 0;
virtual void SetGTKDarkThemeEnabled(bool use_dark_theme) {}
// Converts between content bounds and window bounds.
virtual gfx::Rect ContentBoundsToWindowBounds(

View file

@ -32,11 +32,6 @@ class NativeWindowMac : public NativeWindow, public ui::NativeThemeObserver {
NativeWindowMac(const gin_helper::Dictionary& options, NativeWindow* parent);
~NativeWindowMac() override;
// Cleanup observers when window is getting closed. Note that the destructor
// can be called much later after window gets closed, so we should not do
// cleanup in destructor.
void Cleanup();
// NativeWindow:
void SetContentView(views::View* view) override;
void Close() override;
@ -68,11 +63,6 @@ class NativeWindowMac : public NativeWindow, public ui::NativeThemeObserver {
void MoveTop() override;
bool IsResizable() override;
void SetMovable(bool movable) override;
void SetAspectRatio(double aspect_ratio,
const gfx::Size& extra_size) override;
void PreviewFile(const std::string& path,
const std::string& display_name) override;
void CloseFilePreview() override;
bool IsMovable() override;
void SetMinimizable(bool minimizable) override;
bool IsMinimizable() override;
@ -122,32 +112,38 @@ class NativeWindowMac : public NativeWindow, public ui::NativeThemeObserver {
void SetProgressBar(double progress, const ProgressState state) override;
void SetOverlayIcon(const gfx::Image& overlay,
const std::string& description) override;
void SetVisibleOnAllWorkspaces(bool visible,
bool visibleOnFullScreen) override;
bool IsVisibleOnAllWorkspaces() override;
void SetAutoHideCursor(bool auto_hide) override;
void SetVibrancy(const std::string& type) override;
void SetTrafficLightPosition(base::Optional<gfx::Point> position) override;
base::Optional<gfx::Point> GetTrafficLightPosition() const override;
void RedrawTrafficLights() override;
void SetTouchBar(
std::vector<gin_helper::PersistentDictionary> items) override;
void RefreshTouchBarItem(const std::string& item_id) override;
void SetEscapeTouchBarItem(gin_helper::PersistentDictionary item) override;
void SelectPreviousTab() override;
void SelectNextTab() override;
void MergeAllWindows() override;
void MoveTabToNewWindow() override;
void ToggleTabBar() override;
bool AddTabbedWindow(NativeWindow* window) override;
bool SetWindowButtonVisibility(bool visible) override;
void SetVibrancy(const std::string& type) override;
void SetTouchBar(
std::vector<gin_helper::PersistentDictionary> items) override;
void RefreshTouchBarItem(const std::string& item_id) override;
void SetEscapeTouchBarItem(gin_helper::PersistentDictionary item) override;
void SetGTKDarkThemeEnabled(bool use_dark_theme) override {}
void SetAspectRatio(double aspect_ratio,
const gfx::Size& extra_size) override;
void PreviewFile(const std::string& path,
const std::string& display_name) override;
void CloseFilePreview() override;
gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const override;
gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const override;
// Cleanup observers when window is getting closed. Note that the destructor
// can be called much later after window gets closed, so we should not do
// cleanup in destructor.
void Cleanup();
// Use a custom content view instead of Chromium's BridgedContentView.
void OverrideNSWindowContentView();
@ -156,12 +152,7 @@ class NativeWindowMac : public NativeWindow, public ui::NativeThemeObserver {
void SetCollectionBehavior(bool on, NSUInteger flag);
void SetWindowLevel(int level);
// Custom traffic light positioning
void RedrawTrafficLights() override;
void SetExitingFullScreen(bool flag);
void SetTrafficLightPosition(base::Optional<gfx::Point> position) override;
base::Optional<gfx::Point> GetTrafficLightPosition() const override;
void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override;
enum class VisualEffectState {
kFollowWindow,
@ -189,6 +180,9 @@ class NativeWindowMac : public NativeWindow, public ui::NativeThemeObserver {
bool CanResize() const override;
views::View* GetContentsView() override;
// ui::NativeThemeObserver:
void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override;
private:
// Add custom layers to the content view.
void AddContentViewLayers(bool minimizable, bool closable);

View file

@ -540,73 +540,6 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
NativeWindowMac::~NativeWindowMac() {}
void NativeWindowMac::Cleanup() {
DCHECK(!IsClosed());
ui::NativeTheme::GetInstanceForNativeUi()->RemoveObserver(this);
[NSEvent removeMonitor:wheel_event_monitor_];
}
void NativeWindowMac::RedrawTrafficLights() {
// Ensure maximizable options retain pre-existing state.
SetMaximizable(maximizable_);
// Changing system titlebar is only allowed for "hidden" titleBarStyle.
if (!traffic_light_position_ || title_bar_style_ != TitleBarStyle::kHidden)
return;
if (IsFullscreen())
return;
NSWindow* window = window_;
NSButton* close = [window standardWindowButton:NSWindowCloseButton];
NSButton* miniaturize =
[window standardWindowButton:NSWindowMiniaturizeButton];
NSButton* zoom = [window standardWindowButton:NSWindowZoomButton];
// Safety check just in case apple changes the view structure in a macOS
// update
DCHECK(close.superview);
DCHECK(close.superview.superview);
if (!close.superview || !close.superview.superview)
return;
NSView* titleBarContainerView = close.superview.superview;
// Hide the container when exiting fullscreen, otherwise traffic light buttons
// jump
if (exiting_fullscreen_) {
[titleBarContainerView setHidden:YES];
return;
}
[titleBarContainerView setHidden:NO];
CGFloat buttonHeight = [close frame].size.height;
CGFloat titleBarFrameHeight = buttonHeight + traffic_light_position_->y();
CGRect titleBarRect = titleBarContainerView.frame;
CGFloat titleBarWidth = NSWidth(titleBarRect);
titleBarRect.size.height = titleBarFrameHeight;
titleBarRect.origin.y = window.frame.size.height - titleBarFrameHeight;
[titleBarContainerView setFrame:titleBarRect];
BOOL isRTL = [titleBarContainerView userInterfaceLayoutDirection] ==
NSUserInterfaceLayoutDirectionRightToLeft;
NSArray* windowButtons = @[ close, miniaturize, zoom ];
const CGFloat space_between =
[miniaturize frame].origin.x - [close frame].origin.x;
for (NSUInteger i = 0; i < windowButtons.count; i++) {
NSView* view = [windowButtons objectAtIndex:i];
CGRect rect = [view frame];
if (isRTL) {
CGFloat buttonWidth = NSWidth(rect);
// origin is always top-left, even in RTL
rect.origin.x = titleBarWidth - traffic_light_position_->x() +
(i * space_between) - buttonWidth;
} else {
rect.origin.x = traffic_light_position_->x() + (i * space_between);
}
rect.origin.y = (titleBarFrameHeight - rect.size.height) / 2;
[view setFrameOrigin:rect.origin];
}
}
void NativeWindowMac::SetContentView(views::View* view) {
views::View* root_view = GetContentsView();
if (content_view())
@ -716,16 +649,6 @@ bool NativeWindowMac::IsVisible() {
return [window_ isVisible] && !occluded && !IsMinimized();
}
void NativeWindowMac::SetExitingFullScreen(bool flag) {
exiting_fullscreen_ = flag;
}
void NativeWindowMac::OnNativeThemeUpdated(ui::NativeTheme* observed_theme) {
base::PostTask(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&NativeWindow::RedrawTrafficLights, GetWeakPtr()));
}
bool NativeWindowMac::IsEnabled() {
return [window_ attachedSheet] == nil;
}
@ -902,31 +825,6 @@ bool NativeWindowMac::IsResizable() {
return [window_ styleMask] & NSWindowStyleMaskResizable;
}
void NativeWindowMac::SetAspectRatio(double aspect_ratio,
const gfx::Size& extra_size) {
NativeWindow::SetAspectRatio(aspect_ratio, extra_size);
// Reset the behaviour to default if aspect_ratio is set to 0 or less.
if (aspect_ratio > 0.0)
[window_ setAspectRatio:NSMakeSize(aspect_ratio, 1.0)];
else
[window_ setResizeIncrements:NSMakeSize(1.0, 1.0)];
}
void NativeWindowMac::PreviewFile(const std::string& path,
const std::string& display_name) {
preview_item_.reset([[ElectronPreviewItem alloc]
initWithURL:[NSURL fileURLWithPath:base::SysUTF8ToNSString(path)]
title:base::SysUTF8ToNSString(display_name)]);
[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil];
}
void NativeWindowMac::CloseFilePreview() {
if ([QLPreviewPanel sharedPreviewPanelExists]) {
[[QLPreviewPanel sharedPreviewPanel] close];
}
}
void NativeWindowMac::SetMovable(bool movable) {
[window_ setMovable:movable];
}
@ -1406,60 +1304,6 @@ void NativeWindowMac::SetAutoHideCursor(bool auto_hide) {
[window_ setDisableAutoHideCursor:!auto_hide];
}
void NativeWindowMac::SelectPreviousTab() {
if (@available(macOS 10.12, *)) {
[window_ selectPreviousTab:nil];
}
}
void NativeWindowMac::SelectNextTab() {
if (@available(macOS 10.12, *)) {
[window_ selectNextTab:nil];
}
}
void NativeWindowMac::MergeAllWindows() {
if (@available(macOS 10.12, *)) {
[window_ mergeAllWindows:nil];
}
}
void NativeWindowMac::MoveTabToNewWindow() {
if (@available(macOS 10.12, *)) {
[window_ moveTabToNewWindow:nil];
}
}
void NativeWindowMac::ToggleTabBar() {
if (@available(macOS 10.12, *)) {
[window_ toggleTabBar:nil];
}
}
bool NativeWindowMac::AddTabbedWindow(NativeWindow* window) {
if (window_ == window->GetNativeWindow().GetNativeNSWindow()) {
return false;
} else {
if (@available(macOS 10.12, *))
[window_ addTabbedWindow:window->GetNativeWindow().GetNativeNSWindow()
ordered:NSWindowAbove];
}
return true;
}
bool NativeWindowMac::SetWindowButtonVisibility(bool visible) {
if (title_bar_style_ == TitleBarStyle::kCustomButtonsOnHover) {
return false;
}
window_button_visibility_ = visible;
[[window_ standardWindowButton:NSWindowCloseButton] setHidden:!visible];
[[window_ standardWindowButton:NSWindowMiniaturizeButton] setHidden:!visible];
[[window_ standardWindowButton:NSWindowZoomButton] setHidden:!visible];
return true;
}
void NativeWindowMac::SetVibrancy(const std::string& type) {
NSView* vibrant_view = [window_ vibrantView];
@ -1611,6 +1455,67 @@ base::Optional<gfx::Point> NativeWindowMac::GetTrafficLightPosition() const {
return traffic_light_position_;
}
void NativeWindowMac::RedrawTrafficLights() {
// Ensure maximizable options retain pre-existing state.
SetMaximizable(maximizable_);
// Changing system titlebar is only allowed for "hidden" titleBarStyle.
if (!traffic_light_position_ || title_bar_style_ != TitleBarStyle::kHidden)
return;
if (IsFullscreen())
return;
NSWindow* window = window_;
NSButton* close = [window standardWindowButton:NSWindowCloseButton];
NSButton* miniaturize =
[window standardWindowButton:NSWindowMiniaturizeButton];
NSButton* zoom = [window standardWindowButton:NSWindowZoomButton];
// Safety check just in case apple changes the view structure in a macOS
// update
DCHECK(close.superview);
DCHECK(close.superview.superview);
if (!close.superview || !close.superview.superview)
return;
NSView* titleBarContainerView = close.superview.superview;
// Hide the container when exiting fullscreen, otherwise traffic light buttons
// jump
if (exiting_fullscreen_) {
[titleBarContainerView setHidden:YES];
return;
}
[titleBarContainerView setHidden:NO];
CGFloat buttonHeight = [close frame].size.height;
CGFloat titleBarFrameHeight = buttonHeight + traffic_light_position_->y();
CGRect titleBarRect = titleBarContainerView.frame;
CGFloat titleBarWidth = NSWidth(titleBarRect);
titleBarRect.size.height = titleBarFrameHeight;
titleBarRect.origin.y = window.frame.size.height - titleBarFrameHeight;
[titleBarContainerView setFrame:titleBarRect];
BOOL isRTL = [titleBarContainerView userInterfaceLayoutDirection] ==
NSUserInterfaceLayoutDirectionRightToLeft;
NSArray* windowButtons = @[ close, miniaturize, zoom ];
const CGFloat space_between =
[miniaturize frame].origin.x - [close frame].origin.x;
for (NSUInteger i = 0; i < windowButtons.count; i++) {
NSView* view = [windowButtons objectAtIndex:i];
CGRect rect = [view frame];
if (isRTL) {
CGFloat buttonWidth = NSWidth(rect);
// origin is always top-left, even in RTL
rect.origin.x = titleBarWidth - traffic_light_position_->x() +
(i * space_between) - buttonWidth;
} else {
rect.origin.x = traffic_light_position_->x() + (i * space_between);
}
rect.origin.y = (titleBarFrameHeight - rect.size.height) / 2;
[view setFrameOrigin:rect.origin];
}
}
void NativeWindowMac::SetTouchBar(
std::vector<gin_helper::PersistentDictionary> items) {
if (@available(macOS 10.12.2, *)) {
@ -1638,6 +1543,85 @@ void NativeWindowMac::SetEscapeTouchBarItem(
}
}
void NativeWindowMac::SelectPreviousTab() {
if (@available(macOS 10.12, *)) {
[window_ selectPreviousTab:nil];
}
}
void NativeWindowMac::SelectNextTab() {
if (@available(macOS 10.12, *)) {
[window_ selectNextTab:nil];
}
}
void NativeWindowMac::MergeAllWindows() {
if (@available(macOS 10.12, *)) {
[window_ mergeAllWindows:nil];
}
}
void NativeWindowMac::MoveTabToNewWindow() {
if (@available(macOS 10.12, *)) {
[window_ moveTabToNewWindow:nil];
}
}
void NativeWindowMac::ToggleTabBar() {
if (@available(macOS 10.12, *)) {
[window_ toggleTabBar:nil];
}
}
bool NativeWindowMac::AddTabbedWindow(NativeWindow* window) {
if (window_ == window->GetNativeWindow().GetNativeNSWindow()) {
return false;
} else {
if (@available(macOS 10.12, *))
[window_ addTabbedWindow:window->GetNativeWindow().GetNativeNSWindow()
ordered:NSWindowAbove];
}
return true;
}
bool NativeWindowMac::SetWindowButtonVisibility(bool visible) {
if (title_bar_style_ == TitleBarStyle::kCustomButtonsOnHover) {
return false;
}
window_button_visibility_ = visible;
[[window_ standardWindowButton:NSWindowCloseButton] setHidden:!visible];
[[window_ standardWindowButton:NSWindowMiniaturizeButton] setHidden:!visible];
[[window_ standardWindowButton:NSWindowZoomButton] setHidden:!visible];
return true;
}
void NativeWindowMac::SetAspectRatio(double aspect_ratio,
const gfx::Size& extra_size) {
NativeWindow::SetAspectRatio(aspect_ratio, extra_size);
// Reset the behaviour to default if aspect_ratio is set to 0 or less.
if (aspect_ratio > 0.0)
[window_ setAspectRatio:NSMakeSize(aspect_ratio, 1.0)];
else
[window_ setResizeIncrements:NSMakeSize(1.0, 1.0)];
}
void NativeWindowMac::PreviewFile(const std::string& path,
const std::string& display_name) {
preview_item_.reset([[ElectronPreviewItem alloc]
initWithURL:[NSURL fileURLWithPath:base::SysUTF8ToNSString(path)]
title:base::SysUTF8ToNSString(display_name)]);
[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil];
}
void NativeWindowMac::CloseFilePreview() {
if ([QLPreviewPanel sharedPreviewPanelExists]) {
[[QLPreviewPanel sharedPreviewPanel] close];
}
}
gfx::Rect NativeWindowMac::ContentBoundsToWindowBounds(
const gfx::Rect& bounds) const {
if (has_frame()) {
@ -1664,6 +1648,60 @@ gfx::Rect NativeWindowMac::WindowBoundsToContentBounds(
}
}
void NativeWindowMac::Cleanup() {
DCHECK(!IsClosed());
ui::NativeTheme::GetInstanceForNativeUi()->RemoveObserver(this);
[NSEvent removeMonitor:wheel_event_monitor_];
}
void NativeWindowMac::OverrideNSWindowContentView() {
// When using `views::Widget` to hold WebContents, Chromium would use
// `BridgedContentView` as content view, which does not support draggable
// regions. In order to make draggable regions work, we have to replace the
// content view with a simple NSView.
if (has_frame()) {
container_view_.reset(
[[ElectronAdaptedContentView alloc] initWithShell:this]);
} else {
container_view_.reset([[FullSizeContentView alloc] init]);
[container_view_ setFrame:[[[window_ contentView] superview] bounds]];
}
[container_view_
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[window_ setContentView:container_view_];
AddContentViewLayers(IsMinimizable(), IsClosable());
}
void NativeWindowMac::SetStyleMask(bool on, NSUInteger flag) {
// Changing the styleMask of a frameless windows causes it to change size so
// we explicitly disable resizing while setting it.
ScopedDisableResize disable_resize;
bool was_maximizable = IsMaximizable();
if (on)
[window_ setStyleMask:[window_ styleMask] | flag];
else
[window_ setStyleMask:[window_ styleMask] & (~flag)];
// Change style mask will make the zoom button revert to default, probably
// a bug of Cocoa or macOS.
SetMaximizable(was_maximizable);
}
void NativeWindowMac::SetCollectionBehavior(bool on, NSUInteger flag) {
bool was_maximizable = IsMaximizable();
if (on)
[window_ setCollectionBehavior:[window_ collectionBehavior] | flag];
else
[window_ setCollectionBehavior:[window_ collectionBehavior] & (~flag)];
// Change collectionBehavior will make the zoom button revert to default,
// probably a bug of Cocoa or macOS.
SetMaximizable(was_maximizable);
}
void NativeWindowMac::SetExitingFullScreen(bool flag) {
exiting_fullscreen_ = flag;
}
bool NativeWindowMac::CanResize() const {
return resizable_;
}
@ -1672,6 +1710,12 @@ views::View* NativeWindowMac::GetContentsView() {
return root_view_.get();
}
void NativeWindowMac::OnNativeThemeUpdated(ui::NativeTheme* observed_theme) {
base::PostTask(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&NativeWindow::RedrawTrafficLights, GetWeakPtr()));
}
void NativeWindowMac::AddContentViewLayers(bool minimizable, bool closable) {
// Make sure the bottom corner is rounded for non-modal windows:
// http://crbug.com/396264.
@ -1763,50 +1807,6 @@ void NativeWindowMac::SetForwardMouseMessages(bool forward) {
[window_ setAcceptsMouseMovedEvents:forward];
}
void NativeWindowMac::OverrideNSWindowContentView() {
// When using `views::Widget` to hold WebContents, Chromium would use
// `BridgedContentView` as content view, which does not support draggable
// regions. In order to make draggable regions work, we have to replace the
// content view with a simple NSView.
if (has_frame()) {
container_view_.reset(
[[ElectronAdaptedContentView alloc] initWithShell:this]);
} else {
container_view_.reset([[FullSizeContentView alloc] init]);
[container_view_ setFrame:[[[window_ contentView] superview] bounds]];
}
[container_view_
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[window_ setContentView:container_view_];
AddContentViewLayers(IsMinimizable(), IsClosable());
}
void NativeWindowMac::SetStyleMask(bool on, NSUInteger flag) {
// Changing the styleMask of a frameless windows causes it to change size so
// we explicitly disable resizing while setting it.
ScopedDisableResize disable_resize;
bool was_maximizable = IsMaximizable();
if (on)
[window_ setStyleMask:[window_ styleMask] | flag];
else
[window_ setStyleMask:[window_ styleMask] & (~flag)];
// Change style mask will make the zoom button revert to default, probably
// a bug of Cocoa or macOS.
SetMaximizable(was_maximizable);
}
void NativeWindowMac::SetCollectionBehavior(bool on, NSUInteger flag) {
bool was_maximizable = IsMaximizable();
if (on)
[window_ setCollectionBehavior:[window_ collectionBehavior] | flag];
else
[window_ setCollectionBehavior:[window_ collectionBehavior] & (~flag)];
// Change collectionBehavior will make the zoom button revert to default,
// probably a bug of Cocoa or macOS.
SetMaximizable(was_maximizable);
}
// static
NativeWindow* NativeWindow::Create(const gin_helper::Dictionary& options,
NativeWindow* parent) {