From 9911e60f5b982b418a3d8195bd1dd180bf6dc67d Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Sat, 3 Sep 2016 00:45:20 +0200 Subject: [PATCH] Add support for titleBarStyle: 'hidden-inset' on OS X 10.9 --- atom/browser/native_window_mac.mm | 114 ++++++++++++++++++++++++++---- docs/api/browser-window.md | 1 - 2 files changed, 101 insertions(+), 14 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 10bc609786e9..b44ec4da8d3d 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -191,7 +191,8 @@ bool ScopedDisableResize::disable_resize_ = false; - (void)windowWillEnterFullScreen:(NSNotification*)notification { // Hide the native toolbar before entering fullscreen, so there is no visual // artifacts. - if (shell_->title_bar_style() == atom::NativeWindowMac::HIDDEN_INSET) { + if (base::mac::IsOSYosemiteOrLater() && + shell_->title_bar_style() == atom::NativeWindowMac::HIDDEN_INSET) { NSWindow* window = shell_->GetNativeWindow(); [window setToolbar:nil]; } @@ -214,7 +215,8 @@ bool ScopedDisableResize::disable_resize_ = false; // 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() == atom::NativeWindowMac::HIDDEN_INSET) { + if (base::mac::IsOSYosemiteOrLater() && + shell_->title_bar_style() == atom::NativeWindowMac::HIDDEN_INSET) { base::scoped_nsobject toolbar( [[NSToolbar alloc] initWithIdentifier:@"titlebarStylingToolbar"]); [toolbar setShowsBaselineSeparator:NO]; @@ -236,8 +238,10 @@ bool ScopedDisableResize::disable_resize_ = false; } // Turn off the style for toolbar. - if (shell_->title_bar_style() == atom::NativeWindowMac::HIDDEN_INSET) + if (base::mac::IsOSYosemiteOrLater() && + shell_->title_bar_style() == atom::NativeWindowMac::HIDDEN_INSET) { shell_->SetStyleMask(false, NSFullSizeContentViewWindowMask); + } } - (void)windowDidExitFullScreen:(NSNotification*)notification { @@ -276,13 +280,16 @@ bool ScopedDisableResize::disable_resize_ = false; @private atom::NativeWindowMac* shell_; bool enable_larger_than_screen_; + CGFloat windowButtonsInterButtonSpacing_; } @property BOOL acceptsFirstMouse; @property BOOL disableAutoHideCursor; @property BOOL disableKeyOrMainWindow; +@property NSPoint windowButtonsOffset; - (void)setShell:(atom::NativeWindowMac*)shell; - (void)setEnableLargerThanScreen:(bool)enable; +- (void)enableWindowButtonsOffset; @end @implementation AtomNSWindow @@ -356,6 +363,86 @@ bool ScopedDisableResize::disable_resize_ = false; return !self.disableKeyOrMainWindow; } +- (void)enableWindowButtonsOffset { + auto closeButton = [self standardWindowButton:NSWindowCloseButton]; + auto miniaturizeButton = [self standardWindowButton:NSWindowMiniaturizeButton]; + auto zoomButton = [self standardWindowButton:NSWindowZoomButton]; + + [closeButton setPostsFrameChangedNotifications:YES]; + [miniaturizeButton setPostsFrameChangedNotifications:YES]; + [zoomButton setPostsFrameChangedNotifications:YES]; + + windowButtonsInterButtonSpacing_ = + NSMinX([miniaturizeButton frame]) - NSMaxX([closeButton frame]); + + auto center = [NSNotificationCenter defaultCenter]; + + [center addObserver:self + selector:@selector(adjustCloseButton:) + name:NSViewFrameDidChangeNotification + object:closeButton]; + + [center addObserver:self + selector:@selector(adjustMiniaturizeButton:) + name:NSViewFrameDidChangeNotification + object:miniaturizeButton]; + + [center addObserver:self + selector:@selector(adjustZoomButton:) + name:NSViewFrameDidChangeNotification + object:zoomButton]; +} + +- (void)adjustCloseButton:(NSNotification*)notification { + [self adjustButton:[notification object] + ofKind:NSWindowCloseButton]; +} + +- (void)adjustMiniaturizeButton:(NSNotification*)notification { + [self adjustButton:[notification object] + ofKind:NSWindowMiniaturizeButton]; +} + +- (void)adjustZoomButton:(NSNotification*)notification { + [self adjustButton:[notification object] + ofKind:NSWindowZoomButton]; +} + +- (void)adjustButton:(NSButton*)button + ofKind:(NSWindowButton)kind { + NSRect buttonFrame = [button frame]; + NSRect frameViewBounds = [[self frameView] bounds]; + NSPoint offset = self.windowButtonsOffset; + + buttonFrame.origin = NSMakePoint( + offset.x, + (NSHeight(frameViewBounds) - NSHeight(buttonFrame) - offset.y)); + + switch (kind) { + case NSWindowZoomButton: + buttonFrame.origin.x += NSWidth( + [[self standardWindowButton:NSWindowMiniaturizeButton] frame]); + buttonFrame.origin.x += windowButtonsInterButtonSpacing_; + // fallthrough + case NSWindowMiniaturizeButton: + buttonFrame.origin.x += NSWidth( + [[self standardWindowButton:NSWindowCloseButton] frame]); + buttonFrame.origin.x += windowButtonsInterButtonSpacing_; + // fallthrough + default: + break; + } + + BOOL didPost = [button postsBoundsChangedNotifications]; + [button setPostsFrameChangedNotifications:NO]; + [button setFrame:buttonFrame]; + [button setPostsFrameChangedNotifications:didPost]; +} + +- (NSView*)frameView { + return [[self contentView] superview]; +} + @end @interface ControlRegionView : NSView @@ -423,11 +510,7 @@ struct Converter { *out = atom::NativeWindowMac::HIDDEN; } else if (title_bar_style == "hidden-inset" || // Deprecate this after 2.0 title_bar_style == "hiddenInset") { - if (base::mac::IsOSYosemiteOrLater()) { - *out = atom::NativeWindowMac::HIDDEN_INSET; - } else { - *out = atom::NativeWindowMac::HIDDEN; - } + *out = atom::NativeWindowMac::HIDDEN_INSET; } else { return false; } @@ -550,11 +633,16 @@ NativeWindowMac::NativeWindowMac( // Hide the title bar. if (title_bar_style_ == HIDDEN_INSET) { - [window_ setTitlebarAppearsTransparent:YES]; - base::scoped_nsobject toolbar( - [[NSToolbar alloc] initWithIdentifier:@"titlebarStylingToolbar"]); - [toolbar setShowsBaselineSeparator:NO]; - [window_ setToolbar:toolbar]; + if (base::mac::IsOSYosemiteOrLater()) { + [window_ setTitlebarAppearsTransparent:YES]; + base::scoped_nsobject toolbar( + [[NSToolbar alloc] initWithIdentifier:@"titlebarStylingToolbar"]); + [toolbar setShowsBaselineSeparator:NO]; + [window_ setToolbar:toolbar]; + } else { + [window_ enableWindowButtonsOffset]; + [window_ setWindowButtonsOffset:NSMakePoint(12, 10)]; + } } // On macOS the initial window size doesn't include window frame. diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 3b0ca1fe6915..79ddef46df2e 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -221,7 +221,6 @@ Possible values of the `titleBarStyle` option are: the top left. * `hidden-inset` results in a hidden title bar with an alternative look where the traffic light buttons are slightly more inset from the window edge. - It is not supported on macOS 10.9 Mavericks, where it falls back to `hidden`. The `webPreferences` option is an object that can have the following properties: