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:
parent
6edf6c6a95
commit
8bf66f8974
8 changed files with 262 additions and 304 deletions
|
@ -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 {
|
||||
|
|
31
shell/browser/ui/cocoa/window_buttons_view.h
Normal file
31
shell/browser/ui/cocoa/window_buttons_view.h
Normal 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_
|
119
shell/browser/ui/cocoa/window_buttons_view.mm
Normal file
119
shell/browser/ui/cocoa/window_buttons_view.mm
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue