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>
This commit is contained in:
parent
dd95a6f034
commit
5781850706
6 changed files with 69 additions and 0 deletions
|
@ -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
|
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.
|
issues with mouse events that occur with the standard window toolbar buttons.
|
||||||
**Note:** This option is currently experimental.
|
**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
|
* `fullscreenWindowTitle` Boolean (optional) - Shows the title in the
|
||||||
title bar in full screen mode on macOS for all `titleBarStyle` options.
|
title bar in full screen mode on macOS for all `titleBarStyle` options.
|
||||||
Default is `false`.
|
Default is `false`.
|
||||||
|
|
|
@ -149,6 +149,10 @@ class NativeWindowMac : public NativeWindow {
|
||||||
void SetCollectionBehavior(bool on, NSUInteger flag);
|
void SetCollectionBehavior(bool on, NSUInteger flag);
|
||||||
void SetWindowLevel(int level);
|
void SetWindowLevel(int level);
|
||||||
|
|
||||||
|
// Custom traffic light positioning
|
||||||
|
void RepositionTrafficLights();
|
||||||
|
void SetExitingFullScreen(bool flag);
|
||||||
|
|
||||||
enum class TitleBarStyle {
|
enum class TitleBarStyle {
|
||||||
NORMAL,
|
NORMAL,
|
||||||
HIDDEN,
|
HIDDEN,
|
||||||
|
@ -162,6 +166,7 @@ class NativeWindowMac : public NativeWindow {
|
||||||
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 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_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// views::WidgetDelegate:
|
// views::WidgetDelegate:
|
||||||
|
@ -198,6 +203,8 @@ class NativeWindowMac : public NativeWindow {
|
||||||
bool zoom_to_page_width_ = false;
|
bool zoom_to_page_width_ = false;
|
||||||
bool fullscreen_window_title_ = false;
|
bool fullscreen_window_title_ = false;
|
||||||
bool resizable_ = true;
|
bool resizable_ = true;
|
||||||
|
bool exiting_fullscreen_ = false;
|
||||||
|
gfx::Point traffic_light_position_;
|
||||||
|
|
||||||
NSInteger attention_request_id_ = 0; // identifier from requestUserAttention
|
NSInteger attention_request_id_ = 0; // identifier from requestUserAttention
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#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"
|
||||||
#include "shell/common/deprecate_util.h"
|
#include "shell/common/deprecate_util.h"
|
||||||
|
#include "shell/common/gin_converters/gfx_converter.h"
|
||||||
#include "shell/common/gin_helper/dictionary.h"
|
#include "shell/common/gin_helper/dictionary.h"
|
||||||
#include "shell/common/options_switches.h"
|
#include "shell/common/options_switches.h"
|
||||||
#include "skia/ext/skia_utils_mac.h"
|
#include "skia/ext/skia_utils_mac.h"
|
||||||
|
@ -335,6 +336,7 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
|
||||||
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::kFullscreenWindowTitle, &fullscreen_window_title_);
|
||||||
options.Get(options::kSimpleFullScreen, &always_simple_fullscreen_);
|
options.Get(options::kSimpleFullScreen, &always_simple_fullscreen_);
|
||||||
|
options.Get(options::kTrafficLightPosition, &traffic_light_position_);
|
||||||
|
|
||||||
bool minimizable = true;
|
bool minimizable = true;
|
||||||
options.Get(options::kMinimizable, &minimizable);
|
options.Get(options::kMinimizable, &minimizable);
|
||||||
|
@ -509,6 +511,45 @@ NativeWindowMac::~NativeWindowMac() {
|
||||||
[NSEvent removeMonitor:wheel_event_monitor_];
|
[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];
|
||||||
|
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) {
|
void NativeWindowMac::SetContentView(views::View* view) {
|
||||||
views::View* root_view = GetContentsView();
|
views::View* root_view = GetContentsView();
|
||||||
if (content_view())
|
if (content_view())
|
||||||
|
@ -628,6 +669,10 @@ bool NativeWindowMac::IsVisible() {
|
||||||
return [window_ isVisible] && !occluded && !IsMinimized();
|
return [window_ isVisible] && !occluded && !IsMinimized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeWindowMac::SetExitingFullScreen(bool flag) {
|
||||||
|
exiting_fullscreen_ = flag;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeWindowMac::IsEnabled() {
|
bool NativeWindowMac::IsEnabled() {
|
||||||
return [window_ attachedSheet] == nil;
|
return [window_ attachedSheet] == nil;
|
||||||
}
|
}
|
||||||
|
@ -949,6 +994,9 @@ 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::HIDDEN) {
|
||||||
|
RepositionTrafficLights();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string NativeWindowMac::GetTitle() {
|
std::string NativeWindowMac::GetTitle() {
|
||||||
|
|
|
@ -136,6 +136,9 @@ 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::HIDDEN) {
|
||||||
|
shell_->RepositionTrafficLights();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowWillMove:(NSNotification*)notification {
|
- (void)windowWillMove:(NSNotification*)notification {
|
||||||
|
@ -249,11 +252,19 @@ using TitleBarStyle = electron::NativeWindowMac::TitleBarStyle;
|
||||||
shell_->SetStyleMask(false, NSWindowStyleMaskFullSizeContentView);
|
shell_->SetStyleMask(false, NSWindowStyleMaskFullSizeContentView);
|
||||||
[window setTitlebarAppearsTransparent:YES];
|
[window setTitlebarAppearsTransparent:YES];
|
||||||
}
|
}
|
||||||
|
shell_->SetExitingFullScreen(true);
|
||||||
|
if (shell_->title_bar_style() == TitleBarStyle::HIDDEN) {
|
||||||
|
shell_->RepositionTrafficLights();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (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::HIDDEN) {
|
||||||
|
shell_->RepositionTrafficLights();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowWillClose:(NSNotification*)notification {
|
- (void)windowWillClose:(NSNotification*)notification {
|
||||||
|
|
|
@ -28,6 +28,7 @@ const char kMaximizable[] = "maximizable";
|
||||||
const char kFullScreenable[] = "fullscreenable";
|
const char kFullScreenable[] = "fullscreenable";
|
||||||
const char kClosable[] = "closable";
|
const char kClosable[] = "closable";
|
||||||
const char kFullscreen[] = "fullscreen";
|
const char kFullscreen[] = "fullscreen";
|
||||||
|
const char kTrafficLightPosition[] = "trafficLightPosition";
|
||||||
|
|
||||||
// Whether the window should show in taskbar.
|
// Whether the window should show in taskbar.
|
||||||
const char kSkipTaskbar[] = "skipTaskbar";
|
const char kSkipTaskbar[] = "skipTaskbar";
|
||||||
|
|
|
@ -54,6 +54,7 @@ extern const char kOpacity[];
|
||||||
extern const char kFocusable[];
|
extern const char kFocusable[];
|
||||||
extern const char kWebPreferences[];
|
extern const char kWebPreferences[];
|
||||||
extern const char kVibrancyType[];
|
extern const char kVibrancyType[];
|
||||||
|
extern const char kTrafficLightPosition[];
|
||||||
|
|
||||||
// WebPreferences.
|
// WebPreferences.
|
||||||
extern const char kZoomFactor[];
|
extern const char kZoomFactor[];
|
||||||
|
|
Loading…
Reference in a new issue