Skip to content

Commit

Permalink
feat: custom positioning for traffic light buttons (#21990)
Browse files Browse the repository at this point in the history
* feat: custom positioning for traffic light buttons (#21781)

* feat: custom positioning for traffic light buttons

* remove NSLog and unnecessary call-site in IsVisible()

* no longer need to check if entering fullscreen

* change API to take a point object

Co-authored-by: tonyfwoo <55114329+tonyfwoo@users.noreply.github.com>

* chore: add safety checks to RepositionTrafficLights

Co-authored-by: Tony <TonyWuu@users.noreply.github.com>
Co-authored-by: tonyfwoo <55114329+tonyfwoo@users.noreply.github.com>
  • Loading branch information
3 people committed Jan 31, 2020
1 parent 6cf8abc commit c5574c8
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 0 deletions.
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

0 comments on commit c5574c8

Please sign in to comment.