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 #31222

Merged
merged 15 commits into from Jan 24, 2022
Merged
Show file tree
Hide file tree
Changes from 4 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 @@ -393,6 +393,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
* `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 Control Overlay in pixels.

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
3 changes: 2 additions & 1 deletion docs/api/frameless-window.md
Expand Up @@ -69,7 +69,7 @@ When using a frameless window in conjuction with `win.setWindowButtonVisibility(
that the traffic lights are visible, or using `titleBarStyle: hidden` on Windows, you can access the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and
[CSS Environment Variables][overlay-css-env-vars] by setting the `titleBarOverlay` option to true. Specifying `true` will result in an overlay with default system colors.

On Windows, you can also specify the color of the overlay and its symbols by setting `titleBarOverlay` to an object with the options `color` and `symbolColor`. If an option is not specified, the color will default to its system color for the window control buttons:
You can specify the height of the overlay by setting `titleBarOverlay` to an object with the option `height`. On Windows, you can also specify the color of the overlay and its symbols with the options `color` and `symbolColor`. If the `height` option is not specified, the default title bar height for that system is used. And if a color option is not specified, its system color for the window control buttons is used:

```javascript
const { BrowserWindow } = require('electron')
Expand All @@ -85,6 +85,7 @@ const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: {
height: 40,
color: '#2f3241',
symbolColor: '#74b1be'
}
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;
mlaurencin marked this conversation as resolved.
Show resolved Hide resolved

#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
7 changes: 6 additions & 1 deletion shell/browser/native_window_mac.mm
Expand Up @@ -1824,7 +1824,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 (titlebar_overlay_height() > NSHeight(buttons)) {
overlay.set_height(titlebar_overlay_height());
mlaurencin marked this conversation as resolved.
Show resolved Hide resolved
} 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
20 changes: 16 additions & 4 deletions shell/browser/ui/views/win_caption_button.cc
Expand Up @@ -8,7 +8,6 @@

#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 +36,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 +86,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
9 changes: 8 additions & 1 deletion shell/browser/ui/views/win_caption_button.h
Expand Up @@ -5,6 +5,7 @@
#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 +29,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 +52,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
12 changes: 12 additions & 0 deletions shell/browser/ui/views/win_caption_button_container.cc
Expand Up @@ -96,6 +96,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
3 changes: 3 additions & 0 deletions shell/browser/ui/views/win_caption_button_container.h
Expand Up @@ -35,6 +35,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
21 changes: 14 additions & 7 deletions shell/browser/ui/views/win_frame_view.cc
Expand Up @@ -193,11 +193,17 @@ int WinFrameView::TitlebarMaximizedVisualHeight() const {
return maximized_height;
}

int WinFrameView::TitlebarHeight(bool restored) const {
if (frame()->IsFullscreen() && !restored)
int WinFrameView::TitlebarHeight(int custom_height) const {
if (frame()->IsFullscreen() && !IsMaximized())
return 0;

return TitlebarMaximizedVisualHeight() + FrameTopBorderThickness(false);
int height = TitlebarMaximizedVisualHeight() +
ckerr marked this conversation as resolved.
Show resolved Hide resolved
FrameTopBorderThickness(false) - WindowTopY();
if (custom_height > TitlebarMaximizedVisualHeight()) {
height = IsMaximized() ? custom_height : custom_height - WindowTopY();
}

return height;
mlaurencin marked this conversation as resolved.
Show resolved Hide resolved
}

int WinFrameView::WindowTopY() const {
Expand All @@ -222,13 +228,11 @@ 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
Expand All @@ -239,6 +243,9 @@ void WinFrameView::LayoutCaptionButtons() {
IsMaximized() ? preferred_size.width() : preferred_size.width() - 1;
caption_button_container_->SetBounds(width() - preferred_size.width(),
WindowTopY(), variable_width, height);

int variable_height = IsMaximized() ? height : height - 1;
caption_button_container_->SetButtonSize(gfx::Size(0, variable_height));
}

void WinFrameView::LayoutWindowControlsOverlay() {
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
1 change: 1 addition & 0 deletions shell/common/options_switches.h
Expand Up @@ -60,6 +60,7 @@ extern const char kRoundedCorners[];
extern const char ktitleBarOverlay[];
extern const char kOverlayButtonColor[];
extern const char kOverlaySymbolColor[];
extern const char kOverlayHeight[];

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