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
|
@ -222,16 +222,14 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||||
the top left.
|
the top left.
|
||||||
* `hiddenInset` - Results in a hidden title bar with an alternative look
|
* `hiddenInset` - Results in a hidden title bar with an alternative look
|
||||||
where the traffic light buttons are slightly more inset from the window edge.
|
where the traffic light buttons are slightly more inset from the window edge.
|
||||||
* `customButtonsOnHover` Boolean (optional) - Draw custom close,
|
* `customButtonsOnHover` - Results in a hidden title bar and a full size
|
||||||
and minimize buttons on macOS frameless windows. These buttons will not display
|
content window, the traffic light buttons will display when being hovered
|
||||||
unless hovered over in the top left of the window. These custom buttons prevent
|
over in the top left of the window. **Note:** This option is currently
|
||||||
issues with mouse events that occur with the standard window toolbar buttons.
|
experimental.
|
||||||
**Note:** This option is currently experimental.
|
|
||||||
* `trafficLightPosition` [Point](structures/point.md) (optional) - Set a
|
* `trafficLightPosition` [Point](structures/point.md) (optional) - Set a
|
||||||
custom position for the traffic light buttons. Can only be used with
|
custom position for the traffic light buttons in frameless windows.
|
||||||
`titleBarStyle` set to `hidden` or `customButtonsOnHover`.
|
* `fullscreenWindowTitle` Boolean (optional) _Deprecated_ - Shows the title in
|
||||||
* `fullscreenWindowTitle` Boolean (optional) - Shows the title in the
|
the title bar in full screen mode on macOS for `hiddenInset` titleBarStyle.
|
||||||
title bar in full screen mode on macOS for all `titleBarStyle` options.
|
|
||||||
Default is `false`.
|
Default is `false`.
|
||||||
* `thickFrame` Boolean (optional) - Use `WS_THICKFRAME` style for frameless windows on
|
* `thickFrame` Boolean (optional) - Use `WS_THICKFRAME` style for frameless windows on
|
||||||
Windows, which adds standard window frame. Setting it to `false` will remove
|
Windows, which adds standard window frame. Setting it to `false` will remove
|
||||||
|
@ -1740,13 +1738,12 @@ deprecated and will be removed in an upcoming version of macOS.
|
||||||
|
|
||||||
* `position` [Point](structures/point.md)
|
* `position` [Point](structures/point.md)
|
||||||
|
|
||||||
Set a custom position for the traffic light buttons. Can only be used with
|
Set a custom position for the traffic light buttons in frameless window.
|
||||||
`titleBarStyle` set to `hidden` or `customButtonsOnHover`.
|
|
||||||
|
|
||||||
#### `win.getTrafficLightPosition()` _macOS_
|
#### `win.getTrafficLightPosition()` _macOS_
|
||||||
|
|
||||||
Returns `Point` - The current position for the traffic light buttons. Can only
|
Returns `Point` - The custom position for the traffic light buttons in
|
||||||
be used with `titleBarStyle` set to `hidden` or `customButtonsOnHover`.
|
frameless window.
|
||||||
|
|
||||||
#### `win.setTouchBar(touchBar)` _macOS_
|
#### `win.setTouchBar(touchBar)` _macOS_
|
||||||
|
|
||||||
|
|
|
@ -180,6 +180,8 @@ filenames = {
|
||||||
"shell/browser/ui/cocoa/root_view_mac.mm",
|
"shell/browser/ui/cocoa/root_view_mac.mm",
|
||||||
"shell/browser/ui/cocoa/views_delegate_mac.h",
|
"shell/browser/ui/cocoa/views_delegate_mac.h",
|
||||||
"shell/browser/ui/cocoa/views_delegate_mac.mm",
|
"shell/browser/ui/cocoa/views_delegate_mac.mm",
|
||||||
|
"shell/browser/ui/cocoa/window_buttons_view.h",
|
||||||
|
"shell/browser/ui/cocoa/window_buttons_view.mm",
|
||||||
"shell/browser/ui/drag_util_mac.mm",
|
"shell/browser/ui/drag_util_mac.mm",
|
||||||
"shell/browser/ui/file_dialog_mac.mm",
|
"shell/browser/ui/file_dialog_mac.mm",
|
||||||
"shell/browser/ui/inspectable_web_contents_view_mac.h",
|
"shell/browser/ui/inspectable_web_contents_view_mac.h",
|
||||||
|
|
|
@ -280,8 +280,8 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
void NotifyWindowRotateGesture(float rotation);
|
void NotifyWindowRotateGesture(float rotation);
|
||||||
void NotifyWindowSheetBegin();
|
void NotifyWindowSheetBegin();
|
||||||
void NotifyWindowSheetEnd();
|
void NotifyWindowSheetEnd();
|
||||||
void NotifyWindowEnterFullScreen();
|
virtual void NotifyWindowEnterFullScreen();
|
||||||
void NotifyWindowLeaveFullScreen();
|
virtual void NotifyWindowLeaveFullScreen();
|
||||||
void NotifyWindowEnterHtmlFullScreen();
|
void NotifyWindowEnterHtmlFullScreen();
|
||||||
void NotifyWindowLeaveHtmlFullScreen();
|
void NotifyWindowLeaveHtmlFullScreen();
|
||||||
void NotifyWindowAlwaysOnTopChanged();
|
void NotifyWindowAlwaysOnTopChanged();
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
@class ElectronNSWindowDelegate;
|
@class ElectronNSWindowDelegate;
|
||||||
@class ElectronPreviewItem;
|
@class ElectronPreviewItem;
|
||||||
@class ElectronTouchBar;
|
@class ElectronTouchBar;
|
||||||
@class CustomWindowButtonView;
|
@class WindowButtonsView;
|
||||||
|
|
||||||
namespace electron {
|
namespace electron {
|
||||||
|
|
||||||
|
@ -139,6 +139,11 @@ class NativeWindowMac : public NativeWindow, public ui::NativeThemeObserver {
|
||||||
void CloseFilePreview() override;
|
void CloseFilePreview() override;
|
||||||
gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const override;
|
gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const override;
|
||||||
gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const override;
|
gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const override;
|
||||||
|
void NotifyWindowEnterFullScreen() override;
|
||||||
|
void NotifyWindowLeaveFullScreen() override;
|
||||||
|
|
||||||
|
void NotifyWindowWillEnterFullScreen();
|
||||||
|
void NotifyWindowWillLeaveFullScreen();
|
||||||
|
|
||||||
// Cleanup observers when window is getting closed. Note that the destructor
|
// 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
|
// can be called much later after window gets closed, so we should not do
|
||||||
|
@ -153,8 +158,6 @@ class NativeWindowMac : public NativeWindow, public ui::NativeThemeObserver {
|
||||||
void SetCollectionBehavior(bool on, NSUInteger flag);
|
void SetCollectionBehavior(bool on, NSUInteger flag);
|
||||||
void SetWindowLevel(int level);
|
void SetWindowLevel(int level);
|
||||||
|
|
||||||
void SetExitingFullScreen(bool flag);
|
|
||||||
|
|
||||||
enum class VisualEffectState {
|
enum class VisualEffectState {
|
||||||
kFollowWindow,
|
kFollowWindow,
|
||||||
kActive,
|
kActive,
|
||||||
|
@ -172,7 +175,6 @@ class NativeWindowMac : public NativeWindow, public ui::NativeThemeObserver {
|
||||||
ElectronPreviewItem* preview_item() const { return preview_item_.get(); }
|
ElectronPreviewItem* preview_item() const { return preview_item_.get(); }
|
||||||
ElectronTouchBar* touch_bar() const { return touch_bar_.get(); }
|
ElectronTouchBar* touch_bar() const { return touch_bar_.get(); }
|
||||||
bool zoom_to_page_width() const { return zoom_to_page_width_; }
|
bool zoom_to_page_width() const { return zoom_to_page_width_; }
|
||||||
bool fullscreen_window_title() const { return fullscreen_window_title_; }
|
|
||||||
bool always_simple_fullscreen() const { return always_simple_fullscreen_; }
|
bool always_simple_fullscreen() const { return always_simple_fullscreen_; }
|
||||||
bool exiting_fullscreen() const { return exiting_fullscreen_; }
|
bool exiting_fullscreen() const { return exiting_fullscreen_; }
|
||||||
|
|
||||||
|
@ -186,9 +188,10 @@ class NativeWindowMac : public NativeWindow, public ui::NativeThemeObserver {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Add custom layers to the content view.
|
// Add custom layers to the content view.
|
||||||
void AddContentViewLayers(bool minimizable, bool closable);
|
void AddContentViewLayers();
|
||||||
|
|
||||||
void InternalSetWindowButtonVisibility(bool visible);
|
void InternalSetWindowButtonVisibility(bool visible);
|
||||||
|
void InternalSetStandardButtonsVisibility(bool visible);
|
||||||
void InternalSetParentWindow(NativeWindow* parent, bool attach);
|
void InternalSetParentWindow(NativeWindow* parent, bool attach);
|
||||||
void SetForwardMouseMessages(bool forward);
|
void SetForwardMouseMessages(bool forward);
|
||||||
|
|
||||||
|
@ -197,7 +200,7 @@ class NativeWindowMac : public NativeWindow, public ui::NativeThemeObserver {
|
||||||
base::scoped_nsobject<ElectronNSWindowDelegate> window_delegate_;
|
base::scoped_nsobject<ElectronNSWindowDelegate> window_delegate_;
|
||||||
base::scoped_nsobject<ElectronPreviewItem> preview_item_;
|
base::scoped_nsobject<ElectronPreviewItem> preview_item_;
|
||||||
base::scoped_nsobject<ElectronTouchBar> touch_bar_;
|
base::scoped_nsobject<ElectronTouchBar> touch_bar_;
|
||||||
base::scoped_nsobject<CustomWindowButtonView> buttons_view_;
|
base::scoped_nsobject<WindowButtonsView> buttons_view_;
|
||||||
|
|
||||||
// Event monitor for scroll wheel event.
|
// Event monitor for scroll wheel event.
|
||||||
id wheel_event_monitor_;
|
id wheel_event_monitor_;
|
||||||
|
@ -213,7 +216,6 @@ class NativeWindowMac : public NativeWindow, public ui::NativeThemeObserver {
|
||||||
bool is_kiosk_ = false;
|
bool is_kiosk_ = false;
|
||||||
bool was_fullscreen_ = false;
|
bool was_fullscreen_ = false;
|
||||||
bool zoom_to_page_width_ = false;
|
bool zoom_to_page_width_ = false;
|
||||||
bool fullscreen_window_title_ = false;
|
|
||||||
bool resizable_ = true;
|
bool resizable_ = true;
|
||||||
bool exiting_fullscreen_ = false;
|
bool exiting_fullscreen_ = false;
|
||||||
base::Optional<gfx::Point> traffic_light_position_;
|
base::Optional<gfx::Point> traffic_light_position_;
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "shell/browser/ui/cocoa/electron_preview_item.h"
|
#include "shell/browser/ui/cocoa/electron_preview_item.h"
|
||||||
#include "shell/browser/ui/cocoa/electron_touch_bar.h"
|
#include "shell/browser/ui/cocoa/electron_touch_bar.h"
|
||||||
#include "shell/browser/ui/cocoa/root_view_mac.h"
|
#include "shell/browser/ui/cocoa/root_view_mac.h"
|
||||||
|
#include "shell/browser/ui/cocoa/window_buttons_view.h"
|
||||||
#include "shell/browser/ui/inspectable_web_contents.h"
|
#include "shell/browser/ui/inspectable_web_contents.h"
|
||||||
#include "shell/browser/ui/inspectable_web_contents_view.h"
|
#include "shell/browser/ui/inspectable_web_contents_view.h"
|
||||||
#include "shell/browser/window_list.h"
|
#include "shell/browser/window_list.h"
|
||||||
|
@ -119,106 +120,6 @@
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
// Custom Quit, Minimize and Full Screen button container for frameless
|
|
||||||
// windows.
|
|
||||||
@interface CustomWindowButtonView : NSView {
|
|
||||||
@private
|
|
||||||
BOOL mouse_inside_;
|
|
||||||
gfx::Point margin_;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithMargin:(const base::Optional<gfx::Point>&)margin;
|
|
||||||
- (void)setMargin:(const base::Optional<gfx::Point>&)margin;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation CustomWindowButtonView
|
|
||||||
|
|
||||||
- (id)initWithMargin:(const base::Optional<gfx::Point>&)margin {
|
|
||||||
self = [super initWithFrame:NSZeroRect];
|
|
||||||
[self setMargin:margin];
|
|
||||||
|
|
||||||
NSButton* close_button =
|
|
||||||
[NSWindow standardWindowButton:NSWindowCloseButton
|
|
||||||
forStyleMask:NSWindowStyleMaskTitled];
|
|
||||||
[close_button setTag:1];
|
|
||||||
NSButton* miniaturize_button =
|
|
||||||
[NSWindow standardWindowButton:NSWindowMiniaturizeButton
|
|
||||||
forStyleMask:NSWindowStyleMaskTitled];
|
|
||||||
[miniaturize_button setTag:2];
|
|
||||||
|
|
||||||
CGFloat x = 0;
|
|
||||||
const CGFloat space_between = 20;
|
|
||||||
|
|
||||||
[close_button setFrameOrigin:NSMakePoint(x, 0)];
|
|
||||||
x += space_between;
|
|
||||||
[self addSubview:close_button];
|
|
||||||
|
|
||||||
[miniaturize_button setFrameOrigin:NSMakePoint(x, 0)];
|
|
||||||
x += space_between;
|
|
||||||
[self addSubview:miniaturize_button];
|
|
||||||
|
|
||||||
const auto last_button_frame = miniaturize_button.frame;
|
|
||||||
[self setFrameSize:NSMakeSize(last_button_frame.origin.x +
|
|
||||||
last_button_frame.size.width,
|
|
||||||
last_button_frame.size.height)];
|
|
||||||
|
|
||||||
mouse_inside_ = NO;
|
|
||||||
[self setNeedsDisplayForButtons];
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setMargin:(const base::Optional<gfx::Point>&)margin {
|
|
||||||
margin_ = margin.value_or(gfx::Point(7, 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)viewDidMoveToWindow {
|
|
||||||
if (!self.window) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stay in upper left corner.
|
|
||||||
[self setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin];
|
|
||||||
[self setFrameOrigin:NSMakePoint(margin_.x(), self.window.frame.size.height -
|
|
||||||
self.frame.size.height -
|
|
||||||
margin_.y())];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)_mouseInGroup:(NSButton*)button {
|
|
||||||
return mouse_inside_;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)updateTrackingAreas {
|
|
||||||
auto tracking_area = [[[NSTrackingArea alloc]
|
|
||||||
initWithRect:NSZeroRect
|
|
||||||
options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways |
|
|
||||||
NSTrackingInVisibleRect
|
|
||||||
owner:self
|
|
||||||
userInfo:nil] autorelease];
|
|
||||||
[self addTrackingArea:tracking_area];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)mouseEntered:(NSEvent*)event {
|
|
||||||
[super mouseEntered:event];
|
|
||||||
mouse_inside_ = YES;
|
|
||||||
[self setNeedsDisplayForButtons];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)mouseExited:(NSEvent*)event {
|
|
||||||
[super mouseExited:event];
|
|
||||||
mouse_inside_ = NO;
|
|
||||||
[self setNeedsDisplayForButtons];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setNeedsDisplayForButtons {
|
|
||||||
for (NSView* subview in self.subviews) {
|
|
||||||
[subview setHidden:!mouse_inside_];
|
|
||||||
[subview setNeedsDisplay:YES];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface ElectronProgressBar : NSProgressIndicator
|
@interface ElectronProgressBar : NSProgressIndicator
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -370,11 +271,17 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
|
||||||
options.Get(options::kResizable, &resizable_);
|
options.Get(options::kResizable, &resizable_);
|
||||||
options.Get(options::kTitleBarStyle, &title_bar_style_);
|
options.Get(options::kTitleBarStyle, &title_bar_style_);
|
||||||
options.Get(options::kZoomToPageWidth, &zoom_to_page_width_);
|
options.Get(options::kZoomToPageWidth, &zoom_to_page_width_);
|
||||||
options.Get(options::kFullscreenWindowTitle, &fullscreen_window_title_);
|
|
||||||
options.Get(options::kSimpleFullScreen, &always_simple_fullscreen_);
|
options.Get(options::kSimpleFullScreen, &always_simple_fullscreen_);
|
||||||
options.GetOptional(options::kTrafficLightPosition, &traffic_light_position_);
|
options.GetOptional(options::kTrafficLightPosition, &traffic_light_position_);
|
||||||
options.Get(options::kVisualEffectState, &visual_effect_state_);
|
options.Get(options::kVisualEffectState, &visual_effect_state_);
|
||||||
|
|
||||||
|
if (options.Has(options::kFullscreenWindowTitle)) {
|
||||||
|
EmitWarning(node::Environment::GetCurrent(v8::Isolate::GetCurrent()),
|
||||||
|
"\"fullscreenWindowTitle\" option has been deprecated and is "
|
||||||
|
"no-op now.",
|
||||||
|
"electron");
|
||||||
|
}
|
||||||
|
|
||||||
bool minimizable = true;
|
bool minimizable = true;
|
||||||
options.Get(options::kMinimizable, &minimizable);
|
options.Get(options::kMinimizable, &minimizable);
|
||||||
|
|
||||||
|
@ -457,6 +364,8 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
|
||||||
[window_ setTitleVisibility:NSWindowTitleHidden];
|
[window_ setTitleVisibility:NSWindowTitleHidden];
|
||||||
// Remove non-transparent corners, see http://git.io/vfonD.
|
// Remove non-transparent corners, see http://git.io/vfonD.
|
||||||
[window_ setOpaque:NO];
|
[window_ setOpaque:NO];
|
||||||
|
// Hide the window buttons.
|
||||||
|
InternalSetStandardButtonsVisibility(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a tab only if tabbing identifier is specified and window has
|
// Create a tab only if tabbing identifier is specified and window has
|
||||||
|
@ -471,14 +380,6 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide the title bar.
|
|
||||||
if (title_bar_style_ == TitleBarStyle::kHiddenInset) {
|
|
||||||
base::scoped_nsobject<NSToolbar> toolbar(
|
|
||||||
[[NSToolbar alloc] initWithIdentifier:@"titlebarStylingToolbar"]);
|
|
||||||
[toolbar setShowsBaselineSeparator:NO];
|
|
||||||
[window_ setToolbar:toolbar];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resize to content bounds.
|
// Resize to content bounds.
|
||||||
bool use_content_size = false;
|
bool use_content_size = false;
|
||||||
options.Get(options::kUseContentSize, &use_content_size);
|
options.Get(options::kUseContentSize, &use_content_size);
|
||||||
|
@ -527,7 +428,7 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
|
||||||
|
|
||||||
// Default content view.
|
// Default content view.
|
||||||
SetContentView(new views::View());
|
SetContentView(new views::View());
|
||||||
AddContentViewLayers(minimizable, closable);
|
AddContentViewLayers();
|
||||||
|
|
||||||
original_frame_ = [window_ frame];
|
original_frame_ = [window_ frame];
|
||||||
original_level_ = [window_ level];
|
original_level_ = [window_ level];
|
||||||
|
@ -830,6 +731,8 @@ bool NativeWindowMac::IsMovable() {
|
||||||
|
|
||||||
void NativeWindowMac::SetMinimizable(bool minimizable) {
|
void NativeWindowMac::SetMinimizable(bool minimizable) {
|
||||||
SetStyleMask(minimizable, NSMiniaturizableWindowMask);
|
SetStyleMask(minimizable, NSMiniaturizableWindowMask);
|
||||||
|
if (buttons_view_)
|
||||||
|
[[buttons_view_ viewWithTag:1] setEnabled:minimizable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeWindowMac::IsMinimizable() {
|
bool NativeWindowMac::IsMinimizable() {
|
||||||
|
@ -851,6 +754,8 @@ void NativeWindowMac::SetFullScreenable(bool fullscreenable) {
|
||||||
// On EL Capitan this flag is required to hide fullscreen button.
|
// On EL Capitan this flag is required to hide fullscreen button.
|
||||||
SetCollectionBehavior(!fullscreenable,
|
SetCollectionBehavior(!fullscreenable,
|
||||||
NSWindowCollectionBehaviorFullScreenAuxiliary);
|
NSWindowCollectionBehaviorFullScreenAuxiliary);
|
||||||
|
if (buttons_view_)
|
||||||
|
[[buttons_view_ viewWithTag:2] setEnabled:fullscreenable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeWindowMac::IsFullScreenable() {
|
bool NativeWindowMac::IsFullScreenable() {
|
||||||
|
@ -860,6 +765,8 @@ bool NativeWindowMac::IsFullScreenable() {
|
||||||
|
|
||||||
void NativeWindowMac::SetClosable(bool closable) {
|
void NativeWindowMac::SetClosable(bool closable) {
|
||||||
SetStyleMask(closable, NSWindowStyleMaskClosable);
|
SetStyleMask(closable, NSWindowStyleMaskClosable);
|
||||||
|
if (buttons_view_)
|
||||||
|
[[buttons_view_ viewWithTag:0] setEnabled:closable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeWindowMac::IsClosable() {
|
bool NativeWindowMac::IsClosable() {
|
||||||
|
@ -940,9 +847,6 @@ void NativeWindowMac::Invalidate() {
|
||||||
|
|
||||||
void NativeWindowMac::SetTitle(const std::string& title) {
|
void NativeWindowMac::SetTitle(const std::string& title) {
|
||||||
[window_ setTitle:base::SysUTF8ToNSString(title)];
|
[window_ setTitle:base::SysUTF8ToNSString(title)];
|
||||||
if (title_bar_style_ == TitleBarStyle::kHidden) {
|
|
||||||
RedrawTrafficLights();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string NativeWindowMac::GetTitle() {
|
std::string NativeWindowMac::GetTitle() {
|
||||||
|
@ -1004,14 +908,7 @@ void NativeWindowMac::SetSimpleFullScreen(bool simple_fullscreen) {
|
||||||
window.level = NSPopUpMenuWindowLevel;
|
window.level = NSPopUpMenuWindowLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fullscreen_window_title()) {
|
if (!window_button_visibility_.has_value()) {
|
||||||
// Hide the titlebar
|
|
||||||
SetStyleMask(false, NSWindowStyleMaskTitled);
|
|
||||||
|
|
||||||
// Resize the window to accommodate the _entire_ screen size
|
|
||||||
fullscreenFrame.size.height -=
|
|
||||||
[[[NSApplication sharedApplication] mainMenu] menuBarHeight];
|
|
||||||
} else if (!window_button_visibility_.has_value()) {
|
|
||||||
// Lets keep previous behaviour - hide window controls in titled
|
// Lets keep previous behaviour - hide window controls in titled
|
||||||
// fullscreen mode when not specified otherwise.
|
// fullscreen mode when not specified otherwise.
|
||||||
InternalSetWindowButtonVisibility(false);
|
InternalSetWindowButtonVisibility(false);
|
||||||
|
@ -1027,11 +924,6 @@ void NativeWindowMac::SetSimpleFullScreen(bool simple_fullscreen) {
|
||||||
} else if (!simple_fullscreen && is_simple_fullscreen_) {
|
} else if (!simple_fullscreen && is_simple_fullscreen_) {
|
||||||
is_simple_fullscreen_ = false;
|
is_simple_fullscreen_ = false;
|
||||||
|
|
||||||
if (!fullscreen_window_title()) {
|
|
||||||
// Restore the titlebar
|
|
||||||
SetStyleMask(true, NSWindowStyleMaskTitled);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore default window controls visibility state.
|
// Restore default window controls visibility state.
|
||||||
if (!window_button_visibility_.has_value()) {
|
if (!window_button_visibility_.has_value()) {
|
||||||
bool visibility;
|
bool visibility;
|
||||||
|
@ -1450,9 +1342,7 @@ bool NativeWindowMac::GetWindowButtonVisibility() const {
|
||||||
void NativeWindowMac::SetTrafficLightPosition(
|
void NativeWindowMac::SetTrafficLightPosition(
|
||||||
base::Optional<gfx::Point> position) {
|
base::Optional<gfx::Point> position) {
|
||||||
traffic_light_position_ = std::move(position);
|
traffic_light_position_ = std::move(position);
|
||||||
if (title_bar_style_ == TitleBarStyle::kHidden) {
|
if (buttons_view_) {
|
||||||
RedrawTrafficLights();
|
|
||||||
} else if (title_bar_style_ == TitleBarStyle::kCustomButtonsOnHover) {
|
|
||||||
[buttons_view_ setMargin:position];
|
[buttons_view_ setMargin:position];
|
||||||
[buttons_view_ viewDidMoveToWindow];
|
[buttons_view_ viewDidMoveToWindow];
|
||||||
}
|
}
|
||||||
|
@ -1463,64 +1353,8 @@ base::Optional<gfx::Point> NativeWindowMac::GetTrafficLightPosition() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::RedrawTrafficLights() {
|
void NativeWindowMac::RedrawTrafficLights() {
|
||||||
// Ensure maximizable options retain pre-existing state.
|
if (buttons_view_)
|
||||||
SetMaximizable(maximizable_);
|
[buttons_view_ setNeedsDisplayForButtons];
|
||||||
|
|
||||||
// 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(
|
void NativeWindowMac::SetTouchBar(
|
||||||
|
@ -1642,6 +1476,41 @@ gfx::Rect NativeWindowMac::WindowBoundsToContentBounds(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeWindowMac::NotifyWindowEnterFullScreen() {
|
||||||
|
NativeWindow::NotifyWindowEnterFullScreen();
|
||||||
|
// Restore the window title under fullscreen mode.
|
||||||
|
if (buttons_view_)
|
||||||
|
[window_ setTitleVisibility:NSWindowTitleVisible];
|
||||||
|
RedrawTrafficLights();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeWindowMac::NotifyWindowLeaveFullScreen() {
|
||||||
|
NativeWindow::NotifyWindowLeaveFullScreen();
|
||||||
|
exiting_fullscreen_ = false;
|
||||||
|
// Add back buttonsView after leaving fullscreen mode.
|
||||||
|
if (buttons_view_) {
|
||||||
|
InternalSetStandardButtonsVisibility(false);
|
||||||
|
[[window_ contentView] addSubview:buttons_view_];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeWindowMac::NotifyWindowWillEnterFullScreen() {
|
||||||
|
// Remove the buttonsView otherwise window buttons won't show under
|
||||||
|
// fullscreen mode.
|
||||||
|
if (buttons_view_) {
|
||||||
|
[buttons_view_ removeFromSuperview];
|
||||||
|
InternalSetStandardButtonsVisibility(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeWindowMac::NotifyWindowWillLeaveFullScreen() {
|
||||||
|
// Hide window title after leaving fullscreen.
|
||||||
|
if (buttons_view_)
|
||||||
|
[window_ setTitleVisibility:NSWindowTitleHidden];
|
||||||
|
exiting_fullscreen_ = true;
|
||||||
|
RedrawTrafficLights();
|
||||||
|
}
|
||||||
|
|
||||||
void NativeWindowMac::Cleanup() {
|
void NativeWindowMac::Cleanup() {
|
||||||
DCHECK(!IsClosed());
|
DCHECK(!IsClosed());
|
||||||
ui::NativeTheme::GetInstanceForNativeUi()->RemoveObserver(this);
|
ui::NativeTheme::GetInstanceForNativeUi()->RemoveObserver(this);
|
||||||
|
@ -1663,7 +1532,7 @@ void NativeWindowMac::OverrideNSWindowContentView() {
|
||||||
[container_view_
|
[container_view_
|
||||||
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||||
[window_ setContentView:container_view_];
|
[window_ setContentView:container_view_];
|
||||||
AddContentViewLayers(IsMinimizable(), IsClosable());
|
AddContentViewLayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::SetStyleMask(bool on, NSUInteger flag) {
|
void NativeWindowMac::SetStyleMask(bool on, NSUInteger flag) {
|
||||||
|
@ -1692,10 +1561,6 @@ void NativeWindowMac::SetCollectionBehavior(bool on, NSUInteger flag) {
|
||||||
SetMaximizable(was_maximizable);
|
SetMaximizable(was_maximizable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::SetExitingFullScreen(bool flag) {
|
|
||||||
exiting_fullscreen_ = flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NativeWindowMac::CanResize() const {
|
bool NativeWindowMac::CanResize() const {
|
||||||
return resizable_;
|
return resizable_;
|
||||||
}
|
}
|
||||||
|
@ -1710,7 +1575,7 @@ void NativeWindowMac::OnNativeThemeUpdated(ui::NativeTheme* observed_theme) {
|
||||||
base::BindOnce(&NativeWindow::RedrawTrafficLights, GetWeakPtr()));
|
base::BindOnce(&NativeWindow::RedrawTrafficLights, GetWeakPtr()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::AddContentViewLayers(bool minimizable, bool closable) {
|
void NativeWindowMac::AddContentViewLayers() {
|
||||||
// Make sure the bottom corner is rounded for non-modal windows:
|
// Make sure the bottom corner is rounded for non-modal windows:
|
||||||
// http://crbug.com/396264.
|
// http://crbug.com/396264.
|
||||||
if (!is_modal()) {
|
if (!is_modal()) {
|
||||||
|
@ -1742,46 +1607,39 @@ void NativeWindowMac::AddContentViewLayers(bool minimizable, bool closable) {
|
||||||
[[window_ contentView] viewDidMoveToWindow];
|
[[window_ contentView] viewDidMoveToWindow];
|
||||||
}
|
}
|
||||||
|
|
||||||
// The fullscreen button should always be hidden for frameless window.
|
// Create a custom window buttons view.
|
||||||
[[window_ standardWindowButton:NSWindowFullScreenButton] setHidden:YES];
|
if (title_bar_style_ != TitleBarStyle::kNormal) {
|
||||||
|
buttons_view_.reset(
|
||||||
|
[[WindowButtonsView alloc] initWithMargin:traffic_light_position_]);
|
||||||
|
if (title_bar_style_ == TitleBarStyle::kCustomButtonsOnHover)
|
||||||
|
[buttons_view_ setShowOnHover:YES];
|
||||||
|
if (title_bar_style_ == TitleBarStyle::kHiddenInset &&
|
||||||
|
!traffic_light_position_)
|
||||||
|
[buttons_view_ setMargin:gfx::Point(12, 11)];
|
||||||
|
|
||||||
// Create a custom window buttons view for kCustomButtonsOnHover.
|
if (!IsClosable())
|
||||||
if (title_bar_style_ == TitleBarStyle::kCustomButtonsOnHover) {
|
[[buttons_view_ viewWithTag:0] setEnabled:NO];
|
||||||
buttons_view_.reset([[CustomWindowButtonView alloc]
|
if (!IsMinimizable())
|
||||||
initWithMargin:traffic_light_position_]);
|
[[buttons_view_ viewWithTag:1] setEnabled:NO];
|
||||||
|
if (!IsFullScreenable())
|
||||||
if (!minimizable)
|
[[buttons_view_ viewWithTag:2] setEnabled:NO];
|
||||||
[[buttons_view_ viewWithTag:2] removeFromSuperview];
|
|
||||||
if (!closable)
|
|
||||||
[[buttons_view_ viewWithTag:1] removeFromSuperview];
|
|
||||||
|
|
||||||
[[window_ contentView] addSubview:buttons_view_];
|
[[window_ contentView] addSubview:buttons_view_];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide the window buttons except for kHidden and kHiddenInset.
|
|
||||||
if (title_bar_style_ == TitleBarStyle::kNormal ||
|
|
||||||
title_bar_style_ == TitleBarStyle::kCustomButtonsOnHover) {
|
|
||||||
[[window_ standardWindowButton:NSWindowZoomButton] setHidden:YES];
|
|
||||||
[[window_ standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
|
|
||||||
[[window_ standardWindowButton:NSWindowCloseButton] setHidden:YES];
|
|
||||||
|
|
||||||
// Some third-party macOS utilities check the zoom button's enabled state
|
|
||||||
// to determine whether to show custom UI on hover, so we disable it here
|
|
||||||
// to prevent them from doing so in a frameless app window.
|
|
||||||
SetMaximizable(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::InternalSetWindowButtonVisibility(bool visible) {
|
void NativeWindowMac::InternalSetWindowButtonVisibility(bool visible) {
|
||||||
if (buttons_view_) {
|
if (buttons_view_)
|
||||||
[buttons_view_ setHidden:!visible];
|
[buttons_view_ setHidden:!visible];
|
||||||
} else {
|
else
|
||||||
[[window_ standardWindowButton:NSWindowCloseButton] setHidden:!visible];
|
InternalSetStandardButtonsVisibility(visible);
|
||||||
[[window_ standardWindowButton:NSWindowMiniaturizeButton]
|
}
|
||||||
setHidden:!visible];
|
|
||||||
[[window_ standardWindowButton:NSWindowZoomButton] setHidden:!visible];
|
void NativeWindowMac::InternalSetStandardButtonsVisibility(bool visible) {
|
||||||
}
|
[[window_ standardWindowButton:NSWindowCloseButton] setHidden:!visible];
|
||||||
|
[[window_ standardWindowButton:NSWindowMiniaturizeButton] setHidden:!visible];
|
||||||
|
[[window_ standardWindowButton:NSWindowZoomButton] setHidden:!visible];
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::InternalSetParentWindow(NativeWindow* parent,
|
void NativeWindowMac::InternalSetParentWindow(NativeWindow* parent,
|
||||||
|
|
|
@ -91,14 +91,17 @@ using TitleBarStyle = electron::NativeWindowMac::TitleBarStyle;
|
||||||
|
|
||||||
- (void)windowDidBecomeMain:(NSNotification*)notification {
|
- (void)windowDidBecomeMain:(NSNotification*)notification {
|
||||||
shell_->NotifyWindowFocus();
|
shell_->NotifyWindowFocus();
|
||||||
|
shell_->RedrawTrafficLights();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidResignMain:(NSNotification*)notification {
|
- (void)windowDidResignMain:(NSNotification*)notification {
|
||||||
shell_->NotifyWindowBlur();
|
shell_->NotifyWindowBlur();
|
||||||
|
shell_->RedrawTrafficLights();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidBecomeKey:(NSNotification*)notification {
|
- (void)windowDidBecomeKey:(NSNotification*)notification {
|
||||||
shell_->NotifyWindowIsKeyChanged(true);
|
shell_->NotifyWindowIsKeyChanged(true);
|
||||||
|
shell_->RedrawTrafficLights();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidResignKey:(NSNotification*)notification {
|
- (void)windowDidResignKey:(NSNotification*)notification {
|
||||||
|
@ -110,6 +113,7 @@ using TitleBarStyle = electron::NativeWindowMac::TitleBarStyle;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
shell_->NotifyWindowIsKeyChanged(false);
|
shell_->NotifyWindowIsKeyChanged(false);
|
||||||
|
shell_->RedrawTrafficLights();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSSize)windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize {
|
- (NSSize)windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize {
|
||||||
|
@ -151,9 +155,6 @@ using TitleBarStyle = electron::NativeWindowMac::TitleBarStyle;
|
||||||
- (void)windowDidResize:(NSNotification*)notification {
|
- (void)windowDidResize:(NSNotification*)notification {
|
||||||
[super windowDidResize:notification];
|
[super windowDidResize:notification];
|
||||||
shell_->NotifyWindowResize();
|
shell_->NotifyWindowResize();
|
||||||
if (shell_->title_bar_style() == TitleBarStyle::kHidden) {
|
|
||||||
shell_->RedrawTrafficLights();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowWillMove:(NSNotification*)notification {
|
- (void)windowWillMove:(NSNotification*)notification {
|
||||||
|
@ -212,75 +213,23 @@ using TitleBarStyle = electron::NativeWindowMac::TitleBarStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowWillEnterFullScreen:(NSNotification*)notification {
|
- (void)windowWillEnterFullScreen:(NSNotification*)notification {
|
||||||
// Setting resizable to true before entering fullscreen
|
shell_->NotifyWindowWillEnterFullScreen();
|
||||||
|
// Setting resizable to true before entering fullscreen.
|
||||||
is_resizable_ = shell_->IsResizable();
|
is_resizable_ = shell_->IsResizable();
|
||||||
shell_->SetResizable(true);
|
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 {
|
- (void)windowDidEnterFullScreen:(NSNotification*)notification {
|
||||||
shell_->NotifyWindowEnterFullScreen();
|
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 {
|
- (void)windowWillExitFullScreen:(NSNotification*)notification {
|
||||||
// Restore the titlebar visibility.
|
shell_->NotifyWindowWillLeaveFullScreen();
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidExitFullScreen:(NSNotification*)notification {
|
- (void)windowDidExitFullScreen:(NSNotification*)notification {
|
||||||
shell_->SetResizable(is_resizable_);
|
shell_->SetResizable(is_resizable_);
|
||||||
shell_->NotifyWindowLeaveFullScreen();
|
shell_->NotifyWindowLeaveFullScreen();
|
||||||
shell_->SetExitingFullScreen(false);
|
|
||||||
if (shell_->title_bar_style() == TitleBarStyle::kHidden) {
|
|
||||||
shell_->RedrawTrafficLights();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowWillClose:(NSNotification*)notification {
|
- (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…
Reference in a new issue