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: add WCO height option #33061

Merged
merged 3 commits into from Feb 28, 2022
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
3 changes: 2 additions & 1 deletion docs/api/browser-window.md
Expand Up @@ -391,9 +391,10 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
contain the layout of the document—without requiring scrolling. Enabling
this will cause the `preferred-size-changed` event to be emitted on the
`WebContents` when the preferred size changes. Default is `false`.
* `titleBarOverlay` Object | Boolean (optional) - When using a frameless window in conjunction with `win.setWindowButtonVisibility(true)` on macOS or using a `titleBarStyle` so that the standard window controls ("traffic lights" on macOS) are visible, this property enables the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars]. Specifying `true` will result in an overlay with default system colors. Default is `false`.
* `titleBarOverlay` Object | Boolean (optional) - When using a frameless window in conjuction with `win.setWindowButtonVisibility(true)` on macOS or using a `titleBarStyle` so that the standard window controls ("traffic lights" on macOS) are visible, this property enables the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars]. Specifying `true` will result in an overlay with default system colors. Default is `false`.
* `color` String (optional) _Windows_ - The CSS color of the Window Controls Overlay when enabled. Default is the system color.
* `symbolColor` String (optional) _Windows_ - The CSS color of the symbols on the Window Controls Overlay when enabled. Default is the system color.
* `height` Integer (optional) _macOS_ _Windows_ - The height of the title bar and Window Controls Overlay in pixels. Default is system height.

When setting minimum or maximum window size with `minWidth`/`maxWidth`/
`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from
Expand Down
10 changes: 9 additions & 1 deletion shell/browser/native_window.cc
Expand Up @@ -90,7 +90,15 @@ NativeWindow::NativeWindow(const gin_helper::Dictionary& options,
options.Get(options::ktitleBarOverlay, &titlebar_overlay_);
} else if (titlebar_overlay->IsObject()) {
titlebar_overlay_ = true;
#if !defined(OS_WIN)

gin_helper::Dictionary titlebar_overlay =
gin::Dictionary::CreateEmpty(options.isolate());
options.Get(options::ktitleBarOverlay, &titlebar_overlay);
int height;
if (titlebar_overlay.Get(options::kOverlayHeight, &height))
titlebar_overlay_height_ = height;

#if !(defined(OS_WIN) || defined(OS_MAC))
DCHECK(false);
#endif
}
Expand Down
5 changes: 5 additions & 0 deletions shell/browser/native_window.h
Expand Up @@ -323,6 +323,7 @@ class NativeWindow : public base::SupportsUserData,
kCustomButtonsOnHover,
};
TitleBarStyle title_bar_style() const { return title_bar_style_; }
int titlebar_overlay_height() const { return titlebar_overlay_height_; }

bool has_frame() const { return has_frame_; }
void set_has_frame(bool has_frame) { has_frame_ = has_frame; }
Expand Down Expand Up @@ -358,6 +359,10 @@ class NativeWindow : public base::SupportsUserData,
// The boolean parsing of the "titleBarOverlay" option
bool titlebar_overlay_ = false;

// The custom height parsed from the "height" option in a Object
// "titleBarOverlay"
int titlebar_overlay_height_ = 0;

// The "titleBarStyle" option.
TitleBarStyle title_bar_style_ = TitleBarStyle::kNormal;

Expand Down
8 changes: 7 additions & 1 deletion shell/browser/native_window_mac.mm
Expand Up @@ -369,6 +369,7 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
InternalSetWindowButtonVisibility(false);
} else {
buttons_proxy_.reset([[WindowButtonsProxy alloc] initWithWindow:window_]);
[buttons_proxy_ setHeight:titlebar_overlay_height()];
if (traffic_light_position_) {
[buttons_proxy_ setMargin:*traffic_light_position_];
} else if (title_bar_style_ == TitleBarStyle::kHiddenInset) {
Expand Down Expand Up @@ -1839,7 +1840,12 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
NSRect buttons = [buttons_proxy_ getButtonsContainerBounds];
gfx::Rect overlay;
overlay.set_width(GetContentSize().width() - NSWidth(buttons));
overlay.set_height(NSHeight(buttons));
if ([buttons_proxy_ useCustomHeight]) {
overlay.set_height(titlebar_overlay_height());
} else {
overlay.set_height(NSHeight(buttons));
}

if (!base::i18n::IsRTL())
overlay.set_x(NSMaxX(buttons));
return overlay;
Expand Down
3 changes: 1 addition & 2 deletions shell/browser/native_window_views.cc
Expand Up @@ -179,9 +179,8 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
v8::Local<v8::Value> titlebar_overlay;
if (options.Get(options::ktitleBarOverlay, &titlebar_overlay) &&
titlebar_overlay->IsObject()) {
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
gin_helper::Dictionary titlebar_overlay_obj =
gin::Dictionary::CreateEmpty(isolate);
gin::Dictionary::CreateEmpty(options.isolate());
options.Get(options::ktitleBarOverlay, &titlebar_overlay_obj);

std::string overlay_color_string;
Expand Down
6 changes: 6 additions & 0 deletions shell/browser/ui/cocoa/window_buttons_proxy.h
Expand Up @@ -30,6 +30,8 @@
gfx::Point margin_;
// The default left-top margin.
gfx::Point default_margin_;
// Current height of the title bar container.
float height_;

// Track mouse moves above window buttons.
BOOL show_on_hover_;
Expand All @@ -49,6 +51,10 @@
// Set left-top margin of the window buttons..
- (void)setMargin:(const absl::optional<gfx::Point>&)margin;

// Set height of button container
- (void)setHeight:(const float)height;
- (BOOL)useCustomHeight;

// Return the bounds of all 3 buttons, with margin on all sides.
- (NSRect)getButtonsContainerBounds;

Expand Down
36 changes: 32 additions & 4 deletions shell/browser/ui/cocoa/window_buttons_proxy.mm
Expand Up @@ -36,6 +36,8 @@ - (id)initWithWindow:(NSWindow*)window {

// Remember the default margin.
margin_ = default_margin_ = [self getCurrentMargin];
// Custom height will be used if set larger than default
height_ = 0;

return self;
}
Expand Down Expand Up @@ -86,6 +88,17 @@ - (void)setMargin:(const absl::optional<gfx::Point>&)margin {
[self redraw];
}

- (void)setHeight:(const float)height {
height_ = height;
[self redraw];
}

- (BOOL)useCustomHeight {
NSView* left = [self leftButton];
float button_height = NSHeight(left.frame);
return height_ > button_height + 2 * default_margin_.y();
}

- (NSRect)getButtonsContainerBounds {
return NSInsetRect([self getButtonsBounds], -margin_.x(), -margin_.y());
}
Expand All @@ -111,14 +124,18 @@ - (void)redraw {

NSRect cbounds = titleBarContainer.frame;
cbounds.size.height = button_height + 2 * margin_.y();
// Custom height must be larger than the button height to use
if ([self useCustomHeight]) {
cbounds.size.height = height_;
}
cbounds.origin.y = NSHeight(window_.frame) - NSHeight(cbounds);
[titleBarContainer setFrame:cbounds];

[left setFrameOrigin:NSMakePoint(start, margin_.y())];
[left setFrameOrigin:NSMakePoint(start, [self getCurrentMargin].y())];
start += button_width + padding;
[middle setFrameOrigin:NSMakePoint(start, margin_.y())];
[middle setFrameOrigin:NSMakePoint(start, [self getCurrentMargin].y())];
start += button_width + padding;
[right setFrameOrigin:NSMakePoint(start, margin_.y())];
[right setFrameOrigin:NSMakePoint(start, [self getCurrentMargin].y())];

if (hover_view_)
[hover_view_ setFrame:[self getButtonsBounds]];
Expand Down Expand Up @@ -167,6 +184,7 @@ - (void)updateButtonsVisibility {
- (NSRect)getButtonsBounds {
NSView* left = [self leftButton];
NSView* right = [self rightButton];

return NSMakeRect(NSMinX(left.frame), NSMinY(left.frame),
NSMaxX(right.frame) - NSMinX(left.frame),
NSHeight(left.frame));
Expand All @@ -182,7 +200,17 @@ - (NSRect)getButtonsBounds {
NSView* left = [self leftButton];
NSView* right = [self rightButton];

result.set_y((NSHeight(titleBarContainer.frame) - NSHeight(left.frame)) / 2);
if (height_ != 0) {
result.set_y((height_ - NSHeight(left.frame)) / 2);

// Do not center buttons if height and button position specified
if (margin_.y() != default_margin_.y())
result.set_y(height_ - NSHeight(left.frame) - margin_.y());

} else {
result.set_y((NSHeight(titleBarContainer.frame) - NSHeight(left.frame)) /
2);
}

if (base::i18n::IsRTL())
result.set_x(NSWidth(window_.frame) - NSMaxX(right.frame));
Expand Down
22 changes: 18 additions & 4 deletions shell/browser/ui/views/win_caption_button.cc
Expand Up @@ -2,13 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Modified from chrome/browser/ui/views/frame/windows_10_caption_button.cc

#include "shell/browser/ui/views/win_caption_button.h"

#include <utility>

#include "base/i18n/rtl.h"
#include "base/numerics/safe_conversions.h"
#include "chrome/browser/ui/frame/window_frame_util.h"
#include "chrome/grit/theme_resources.h"
#include "shell/browser/ui/views/win_frame_view.h"
#include "shell/common/color_util.h"
Expand Down Expand Up @@ -37,9 +38,8 @@ WinCaptionButton::WinCaptionButton(PressedCallback callback,
gfx::Size WinCaptionButton::CalculatePreferredSize() const {
// TODO(bsep): The sizes in this function are for 1x device scale and don't
// match Windows button sizes at hidpi.
int height = WindowFrameUtil::kWindows10GlassCaptionButtonHeightRestored;
int base_width = WindowFrameUtil::kWindows10GlassCaptionButtonWidth;
return gfx::Size(base_width + GetBetweenButtonSpacing(), height);

return gfx::Size(base_width_ + GetBetweenButtonSpacing(), height_);
}

void WinCaptionButton::OnPaintBackground(gfx::Canvas* canvas) {
Expand Down Expand Up @@ -88,6 +88,20 @@ void WinCaptionButton::PaintButtonContents(gfx::Canvas* canvas) {
PaintSymbol(canvas);
}

gfx::Size WinCaptionButton::GetSize() const {
return gfx::Size(base_width_, height_);
}

void WinCaptionButton::SetSize(gfx::Size size) {
int width = size.width();
int height = size.height();

if (width > 0)
base_width_ = width;
if (height > 0)
height_ = height;
}

int WinCaptionButton::GetBetweenButtonSpacing() const {
const int display_order_index = GetButtonDisplayOrderIndex();
return display_order_index == 0
Expand Down
11 changes: 10 additions & 1 deletion shell/browser/ui/views/win_caption_button.h
Expand Up @@ -2,9 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Modified from chrome/browser/ui/views/frame/windows_10_caption_button.h

#ifndef SHELL_BROWSER_UI_VIEWS_WIN_CAPTION_BUTTON_H_
#define SHELL_BROWSER_UI_VIEWS_WIN_CAPTION_BUTTON_H_

#include "chrome/browser/ui/frame/window_frame_util.h"
#include "chrome/browser/ui/view_ids.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/gfx/canvas.h"
Expand All @@ -28,7 +31,10 @@ class WinCaptionButton : public views::Button {
void OnPaintBackground(gfx::Canvas* canvas) override;
void PaintButtonContents(gfx::Canvas* canvas) override;

// private:
gfx::Size GetSize() const;
void SetSize(gfx::Size size);

private:
// Returns the amount we should visually reserve on the left (right in RTL)
// for spacing between buttons. We do this instead of repositioning the
// buttons to avoid the sliver of deadspace that would result.
Expand All @@ -48,6 +54,9 @@ class WinCaptionButton : public views::Button {

WinFrameView* frame_view_;
ViewID button_type_;

int base_width_ = WindowFrameUtil::kWindows10GlassCaptionButtonWidth;
int height_ = WindowFrameUtil::kWindows10GlassCaptionButtonHeightRestored;
};
} // namespace electron

Expand Down
15 changes: 15 additions & 0 deletions shell/browser/ui/views/win_caption_button_container.cc
Expand Up @@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Modified from
// chrome/browser/ui/views/frame/glass_browser_caption_button_container.cc

#include "shell/browser/ui/views/win_caption_button_container.h"

#include <memory>
Expand Down Expand Up @@ -96,6 +99,18 @@ int WinCaptionButtonContainer::NonClientHitTest(const gfx::Point& point) const {
return HTCAPTION;
}

gfx::Size WinCaptionButtonContainer::GetButtonSize() const {
// Close button size is set the same as all the buttons
return close_button_->GetSize();
}

void WinCaptionButtonContainer::SetButtonSize(gfx::Size size) {
minimize_button_->SetSize(size);
maximize_button_->SetSize(size);
restore_button_->SetSize(size);
close_button_->SetSize(size);
}

void WinCaptionButtonContainer::ResetWindowControls() {
minimize_button_->SetState(views::Button::STATE_NORMAL);
maximize_button_->SetState(views::Button::STATE_NORMAL);
Expand Down
6 changes: 6 additions & 0 deletions shell/browser/ui/views/win_caption_button_container.h
Expand Up @@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Modified from
// chrome/browser/ui/views/frame/glass_browser_caption_button_container.h

#ifndef SHELL_BROWSER_UI_VIEWS_WIN_CAPTION_BUTTON_CONTAINER_H_
#define SHELL_BROWSER_UI_VIEWS_WIN_CAPTION_BUTTON_CONTAINER_H_

Expand Down Expand Up @@ -35,6 +38,9 @@ class WinCaptionButtonContainer : public views::View,
// See also ClientView::NonClientHitTest.
int NonClientHitTest(const gfx::Point& point) const;

gfx::Size GetButtonSize() const;
void SetButtonSize(gfx::Size size);

private:
// views::View:
void AddedToWidget() override;
Expand Down
41 changes: 28 additions & 13 deletions shell/browser/ui/views/win_frame_view.cc
Expand Up @@ -193,13 +193,20 @@ int WinFrameView::TitlebarMaximizedVisualHeight() const {
return maximized_height;
}

int WinFrameView::TitlebarHeight(bool restored) const {
if (frame()->IsFullscreen() && !restored)
// NOTE(@mlaurencin): Usage of IsWebUITabStrip simplified out from Chromium
int WinFrameView::TitlebarHeight(int custom_height) const {
if (frame()->IsFullscreen() && !IsMaximized())
return 0;

return TitlebarMaximizedVisualHeight() + FrameTopBorderThickness(false);
int height = TitlebarMaximizedVisualHeight() +
FrameTopBorderThickness(false) - WindowTopY();
if (custom_height > TitlebarMaximizedVisualHeight())
height = custom_height - WindowTopY();

return height;
}

// NOTE(@mlaurencin): Usage of IsWebUITabStrip simplified out from Chromium
int WinFrameView::WindowTopY() const {
// The window top is SM_CYSIZEFRAME pixels when maximized (see the comment in
// FrameTopBorderThickness()) and floor(system dsf) pixels when restored.
Expand All @@ -222,27 +229,35 @@ void WinFrameView::LayoutCaptionButtons() {
}

caption_button_container_->SetVisible(true);

const gfx::Size preferred_size =
caption_button_container_->GetPreferredSize();
int height = preferred_size.height();

height = IsMaximized() ? TitlebarMaximizedVisualHeight()
: TitlebarHeight(false) - WindowTopY();
int custom_height = window()->titlebar_overlay_height();
int height = TitlebarHeight(custom_height);

// TODO(mlaurencin): This -1 creates a 1 pixel gap between the right
// edge of the overlay and the edge of the window, allowing for this edge
// portion to return the correct hit test and be manually resized properly.
// Alternatives can be explored, but the differences in view structures
// between Electron and Chromium may result in this as the best option.
// TODO(mlaurencin): This -1 creates a 1 pixel margin between the right
// edge of the button container and the edge of the window, allowing for this
// edge portion to return the correct hit test and be manually resized
// properly. Alternatives can be explored, but the differences in view
// structures between Electron and Chromium may result in this as the best
// option.
int variable_width =
IsMaximized() ? preferred_size.width() : preferred_size.width() - 1;
caption_button_container_->SetBounds(width() - preferred_size.width(),
WindowTopY(), variable_width, height);

// Needed for heights larger than default
caption_button_container_->SetButtonSize(gfx::Size(0, height));
}

void WinFrameView::LayoutWindowControlsOverlay() {
int overlay_height = caption_button_container_->size().height();
int overlay_height = window()->titlebar_overlay_height();
if (overlay_height == 0) {
// Accounting for the 1 pixel margin at the top of the button container
overlay_height = IsMaximized()
? caption_button_container_->size().height()
: caption_button_container_->size().height() + 1;
}
int overlay_width = caption_button_container_->size().width();
int bounding_rect_width = width() - overlay_width;
auto bounding_rect =
Expand Down
2 changes: 1 addition & 1 deletion shell/browser/ui/views/win_frame_view.h
Expand Up @@ -67,7 +67,7 @@ class WinFrameView : public FramelessView {

// Returns the height of the titlebar for popups or other browser types that
// don't have tabs.
int TitlebarHeight(bool restored) const;
int TitlebarHeight(int custom_height) const;

// Returns the y coordinate for the top of the frame, which in maximized mode
// is the top of the screen and in restored mode is 1 pixel below the top of
Expand Down
3 changes: 3 additions & 0 deletions shell/common/options_switches.cc
Expand Up @@ -36,6 +36,9 @@ const char kRoundedCorners[] = "roundedCorners";
const char kOverlayButtonColor[] = "color";
const char kOverlaySymbolColor[] = "symbolColor";

// The custom height for Window Controls Overlay.
const char kOverlayHeight[] = "height";

// Whether the window should show in taskbar.
const char kSkipTaskbar[] = "skipTaskbar";

Expand Down