fix: move window buttons in-place on macOS (#30322)
This commit is contained in:
parent
1c29734c91
commit
97929eab5f
9 changed files with 334 additions and 278 deletions
|
@ -32,7 +32,7 @@
|
|||
#include "shell/browser/ui/cocoa/electron_preview_item.h"
|
||||
#include "shell/browser/ui/cocoa/electron_touch_bar.h"
|
||||
#include "shell/browser/ui/cocoa/root_view_mac.h"
|
||||
#include "shell/browser/ui/cocoa/window_buttons_view.h"
|
||||
#include "shell/browser/ui/cocoa/window_buttons_proxy.h"
|
||||
#include "shell/browser/ui/inspectable_web_contents.h"
|
||||
#include "shell/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "shell/browser/window_list.h"
|
||||
|
@ -381,8 +381,26 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
|
|||
[window_ setTitleVisibility:NSWindowTitleHidden];
|
||||
// Remove non-transparent corners, see http://git.io/vfonD.
|
||||
[window_ setOpaque:NO];
|
||||
// Hide the window buttons.
|
||||
InternalSetStandardButtonsVisibility(false);
|
||||
// Show window buttons if titleBarStyle is not "normal".
|
||||
if (title_bar_style_ == TitleBarStyle::kNormal) {
|
||||
InternalSetWindowButtonVisibility(false);
|
||||
} else {
|
||||
buttons_proxy_.reset([[WindowButtonsProxy alloc] initWithWindow:window_]);
|
||||
if (traffic_light_position_) {
|
||||
[buttons_proxy_ setMargin:*traffic_light_position_];
|
||||
} else if (title_bar_style_ == TitleBarStyle::kHiddenInset) {
|
||||
// For macOS >= 11, while this value does not match offical macOS apps
|
||||
// like Safari or Notes, it matches titleBarStyle's old implementation
|
||||
// before Electron <= 12.
|
||||
[buttons_proxy_ setMargin:gfx::Point(12, 11)];
|
||||
}
|
||||
if (title_bar_style_ == TitleBarStyle::kCustomButtonsOnHover) {
|
||||
[buttons_proxy_ setShowOnHover:YES];
|
||||
} else {
|
||||
// customButtonsOnHover does not show buttons initialiy.
|
||||
InternalSetWindowButtonVisibility(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a tab only if tabbing identifier is specified and window has
|
||||
|
@ -461,9 +479,6 @@ void NativeWindowMac::SetContentView(views::View* view) {
|
|||
set_content_view(view);
|
||||
root_view->AddChildView(content_view());
|
||||
|
||||
if (buttons_view_)
|
||||
ReorderButtonsView();
|
||||
|
||||
root_view->Layout();
|
||||
}
|
||||
|
||||
|
@ -806,8 +821,6 @@ bool NativeWindowMac::IsMovable() {
|
|||
|
||||
void NativeWindowMac::SetMinimizable(bool minimizable) {
|
||||
SetStyleMask(minimizable, NSMiniaturizableWindowMask);
|
||||
if (buttons_view_)
|
||||
[[buttons_view_ viewWithTag:1] setEnabled:minimizable];
|
||||
}
|
||||
|
||||
bool NativeWindowMac::IsMinimizable() {
|
||||
|
@ -829,8 +842,6 @@ void NativeWindowMac::SetFullScreenable(bool fullscreenable) {
|
|||
// On EL Capitan this flag is required to hide fullscreen button.
|
||||
SetCollectionBehavior(!fullscreenable,
|
||||
NSWindowCollectionBehaviorFullScreenAuxiliary);
|
||||
if (buttons_view_)
|
||||
[[buttons_view_ viewWithTag:2] setEnabled:fullscreenable];
|
||||
}
|
||||
|
||||
bool NativeWindowMac::IsFullScreenable() {
|
||||
|
@ -840,8 +851,6 @@ bool NativeWindowMac::IsFullScreenable() {
|
|||
|
||||
void NativeWindowMac::SetClosable(bool closable) {
|
||||
SetStyleMask(closable, NSWindowStyleMaskClosable);
|
||||
if (buttons_view_)
|
||||
[[buttons_view_ viewWithTag:0] setEnabled:closable];
|
||||
}
|
||||
|
||||
bool NativeWindowMac::IsClosable() {
|
||||
|
@ -947,6 +956,8 @@ void NativeWindowMac::Invalidate() {
|
|||
|
||||
void NativeWindowMac::SetTitle(const std::string& title) {
|
||||
[window_ setTitle:base::SysUTF8ToNSString(title)];
|
||||
if (buttons_proxy_)
|
||||
[buttons_proxy_ redraw];
|
||||
}
|
||||
|
||||
std::string NativeWindowMac::GetTitle() {
|
||||
|
@ -1182,8 +1193,6 @@ void NativeWindowMac::AddBrowserView(NativeBrowserView* view) {
|
|||
}
|
||||
|
||||
[CATransaction commit];
|
||||
|
||||
ReorderButtonsView();
|
||||
}
|
||||
|
||||
void NativeWindowMac::RemoveBrowserView(NativeBrowserView* view) {
|
||||
|
@ -1225,8 +1234,6 @@ void NativeWindowMac::SetTopBrowserView(NativeBrowserView* view) {
|
|||
}
|
||||
|
||||
[CATransaction commit];
|
||||
|
||||
ReorderButtonsView();
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetParentWindow(NativeWindow* parent) {
|
||||
|
@ -1488,25 +1495,26 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
|
|||
|
||||
void NativeWindowMac::SetWindowButtonVisibility(bool visible) {
|
||||
window_button_visibility_ = visible;
|
||||
InternalSetWindowButtonVisibility(visible);
|
||||
// The visibility of window buttons are managed by |buttons_proxy_| if the
|
||||
// style is customButtonsOnHover.
|
||||
if (title_bar_style_ == TitleBarStyle::kCustomButtonsOnHover)
|
||||
[buttons_proxy_ setVisible:visible];
|
||||
else
|
||||
InternalSetWindowButtonVisibility(visible);
|
||||
NotifyLayoutWindowControlsOverlay();
|
||||
}
|
||||
|
||||
bool NativeWindowMac::GetWindowButtonVisibility() const {
|
||||
if (buttons_view_)
|
||||
return ![buttons_view_ isHidden];
|
||||
else
|
||||
return ![window_ standardWindowButton:NSWindowZoomButton].hidden ||
|
||||
![window_ standardWindowButton:NSWindowMiniaturizeButton].hidden ||
|
||||
![window_ standardWindowButton:NSWindowCloseButton].hidden;
|
||||
return ![window_ standardWindowButton:NSWindowZoomButton].hidden ||
|
||||
![window_ standardWindowButton:NSWindowMiniaturizeButton].hidden ||
|
||||
![window_ standardWindowButton:NSWindowCloseButton].hidden;
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetTrafficLightPosition(
|
||||
absl::optional<gfx::Point> position) {
|
||||
traffic_light_position_ = std::move(position);
|
||||
if (buttons_view_) {
|
||||
[buttons_view_ setMargin:traffic_light_position_];
|
||||
[buttons_view_ viewDidMoveToWindow];
|
||||
if (buttons_proxy_) {
|
||||
[buttons_proxy_ setMargin:traffic_light_position_];
|
||||
NotifyLayoutWindowControlsOverlay();
|
||||
}
|
||||
}
|
||||
|
@ -1516,8 +1524,8 @@ absl::optional<gfx::Point> NativeWindowMac::GetTrafficLightPosition() const {
|
|||
}
|
||||
|
||||
void NativeWindowMac::RedrawTrafficLights() {
|
||||
if (buttons_view_)
|
||||
[buttons_view_ setNeedsDisplayForButtons];
|
||||
if (buttons_proxy_ && !IsFullscreen())
|
||||
[buttons_proxy_ redraw];
|
||||
}
|
||||
|
||||
// In simpleFullScreen mode, update the frame for new bounds.
|
||||
|
@ -1649,35 +1657,30 @@ gfx::Rect NativeWindowMac::WindowBoundsToContentBounds(
|
|||
void NativeWindowMac::NotifyWindowEnterFullScreen() {
|
||||
NativeWindow::NotifyWindowEnterFullScreen();
|
||||
// Restore the window title under fullscreen mode.
|
||||
if (buttons_view_)
|
||||
if (buttons_proxy_)
|
||||
[window_ setTitleVisibility:NSWindowTitleVisible];
|
||||
RedrawTrafficLights();
|
||||
}
|
||||
|
||||
void NativeWindowMac::NotifyWindowLeaveFullScreen() {
|
||||
NativeWindow::NotifyWindowLeaveFullScreen();
|
||||
// Restore window buttons.
|
||||
if (buttons_proxy_ && window_button_visibility_.value_or(true)) {
|
||||
[buttons_proxy_ redraw];
|
||||
[buttons_proxy_ setVisible:YES];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::NotifyWindowWillEnterFullScreen() {
|
||||
// Remove the buttonsView otherwise window buttons won't show under
|
||||
// fullscreen mode.
|
||||
if (buttons_view_) {
|
||||
[buttons_view_ removeFromSuperview];
|
||||
InternalSetStandardButtonsVisibility(true);
|
||||
}
|
||||
|
||||
UpdateVibrancyRadii(true);
|
||||
}
|
||||
|
||||
void NativeWindowMac::NotifyWindowWillLeaveFullScreen() {
|
||||
// Hide window title and restore buttonsView when leaving fullscreen.
|
||||
if (buttons_view_) {
|
||||
if (buttons_proxy_) {
|
||||
// Hide window title when leaving fullscreen.
|
||||
[window_ setTitleVisibility:NSWindowTitleHidden];
|
||||
InternalSetStandardButtonsVisibility(false);
|
||||
[[window_ contentView] addSubview:buttons_view_];
|
||||
// Hide the container otherwise traffic light buttons jump.
|
||||
[buttons_proxy_ setVisible:NO];
|
||||
}
|
||||
|
||||
RedrawTrafficLights();
|
||||
UpdateVibrancyRadii(false);
|
||||
}
|
||||
|
||||
|
@ -1689,13 +1692,6 @@ bool NativeWindowMac::IsActive() const {
|
|||
return is_active_;
|
||||
}
|
||||
|
||||
void NativeWindowMac::ReorderButtonsView() {
|
||||
if (buttons_view_ && !IsFullscreen()) {
|
||||
[buttons_view_ removeFromSuperview];
|
||||
[[window_ contentView] addSubview:buttons_view_];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::Cleanup() {
|
||||
DCHECK(!IsClosed());
|
||||
ui::NativeTheme::GetInstanceForNativeUi()->RemoveObserver(this);
|
||||
|
@ -1791,37 +1787,10 @@ void NativeWindowMac::AddContentViewLayers() {
|
|||
(IMP)ViewDidMoveToSuperview, "v@:");
|
||||
[[window_ contentView] viewDidMoveToWindow];
|
||||
}
|
||||
|
||||
// Create a custom window buttons view.
|
||||
if (title_bar_style_ != TitleBarStyle::kNormal) {
|
||||
buttons_view_.reset(
|
||||
[[WindowButtonsView alloc] initWithMargin:traffic_light_position_]);
|
||||
if (title_bar_style_ == TitleBarStyle::kCustomButtonsOnHover)
|
||||
[buttons_view_ setShowOnHover:YES];
|
||||
if (title_bar_style_ == TitleBarStyle::kHiddenInset &&
|
||||
!traffic_light_position_)
|
||||
[buttons_view_ setMargin:[WindowButtonsView hiddenInsetMargin]];
|
||||
|
||||
if (!IsClosable())
|
||||
[[buttons_view_ viewWithTag:0] setEnabled:NO];
|
||||
if (!IsMinimizable())
|
||||
[[buttons_view_ viewWithTag:1] setEnabled:NO];
|
||||
if (!IsFullScreenable())
|
||||
[[buttons_view_ viewWithTag:2] setEnabled:NO];
|
||||
|
||||
[[window_ contentView] addSubview:buttons_view_];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::InternalSetWindowButtonVisibility(bool visible) {
|
||||
if (buttons_view_)
|
||||
[buttons_view_ setHidden:!visible];
|
||||
else
|
||||
InternalSetStandardButtonsVisibility(visible);
|
||||
}
|
||||
|
||||
void NativeWindowMac::InternalSetStandardButtonsVisibility(bool visible) {
|
||||
[[window_ standardWindowButton:NSWindowCloseButton] setHidden:!visible];
|
||||
[[window_ standardWindowButton:NSWindowMiniaturizeButton] setHidden:!visible];
|
||||
[[window_ standardWindowButton:NSWindowZoomButton] setHidden:!visible];
|
||||
|
@ -1861,24 +1830,17 @@ void NativeWindowMac::SetForwardMouseMessages(bool forward) {
|
|||
}
|
||||
|
||||
gfx::Rect NativeWindowMac::GetWindowControlsOverlayRect() {
|
||||
gfx::Rect bounding_rect;
|
||||
if (titlebar_overlay_ && !has_frame() && buttons_view_ &&
|
||||
![buttons_view_ isHidden]) {
|
||||
NSRect button_frame = [buttons_view_ frame];
|
||||
gfx::Point buttons_view_margin = [buttons_view_ getMargin];
|
||||
const int overlay_width = GetContentSize().width() - NSWidth(button_frame) -
|
||||
buttons_view_margin.x();
|
||||
CGFloat overlay_height =
|
||||
NSHeight(button_frame) + buttons_view_margin.y() * 2;
|
||||
if (base::i18n::IsRTL()) {
|
||||
bounding_rect = gfx::Rect(0, 0, overlay_width, overlay_height);
|
||||
} else {
|
||||
bounding_rect =
|
||||
gfx::Rect(button_frame.size.width + buttons_view_margin.x(), 0,
|
||||
overlay_width, overlay_height);
|
||||
}
|
||||
if (titlebar_overlay_ && buttons_proxy_ &&
|
||||
window_button_visibility_.value_or(true)) {
|
||||
NSRect buttons = [buttons_proxy_ getButtonsContainerBounds];
|
||||
gfx::Rect overlay;
|
||||
overlay.set_width(GetContentSize().width() - NSWidth(buttons));
|
||||
overlay.set_height(NSHeight(buttons));
|
||||
if (!base::i18n::IsRTL())
|
||||
overlay.set_x(NSMaxX(buttons));
|
||||
return overlay;
|
||||
}
|
||||
return bounding_rect;
|
||||
return gfx::Rect();
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue