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: enable windows control overlay on Windows #29600

Merged
merged 36 commits into from
Aug 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9e9f507
rebase "feat: enable windows control overlay on Windows"
mlaurencin May 4, 2021
2e73bad
correct compilation error
jkleinsc Jun 9, 2021
c578ce4
fix linting errors
mlaurencin Jun 9, 2021
2f223d2
modify includes and build file
mlaurencin Jun 9, 2021
70eee04
change `hidden` option to `overlay`
mlaurencin Jun 15, 2021
053ee16
add patch to fix visual layout
mlaurencin Jun 16, 2021
6ee51e6
add button background color parameter
mlaurencin Jun 17, 2021
ab0ad2f
add button text color parameter
mlaurencin Jun 18, 2021
4c0a117
modify `overlay` in docs and modify button hover/press transition color
mlaurencin Jun 21, 2021
be293b5
change `text` to `symbol`
mlaurencin Jun 29, 2021
7fe47bc
remove todo and fix `text` replacement
mlaurencin Jun 29, 2021
c82d86d
add new titleBarOverlay property and remove titleBarStyle `overlay`
mlaurencin Jul 12, 2021
94674d4
update browser and frameless window docs
mlaurencin Jul 13, 2021
83eba0f
remove chromium patches
mlaurencin Jul 13, 2021
76965a1
chore: update patches
patchup[bot] Jul 13, 2021
7655b9a
change button hover color, update trailing `_`, update test file
mlaurencin Jul 13, 2021
2eda4bf
add dchecks, update title bar drawing checks, update test file
mlaurencin Jul 15, 2021
556e53f
modify for mac and linux builds
mlaurencin Jul 20, 2021
d5b5866
update docs with overlayColor and overlaySymbolColor
mlaurencin Jul 21, 2021
126d976
add corner and side hit test info
mlaurencin Jul 26, 2021
4703f62
Merge branch 'main' into windows-control-overlay-add
jkleinsc Jul 26, 2021
0ab75b2
modify docs and copyright info
mlaurencin Jul 28, 2021
10dc4d8
modify `titlebar_overlay_` as boolean or object
mlaurencin Jul 29, 2021
4e5b292
move `title_bar_style_ to `NativeWindow`
mlaurencin Jul 29, 2021
63b581c
update docs with boolean and object titlebar_overlay_
mlaurencin Jul 30, 2021
c464510
add `IsEmpty` checks
mlaurencin Aug 2, 2021
0f29067
move get options for boolean and object checks
mlaurencin Aug 2, 2021
1bfb8bb
fix linting error
mlaurencin Aug 4, 2021
1fcca6d
disable `use_lld` for macos
mlaurencin Aug 6, 2021
91a3c5d
Merge branch 'main' into windows-control-overlay-add
jkleinsc Aug 9, 2021
5713c20
Update docs/api/frameless-window.md
mlaurencin Aug 9, 2021
6827045
Update docs/api/frameless-window.md
mlaurencin Aug 9, 2021
75da694
Update docs/api/frameless-window.md
mlaurencin Aug 9, 2021
4864bb3
Apply docs suggestions from code review
mlaurencin Aug 9, 2021
5757e00
modify `true` option description `titleBarOverlay`
mlaurencin Aug 9, 2021
1f1a51d
ci: cleanup keychain after tests on arm64 mac (#30472)
jkleinsc Aug 10, 2021
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
2 changes: 2 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ step-maybe-cleanup-arm64-mac: &step-maybe-cleanup-arm64-mac
killall Safari || echo "No Safari processes left running"
rm -rf ~/Library/Application\ Support/Electron*
rm -rf ~/Library/Application\ Support/electron*
security delete-generic-password -l "Chromium Safe Storage"
security delete-generic-password -l "Electron Test Main Safe Storage"
elif [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
XVFB=/usr/bin/Xvfb
/sbin/start-stop-daemon --stop --exec $XVFB || echo "Xvfb not running"
Expand Down
3 changes: 3 additions & 0 deletions chromium_src/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,11 @@ static_library("chrome") {
"//chrome/browser/extensions/global_shortcut_listener_win.h",
"//chrome/browser/icon_loader_win.cc",
"//chrome/browser/media/webrtc/window_icon_util_win.cc",
"//chrome/browser/ui/frame/window_frame_util.h",
"//chrome/browser/ui/view_ids.h",
"//chrome/browser/win/chrome_process_finder.cc",
"//chrome/browser/win/chrome_process_finder.h",
"//chrome/browser/win/titlebar_config.h",
"//chrome/child/v8_crashpad_support_win.cc",
"//chrome/child/v8_crashpad_support_win.h",
]
Expand Down
20 changes: 8 additions & 12 deletions docs/api/browser-window.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,16 +213,13 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
* `followWindow` - The backdrop should automatically appear active when the window is active, and inactive when it is not. This is the default.
* `active` - The backdrop should always appear active.
* `inactive` - The backdrop should always appear inactive.
* `titleBarStyle` String (optional) - The style of window title bar.
* `titleBarStyle` String (optional) _macOS_ _Windows_ - The style of window title bar.
Default is `default`. Possible values are:
* `default` - Results in the standard gray opaque Mac title
bar.
* `hidden` - Results in a hidden title bar and a full size content window, yet
the title bar still has the standard window controls ("traffic lights") in
the top left.
* `hiddenInset` - Results in a hidden title bar with an alternative look
* `default` - Results in the standard title bar for macOS or Windows respectively.
* `hidden` - Results in a hidden title bar and a full size content window. On macOS, the window still has the standard window controls (“traffic lights”) in the top left. On Windows, when combined with `titleBarOverlay: true` it will activate the Window Controls Overlay (see `titleBarOverlay` for more information), otherwise no window controls will be shown.
* `hiddenInset` - Only on macOS, results in a hidden title bar with an alternative look
where the traffic light buttons are slightly more inset from the window edge.
* `customButtonsOnHover` - Results in a hidden title bar and a full size
* `customButtonsOnHover` - Only on macOS, results in a hidden title bar and a full size
content window, the traffic light buttons will display when being hovered
over in the top left of the window. **Note:** This option is currently
experimental.
Expand Down Expand Up @@ -392,10 +389,9 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
contain the layout of the document—without requiring scrolling. Enabling
this will cause the `preferred-size-changed` event to be emitted on the
`WebContents` when the preferred size changes. Default is `false`.
* `titleBarOverlay` Boolean (optional) - On macOS, when using a frameless window in conjunction with
`win.setWindowButtonVisibility(true)` or using a `titleBarStyle` so that the traffic lights are visible,
this property enables the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and
[CSS Environment Variables][overlay-css-env-vars]. Default is `false`.
* `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.

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
32 changes: 24 additions & 8 deletions docs/api/frameless-window.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,26 @@ const win = new BrowserWindow({ width: 800, height: 600, frame: false })
win.show()
```

### Alternatives on macOS
### Alternatives

There's an alternative way to specify a chromeless window.
There's an alternative way to specify a chromeless window on macOS and Windows.
Instead of setting `frame` to `false` which disables both the titlebar and window controls,
you may want to have the title bar hidden and your content extend to the full window size,
yet still preserve the window controls ("traffic lights") for standard window actions.
yet still preserve the window controls ("traffic lights" on macOS) for standard window actions.
You can do so by specifying the `titleBarStyle` option:

#### `hidden`

Results in a hidden title bar and a full size content window, yet the title bar still has the standard window controls (“traffic lights”) in the top left.
Results in a hidden title bar and a full size content window. On macOS, the title bar still has the standard window controls (“traffic lights”) in the top left.

```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hidden' })
win.show()
```

### Alternatives on macOS

#### `hiddenInset`

Results in a hidden title bar with an alternative look where the traffic light buttons are slightly more inset from the window edge.
Expand Down Expand Up @@ -63,19 +65,33 @@ win.show()

## Windows Control Overlay

On macOS, when using a frameless window in conjuction with `win.setWindowButtonVisibility(true)` or using one of the `titleBarStyle`s described above so
that the traffic lights are visible, 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:
When using a frameless window in conjuction with `win.setWindowButtonVisibility(true)` on macOS, using one of the `titleBarStyle`s as described above so
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:

```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hiddenInset',
titleBarStyle: 'hidden',
titleBarOverlay: true
})
win.show()
```

```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: {
color: '#2f3241',
symbolColor: '#74b1be'
}
})
win.show()
```

## Transparent window

By setting the `transparent` option to `true`, you can also make the frameless
Expand Down
14 changes: 14 additions & 0 deletions electron_strings.grdp
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<grit-part>
<!-- Windows Caption Buttons -->
<message name="IDS_APP_ACCNAME_CLOSE" desc="The accessible name for the Close button.">
Close
</message>
<message name="IDS_APP_ACCNAME_MINIMIZE" desc="The accessible name for the Minimize button.">
Minimize
</message>
<message name="IDS_APP_ACCNAME_MAXIMIZE" desc="The accessible name for the Maximize button.">
Maximize
</message>
<message name="IDS_APP_ACCNAME_RESTORE" desc="The accessible name for the Restore button.">
Restore
</message>

<!-- Printing Service -->
<message name="IDS_UTILITY_PROCESS_PRINTING_SERVICE_NAME" desc="The name of the utility process used for printing conversions.">
Printing Service
Expand Down
4 changes: 4 additions & 0 deletions filenames.gni
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ filenames = {
"shell/browser/ui/views/electron_views_delegate_win.cc",
"shell/browser/ui/views/win_frame_view.cc",
"shell/browser/ui/views/win_frame_view.h",
"shell/browser/ui/views/win_caption_button.cc",
"shell/browser/ui/views/win_caption_button.h",
"shell/browser/ui/views/win_caption_button_container.cc",
"shell/browser/ui/views/win_caption_button_container.h",
"shell/browser/ui/win/dialog_thread.cc",
"shell/browser/ui/win/dialog_thread.h",
"shell/browser/ui/win/electron_desktop_native_widget_aura.cc",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {
"@electron/docs-parser": "^0.12.1",
"@electron/typescript-definitions": "^8.9.4",
"@electron/typescript-definitions": "^8.9.5",
"@octokit/auth-app": "^2.10.0",
"@octokit/rest": "^18.0.3",
"@primer/octicons": "^10.0.0",
Expand Down
1 change: 1 addition & 0 deletions patches/chromium/.patches
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,4 @@ hack_to_allow_gclient_sync_with_host_os_mac_on_linux_in_ci.patch
don_t_run_pcscan_notifythreadcreated_if_pcscan_is_disabled.patch
add_gin_wrappable_crash_key.patch
logging_win32_only_create_a_console_if_logging_to_stderr.patch
disable_use_lld_for_macos.patch
21 changes: 21 additions & 0 deletions patches/chromium/disable_use_lld_for_macos.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: mlaurencin <mlaurencin@electronjs.org>
Date: Fri, 6 Aug 2021 15:29:48 -0700
Subject: disable use_lld for macOS

This patch disables use_lld on macOS, in order to prevent a linking bug
that occurs when building for arm64.

diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni
index 4a714ab0a5cdafded76bba553205f94599c27a30..d2723dd224a8afd2b6dd99ec11e9e71b7f76fe4a 100644
--- a/build/config/compiler/compiler.gni
+++ b/build/config/compiler/compiler.gni
@@ -201,7 +201,7 @@ declare_args() {
# In late bring-up on macOS (see docs/mac_lld.md), and not functional at all for
# iOS. The default linker everywhere else.
use_lld =
- is_clang && (!is_apple || (target_os == "mac" && chrome_pgo_phase != 1))
deepak1556 marked this conversation as resolved.
Show resolved Hide resolved
+ is_clang && !is_apple
}

declare_args() {
42 changes: 41 additions & 1 deletion shell/browser/native_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,34 @@
#include "ui/display/win/screen_win.h"
#endif

namespace gin {

template <>
struct Converter<electron::NativeWindow::TitleBarStyle> {
static bool FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
electron::NativeWindow::TitleBarStyle* out) {
using TitleBarStyle = electron::NativeWindow::TitleBarStyle;
std::string title_bar_style;
if (!ConvertFromV8(isolate, val, &title_bar_style))
return false;
if (title_bar_style == "hidden") {
*out = TitleBarStyle::kHidden;
#if defined(OS_MAC)
} else if (title_bar_style == "hiddenInset") {
*out = TitleBarStyle::kHiddenInset;
} else if (title_bar_style == "customButtonsOnHover") {
*out = TitleBarStyle::kCustomButtonsOnHover;
#endif
} else {
return false;
}
return true;
}
};

} // namespace gin

namespace electron {

namespace {
Expand Down Expand Up @@ -54,7 +82,19 @@ NativeWindow::NativeWindow(const gin_helper::Dictionary& options,
options.Get(options::kFrame, &has_frame_);
options.Get(options::kTransparent, &transparent_);
options.Get(options::kEnableLargerThanScreen, &enable_larger_than_screen_);
options.Get(options::ktitleBarOverlay, &titlebar_overlay_);
options.Get(options::kTitleBarStyle, &title_bar_style_);

v8::Local<v8::Value> titlebar_overlay;
if (options.Get(options::ktitleBarOverlay, &titlebar_overlay)) {
if (titlebar_overlay->IsBoolean()) {
options.Get(options::ktitleBarOverlay, &titlebar_overlay_);
} else if (titlebar_overlay->IsObject()) {
titlebar_overlay_ = true;
#if !defined(OS_WIN)
DCHECK(false);
#endif
}
}

if (parent)
options.Get("modal", &is_modal_);
Expand Down
12 changes: 12 additions & 0 deletions shell/browser/native_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,14 @@ class NativeWindow : public base::SupportsUserData,
views::Widget* widget() const { return widget_.get(); }
views::View* content_view() const { return content_view_; }

enum class TitleBarStyle {
kNormal,
kHidden,
kHiddenInset,
kCustomButtonsOnHover,
};
TitleBarStyle title_bar_style() const { return title_bar_style_; }

bool has_frame() const { return has_frame_; }
void set_has_frame(bool has_frame) { has_frame_ = has_frame; }

Expand Down Expand Up @@ -347,8 +355,12 @@ class NativeWindow : public base::SupportsUserData,
[&browser_view](NativeBrowserView* n) { return (n == browser_view); });
}

// The boolean parsing of the "titleBarOverlay" option
bool titlebar_overlay_ = false;

// The "titleBarStyle" option.
TitleBarStyle title_bar_style_ = TitleBarStyle::kNormal;

private:
std::unique_ptr<views::Widget> widget_;

Expand Down
11 changes: 0 additions & 11 deletions shell/browser/native_window_mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,6 @@ class NativeWindowMac : public NativeWindow,
kInactive,
};

enum class TitleBarStyle {
kNormal,
kHidden,
kHiddenInset,
kCustomButtonsOnHover,
};
TitleBarStyle title_bar_style() const { return title_bar_style_; }

ElectronPreviewItem* preview_item() const { return preview_item_.get(); }
ElectronTouchBar* touch_bar() const { return touch_bar_.get(); }
bool zoom_to_page_width() const { return zoom_to_page_width_; }
Expand Down Expand Up @@ -248,9 +240,6 @@ class NativeWindowMac : public NativeWindow,
// The presentation options before entering kiosk mode.
NSApplicationPresentationOptions kiosk_options_;

// The "titleBarStyle" option.
TitleBarStyle title_bar_style_ = TitleBarStyle::kNormal;

// The "visualEffectState" option.
VisualEffectState visual_effect_state_ = VisualEffectState::kFollowWindow;

Expand Down
23 changes: 0 additions & 23 deletions shell/browser/native_window_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -165,28 +165,6 @@ - (void)drawRect:(NSRect)dirtyRect {

namespace gin {

template <>
struct Converter<electron::NativeWindowMac::TitleBarStyle> {
static bool FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
electron::NativeWindowMac::TitleBarStyle* out) {
using TitleBarStyle = electron::NativeWindowMac::TitleBarStyle;
std::string title_bar_style;
if (!ConvertFromV8(isolate, val, &title_bar_style))
return false;
if (title_bar_style == "hidden") {
*out = TitleBarStyle::kHidden;
} else if (title_bar_style == "hiddenInset") {
*out = TitleBarStyle::kHiddenInset;
} else if (title_bar_style == "customButtonsOnHover") {
*out = TitleBarStyle::kCustomButtonsOnHover;
} else {
return false;
}
return true;
}
};

template <>
struct Converter<electron::NativeWindowMac::VisualEffectState> {
static bool FromV8(v8::Isolate* isolate,
Expand Down Expand Up @@ -276,7 +254,6 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {

bool resizable = true;
options.Get(options::kResizable, &resizable);
options.Get(options::kTitleBarStyle, &title_bar_style_);
options.Get(options::kZoomToPageWidth, &zoom_to_page_width_);
options.Get(options::kSimpleFullScreen, &always_simple_fullscreen_);
options.GetOptional(options::kTrafficLightPosition, &traffic_light_position_);
Expand Down
33 changes: 33 additions & 0 deletions shell/browser/native_window_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,14 @@

#elif defined(OS_WIN)
#include "base/win/win_util.h"
#include "extensions/common/image_util.h"
#include "shell/browser/ui/views/win_frame_view.h"
#include "shell/browser/ui/win/electron_desktop_native_widget_aura.h"
#include "skia/ext/skia_utils_win.h"
#include "ui/base/win/shell.h"
#include "ui/display/screen.h"
#include "ui/display/win/screen_win.h"
#include "ui/gfx/color_utils.h"
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
#endif

Expand Down Expand Up @@ -165,6 +167,37 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
options.Get("thickFrame", &thick_frame_);
if (transparent())
thick_frame_ = false;

overlay_button_color_ = color_utils::GetSysSkColor(COLOR_BTNFACE);
overlay_symbol_color_ = color_utils::GetSysSkColor(COLOR_BTNTEXT);

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);
options.Get(options::ktitleBarOverlay, &titlebar_overlay_obj);

std::string overlay_color_string;
if (titlebar_overlay_obj.Get(options::kOverlayButtonColor,
&overlay_color_string)) {
bool success = extensions::image_util::ParseCssColorString(
overlay_color_string, &overlay_button_color_);
DCHECK(success);
}

std::string overlay_symbol_color_string;
if (titlebar_overlay_obj.Get(options::kOverlaySymbolColor,
&overlay_symbol_color_string)) {
bool success = extensions::image_util::ParseCssColorString(
overlay_symbol_color_string, &overlay_symbol_color_);
DCHECK(success);
}
}

if (title_bar_style_ != TitleBarStyle::kNormal)
set_has_frame(false);
#endif

if (enable_larger_than_screen())
Expand Down