Compare commits

..

9 Commits

Author SHA1 Message Date
Sudowoodo Release Bot
7e1099a8e4 Bump v19.0.10 2022-07-27 08:31:31 -07:00
Shelley Vohr
438347d891 fix: html fullscreen transitions stacking (#34908) 2022-07-27 16:24:19 +02:00
trop[bot]
c005d4ff56 fix: handle WCO pressed state when going maximized -> minimized (#35073)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-07-27 11:43:00 +02:00
trop[bot]
729b0f5508 fix: allow setsize to be called within a move or resize for preventDefault (#35083)
fix: #34599 allow setsize to be called within a move or resize for preventDefault

Co-authored-by: Ian German Mesner <mesner@gmail.com>
2022-07-27 11:42:45 +02:00
trop[bot]
ea21d940ec fix: use win_clang_x64 binary for x86 extract symbols (#35090)
fix: use win_clang_x64 for x86 extract symbols

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
2022-07-27 11:09:41 +02:00
trop[bot]
9df18f3fcf fix: add support for --ozone-platform-hint flag on Linux (#35015)
* fix: add support for --ozone-platform-hint flag on Linux

* fixup! fix: add support for --ozone-platform-hint flag on Linux

Co-authored-by: Valentin Hăloiu <valentin.haloiu@gmail.com>
2022-07-26 18:25:36 +02:00
trop[bot]
f724a9ca2f docs: Add missing link to tutorial page (#35040)
Add missing link to tutorial page

Co-authored-by: Mike Lee <mikemunkyu.lee@gmail.com>
2022-07-26 18:24:49 +02:00
Milan Burda
f3f1171a09 fix: inertial scroll is broken when the scrollable element has an overlay with pointer-events: none (#35051)
Backport: https://chromium-review.googlesource.com/c/chromium/src/+/3681882
2022-07-26 11:30:07 +09:00
trop[bot]
b7f68027a7 fix: crash on BrowserWindow.setEnabled() (#34971)
fix: crash on BrowserWindow.setEnabled()

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-07-21 15:18:16 -04:00
26 changed files with 539 additions and 80 deletions

View File

@@ -1 +1 @@
19.0.9
19.0.10

View File

@@ -24,7 +24,11 @@ template("extract_symbols") {
assert(defined(invoker.binary), "Need binary to dump")
assert(defined(invoker.symbol_dir), "Need directory for symbol output")
dump_syms_label = "//third_party/breakpad:dump_syms($host_toolchain)"
if (host_os == "win" && target_cpu == "x86") {
dump_syms_label = "//third_party/breakpad:dump_syms(//build/toolchain/win:win_clang_x64)"
} else {
dump_syms_label = "//third_party/breakpad:dump_syms($host_toolchain)"
}
dump_syms_binary = get_label_info(dump_syms_label, "root_out_dir") +
"/dump_syms$_host_executable_suffix"

View File

@@ -66,6 +66,7 @@ Are you getting stuck anywhere? Here are a few links to places to look:
<!-- Links -->
[tutorial]: tutorial-1-prerequisites.md
[api documentation]: ../api/app.md
[chromium]: https://www.chromium.org/
[discord]: https://discord.com/invite/APGC3k5yaH

View File

@@ -23,6 +23,7 @@ filenames = {
lib_sources_linux = [
"shell/browser/browser_linux.cc",
"shell/browser/electron_browser_main_parts_linux.cc",
"shell/browser/lib/power_observer_linux.cc",
"shell/browser/lib/power_observer_linux.h",
"shell/browser/linux/unity_service.cc",

View File

@@ -1,6 +1,6 @@
{
"name": "electron",
"version": "19.0.9",
"version": "19.0.10",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {

View File

@@ -121,3 +121,4 @@ custom_protocols_plzserviceworker.patch
posix_replace_doubleforkandexec_with_forkandspawn.patch
cherry-pick-22c61cfae5d1.patch
remove_default_window_title.patch
keep_handling_scroll_update_if_you_can.patch

View File

@@ -0,0 +1,164 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mehdi Kazemi <mehdika@chromium.org>
Date: Tue, 7 Jun 2022 17:32:20 +0000
Subject: Keep handling scroll update if you can!
If scroll_gesture_handling_node_ doesn't have a layout object, but you can still handle GSU, do that!
Change-Id: Ib82dad96d319b186a5cc2f2eb07495ca5ae994a3
Bug: 1330045
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3681882
Reviewed-by: Steve Kobes <skobes@chromium.org>
Commit-Queue: Mehdi Kazemi <mehdika@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1011539}
diff --git a/third_party/blink/renderer/core/input/scroll_manager.cc b/third_party/blink/renderer/core/input/scroll_manager.cc
index 28b6092d264219802f718bfaf58f2da4c6054e43..604cad242a9e5626c7d6bac305cb2e323e1f1fca 100644
--- a/third_party/blink/renderer/core/input/scroll_manager.cc
+++ b/third_party/blink/renderer/core/input/scroll_manager.cc
@@ -589,12 +589,6 @@ WebInputEventResult ScrollManager::HandleGestureScrollUpdate(
return WebInputEventResult::kNotHandled;
}
- Node* node = scroll_gesture_handling_node_.Get();
- if (!node || !node->GetLayoutObject()) {
- TRACE_EVENT_INSTANT0("input", "Lost scroll_gesture_handling_node",
- TRACE_EVENT_SCOPE_THREAD);
- return WebInputEventResult::kNotHandled;
- }
if (snap_fling_controller_) {
if (snap_fling_controller_->HandleGestureScrollUpdate(
GetGestureScrollUpdateInfo(gesture_event))) {
@@ -615,7 +609,10 @@ WebInputEventResult ScrollManager::HandleGestureScrollUpdate(
if (delta.IsZero())
return WebInputEventResult::kNotHandled;
- LayoutObject* layout_object = node->GetLayoutObject();
+ LayoutObject* layout_object =
+ scroll_gesture_handling_node_
+ ? scroll_gesture_handling_node_->GetLayoutObject()
+ : nullptr;
// Try to send the event to the correct view.
WebInputEventResult result =
diff --git a/third_party/blink/web_tests/fast/events/touch/touch-latched-scroll-node-removed.html b/third_party/blink/web_tests/fast/events/touch/touch-latched-scroll-node-removed.html
index 90265f908ad0ce93d7bd401df2aa6657cf25e6fb..b9b34c24496868355c6eff06f738a95832956481 100644
--- a/third_party/blink/web_tests/fast/events/touch/touch-latched-scroll-node-removed.html
+++ b/third_party/blink/web_tests/fast/events/touch/touch-latched-scroll-node-removed.html
@@ -62,6 +62,7 @@ childDiv.addEventListener('scroll', () => {
promise_test( async () => {
setUpForTest();
+ await waitForCompositorCommit();
// Start scrolling on the child div and remove the div in the middle of
// scrolling, then check that parentDiv have not scrolled.
var x = (rect.left + rect.right) / 2;
@@ -69,6 +70,7 @@ promise_test( async () => {
// Slow scrolling gives enough time to switch from cc to main.
var pixels_per_sec = 100;
await smoothScroll(400, x, y, GestureSourceType.TOUCH_INPUT, 'down', pixels_per_sec);
- await waitFor( () => {return parentDiv.scrollTop === 0});
-}, "New node must start wheel scrolling when the latched node is removed.");
+ await conditionHolds( () => { return parentDiv.scrollTop === 0; },
+ "parentDiv has scrolled, which should not have!" );
+}, "New node must NOT start wheel scrolling when the latched node is removed.");
</script>
diff --git a/third_party/blink/web_tests/fast/events/wheel/wheel-latched-scroll-node-removed.html b/third_party/blink/web_tests/fast/events/wheel/wheel-latched-scroll-node-removed.html
index 966a887b2129fa26cd990b367a7df1fc9135a207..493f13d9c519422b00fe0e11874032fdf25130db 100644
--- a/third_party/blink/web_tests/fast/events/wheel/wheel-latched-scroll-node-removed.html
+++ b/third_party/blink/web_tests/fast/events/wheel/wheel-latched-scroll-node-removed.html
@@ -62,6 +62,7 @@ childDiv.addEventListener('scroll', () => {
promise_test( async () => {
setUpForTest();
+ await waitForCompositorCommit();
// Start scrolling on the child div and remove the div in the middle of
// scrolling, then check that parentDiv have not scrolled.
var x = (rect.left + rect.right) / 2;
@@ -69,6 +70,7 @@ promise_test( async () => {
// Slow scrolling gives enough time to switch from cc to main.
var pixels_per_sec = 100;
await smoothScroll(400, x, y, GestureSourceType.MOUSE_INPUT, 'down', pixels_per_sec);
- await waitFor( () => {return parentDiv.scrollTop === 0});
-}, "New node must start wheel scrolling when the latched node is removed.");
+ await conditionHolds( () => { return parentDiv.scrollTop === 0; },
+ "parentDiv has scrolled, which should not have!" );
+}, "New node must NOT start wheel scrolling when the latched node is removed.");
</script>
diff --git a/third_party/blink/web_tests/fast/scrolling/inertial-scrolling-with-pointer-events-none-overlay.html b/third_party/blink/web_tests/fast/scrolling/inertial-scrolling-with-pointer-events-none-overlay.html
new file mode 100644
index 0000000000000000000000000000000000000000..47291b70316beaac16adaa6ddd0035ebeb9ec84f
--- /dev/null
+++ b/third_party/blink/web_tests/fast/scrolling/inertial-scrolling-with-pointer-events-none-overlay.html
@@ -0,0 +1,71 @@
+<!DOCTYPE HTML>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../../resources/testdriver.js"></script>
+<script src="../../resources/testdriver-actions.js"></script>
+<script src="../../resources/testdriver-vendor.js"></script>
+<script src="../../resources/gesture-util.js"></script>
+
+<style>
+#container {
+ width: 400px;
+ height: 400px;
+ overflow: auto;
+}
+
+#inner {
+ height: 3000px;
+ background-color: #eee;
+}
+
+#overlay {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ pointer-events: none;
+}
+
+p {
+ margin: 0;
+ padding: 1000px 0;
+}
+</style>
+
+<body style="margin:0" onload=runTest()>
+ <div id="container">
+ <div id="inner"></div>
+ </div>
+ <div id="overlay"></div>
+</body>
+
+<script>
+const container = document.getElementById('container');
+const inner = document.getElementById('inner');
+
+const update = () => inner.innerHTML = '<p>Content</p>';
+setInterval(update, 200);
+
+function runTest() {
+ promise_test (async (t) => {
+ const pixels_to_scroll = 100;
+ const start_x = 200;
+ const start_y = 200;
+ const speed_in_pixels_s = 900;
+
+ await waitForCompositorCommit();
+ await swipe(pixels_to_scroll, start_x, start_y, 'up', speed_in_pixels_s);
+ await waitForAnimationEndTimeBased(() => { return container.scrollTop; });
+ assert_greater_than(container.scrollTop, pixels_to_scroll,
+ "container should scroll at least 100 pixels, which is the length of the swipe.");
+
+ const scroll_top_previous_value = container.scrollTop;
+
+ await waitForCompositorCommit();
+ await swipe(pixels_to_scroll, start_x, start_y, 'up', speed_in_pixels_s);
+ await waitForAnimationEndTimeBased(() => { return container.scrollTop; });
+ assert_greater_than(container.scrollTop, scroll_top_previous_value + pixels_to_scroll);
+ }, "Make sure inertial scrolling is not broken with pointer-events:none overlay.");
+}
+</script>

View File

@@ -3524,7 +3524,12 @@ void WebContents::EnumerateDirectory(
bool WebContents::IsFullscreenForTabOrPending(
const content::WebContents* source) {
return html_fullscreen_;
bool transition_fs = owner_window()
? owner_window()->fullscreen_transition_state() !=
NativeWindow::FullScreenTransitionState::NONE
: false;
return html_fullscreen_ || transition_fs;
}
bool WebContents::TakeFocus(content::WebContents* source, bool reverse) {
@@ -3846,9 +3851,8 @@ void WebContents::SetHtmlApiFullscreen(bool enter_fullscreen) {
? !web_preferences->ShouldDisableHtmlFullscreenWindowResize()
: true;
if (html_fullscreenable) {
if (html_fullscreenable)
owner_window_->SetFullScreen(enter_fullscreen);
}
UpdateHtmlApiFullscreen(enter_fullscreen);
native_fullscreen_ = false;

View File

@@ -218,6 +218,7 @@ int ElectronBrowserMainParts::PreEarlyInitialization() {
HandleSIGCHLD();
#endif
#if BUILDFLAG(IS_LINUX)
DetectOzonePlatform();
ui::OzonePlatform::PreEarlyInitialization();
#endif

View File

@@ -122,6 +122,10 @@ class ElectronBrowserMainParts : public content::BrowserMainParts {
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
#endif
#if BUILDFLAG(IS_LINUX)
void DetectOzonePlatform();
#endif
#if BUILDFLAG(IS_MAC)
void FreeAppDelegate();
void RegisterURLHandler();

View File

@@ -0,0 +1,135 @@
// Copyright (c) 2022 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/electron_browser_main_parts.h"
#include "base/command_line.h"
#include "base/environment.h"
#include "ui/ozone/buildflags.h"
#include "ui/ozone/public/ozone_switches.h"
#if BUILDFLAG(OZONE_PLATFORM_WAYLAND)
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/nix/xdg_util.h"
#include "base/threading/thread_restrictions.h"
#endif
#if BUILDFLAG(OZONE_PLATFORM_WAYLAND)
constexpr char kPlatformWayland[] = "wayland";
bool HasWaylandDisplay(base::Environment* env) {
std::string wayland_display;
const bool has_wayland_display =
env->GetVar("WAYLAND_DISPLAY", &wayland_display) &&
!wayland_display.empty();
if (has_wayland_display)
return true;
std::string xdg_runtime_dir;
const bool has_xdg_runtime_dir =
env->GetVar("XDG_RUNTIME_DIR", &xdg_runtime_dir) &&
!xdg_runtime_dir.empty();
if (has_xdg_runtime_dir) {
auto wayland_server_pipe =
base::FilePath(xdg_runtime_dir).Append("wayland-0");
// Normally, this should happen exactly once, at the startup of the main
// process.
base::ScopedAllowBlocking allow_blocking;
return base::PathExists(wayland_server_pipe);
}
return false;
}
#endif // BUILDFLAG(OZONE_PLATFORM_WAYLAND)
#if BUILDFLAG(OZONE_PLATFORM_X11)
constexpr char kPlatformX11[] = "x11";
#endif
namespace electron {
namespace {
// Evaluates the environment and returns the effective platform name for the
// given |ozone_platform_hint|.
// For the "auto" value, returns "wayland" if the XDG session type is "wayland",
// "x11" otherwise.
// For the "wayland" value, checks if the Wayland server is available, and
// returns "x11" if it is not.
// See https://crbug.com/1246928.
std::string MaybeFixPlatformName(const std::string& ozone_platform_hint) {
#if BUILDFLAG(OZONE_PLATFORM_WAYLAND)
// Wayland is selected if both conditions below are true:
// 1. The user selected either 'wayland' or 'auto'.
// 2. The XDG session type is 'wayland', OR the user has selected 'wayland'
// explicitly and a Wayland server is running.
// Otherwise, fall back to X11.
if (ozone_platform_hint == kPlatformWayland ||
ozone_platform_hint == "auto") {
auto env(base::Environment::Create());
std::string xdg_session_type;
const bool has_xdg_session_type =
env->GetVar(base::nix::kXdgSessionTypeEnvVar, &xdg_session_type) &&
!xdg_session_type.empty();
if ((has_xdg_session_type && xdg_session_type == "wayland") ||
(ozone_platform_hint == kPlatformWayland &&
HasWaylandDisplay(env.get()))) {
return kPlatformWayland;
}
}
#endif // BUILDFLAG(OZONE_PLATFORM_WAYLAND)
#if BUILDFLAG(OZONE_PLATFORM_X11)
if (ozone_platform_hint == kPlatformX11) {
return kPlatformX11;
}
#if BUILDFLAG(OZONE_PLATFORM_WAYLAND)
if (ozone_platform_hint == kPlatformWayland ||
ozone_platform_hint == "auto") {
// We are here if:
// - The binary has both X11 and Wayland backends.
// - The user wanted Wayland but that did not work, otherwise it would have
// been returned above.
if (ozone_platform_hint == kPlatformWayland) {
LOG(WARNING) << "No Wayland server is available. Falling back to X11.";
} else {
LOG(WARNING) << "This is not a Wayland session. Falling back to X11. "
"If you need to run Chrome on Wayland using some "
"embedded compositor, e. g., Weston, please specify "
"Wayland as your preferred Ozone platform, or use "
"--ozone-platform=wayland.";
}
return kPlatformX11;
}
#endif // BUILDFLAG(OZONE_PLATFORM_WAYLAND)
#endif // BUILDFLAG(OZONE_PLATFORM_X11)
return ozone_platform_hint;
}
} // namespace
void ElectronBrowserMainParts::DetectOzonePlatform() {
auto* const command_line = base::CommandLine::ForCurrentProcess();
if (!command_line->HasSwitch(switches::kOzonePlatform)) {
const auto ozone_platform_hint =
command_line->GetSwitchValueASCII(switches::kOzonePlatformHint);
if (!ozone_platform_hint.empty()) {
command_line->AppendSwitchASCII(
switches::kOzonePlatform, MaybeFixPlatformName(ozone_platform_hint));
}
}
auto env = base::Environment::Create();
std::string desktop_startup_id;
if (env->GetVar("DESKTOP_STARTUP_ID", &desktop_startup_id))
command_line->AppendSwitchASCII("desktop-startup-id", desktop_startup_id);
}
} // namespace electron

View File

@@ -718,6 +718,15 @@ std::string NativeWindow::GetAccessibleTitle() {
return base::UTF16ToUTF8(accessible_title_);
}
void NativeWindow::HandlePendingFullscreenTransitions() {
if (pending_transitions_.empty())
return;
bool next_transition = pending_transitions_.front();
pending_transitions_.pop();
SetFullScreen(next_transition);
}
// static
int32_t NativeWindow::next_id_ = 0;

View File

@@ -7,6 +7,7 @@
#include <list>
#include <memory>
#include <queue>
#include <string>
#include <vector>
@@ -317,6 +318,17 @@ class NativeWindow : public base::SupportsUserData,
observers_.RemoveObserver(obs);
}
enum class FullScreenTransitionState { ENTERING, EXITING, NONE };
// Handle fullscreen transitions.
void HandlePendingFullscreenTransitions();
void set_fullscreen_transition_state(FullScreenTransitionState state) {
fullscreen_transition_state_ = state;
}
FullScreenTransitionState fullscreen_transition_state() const {
return fullscreen_transition_state_;
}
views::Widget* widget() const { return widget_.get(); }
views::View* content_view() const { return content_view_; }
@@ -375,6 +387,10 @@ class NativeWindow : public base::SupportsUserData,
// The "titleBarStyle" option.
TitleBarStyle title_bar_style_ = TitleBarStyle::kNormal;
std::queue<bool> pending_transitions_;
FullScreenTransitionState fullscreen_transition_state_ =
FullScreenTransitionState::NONE;
private:
std::unique_ptr<views::Widget> widget_;

View File

@@ -8,7 +8,6 @@
#import <Cocoa/Cocoa.h>
#include <memory>
#include <queue>
#include <string>
#include <vector>
@@ -174,11 +173,6 @@ class NativeWindowMac : public NativeWindow,
void SetCollectionBehavior(bool on, NSUInteger flag);
void SetWindowLevel(int level);
enum class FullScreenTransitionState { ENTERING, EXITING, NONE };
// Handle fullscreen transitions.
void SetFullScreenTransitionState(FullScreenTransitionState state);
void HandlePendingFullscreenTransitions();
bool HandleDeferredClose();
void SetHasDeferredWindowClose(bool defer_close) {
has_deferred_window_close_ = defer_close;
@@ -249,13 +243,6 @@ class NativeWindowMac : public NativeWindow,
bool zoom_to_page_width_ = false;
absl::optional<gfx::Point> traffic_light_position_;
std::queue<bool> pending_transitions_;
FullScreenTransitionState fullscreen_transition_state() const {
return fullscreen_transition_state_;
}
FullScreenTransitionState fullscreen_transition_state_ =
FullScreenTransitionState::NONE;
// Trying to close an NSWindow during a fullscreen transition will cause the
// window to lock up. Use this to track if CloseWindow was called during a
// fullscreen transition, to defer the -[NSWindow close] call until the

View File

@@ -483,7 +483,8 @@ void NativeWindowMac::Close() {
// [window_ performClose:nil], the window won't close properly
// even after the user has ended the sheet.
// Ensure it's closed before calling [window_ performClose:nil].
SetEnabled(true);
if ([window_ attachedSheet])
[window_ endSheet:[window_ attachedSheet]];
[window_ performClose:nil];
@@ -553,7 +554,8 @@ void NativeWindowMac::Hide() {
// If a sheet is attached to the window when we call [window_ orderOut:nil],
// the sheet won't be able to show again on the same window.
// Ensure it's closed before calling [window_ orderOut:nil].
SetEnabled(true);
if ([window_ attachedSheet])
[window_ endSheet:[window_ attachedSheet]];
if (is_modal() && parent()) {
[window_ orderOut:nil];
@@ -586,20 +588,24 @@ bool NativeWindowMac::IsVisible() {
return [window_ isVisible] && !occluded && !IsMinimized();
}
void NativeWindowMac::SetFullScreenTransitionState(
FullScreenTransitionState state) {
fullscreen_transition_state_ = state;
}
bool NativeWindowMac::IsEnabled() {
return [window_ attachedSheet] == nil;
}
void NativeWindowMac::SetEnabled(bool enable) {
if (!enable) {
[window_ beginSheet:window_
NSRect frame = [window_ frame];
NSWindow* window =
[[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, frame.size.width,
frame.size.height)
styleMask:NSWindowStyleMaskTitled
backing:NSBackingStoreBuffered
defer:NO];
[window setAlphaValue:0.5];
[window_ beginSheet:window
completionHandler:^(NSModalResponse returnCode) {
NSLog(@"modal enabled");
NSLog(@"main window disabled");
return;
}];
} else if ([window_ attachedSheet]) {
@@ -674,15 +680,6 @@ bool NativeWindowMac::IsMinimized() {
return [window_ isMiniaturized];
}
void NativeWindowMac::HandlePendingFullscreenTransitions() {
if (pending_transitions_.empty())
return;
bool next_transition = pending_transitions_.front();
pending_transitions_.pop();
SetFullScreen(next_transition);
}
bool NativeWindowMac::HandleDeferredClose() {
if (has_deferred_window_close_) {
SetHasDeferredWindowClose(false);

View File

@@ -729,7 +729,6 @@ void NativeWindowViews::SetBounds(const gfx::Rect& bounds, bool animate) {
#if BUILDFLAG(IS_WIN)
if (is_moving_ || is_resizing_) {
pending_bounds_change_ = bounds;
return;
}
#endif

View File

@@ -225,6 +225,7 @@ class NativeWindowViews : public NativeWindow,
#if BUILDFLAG(IS_WIN)
void HandleSizeEvent(WPARAM w_param, LPARAM l_param);
void ResetWindowControls();
void SetForwardMouseMessages(bool forward);
static LRESULT CALLBACK SubclassProc(HWND hwnd,
UINT msg,

View File

@@ -415,6 +415,7 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
last_window_state_ != ui::SHOW_STATE_MAXIMIZED) {
last_window_state_ = ui::SHOW_STATE_MAXIMIZED;
NotifyWindowMaximize();
ResetWindowControls();
} else if (w_param == SIZE_MINIMIZED &&
last_window_state_ != ui::SHOW_STATE_MINIMIZED) {
last_window_state_ = ui::SHOW_STATE_MINIMIZED;
@@ -440,18 +441,23 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
default:
break;
}
// If a given window was minimized/maximized and has since been
// restored, ensure the WCO buttons are set to normal state.
auto* ncv = widget()->non_client_view();
if (IsWindowControlsOverlayEnabled() && ncv) {
auto* frame_view = static_cast<WinFrameView*>(ncv->frame_view());
frame_view->caption_button_container()->ResetWindowControls();
}
ResetWindowControls();
break;
}
}
}
void NativeWindowViews::ResetWindowControls() {
// If a given window was minimized and has since been
// unminimized (restored/maximized), ensure the WCO buttons
// are reset to their default unpressed state.
auto* ncv = widget()->non_client_view();
if (IsWindowControlsOverlayEnabled() && ncv) {
auto* frame_view = static_cast<WinFrameView*>(ncv->frame_view());
frame_view->caption_button_container()->ResetWindowControls();
}
}
void NativeWindowViews::SetForwardMouseMessages(bool forward) {
if (forward && !forwarding_mouse_messages_) {
forwarding_mouse_messages_ = true;

View File

@@ -50,8 +50,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 19,0,9,0
PRODUCTVERSION 19,0,9,0
FILEVERSION 19,0,10,0
PRODUCTVERSION 19,0,10,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -68,12 +68,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Electron"
VALUE "FileVersion", "19.0.9"
VALUE "FileVersion", "19.0.10"
VALUE "InternalName", "electron.exe"
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "electron.exe"
VALUE "ProductName", "Electron"
VALUE "ProductVersion", "19.0.9"
VALUE "ProductVersion", "19.0.10"
VALUE "SquirrelAwareVersion", "1"
END
END

View File

@@ -238,7 +238,7 @@ using FullScreenTransitionState =
// Store resizable mask so it can be restored after exiting fullscreen.
is_resizable_ = shell_->HasStyleMask(NSWindowStyleMaskResizable);
shell_->SetFullScreenTransitionState(FullScreenTransitionState::ENTERING);
shell_->set_fullscreen_transition_state(FullScreenTransitionState::ENTERING);
shell_->NotifyWindowWillEnterFullScreen();
@@ -247,7 +247,7 @@ using FullScreenTransitionState =
}
- (void)windowDidEnterFullScreen:(NSNotification*)notification {
shell_->SetFullScreenTransitionState(FullScreenTransitionState::NONE);
shell_->set_fullscreen_transition_state(FullScreenTransitionState::NONE);
shell_->NotifyWindowEnterFullScreen();
@@ -258,13 +258,13 @@ using FullScreenTransitionState =
}
- (void)windowWillExitFullScreen:(NSNotification*)notification {
shell_->SetFullScreenTransitionState(FullScreenTransitionState::EXITING);
shell_->set_fullscreen_transition_state(FullScreenTransitionState::EXITING);
shell_->NotifyWindowWillLeaveFullScreen();
}
- (void)windowDidExitFullScreen:(NSNotification*)notification {
shell_->SetFullScreenTransitionState(FullScreenTransitionState::NONE);
shell_->set_fullscreen_transition_state(FullScreenTransitionState::NONE);
shell_->SetResizable(is_resizable_);
shell_->NotifyWindowLeaveFullScreen();

View File

@@ -4323,6 +4323,14 @@ describe('BrowserWindow module', () => {
await createTwo();
});
ifit(process.platform !== 'darwin')('can disable and enable a window', () => {
const w = new BrowserWindow({ show: false });
w.setEnabled(false);
expect(w.isEnabled()).to.be.false('w.isEnabled()');
w.setEnabled(true);
expect(w.isEnabled()).to.be.true('!w.isEnabled()');
});
ifit(process.platform !== 'darwin')('disables parent window', () => {
const w = new BrowserWindow({ show: false });
const c = new BrowserWindow({ show: false, parent: w, modal: true });
@@ -4973,19 +4981,80 @@ describe('BrowserWindow module', () => {
expect(w.isFullScreen()).to.be.false('is fullscreen');
});
it('handles several HTML fullscreen transitions', async () => {
const w = new BrowserWindow();
await w.loadFile(path.join(fixtures, 'pages', 'a.html'));
expect(w.isFullScreen()).to.be.false('is fullscreen');
const enterFullScreen = emittedOnce(w, 'enter-full-screen');
const leaveFullScreen = emittedOnce(w, 'leave-full-screen');
await w.webContents.executeJavaScript('document.getElementById("div").requestFullscreen()', true);
await enterFullScreen;
await w.webContents.executeJavaScript('document.exitFullscreen()', true);
await leaveFullScreen;
expect(w.isFullScreen()).to.be.false('is fullscreen');
await delay();
await w.webContents.executeJavaScript('document.getElementById("div").requestFullscreen()', true);
await enterFullScreen;
await w.webContents.executeJavaScript('document.exitFullscreen()', true);
await leaveFullScreen;
expect(w.isFullScreen()).to.be.false('is fullscreen');
});
it('handles several transitions in close proximity', async () => {
const w = new BrowserWindow();
expect(w.isFullScreen()).to.be.false('is fullscreen');
const enterFS = emittedNTimes(w, 'enter-full-screen', 2);
const leaveFS = emittedNTimes(w, 'leave-full-screen', 2);
w.setFullScreen(true);
w.setFullScreen(false);
w.setFullScreen(true);
w.setFullScreen(false);
const enterFullScreen = emittedNTimes(w, 'enter-full-screen', 2);
await enterFullScreen;
await Promise.all([enterFS, leaveFS]);
expect(w.isFullScreen()).to.be.true('not fullscreen');
expect(w.isFullScreen()).to.be.false('not fullscreen');
});
it('handles several chromium-initiated transitions in close proximity', async () => {
const w = new BrowserWindow();
await w.loadFile(path.join(fixtures, 'pages', 'a.html'));
expect(w.isFullScreen()).to.be.false('is fullscreen');
let enterCount = 0;
let exitCount = 0;
const done = new Promise<void>(resolve => {
const checkDone = () => {
if (enterCount === 2 && exitCount === 2) resolve();
};
w.webContents.on('enter-html-full-screen', () => {
enterCount++;
checkDone();
});
w.webContents.on('leave-html-full-screen', () => {
exitCount++;
checkDone();
});
});
await w.webContents.executeJavaScript('document.getElementById("div").requestFullscreen()', true);
await w.webContents.executeJavaScript('document.exitFullscreen()');
await w.webContents.executeJavaScript('document.getElementById("div").requestFullscreen()', true);
await w.webContents.executeJavaScript('document.exitFullscreen()');
await done;
});
it('does not crash when exiting simpleFullScreen (properties)', async () => {

View File

@@ -10,7 +10,7 @@ import * as url from 'url';
import * as ChildProcess from 'child_process';
import { EventEmitter } from 'events';
import { promisify } from 'util';
import { ifit, ifdescribe, delay, defer } from './spec-helpers';
import { ifit, ifdescribe, defer, delay } from './spec-helpers';
import { AddressInfo } from 'net';
import { PipeTransport } from './pipe-transport';
@@ -1653,7 +1653,7 @@ describe('iframe using HTML fullscreen API while window is OS-fullscreened', ()
server.close();
});
it('can fullscreen from out-of-process iframes (OOPIFs)', async () => {
ifit(process.platform !== 'darwin')('can fullscreen from out-of-process iframes (non-macOS)', async () => {
const fullscreenChange = emittedOnce(ipcMain, 'fullscreenChange');
const html =
'<iframe style="width: 0" frameborder=0 src="http://localhost:8989" allowfullscreen></iframe>';
@@ -1677,8 +1677,37 @@ describe('iframe using HTML fullscreen API while window is OS-fullscreened', ()
expect(width).to.equal(0);
});
ifit(process.platform === 'darwin')('can fullscreen from out-of-process iframes (macOS)', async () => {
await emittedOnce(w, 'enter-full-screen');
const fullscreenChange = emittedOnce(ipcMain, 'fullscreenChange');
const html =
'<iframe style="width: 0" frameborder=0 src="http://localhost:8989" allowfullscreen></iframe>';
w.loadURL(`data:text/html,${html}`);
await fullscreenChange;
const fullscreenWidth = await w.webContents.executeJavaScript(
"document.querySelector('iframe').offsetWidth"
);
expect(fullscreenWidth > 0).to.be.true();
await w.webContents.executeJavaScript(
"document.querySelector('iframe').contentWindow.postMessage('exitFullscreen', '*')"
);
await emittedOnce(w.webContents, 'leave-html-full-screen');
const width = await w.webContents.executeJavaScript(
"document.querySelector('iframe').offsetWidth"
);
expect(width).to.equal(0);
w.setFullScreen(false);
await emittedOnce(w, 'leave-full-screen');
});
// TODO(jkleinsc) fix this flaky test on WOA
ifit(process.platform !== 'win32' || process.arch !== 'arm64')('can fullscreen from in-process iframes', async () => {
if (process.platform === 'darwin') await emittedOnce(w, 'enter-full-screen');
const fullscreenChange = emittedOnce(ipcMain, 'fullscreenChange');
w.loadFile(path.join(fixturesPath, 'pages', 'fullscreen-ipif.html'));
await fullscreenChange;

View File

@@ -2,6 +2,7 @@
<div id="div">
WebView
</div>
<video></video>
<script type="text/javascript" charset="utf-8">
const {ipcRenderer} = require('electron')
ipcRenderer.send('webview-ready')

View File

@@ -426,11 +426,16 @@ describe('<webview> tag', function () {
contextIsolation: false
}
});
const attachPromise = emittedOnce(w.webContents, 'did-attach-webview');
const loadPromise = emittedOnce(w.webContents, 'did-finish-load');
const readyPromise = emittedOnce(ipcMain, 'webview-ready');
w.loadFile(path.join(__dirname, 'fixtures', 'webview', 'fullscreen', 'main.html'));
const [, webview] = await attachPromise;
await readyPromise;
await Promise.all([readyPromise, loadPromise]);
return [w, webview];
};
@@ -442,17 +447,38 @@ describe('<webview> tag', function () {
closeAllWindows();
});
it('should make parent frame element fullscreen too', async () => {
ifit(process.platform !== 'darwin')('should make parent frame element fullscreen too (non-macOS)', async () => {
const [w, webview] = await loadWebViewWindow();
expect(await w.webContents.executeJavaScript('isIframeFullscreen()')).to.be.false();
const parentFullscreen = emittedOnce(ipcMain, 'fullscreenchange');
await webview.executeJavaScript('document.getElementById("div").requestFullscreen()', true);
await parentFullscreen;
expect(await w.webContents.executeJavaScript('isIframeFullscreen()')).to.be.true();
const close = emittedOnce(w, 'closed');
w.close();
await emittedOnce(w, 'closed');
await close;
});
ifit(process.platform === 'darwin')('should make parent frame element fullscreen too (macOS)', async () => {
const [w, webview] = await loadWebViewWindow();
expect(await w.webContents.executeJavaScript('isIframeFullscreen()')).to.be.false();
const parentFullscreen = emittedOnce(ipcMain, 'fullscreenchange');
const enterHTMLFS = emittedOnce(w.webContents, 'enter-html-full-screen');
const leaveHTMLFS = emittedOnce(w.webContents, 'leave-html-full-screen');
await webview.executeJavaScript('document.getElementById("div").requestFullscreen()', true);
expect(await w.webContents.executeJavaScript('isIframeFullscreen()')).to.be.true();
await webview.executeJavaScript('document.exitFullscreen()');
await Promise.all([enterHTMLFS, leaveHTMLFS, parentFullscreen]);
const close = emittedOnce(w, 'closed');
w.close();
await close;
});
// FIXME(zcbenz): Fullscreen events do not work on Linux.
@@ -468,8 +494,9 @@ describe('<webview> tag', function () {
await delay(0);
expect(w.isFullScreen()).to.be.false();
const close = emittedOnce(w, 'closed');
w.close();
await emittedOnce(w, 'closed');
await close;
});
// Sending ESC via sendInputEvent only works on Windows.
@@ -485,8 +512,9 @@ describe('<webview> tag', function () {
await delay(0);
expect(w.isFullScreen()).to.be.false();
const close = emittedOnce(w, 'closed');
w.close();
await emittedOnce(w, 'closed');
await close;
});
it('pressing ESC should emit the leave-html-full-screen event', async () => {
@@ -513,11 +541,27 @@ describe('<webview> tag', function () {
const leaveFSWindow = emittedOnce(w, 'leave-html-full-screen');
const leaveFSWebview = emittedOnce(webContents, 'leave-html-full-screen');
webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Escape' });
await leaveFSWindow;
await leaveFSWebview;
await leaveFSWindow;
const close = emittedOnce(w, 'closed');
w.close();
await emittedOnce(w, 'closed');
await close;
});
it('should support user gesture', async () => {
const [w, webview] = await loadWebViewWindow();
const waitForEnterHtmlFullScreen = emittedOnce(webview, 'enter-html-full-screen');
const jsScript = "document.querySelector('video').webkitRequestFullscreen()";
webview.executeJavaScript(jsScript, true);
await waitForEnterHtmlFullScreen;
const close = emittedOnce(w, 'closed');
w.close();
await close;
});
});

View File

@@ -1 +1 @@
<video></video>
<video></video>

View File

@@ -922,20 +922,6 @@ describe('<webview> tag', function () {
});
describe('executeJavaScript', () => {
it('should support user gesture', async () => {
await loadWebView(webview, {
src: `file://${fixtures}/pages/fullscreen.html`
});
// Event handler has to be added before js execution.
const waitForEnterHtmlFullScreen = waitForEvent(webview, 'enter-html-full-screen');
const jsScript = "document.querySelector('video').webkitRequestFullscreen()";
webview.executeJavaScript(jsScript, true);
return waitForEnterHtmlFullScreen;
});
it('can return the result of the executed script', async () => {
await loadWebView(webview, {
src: 'about:blank'