Repository: electron/electron
Pull request: feat: add roundedCorners option for BrowserWindow

#### Description of Change

Add an option to remove rounded corners of frameless windows on macOS, close https://github.com/electron/electron/issues/414.

#### Checklist

- [x] PR description included and stakeholders cc'd
- [x] `npm test` passes
- [ ] tests are [changed or added](https://github.com/electron/electron/blob/master/docs/development/testing.md)
- [x] relevant documentation is changed or added
- [x] [PR release notes](https://github.com/electron/clerk/blob/master/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/master/README.md#examples).

#### Release Notes

Notes: Add `roundedCorners` option for `BrowserWindow`.

Changed files:
filename: docs/api/browser-window.md
patch: @@ -228,6 +228,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
       experimental.
   * `trafficLightPosition` [Point](structures/point.md) (optional) - Set a
     custom position for the traffic light buttons in frameless windows.
+  * `roundedCorners` Boolean (optional) - Whether frameless window should have
+    rounded corners on macOS. Default is `true`.
   * `fullscreenWindowTitle` Boolean (optional) _Deprecated_ - Shows the title in
     the title bar in full screen mode on macOS for `hiddenInset` titleBarStyle.
     Default is `false`.

filename: shell/browser/native_window_mac.mm
patch: @@ -305,17 +305,25 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
     useStandardWindow = false;
   }
 
+  // The window without titlebar is treated the same with frameless window.
+  if (title_bar_style_ != TitleBarStyle::kNormal)
+    set_has_frame(false);
+
   NSUInteger styleMask = NSWindowStyleMaskTitled;
+
+  // The NSWindowStyleMaskFullSizeContentView style removes rounded corners
+  // for framless window.
+  bool rounded_corner = true;
+  options.Get(options::kRoundedCorners, &rounded_corner);
+  if (!rounded_corner && !has_frame())
+    styleMask = NSWindowStyleMaskFullSizeContentView;
+
   if (minimizable)
     styleMask |= NSMiniaturizableWindowMask;
   if (closable)
     styleMask |= NSWindowStyleMaskClosable;
   if (resizable_)
     styleMask |= NSResizableWindowMask;
-
-  // The window without titlebar is treated the same with frameless window.
-  if (title_bar_style_ != TitleBarStyle::kNormal)
-    set_has_frame(false);
   if (!useStandardWindow || transparent() || !has_frame())
     styleMask |= NSTexturedBackgroundWindowMask;
 
@@ -1234,8 +1242,11 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
       [effect_view setState:NSVisualEffectStateFollowsWindowActiveState];
     }
 
-    // Make frameless Vibrant windows have rounded corners.
-    if (!has_frame() && !is_modal()) {
+    // Make Vibrant view have rounded corners, so the frameless window can keep
+    // its rounded corners.
+    const bool no_rounded_corner =
+        [window_ styleMask] & NSWindowStyleMaskFullSizeContentView;
+    if (!has_frame() && !is_modal() && !no_rounded_corner) {
       CGFloat radius = 5.0f;  // default corner radius
       CGFloat dimension = 2 * radius + 1;
       NSSize size = NSMakeSize(dimension, dimension);
@@ -1254,7 +1265,6 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
       [maskImage setResizingMode:NSImageResizingModeStretch];
 
       [effect_view setMaskImage:maskImage];
-      [window_ setCornerMask:maskImage];
     }
 
     [[window_ contentView] addSubview:effect_view

filename: shell/common/options_switches.cc
patch: @@ -29,6 +29,7 @@ const char kFullScreenable[] = "fullscreenable";
 const char kClosable[] = "closable";
 const char kFullscreen[] = "fullscreen";
 const char kTrafficLightPosition[] = "trafficLightPosition";
+const char kRoundedCorners[] = "roundedCorners";
 
 // Whether the window should show in taskbar.
 const char kSkipTaskbar[] = "skipTaskbar";

filename: shell/common/options_switches.h
patch: @@ -56,6 +56,7 @@ extern const char kWebPreferences[];
 extern const char kVibrancyType[];
 extern const char kVisualEffectState[];
 extern const char kTrafficLightPosition[];
+extern const char kRoundedCorners[];
 
 // WebPreferences.
 extern const char kZoomFactor[];