Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat: Add BrowserWindow.setWindowButtonVisibility()
Fixes #12701 and supersedes #13131.

Ideally we would have added `setTitleBarStyle()`, but that is a
significantly more involved change. For example, consider the case where
we switch from `hidden` to `normal`. We would not only have to show the
traffic light buttons, we would also have to switch the window from a
frameless to a framed window and deal with various other window state.
Lets instead implement a simple solution for #12701.
  • Loading branch information
poiru authored and nornagon committed Jul 25, 2018
1 parent 00c0c18 commit a42ca9e
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 7 deletions.
9 changes: 9 additions & 0 deletions atom/browser/api/atom_api_top_level_window.cc
Expand Up @@ -738,6 +738,13 @@ void TopLevelWindow::AddTabbedWindow(NativeWindow* window,
args->ThrowError("AddTabbedWindow cannot be called by a window on itself.");
}

void TopLevelWindow::SetWindowButtonVisibility(bool visible,
mate::Arguments* args) {
if (!window_->SetWindowButtonVisibility(visible)) {
args->ThrowError("Not supported for this window");
}
}

void TopLevelWindow::SetAutoHideMenuBar(bool auto_hide) {
window_->SetAutoHideMenuBar(auto_hide);
}
Expand Down Expand Up @@ -1030,6 +1037,8 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
.SetMethod("moveTabToNewWindow", &TopLevelWindow::MoveTabToNewWindow)
.SetMethod("toggleTabBar", &TopLevelWindow::ToggleTabBar)
.SetMethod("addTabbedWindow", &TopLevelWindow::AddTabbedWindow)
.SetMethod("setWindowButtonVisibility",
&TopLevelWindow::SetWindowButtonVisibility)
#endif
.SetMethod("setAutoHideMenuBar", &TopLevelWindow::SetAutoHideMenuBar)
.SetMethod("isMenuBarAutoHide", &TopLevelWindow::IsMenuBarAutoHide)
Expand Down
1 change: 1 addition & 0 deletions atom/browser/api/atom_api_top_level_window.h
Expand Up @@ -173,6 +173,7 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
void MoveTabToNewWindow();
void ToggleTabBar();
void AddTabbedWindow(NativeWindow* window, mate::Arguments* args);
void SetWindowButtonVisibility(bool visible, mate::Arguments* args);
void SetAutoHideMenuBar(bool auto_hide);
bool IsMenuBarAutoHide();
void SetMenuBarVisibility(bool visible);
Expand Down
4 changes: 4 additions & 0 deletions atom/browser/native_window.cc
Expand Up @@ -355,6 +355,10 @@ bool NativeWindow::IsMenuBarVisible() {
return true;
}

bool NativeWindow::SetWindowButtonVisibility(bool visible) {
return false;
}

double NativeWindow::GetAspectRatio() {
return aspect_ratio_;
}
Expand Down
3 changes: 3 additions & 0 deletions atom/browser/native_window.h
Expand Up @@ -187,6 +187,9 @@ class NativeWindow : public base::SupportsUserData,
virtual void ToggleTabBar();
virtual bool AddTabbedWindow(NativeWindow* window);

// Returns false if unsupported.
virtual bool SetWindowButtonVisibility(bool visible);

// Toggle the menu bar.
virtual void SetAutoHideMenuBar(bool auto_hide);
virtual bool IsMenuBarAutoHide();
Expand Down
6 changes: 6 additions & 0 deletions atom/browser/native_window_mac.h
Expand Up @@ -119,6 +119,8 @@ class NativeWindowMac : public NativeWindow {
void ToggleTabBar() override;
bool AddTabbedWindow(NativeWindow* window) override;

bool SetWindowButtonVisibility(bool visible) override;

void SetVibrancy(const std::string& type) override;
void SetTouchBar(
const std::vector<mate::PersistentDictionary>& items) override;
Expand Down Expand Up @@ -193,6 +195,10 @@ class NativeWindowMac : public NativeWindow {
// The "titleBarStyle" option.
TitleBarStyle title_bar_style_ = NORMAL;

// The visibility mode of window button controls when explicitly set through
// setWindowButtonVisibility().
base::Optional<bool> window_button_visibility_;

// Simple (pre-Lion) Fullscreen Settings
bool always_simple_fullscreen_ = false;
bool is_simple_fullscreen_ = false;
Expand Down
32 changes: 25 additions & 7 deletions atom/browser/native_window_mac.mm
Expand Up @@ -884,8 +884,9 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
// Resize the window to accomodate the _entire_ screen size
fullscreenFrame.size.height -=
[[[NSApplication sharedApplication] mainMenu] menuBarHeight];
} else {
// No need to hide the title, but we should still hide the window buttons
} else if (!window_button_visibility_.has_value()) {
// Lets keep previous behaviour - hide window controls in titled
// fullscreen mode when not specified otherwise.
[[window standardWindowButton:NSWindowZoomButton] setHidden:YES];
[[window standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
[[window standardWindowButton:NSWindowCloseButton] setHidden:YES];
Expand All @@ -904,13 +905,17 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
if (!fullscreen_window_title()) {
// Restore the titlebar
SetStyleMask(true, NSTitledWindowMask);
} else {
// Show the window buttons
[[window standardWindowButton:NSWindowZoomButton] setHidden:NO];
[[window standardWindowButton:NSWindowMiniaturizeButton] setHidden:NO];
[[window standardWindowButton:NSWindowCloseButton] setHidden:NO];
}

// Restore window controls visibility state
const bool window_button_hidden = !window_button_visibility_.value_or(true);
[[window standardWindowButton:NSWindowZoomButton]
setHidden:window_button_hidden];
[[window standardWindowButton:NSWindowMiniaturizeButton]
setHidden:window_button_hidden];
[[window standardWindowButton:NSWindowCloseButton]
setHidden:window_button_hidden];

[window setFrame:original_frame_ display:YES animate:YES];

[NSApp setPresentationOptions:simple_fullscreen_options_];
Expand Down Expand Up @@ -1148,6 +1153,19 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
return true;
}

bool NativeWindowMac::SetWindowButtonVisibility(bool visible) {
if (title_bar_style_ == CUSTOM_BUTTONS_ON_HOVER) {
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) {
if (@available(macOS 10.10, *)) {
NSView* vibrant_view = [window_ vibrantView];
Expand Down
7 changes: 7 additions & 0 deletions docs/api/browser-window.md
Expand Up @@ -1342,6 +1342,13 @@ Same as `webContents.showDefinitionForSelection()`.

Changes window icon.

#### `win.setWindowButtonVisibility(visible)` _macOS_

* `visible` Boolean

Sets whether the window traffic light buttons should be visible. This has no
effect when `titleBarStyle` is set to `customButtonsOnHover`.

#### `win.setAutoHideMenuBar(hide)`

* `hide` Boolean
Expand Down
27 changes: 27 additions & 0 deletions spec/api-browser-window-spec.js
Expand Up @@ -765,6 +765,33 @@ describe('BrowserWindow module', () => {
})
})

describe('BrowserWindow.setWindowButtonVisibility()', () => {
before(function () {
if (process.platform !== 'darwin') {
this.skip()
}
})

it('does not throw', () => {
assert.doesNotThrow(() => {
w.setWindowButtonVisibility(true)
w.setWindowButtonVisibility(false)
})
})

it('throws with custom title bar buttons', () => {
assert.throws(() => {
w.destroy()
w = new BrowserWindow({
show: false,
titleBarStyle: 'customButtonsOnHover',
frame: false
})
w.setWindowButtonVisibility(true)
}, /Not supported for this window/)
})
})

describe('BrowserWindow.setVibrancy(type)', () => {
it('allows setting, changing, and removing the vibrancy', () => {
assert.doesNotThrow(() => {
Expand Down

0 comments on commit a42ca9e

Please sign in to comment.