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 title bar style setters #33066

Merged
merged 2 commits into from Mar 25, 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
10 changes: 10 additions & 0 deletions docs/api/browser-window.md
Expand Up @@ -1808,6 +1808,16 @@ with `addBrowserView` or `setBrowserView`.
**Note:** The BrowserView API is currently experimental and may change or be
removed in future Electron releases.

#### `win.setTitleBarOverlay(options)` _Windows_

* `options` Object
* `color` String (optional) _Windows_ - The CSS color of the Window Controls Overlay when enabled.
* `symbolColor` String (optional) _Windows_ - The CSS color of the symbols on the Window Controls Overlay when enabled.
* `height` Integer (optional) _Windows_ - The height of the title bar and Window Controls Overlay in pixels.

On a Window with Window Controls Overlay already enabled, this method updates
the style of the title bar overlay.

[runtime-enabled-features]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70
[page-visibility-api]: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
[quick-look]: https://en.wikipedia.org/wiki/Quick_Look
Expand Down
71 changes: 71 additions & 0 deletions shell/browser/api/electron_api_browser_window.cc
Expand Up @@ -10,6 +10,7 @@
#include "content/browser/web_contents/web_contents_impl.h" // nogncheck
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/common/color_parser.h"
#include "shell/browser/api/electron_api_web_contents_view.h"
#include "shell/browser/browser.h"
#include "shell/browser/native_browser_view.h"
Expand All @@ -24,6 +25,14 @@
#include "shell/common/options_switches.h"
#include "ui/gl/gpu_switching_manager.h"

#if defined(TOOLKIT_VIEWS)
#include "shell/browser/native_window_views.h"
#endif

#if BUILDFLAG(IS_WIN)
#include "shell/browser/ui/views/win_frame_view.h"
#endif

namespace electron {

namespace api {
Expand Down Expand Up @@ -466,6 +475,65 @@ v8::Local<v8::Value> BrowserWindow::GetWebContents(v8::Isolate* isolate) {
return v8::Local<v8::Value>::New(isolate, web_contents_);
}

#if BUILDFLAG(IS_WIN)
void BrowserWindow::SetTitleBarOverlay(const gin_helper::Dictionary& options,
gin_helper::Arguments* args) {
// Ensure WCO is already enabled on this window
if (!window_->titlebar_overlay_enabled()) {
args->ThrowError("Titlebar overlay is not enabled");
clavin marked this conversation as resolved.
Show resolved Hide resolved
return;
}

auto* window = static_cast<NativeWindowViews*>(window_.get());
bool updated = false;

// Check and update the button color
std::string btn_color;
if (options.Get(options::kOverlayButtonColor, &btn_color)) {
// Parse the string as a CSS color
SkColor color;
if (!content::ParseCssColorString(btn_color, &color)) {
args->ThrowError("Could not parse color as CSS color");
return;
}

// Update the view
window->set_overlay_button_color(color);
updated = true;
}

// Check and update the symbol color
std::string symbol_color;
if (options.Get(options::kOverlaySymbolColor, &symbol_color)) {
// Parse the string as a CSS color
SkColor color;
if (!content::ParseCssColorString(symbol_color, &color)) {
args->ThrowError("Could not parse symbol color as CSS color");
return;
}

// Update the view
window->set_overlay_symbol_color(color);
updated = true;
}

// Check and update the height
int height = 0;
if (options.Get(options::kOverlayHeight, &height)) {
window->set_titlebar_overlay_height(height);
updated = true;
}

// If anything was updated, invalidate the layout and schedule a paint of the
// window's frame view
if (updated) {
auto* frame_view = static_cast<WinFrameView*>(
window->widget()->non_client_view()->frame_view());
frame_view->InvalidateCaptionButtons();
}
}
#endif

void BrowserWindow::ScheduleUnresponsiveEvent(int ms) {
if (!window_unresponsive_closure_.IsCancelled())
return;
Expand Down Expand Up @@ -524,6 +592,9 @@ void BrowserWindow::BuildPrototype(v8::Isolate* isolate,
.SetMethod("focusOnWebView", &BrowserWindow::FocusOnWebView)
.SetMethod("blurWebView", &BrowserWindow::BlurWebView)
.SetMethod("isWebViewFocused", &BrowserWindow::IsWebViewFocused)
#if BUILDFLAG(IS_WIN)
.SetMethod("setTitleBarOverlay", &BrowserWindow::SetTitleBarOverlay)
#endif
.SetProperty("webContents", &BrowserWindow::GetWebContents);
}

Expand Down
4 changes: 4 additions & 0 deletions shell/browser/api/electron_api_browser_window.h
Expand Up @@ -99,6 +99,10 @@ class BrowserWindow : public BaseWindow,
void BlurWebView();
bool IsWebViewFocused();
v8::Local<v8::Value> GetWebContents(v8::Isolate* isolate);
#if BUILDFLAG(IS_WIN)
void SetTitleBarOverlay(const gin_helper::Dictionary& options,
gin_helper::Arguments* args);
#endif

private:
#if BUILDFLAG(IS_MAC)
Expand Down
4 changes: 4 additions & 0 deletions shell/browser/native_window.h
Expand Up @@ -328,6 +328,10 @@ class NativeWindow : public base::SupportsUserData,
};
TitleBarStyle title_bar_style() const { return title_bar_style_; }
int titlebar_overlay_height() const { return titlebar_overlay_height_; }
void set_titlebar_overlay_height(int height) {
titlebar_overlay_height_ = height;
}
bool titlebar_overlay_enabled() const { return titlebar_overlay_; }

bool has_frame() const { return has_frame_; }
void set_has_frame(bool has_frame) { has_frame_ = has_frame; }
Expand Down
6 changes: 6 additions & 0 deletions shell/browser/native_window_views.h
Expand Up @@ -181,7 +181,13 @@ class NativeWindowViews : public NativeWindow,
titlebar_overlay_;
}
SkColor overlay_button_color() const { return overlay_button_color_; }
void set_overlay_button_color(SkColor color) {
overlay_button_color_ = color;
}
SkColor overlay_symbol_color() const { return overlay_symbol_color_; }
void set_overlay_symbol_color(SkColor color) {
overlay_symbol_color_ = color;
}
#endif

private:
Expand Down
2 changes: 2 additions & 0 deletions shell/browser/ui/views/win_caption_button.cc
Expand Up @@ -100,6 +100,8 @@ void WinCaptionButton::SetSize(gfx::Size size) {
base_width_ = width;
if (height > 0)
height_ = height;

InvalidateLayout();
}

int WinCaptionButton::GetBetweenButtonSpacing() const {
Expand Down
8 changes: 8 additions & 0 deletions shell/browser/ui/views/win_frame_view.cc
Expand Up @@ -54,6 +54,14 @@ SkColor WinFrameView::GetReadableFeatureColor(SkColor background_color) {
: SK_ColorBLACK;
}

void WinFrameView::InvalidateCaptionButtons() {
// Ensure that the caption buttons container exists
DCHECK(caption_button_container_);

caption_button_container_->InvalidateLayout();
caption_button_container_->SchedulePaint();
}

gfx::Rect WinFrameView::GetWindowBoundsForClientBounds(
const gfx::Rect& client_bounds) const {
return views::GetWindowBoundsForClientBounds(
Expand Down
3 changes: 3 additions & 0 deletions shell/browser/ui/views/win_frame_view.h
Expand Up @@ -30,6 +30,9 @@ class WinFrameView : public FramelessView {

SkColor GetReadableFeatureColor(SkColor background_color);

// Tells the NonClientView to invalidate the WinFrameView's caption buttons.
void InvalidateCaptionButtons();

// views::NonClientFrameView:
gfx::Rect GetWindowBoundsForClientBounds(
const gfx::Rect& client_bounds) const override;
Expand Down