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: support Mica/Acrylic on Windows #38361

Merged
merged 1 commit into from
May 18, 2023
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/api/browser-window.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,9 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
`tooltip`, `content`, `under-window`, or `under-page`. Please note that
`appearance-based`, `light`, `dark`, `medium-light`, and `ultra-dark` are
deprecated and have been removed in macOS Catalina (10.15).
* `backgroundMaterial` string (optional) _Windows_ - Set the window's
system-drawn background material, including behind the non-client area.
Can be `auto`, `none`, `mica`, `acrylic` or `tabbed`. See [win.setBackgroundMaterial](#winsetbackgroundmaterialmaterial-windows) for more information.
* `zoomToPageWidth` boolean (optional) _macOS_ - Controls the behavior on
macOS when option-clicking the green stoplight button on the toolbar or by
clicking the Window > Zoom menu item. If `true`, the window will grow to
Expand Down Expand Up @@ -1855,6 +1858,21 @@ Set a custom position for the traffic light buttons in frameless window.
Returns `Point` - The custom position for the traffic light buttons in
frameless window.

#### `win.setBackgroundMaterial(material)` _Windows_

* `material` string
* `auto` - Let the Desktop Window Manager (DWM) automatically decide the system-drawn backdrop material for this window. This is the default.
* `none` - Don't draw any system backdrop.
* `mica` - Draw the backdrop material effect corresponding to a long-lived window.
* `acrylic` - Draw the backdrop material effect corresponding to a transient window.
* `tabbed` - Draw the backdrop material effect corresponding to a window with a tabbed title bar.

This method sets the browser window's system-drawn background material, including behind the non-client area.

See the [Windows documentation](https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwm_systembackdrop_type) for more details.

**Note:** This method is only supported on Windows 11 22H2 and up.

#### `win.setTouchBar(touchBar)` _macOS_

* `touchBar` TouchBar | null
Expand Down
9 changes: 5 additions & 4 deletions shell/browser/api/electron_api_base_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,10 @@ void BaseWindow::SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value) {
window_->SetVibrancy(type);
}

void BaseWindow::SetBackgroundMaterial(const std::string& material_type) {
window_->SetBackgroundMaterial(material_type);
}

#if BUILDFLAG(IS_MAC)
std::string BaseWindow::GetAlwaysOnTopLevel() {
return window_->GetAlwaysOnTopLevel();
Expand Down Expand Up @@ -1276,15 +1280,12 @@ void BaseWindow::BuildPrototype(v8::Isolate* isolate,
&BaseWindow::SetTrafficLightPosition)
.SetMethod("getTrafficLightPosition",
&BaseWindow::GetTrafficLightPosition)
#endif

#if BUILDFLAG(IS_MAC)
.SetMethod("isHiddenInMissionControl",
&BaseWindow::IsHiddenInMissionControl)
.SetMethod("setHiddenInMissionControl",
&BaseWindow::SetHiddenInMissionControl)
#endif

.SetMethod("setBackgroundMaterial", &BaseWindow::SetBackgroundMaterial)
.SetMethod("_setTouchBarItems", &BaseWindow::SetTouchBar)
.SetMethod("_refreshTouchBarItem", &BaseWindow::RefreshTouchBarItem)
.SetMethod("_setEscapeTouchBarItem", &BaseWindow::SetEscapeTouchBarItem)
Expand Down
1 change: 1 addition & 0 deletions shell/browser/api/electron_api_base_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
bool IsVisibleOnAllWorkspaces();
void SetAutoHideCursor(bool auto_hide);
virtual void SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value);
void SetBackgroundMaterial(const std::string& vibrancy);

#if BUILDFLAG(IS_MAC)
std::string GetAlwaysOnTopLevel();
Expand Down
7 changes: 7 additions & 0 deletions shell/browser/native_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,11 @@ void NativeWindow::InitFromOptions(const gin_helper::Dictionary& options) {
if (options.Get(options::kVibrancyType, &type)) {
SetVibrancy(type);
}
#elif BUILDFLAG(IS_WIN)
std::string material;
if (options.Get(options::kBackgroundMaterial, &material)) {
SetBackgroundMaterial(material);
}
#endif
std::string color;
if (options.Get(options::kBackgroundColor, &color)) {
Expand Down Expand Up @@ -445,6 +450,8 @@ bool NativeWindow::AddTabbedWindow(NativeWindow* window) {

void NativeWindow::SetVibrancy(const std::string& type) {}

void NativeWindow::SetBackgroundMaterial(const std::string& type) {}

void NativeWindow::SetTouchBar(
std::vector<gin_helper::PersistentDictionary> items) {}

Expand Down
2 changes: 2 additions & 0 deletions shell/browser/native_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ class NativeWindow : public base::SupportsUserData,
// Vibrancy API
virtual void SetVibrancy(const std::string& type);

virtual void SetBackgroundMaterial(const std::string& type);

// Traffic Light API
#if BUILDFLAG(IS_MAC)
virtual void SetWindowButtonVisibility(bool visible) = 0;
Expand Down
30 changes: 30 additions & 0 deletions shell/browser/native_window_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "shell/browser/native_window_views.h"

#if BUILDFLAG(IS_WIN)
#include <dwmapi.h>
#include <wrl/client.h>
#endif

Expand Down Expand Up @@ -68,6 +69,7 @@

#elif BUILDFLAG(IS_WIN)
#include "base/win/win_util.h"
#include "base/win/windows_version.h"
#include "content/public/common/color_parser.h"
#include "shell/browser/ui/views/win_frame_view.h"
#include "shell/browser/ui/win/electron_desktop_native_widget_aura.h"
Expand All @@ -82,6 +84,19 @@ namespace electron {

#if BUILDFLAG(IS_WIN)

DWM_SYSTEMBACKDROP_TYPE GetBackdropFromString(const std::string& material) {
if (material == "none") {
return DWMSBT_NONE;
} else if (material == "acrylic") {
return DWMSBT_TRANSIENTWINDOW;
} else if (material == "mica") {
return DWMSBT_MAINWINDOW;
} else if (material == "tabbed") {
return DWMSBT_TABBEDWINDOW;
}
return DWMSBT_AUTO;
}

// Similar to the ones in display::win::ScreenWin, but with rounded values
// These help to avoid problems that arise from unresizable windows where the
// original ceil()-ed values can cause calculation errors, since converting
Expand Down Expand Up @@ -1388,6 +1403,21 @@ bool NativeWindowViews::IsMenuBarVisible() {
return root_view_->IsMenuBarVisible();
}

void NativeWindowViews::SetBackgroundMaterial(const std::string& material) {
#if BUILDFLAG(IS_WIN)
// DWMWA_USE_HOSTBACKDROPBRUSH is only supported on Windows 11 22H2 and up.
if (base::win::GetVersion() < base::win::Version::WIN11_22H2)
return;

DWM_SYSTEMBACKDROP_TYPE backdrop_type = GetBackdropFromString(material);
HRESULT result =
DwmSetWindowAttribute(GetAcceleratedWidget(), DWMWA_SYSTEMBACKDROP_TYPE,
&backdrop_type, sizeof(backdrop_type));
if (FAILED(result))
LOG(WARNING) << "Failed to set background material to " << material;
#endif
}

void NativeWindowViews::SetVisibleOnAllWorkspaces(
bool visible,
bool visibleOnFullScreen,
Expand Down
1 change: 1 addition & 0 deletions shell/browser/native_window_views.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class NativeWindowViews : public NativeWindow,
bool IsMenuBarAutoHide() override;
void SetMenuBarVisibility(bool visible) override;
bool IsMenuBarVisible() override;
void SetBackgroundMaterial(const std::string& type) override;

void SetVisibleOnAllWorkspaces(bool visible,
bool visibleOnFullScreen,
Expand Down
3 changes: 3 additions & 0 deletions shell/common/options_switches.cc
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ const char kWebPreferences[] = "webPreferences";
// Add a vibrancy effect to the browser window
const char kVibrancyType[] = "vibrancy";

// Add a vibrancy effect to the browser window.
const char kBackgroundMaterial[] = "backgroundMaterial";

// Specify how the material appearance should reflect window activity state on
// macOS.
const char kVisualEffectState[] = "visualEffectState";
Expand Down
1 change: 1 addition & 0 deletions shell/common/options_switches.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ extern const char kOpacity[];
extern const char kFocusable[];
extern const char kWebPreferences[];
extern const char kVibrancyType[];
extern const char kBackgroundMaterial[];
extern const char kVisualEffectState[];
extern const char kTrafficLightPosition[];
extern const char kRoundedCorners[];
Expand Down