fix: clean up implementations of titleBarStyle (#27489)

* Rewrite titleBarStyle impls with WindowButtonsView

* Remove fullscreenWindowTitle option

* Make buttons show correctly under RTL

* Fix docs about traffic lights position

* Fix test on fullscreen resizable

* Fix button states with closabe/minimizable/fullscreenable

* Fix typo

* Deprecate the fullscreenWindowTitle option
This commit is contained in:
Cheng Zhao 2021-01-31 08:15:10 +09:00 committed by GitHub
parent 6edf6c6a95
commit 8bf66f8974
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 262 additions and 304 deletions

View file

@ -91,14 +91,17 @@ using TitleBarStyle = electron::NativeWindowMac::TitleBarStyle;
- (void)windowDidBecomeMain:(NSNotification*)notification {
shell_->NotifyWindowFocus();
shell_->RedrawTrafficLights();
}
- (void)windowDidResignMain:(NSNotification*)notification {
shell_->NotifyWindowBlur();
shell_->RedrawTrafficLights();
}
- (void)windowDidBecomeKey:(NSNotification*)notification {
shell_->NotifyWindowIsKeyChanged(true);
shell_->RedrawTrafficLights();
}
- (void)windowDidResignKey:(NSNotification*)notification {
@ -110,6 +113,7 @@ using TitleBarStyle = electron::NativeWindowMac::TitleBarStyle;
return;
shell_->NotifyWindowIsKeyChanged(false);
shell_->RedrawTrafficLights();
}
- (NSSize)windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize {
@ -151,9 +155,6 @@ using TitleBarStyle = electron::NativeWindowMac::TitleBarStyle;
- (void)windowDidResize:(NSNotification*)notification {
[super windowDidResize:notification];
shell_->NotifyWindowResize();
if (shell_->title_bar_style() == TitleBarStyle::kHidden) {
shell_->RedrawTrafficLights();
}
}
- (void)windowWillMove:(NSNotification*)notification {
@ -212,75 +213,23 @@ using TitleBarStyle = electron::NativeWindowMac::TitleBarStyle;
}
- (void)windowWillEnterFullScreen:(NSNotification*)notification {
// Setting resizable to true before entering fullscreen
shell_->NotifyWindowWillEnterFullScreen();
// Setting resizable to true before entering fullscreen.
is_resizable_ = shell_->IsResizable();
shell_->SetResizable(true);
// Hide the native toolbar before entering fullscreen, so there is no visual
// artifacts.
if (shell_->title_bar_style() == TitleBarStyle::kHiddenInset) {
NSWindow* window = shell_->GetNativeWindow().GetNativeNSWindow();
[window setToolbar:nil];
}
}
- (void)windowDidEnterFullScreen:(NSNotification*)notification {
shell_->NotifyWindowEnterFullScreen();
// For frameless window we don't show set title for normal mode since the
// titlebar is expected to be empty, but after entering fullscreen mode we
// have to set one, because title bar is visible here.
NSWindow* window = shell_->GetNativeWindow().GetNativeNSWindow();
if ((shell_->transparent() || !shell_->has_frame()) &&
// FIXME(zcbenz): Showing titlebar for hiddenInset window is weird under
// fullscreen mode.
// Show title if fullscreen_window_title flag is set
(shell_->title_bar_style() != TitleBarStyle::kHiddenInset ||
shell_->fullscreen_window_title())) {
[window setTitleVisibility:NSWindowTitleVisible];
}
// Restore the native toolbar immediately after entering fullscreen, if we
// do this before leaving fullscreen, traffic light buttons will be jumping.
if (shell_->title_bar_style() == TitleBarStyle::kHiddenInset) {
base::scoped_nsobject<NSToolbar> toolbar(
[[NSToolbar alloc] initWithIdentifier:@"titlebarStylingToolbar"]);
[toolbar setShowsBaselineSeparator:NO];
[window setToolbar:toolbar];
// Set window style to hide the toolbar, otherwise the toolbar will show
// in fullscreen mode.
[window setTitlebarAppearsTransparent:NO];
shell_->SetStyleMask(true, NSWindowStyleMaskFullSizeContentView);
}
}
- (void)windowWillExitFullScreen:(NSNotification*)notification {
// Restore the titlebar visibility.
NSWindow* window = shell_->GetNativeWindow().GetNativeNSWindow();
if ((shell_->transparent() || !shell_->has_frame()) &&
(shell_->title_bar_style() != TitleBarStyle::kHiddenInset ||
shell_->fullscreen_window_title())) {
[window setTitleVisibility:NSWindowTitleHidden];
}
// Turn off the style for toolbar.
if (shell_->title_bar_style() == TitleBarStyle::kHiddenInset) {
shell_->SetStyleMask(false, NSWindowStyleMaskFullSizeContentView);
[window setTitlebarAppearsTransparent:YES];
}
shell_->SetExitingFullScreen(true);
if (shell_->title_bar_style() == TitleBarStyle::kHidden) {
shell_->RedrawTrafficLights();
}
shell_->NotifyWindowWillLeaveFullScreen();
}
- (void)windowDidExitFullScreen:(NSNotification*)notification {
shell_->SetResizable(is_resizable_);
shell_->NotifyWindowLeaveFullScreen();
shell_->SetExitingFullScreen(false);
if (shell_->title_bar_style() == TitleBarStyle::kHidden) {
shell_->RedrawTrafficLights();
}
}
- (void)windowWillClose:(NSNotification*)notification {

View file

@ -0,0 +1,31 @@
// Copyright (c) 2021 Microsoft, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_BROWSER_UI_COCOA_WINDOW_BUTTONS_VIEW_H_
#define SHELL_BROWSER_UI_COCOA_WINDOW_BUTTONS_VIEW_H_
#import <Cocoa/Cocoa.h>
#include "base/mac/scoped_nsobject.h"
#include "base/optional.h"
#include "ui/gfx/geometry/point.h"
// Custom Quit, Minimize and Full Screen button container for frameless
// windows.
@interface WindowButtonsView : NSView {
@private
BOOL mouse_inside_;
BOOL show_on_hover_;
BOOL is_rtl_;
gfx::Point margin_;
base::scoped_nsobject<NSTrackingArea> tracking_area_;
}
- (id)initWithMargin:(const base::Optional<gfx::Point>&)margin;
- (void)setMargin:(const base::Optional<gfx::Point>&)margin;
- (void)setShowOnHover:(BOOL)yes;
- (void)setNeedsDisplayForButtons;
@end
#endif // SHELL_BROWSER_UI_COCOA_WINDOW_BUTTONS_VIEW_H_

View file

@ -0,0 +1,119 @@
// Copyright (c) 2021 Microsoft, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/ui/cocoa/window_buttons_view.h"
#include "base/i18n/rtl.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "ui/gfx/mac/coordinate_conversion.h"
namespace {
const CGFloat kButtonPadding = 20.;
const NSWindowButton kButtonTypes[] = {
NSWindowCloseButton,
NSWindowMiniaturizeButton,
NSWindowZoomButton,
};
} // namespace
@implementation WindowButtonsView
- (id)initWithMargin:(const base::Optional<gfx::Point>&)margin {
self = [super initWithFrame:NSZeroRect];
[self setMargin:margin];
mouse_inside_ = false;
show_on_hover_ = false;
is_rtl_ = base::i18n::IsRTL();
for (size_t i = 0; i < base::size(kButtonTypes); ++i) {
NSButton* button = [NSWindow standardWindowButton:kButtonTypes[i]
forStyleMask:NSWindowStyleMaskTitled];
[button setTag:i];
int left_index = is_rtl_ ? base::size(kButtonTypes) - i - 1 : i;
[button setFrameOrigin:NSMakePoint(left_index * kButtonPadding, 0)];
[self addSubview:button];
}
NSView* last_button =
is_rtl_ ? [[self subviews] firstObject] : [[self subviews] lastObject];
[self setFrameSize:NSMakeSize(last_button.frame.origin.x +
last_button.frame.size.width,
last_button.frame.size.height)];
[self setNeedsDisplayForButtons];
return self;
}
- (void)setMargin:(const base::Optional<gfx::Point>&)margin {
margin_ = margin.value_or(gfx::Point(7, 3));
}
- (void)setShowOnHover:(BOOL)yes {
show_on_hover_ = yes;
[self setNeedsDisplayForButtons];
}
- (void)setNeedsDisplayForButtons {
for (NSView* subview in self.subviews) {
[subview setHidden:(show_on_hover_ && !mouse_inside_)];
[subview setNeedsDisplay:YES];
}
}
- (void)removeFromSuperview {
[super removeFromSuperview];
mouse_inside_ = NO;
}
- (void)viewDidMoveToWindow {
// Stay in upper left corner.
CGFloat y =
self.superview.frame.size.height - self.frame.size.height - margin_.y();
if (is_rtl_) {
CGFloat x =
self.superview.frame.size.width - self.frame.size.width - margin_.x();
[self setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin];
[self setFrameOrigin:NSMakePoint(x, y)];
} else {
[self setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin];
[self setFrameOrigin:NSMakePoint(margin_.x(), y)];
}
}
- (BOOL)_mouseInGroup:(NSButton*)button {
return mouse_inside_;
}
- (void)updateTrackingAreas {
[super updateTrackingAreas];
if (tracking_area_)
[self removeTrackingArea:tracking_area_.get()];
tracking_area_.reset([[NSTrackingArea alloc]
initWithRect:NSZeroRect
options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways |
NSTrackingInVisibleRect
owner:self
userInfo:nil]);
[self addTrackingArea:tracking_area_.get()];
}
- (void)mouseEntered:(NSEvent*)event {
[super mouseEntered:event];
mouse_inside_ = YES;
[self setNeedsDisplayForButtons];
}
- (void)mouseExited:(NSEvent*)event {
[super mouseExited:event];
mouse_inside_ = NO;
[self setNeedsDisplayForButtons];
}
@end