Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: custom positioning for traffic light buttons #21990

Merged
merged 2 commits into from Jan 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/api/browser-window.md
Expand Up @@ -229,6 +229,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
unless hovered over in the top left of the window. These custom buttons prevent
issues with mouse events that occur with the standard window toolbar buttons.
**Note:** This option is currently experimental.
* `trafficLightPosition` [Point](structures/point.md) (optional) - Set a custom position for the traffic light buttons. Can only be used with `titleBarStyle` set to `hidden`
* `fullscreenWindowTitle` Boolean (optional) - Shows the title in the
title bar in full screen mode on macOS for all `titleBarStyle` options.
Default is `false`.
Expand Down
7 changes: 7 additions & 0 deletions shell/browser/native_window_mac.h
Expand Up @@ -149,6 +149,10 @@ class NativeWindowMac : public NativeWindow {
void SetCollectionBehavior(bool on, NSUInteger flag);
void SetWindowLevel(int level);

// Custom traffic light positioning
void RepositionTrafficLights();
void SetExitingFullScreen(bool flag);

enum class TitleBarStyle {
NORMAL,
HIDDEN,
Expand All @@ -162,6 +166,7 @@ class NativeWindowMac : public NativeWindow {
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 exiting_fullscreen() const { return exiting_fullscreen_; }

protected:
// views::WidgetDelegate:
Expand Down Expand Up @@ -198,6 +203,8 @@ class NativeWindowMac : public NativeWindow {
bool zoom_to_page_width_ = false;
bool fullscreen_window_title_ = false;
bool resizable_ = true;
bool exiting_fullscreen_ = false;
gfx::Point traffic_light_position_;

NSInteger attention_request_id_ = 0; // identifier from requestUserAttention

Expand Down
58 changes: 58 additions & 0 deletions shell/browser/native_window_mac.mm
Expand Up @@ -31,6 +31,7 @@
#include "shell/browser/ui/inspectable_web_contents_view.h"
#include "shell/browser/window_list.h"
#include "shell/common/deprecate_util.h"
#include "shell/common/gin_converters/gfx_converter.h"
#include "shell/common/options_switches.h"
#include "skia/ext/skia_utils_mac.h"
#include "third_party/webrtc/modules/desktop_capture/mac/window_list_utils.h"
Expand Down Expand Up @@ -337,6 +338,11 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
options.Get(options::kZoomToPageWidth, &zoom_to_page_width_);
options.Get(options::kFullscreenWindowTitle, &fullscreen_window_title_);
options.Get(options::kSimpleFullScreen, &always_simple_fullscreen_);
v8::Local<v8::Value> traffic_light_options;
if (options.Get(options::kTrafficLightPosition, &traffic_light_options)) {
gin::ConvertFromV8(options.isolate(), traffic_light_options,
&traffic_light_position_);
}

bool minimizable = true;
options.Get(options::kMinimizable, &minimizable);
Expand Down Expand Up @@ -511,6 +517,51 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
[NSEvent removeMonitor:wheel_event_monitor_];
}

void NativeWindowMac::RepositionTrafficLights() {
if (!traffic_light_position_.x() && !traffic_light_position_.y()) {
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;
titleBarRect.size.height = titleBarFrameHeight;
titleBarRect.origin.y = window.frame.size.height - titleBarFrameHeight;
[titleBarContainerView setFrame:titleBarRect];

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];
rect.origin.x = traffic_light_position_.x() + (i * space_between);
rect.origin.y = (titleBarFrameHeight - rect.size.height) / 2;
[view setFrameOrigin:rect.origin];
}
}

void NativeWindowMac::SetContentView(views::View* view) {
views::View* root_view = GetContentsView();
if (content_view())
Expand Down Expand Up @@ -630,6 +681,10 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
return [window_ isVisible] && !occluded && !IsMinimized();
}

void NativeWindowMac::SetExitingFullScreen(bool flag) {
exiting_fullscreen_ = flag;
}

bool NativeWindowMac::IsEnabled() {
return [window_ attachedSheet] == nil;
}
Expand Down Expand Up @@ -951,6 +1006,9 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {

void NativeWindowMac::SetTitle(const std::string& title) {
[window_ setTitle:base::SysUTF8ToNSString(title)];
if (title_bar_style_ == TitleBarStyle::HIDDEN) {
RepositionTrafficLights();
}
}

std::string NativeWindowMac::GetTitle() {
Expand Down
11 changes: 11 additions & 0 deletions shell/browser/ui/cocoa/atom_ns_window_delegate.mm
Expand Up @@ -136,6 +136,9 @@ - (NSSize)windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize {
- (void)windowDidResize:(NSNotification*)notification {
[super windowDidResize:notification];
shell_->NotifyWindowResize();
if (shell_->title_bar_style() == TitleBarStyle::HIDDEN) {
shell_->RepositionTrafficLights();
}
}

- (void)windowWillMove:(NSNotification*)notification {
Expand Down Expand Up @@ -249,11 +252,19 @@ - (void)windowWillExitFullScreen:(NSNotification*)notification {
shell_->SetStyleMask(false, NSWindowStyleMaskFullSizeContentView);
[window setTitlebarAppearsTransparent:YES];
}
shell_->SetExitingFullScreen(true);
if (shell_->title_bar_style() == TitleBarStyle::HIDDEN) {
shell_->RepositionTrafficLights();
}
}

- (void)windowDidExitFullScreen:(NSNotification*)notification {
shell_->SetResizable(is_resizable_);
shell_->NotifyWindowLeaveFullScreen();
shell_->SetExitingFullScreen(false);
if (shell_->title_bar_style() == TitleBarStyle::HIDDEN) {
shell_->RepositionTrafficLights();
}
}

- (void)windowWillClose:(NSNotification*)notification {
Expand Down
1 change: 1 addition & 0 deletions shell/common/options_switches.cc
Expand Up @@ -28,6 +28,7 @@ const char kMaximizable[] = "maximizable";
const char kFullScreenable[] = "fullscreenable";
const char kClosable[] = "closable";
const char kFullscreen[] = "fullscreen";
const char kTrafficLightPosition[] = "trafficLightPosition";

// Whether the window should show in taskbar.
const char kSkipTaskbar[] = "skipTaskbar";
Expand Down
1 change: 1 addition & 0 deletions shell/common/options_switches.h
Expand Up @@ -54,6 +54,7 @@ extern const char kOpacity[];
extern const char kFocusable[];
extern const char kWebPreferences[];
extern const char kVibrancyType[];
extern const char kTrafficLightPosition[];

// WebPreferences.
extern const char kZoomFactor[];
Expand Down