Skip to content

Commit

Permalink
feat: support Mica/Acrylic on Windows (#38361)
Browse files Browse the repository at this point in the history
  • Loading branch information
codebytere committed May 18, 2023
1 parent 2594d94 commit 4cfd732
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 4 deletions.
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

0 comments on commit 4cfd732

Please sign in to comment.