Compare commits

..

1 Commits

Author SHA1 Message Date
Keeley Hammond
0be6d43f4c build: add ensure_bootstrap command to depot_tools install 2025-05-19 21:11:36 -07:00
27 changed files with 201 additions and 366 deletions

View File

@@ -38,9 +38,6 @@ runs:
run: |
GN_APPENDED_ARGS="$GN_EXTRA_ARGS target_cpu=\"x64\" v8_snapshot_toolchain=\"//build/toolchain/mac:clang_x64\""
echo "GN_EXTRA_ARGS=$GN_APPENDED_ARGS" >> $GITHUB_ENV
- name: Add Clang problem matcher
shell: bash
run: echo "::add-matcher::src/electron/.github/problem-matchers/clang.json"
- name: Build Electron ${{ inputs.step-suffix }}
shell: bash
run: |
@@ -202,9 +199,6 @@ runs:
e build --target electron:libcxx_headers_zip -j $NUMBER_OF_NINJA_PROCESSES
e build --target electron:libcxxabi_headers_zip -j $NUMBER_OF_NINJA_PROCESSES
e build --target electron:libcxx_objects_zip -j $NUMBER_OF_NINJA_PROCESSES
- name: Remove Clang problem matcher
shell: bash
run: echo "::remove-matcher owner=clang::"
- name: Generate TypeScript Definitions ${{ inputs.step-suffix }}
if: ${{ inputs.is-release == 'true' }}
shell: bash

View File

@@ -80,9 +80,6 @@ runs:
else
echo "The cross mount cache has $freespace_human free space - continuing"
fi
- name: Add patch conflict problem matcher
shell: bash
run: echo "::add-matcher::src/electron/.github/problem-matchers/patch-conflict.json"
- name: Gclient Sync
if: steps.check-cache.outputs.cache_exists == 'false'
shell: bash
@@ -131,11 +128,7 @@ runs:
echo "No changes to patches detected"
fi
fi
- name: Remove patch conflict problem matcher
shell: bash
run: |
echo "::remove-matcher owner=merge-conflict::"
echo "::remove-matcher owner=patch-conflict::"
# delete all .git directories under src/ except for
# third_party/angle/ and third_party/dawn/ because of build time generation of files
# gen/angle/commit.h depends on third_party/angle/.git/HEAD

View File

@@ -15,16 +15,12 @@ runs:
fi
export BUILD_TOOLS_SHA=6e8526315ea3b4828882497e532b8340e64e053c
npm i -g @electron/build-tools
# Update depot_tools to ensure python
e d update_depot_tools
e d ensure_bootstrap
e auto-update disable
# Disable further updates of depot_tools
e d auto-update disable
if [ "$(expr substr $(uname -s) 1 10)" == "MSYS_NT-10" ]; then
e d cipd.bat --version
cp "C:\Python311\python.exe" "C:\Python311\python3.exe"
echo "C:\Users\ContainerAdministrator\.electron_build_tools\third_party\depot_tools" >> $GITHUB_PATH
else
echo "$HOME/.electron_build_tools/third_party/depot_tools" >> $GITHUB_PATH
echo "$HOME/.electron_build_tools/third_party/depot_tools/python-bin" >> $GITHUB_PATH
fi
fi
echo "$HOME/.electron_build_tools/third_party/depot_tools" >> $GITHUB_PATH
echo "$HOME/.electron_build_tools/third_party/depot_tools/python-bin" >> $GITHUB_PATH

View File

@@ -1,18 +0,0 @@
{
"problemMatcher": [
{
"owner": "clang",
"fromPath": "src/out/Default/args.gn",
"pattern": [
{
"regexp": "^(.+)[(:](\\d+)[:,](\\d+)\\)?:\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
]
}
]
}

View File

@@ -1,24 +0,0 @@
{
"problemMatcher": [
{
"owner": "merge-conflict",
"pattern": [
{
"regexp": "^CONFLICT\\s\\(\\S+\\): (Merge conflict in \\S+)$",
"message": 1
}
]
},
{
"owner": "patch-conflict",
"pattern": [
{
"regexp": "^error: (patch failed: (\\S+):(\\d+))$",
"message": 1,
"file": 2,
"line": 3
}
]
}
]
}

View File

@@ -50,6 +50,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
uses: github/codeql-action/upload-sarif@45775bd8235c68ba998cffa5171334d58593da47 # v3.28.15
with:
sarif_file: results.sarif

View File

@@ -27,7 +27,7 @@ void MenuViews::PopupAt(BaseWindow* window,
int positioning_item,
ui::mojom::MenuSourceType source_type,
base::OnceClosure callback) {
const NativeWindow* native_window = window->window();
auto* native_window = static_cast<NativeWindowViews*>(window->window());
if (!native_window)
return;

View File

@@ -34,6 +34,17 @@
selector:@selector(onScreenUnlocked:)
name:@"com.apple.screenIsUnlocked"
object:nil];
// A notification that the workspace posts before the machine goes to sleep.
[distributed_center addObserver:self
selector:@selector(isSuspending:)
name:NSWorkspaceWillSleepNotification
object:nil];
// A notification that the workspace posts when the machine wakes from
// sleep.
[distributed_center addObserver:self
selector:@selector(isResuming:)
name:NSWorkspaceDidWakeNotification
object:nil];
NSNotificationCenter* shared_center =
[[NSWorkspace sharedWorkspace] notificationCenter];
@@ -62,6 +73,18 @@
self->emitters.push_back(monitor_);
}
- (void)isSuspending:(NSNotification*)notify {
for (auto* emitter : self->emitters) {
emitter->Emit("suspend");
}
}
- (void)isResuming:(NSNotification*)notify {
for (auto* emitter : self->emitters) {
emitter->Emit("resume");
}
}
- (void)onScreenLocked:(NSNotification*)notification {
for (auto* emitter : self->emitters) {
emitter->Emit("lock-screen");

View File

@@ -88,6 +88,18 @@ LRESULT CALLBACK PowerMonitor::WndProc(HWND hwnd,
base::Unretained(this)));
}
}
} else if (message == WM_POWERBROADCAST) {
if (wparam == PBT_APMRESUMEAUTOMATIC) {
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce([](PowerMonitor* pm) { pm->Emit("resume"); },
base::Unretained(this)));
} else if (wparam == PBT_APMSUSPEND) {
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce([](PowerMonitor* pm) { pm->Emit("suspend"); },
base::Unretained(this)));
}
}
return ::DefWindowProc(hwnd, message, wparam, lparam);
}

View File

@@ -2007,8 +2007,13 @@ void WebContents::ReadyToCommitNavigation(
// Don't focus content in an inactive window.
if (!owner_window())
return;
#if BUILDFLAG(IS_MAC)
if (!owner_window()->IsActive())
return;
#else
if (!owner_window()->widget()->IsActive())
return;
#endif
// Don't focus content after subframe navigations.
if (!navigation_handle->IsInMainFrame())
return;

View File

@@ -8,14 +8,12 @@
#include <utility>
#include "base/auto_reset.h"
#include "base/mac/mac_util.h"
#include "base/observer_list.h"
#include "base/strings/sys_string_conversions.h"
#include "content/public/browser/browser_accessibility_state.h"
#include "content/public/browser/native_event_processor_mac.h"
#include "content/public/browser/native_event_processor_observer_mac.h"
#include "content/public/browser/scoped_accessibility_mode.h"
#include "content/public/common/content_features.h"
#include "shell/browser/browser.h"
#include "shell/browser/mac/dict_util.h"
#import "shell/browser/mac/electron_application_delegate.h"
@@ -33,19 +31,12 @@ inline void dispatch_sync_main(dispatch_block_t block) {
} // namespace
@interface AtomApplication () <NativeEventProcessor> {
int _AXEnhancedUserInterfaceRequests;
BOOL _voiceOverEnabled;
BOOL _sonomaAccessibilityRefinementsAreActive;
base::ObserverList<content::NativeEventProcessorObserver>::Unchecked
observers_;
}
// Enables/disables screen reader support on changes to VoiceOver status.
- (void)voiceOverStateChanged:(BOOL)voiceOverEnabled;
@end
@implementation AtomApplication {
std::unique_ptr<content::ScopedAccessibilityMode>
_scoped_accessibility_mode_voiceover;
std::unique_ptr<content::ScopedAccessibilityMode>
_scoped_accessibility_mode_general;
}
@@ -54,37 +45,6 @@ inline void dispatch_sync_main(dispatch_block_t block) {
return (AtomApplication*)[super sharedApplication];
}
- (void)finishLaunching {
[super finishLaunching];
_sonomaAccessibilityRefinementsAreActive =
base::mac::MacOSVersion() >= 14'00'00 &&
base::FeatureList::IsEnabled(
features::kSonomaAccessibilityActivationRefinements);
}
- (void)observeValueForKeyPath:(NSString*)keyPath
ofObject:(id)object
change:(NSDictionary*)change
context:(void*)context {
if ([keyPath isEqualToString:@"voiceOverEnabled"] &&
context == content::BrowserAccessibilityState::GetInstance()) {
NSNumber* newValueNumber = [change objectForKey:NSKeyValueChangeNewKey];
DCHECK([newValueNumber isKindOfClass:[NSNumber class]]);
if ([newValueNumber isKindOfClass:[NSNumber class]]) {
[self voiceOverStateChanged:[newValueNumber boolValue]];
}
return;
}
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
}
- (void)willPowerOff:(NSNotification*)notify {
userStoppedShutdown_ = shouldShutdown_ && !shouldShutdown_.Run();
}
@@ -254,7 +214,14 @@ inline void dispatch_sync_main(dispatch_block_t block) {
- (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute {
bool is_manual_ax = [attribute isEqualToString:@"AXManualAccessibility"];
if ([attribute isEqualToString:@"AXEnhancedUserInterface"] || is_manual_ax) {
[self enableScreenReaderCompleteModeAfterDelay:[value boolValue]];
if (![value boolValue]) {
_scoped_accessibility_mode_general.reset();
} else if (!_scoped_accessibility_mode_general) {
_scoped_accessibility_mode_general =
content::BrowserAccessibilityState::GetInstance()
->CreateScopedModeForProcess(ui::kAXModeComplete);
}
electron::Browser::Get()->OnAccessibilitySupportChanged();
// Don't call the superclass function for AXManualAccessibility,
@@ -274,11 +241,8 @@ inline void dispatch_sync_main(dispatch_block_t block) {
// recommends turning on a11y when an AT accesses the 'accessibilityRole'
// property. This function is accessed frequently, so we only change the
// accessibility state when accessibility is already disabled.
if (!_scoped_accessibility_mode_general &&
!_scoped_accessibility_mode_voiceover) {
ui::AXMode target_mode = _sonomaAccessibilityRefinementsAreActive
? ui::AXMode::kNativeAPIs
: ui::kAXModeBasic;
if (!_scoped_accessibility_mode_general) {
ui::AXMode target_mode = ui::kAXModeBasic;
_scoped_accessibility_mode_general =
content::BrowserAccessibilityState::GetInstance()
->CreateScopedModeForProcess(target_mode |
@@ -288,82 +252,6 @@ inline void dispatch_sync_main(dispatch_block_t block) {
return [super accessibilityRole];
}
- (void)enableScreenReaderCompleteMode:(BOOL)enable {
if (enable) {
if (!_scoped_accessibility_mode_voiceover) {
_scoped_accessibility_mode_voiceover =
content::BrowserAccessibilityState::GetInstance()
->CreateScopedModeForProcess(ui::kAXModeComplete |
ui::AXMode::kFromPlatform |
ui::AXMode::kScreenReader);
}
} else {
_scoped_accessibility_mode_voiceover.reset();
}
}
// We need to call enableScreenReaderCompleteMode:YES from performSelector:...
// but there's no way to supply a BOOL as a parameter, so we have this
// explicit enable... helper method.
- (void)enableScreenReaderCompleteMode {
_AXEnhancedUserInterfaceRequests = 0;
[self enableScreenReaderCompleteMode:YES];
}
- (void)voiceOverStateChanged:(BOOL)voiceOverEnabled {
_voiceOverEnabled = voiceOverEnabled;
[self enableScreenReaderCompleteMode:voiceOverEnabled];
}
// Enables or disables screen reader support for non-VoiceOver assistive
// technology (AT), possibly after a delay.
//
// Now that we directly monitor VoiceOver status, we no longer watch for
// changes to AXEnhancedUserInterface for that signal from VO. However, other
// AT can set a value for AXEnhancedUserInterface, so we can't ignore it.
// Unfortunately, as of macOS Sonoma, we sometimes see spurious changes to
// AXEnhancedUserInterface (quick on and off). We debounce by waiting for these
// changes to settle down before updating the screen reader state.
- (void)enableScreenReaderCompleteModeAfterDelay:(BOOL)enable {
// If VoiceOver is already explicitly enabled, ignore requests from other AT.
if (_voiceOverEnabled) {
return;
}
// If this is a request to disable screen reader support, and we haven't seen
// a corresponding enable request, go ahead and disable.
if (!enable && _AXEnhancedUserInterfaceRequests == 0) {
[self enableScreenReaderCompleteMode:NO];
return;
}
// Use a counter to track requests for changes to the screen reader state.
if (enable) {
_AXEnhancedUserInterfaceRequests++;
} else {
_AXEnhancedUserInterfaceRequests--;
}
DCHECK_GE(_AXEnhancedUserInterfaceRequests, 0);
// _AXEnhancedUserInterfaceRequests > 0 means we want to enable screen
// reader support, but we'll delay that action until there are no more state
// change requests within a two-second window. Cancel any pending
// performSelector:..., and schedule a new one to restart the countdown.
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:@selector
(enableScreenReaderCompleteMode)
object:nil];
if (_AXEnhancedUserInterfaceRequests > 0) {
const float kTwoSecondDelay = 2.0;
[self performSelector:@selector(enableScreenReaderCompleteMode)
withObject:nil
afterDelay:kTwoSecondDelay];
}
}
- (void)orderFrontStandardAboutPanel:(id)sender {
electron::Browser::Get()->ShowAboutPanel();
}

View File

@@ -75,12 +75,10 @@ namespace electron {
namespace {
#if BUILDFLAG(IS_WIN)
gfx::Size GetExpandedWindowSize(const NativeWindow* window,
bool transparent,
gfx::Size size) {
gfx::Size GetExpandedWindowSize(const NativeWindow* window, gfx::Size size) {
if (!base::FeatureList::IsEnabled(
views::features::kEnableTransparentHwndEnlargement) ||
!transparent) {
!window->transparent()) {
return size;
}
@@ -99,15 +97,11 @@ gfx::Size GetExpandedWindowSize(const NativeWindow* window,
NativeWindow::NativeWindow(const gin_helper::Dictionary& options,
NativeWindow* parent)
: title_bar_style_{options.ValueOrDefault(options::kTitleBarStyle,
TitleBarStyle::kNormal)},
transparent_{options.ValueOrDefault(options::kTransparent, false)},
enable_larger_than_screen_{
options.ValueOrDefault(options::kEnableLargerThanScreen, false)},
is_modal_{parent != nullptr && options.ValueOrDefault("modal", false)},
has_frame_{options.ValueOrDefault(options::kFrame, true) &&
title_bar_style_ == TitleBarStyle::kNormal},
parent_{parent} {
: widget_(std::make_unique<views::Widget>()), parent_(parent) {
options.Get(options::kFrame, &has_frame_);
options.Get(options::kTransparent, &transparent_);
options.Get(options::kEnableLargerThanScreen, &enable_larger_than_screen_);
options.Get(options::kTitleBarStyle, &title_bar_style_);
#if BUILDFLAG(IS_WIN)
options.Get(options::kBackgroundMaterial, &background_material_);
#elif BUILDFLAG(IS_MAC)
@@ -130,6 +124,20 @@ NativeWindow::NativeWindow(const gin_helper::Dictionary& options,
}
}
if (parent)
options.Get("modal", &is_modal_);
#if defined(USE_OZONE)
// Ozone X11 likes to prefer custom frames, but we don't need them unless
// on Wayland.
if (base::FeatureList::IsEnabled(features::kWaylandWindowDecorations) &&
!ui::OzonePlatform::GetInstance()
->GetPlatformRuntimeProperties()
.supports_server_side_window_decorations) {
has_client_frame_ = true;
}
#endif
WindowList::AddWindow(this);
}
@@ -409,15 +417,14 @@ gfx::Size NativeWindow::GetContentMinimumSize() const {
}
gfx::Size NativeWindow::GetContentMaximumSize() const {
const auto size_constraints = GetContentSizeConstraints();
gfx::Size maximum_size = size_constraints.GetMaximumSize();
gfx::Size maximum_size = GetContentSizeConstraints().GetMaximumSize();
#if BUILDFLAG(IS_WIN)
if (size_constraints.HasMaximumSize())
maximum_size = GetExpandedWindowSize(this, transparent(), maximum_size);
#endif
return GetContentSizeConstraints().HasMaximumSize()
? GetExpandedWindowSize(this, maximum_size)
: maximum_size;
#else
return maximum_size;
#endif
}
void NativeWindow::SetSheetOffset(const double offsetX, const double offsetY) {
@@ -830,22 +837,6 @@ bool NativeWindow::IsTranslucent() const {
return false;
}
// static
bool NativeWindow::PlatformHasClientFrame() {
#if defined(USE_OZONE)
// Ozone X11 likes to prefer custom frames,
// but we don't need them unless on Wayland.
static const bool has_client_frame =
base::FeatureList::IsEnabled(features::kWaylandWindowDecorations) &&
!ui::OzonePlatform::GetInstance()
->GetPlatformRuntimeProperties()
.supports_server_side_window_decorations;
return has_client_frame;
#else
return false;
#endif
}
// static
void NativeWindowRelay::CreateForWebContents(
content::WebContents* web_contents,

View File

@@ -8,11 +8,11 @@
#include <list>
#include <memory>
#include <optional>
#include <queue>
#include <string>
#include <string_view>
#include <vector>
#include "base/containers/queue.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
@@ -157,10 +157,10 @@ class NativeWindow : public base::SupportsUserData,
virtual ui::ZOrderLevel GetZOrderLevel() const = 0;
virtual void Center() = 0;
virtual void Invalidate() = 0;
[[nodiscard]] virtual bool IsActive() const = 0;
#if BUILDFLAG(IS_MAC)
virtual std::string GetAlwaysOnTopLevel() const = 0;
virtual void SetActive(bool is_key) = 0;
virtual bool IsActive() const = 0;
virtual void RemoveChildFromParentWindow() = 0;
virtual void RemoveChildWindow(NativeWindow* child) = 0;
virtual void AttachChildren() = 0;
@@ -374,16 +374,14 @@ class NativeWindow : public base::SupportsUserData,
views::Widget* widget() const { return widget_.get(); }
views::View* content_view() const { return content_view_; }
enum class TitleBarStyle : uint8_t {
enum class TitleBarStyle {
kNormal,
kHidden,
kHiddenInset,
kCustomButtonsOnHover,
};
[[nodiscard]] TitleBarStyle title_bar_style() const {
return title_bar_style_;
}
TitleBarStyle title_bar_style() const { return title_bar_style_; }
bool IsWindowControlsOverlayEnabled() const {
bool valid_titlebar_style = title_bar_style() == TitleBarStyle::kHidden
@@ -397,11 +395,14 @@ class NativeWindow : public base::SupportsUserData,
int titlebar_overlay_height() const { return titlebar_overlay_height_; }
[[nodiscard]] bool has_frame() const { return has_frame_; }
bool has_frame() const { return has_frame_; }
bool has_client_frame() const { return has_client_frame_; }
bool transparent() const { return transparent_; }
bool enable_larger_than_screen() const { return enable_larger_than_screen_; }
NativeWindow* parent() const { return parent_; }
[[nodiscard]] bool is_modal() const { return is_modal_; }
bool is_modal() const { return is_modal_; }
[[nodiscard]] constexpr int32_t window_id() const { return window_id_; }
@@ -427,21 +428,15 @@ class NativeWindow : public base::SupportsUserData,
void UpdateBackgroundThrottlingState();
protected:
NativeWindow(const gin_helper::Dictionary& options, NativeWindow* parent);
void set_titlebar_overlay_height(int height) {
titlebar_overlay_height_ = height;
}
[[nodiscard]] bool has_client_frame() const { return has_client_frame_; }
constexpr void set_has_frame(const bool val) { has_frame_ = val; }
[[nodiscard]] bool transparent() const { return transparent_; }
[[nodiscard]] constexpr bool is_closed() const { return is_closed_; }
[[nodiscard]] bool is_closed() const { return is_closed_; }
[[nodiscard]] bool enable_larger_than_screen() const {
return enable_larger_than_screen_;
}
NativeWindow(const gin_helper::Dictionary& options, NativeWindow* parent);
virtual void OnTitleChanged() {}
@@ -466,6 +461,9 @@ class NativeWindow : public base::SupportsUserData,
// The boolean parsing of the "titleBarOverlay" option
bool titlebar_overlay_ = false;
// The "titleBarStyle" option.
TitleBarStyle title_bar_style_ = TitleBarStyle::kNormal;
// Minimum and maximum size.
std::optional<extensions::SizeConstraints> size_constraints_;
// Same as above but stored as content size, we are storing 2 types of size
@@ -473,41 +471,18 @@ class NativeWindow : public base::SupportsUserData,
// on HiDPI displays on some environments.
std::optional<extensions::SizeConstraints> content_size_constraints_;
base::queue<bool> pending_transitions_;
std::queue<bool> pending_transitions_;
FullScreenTransitionType fullscreen_transition_type_ =
FullScreenTransitionType::kNone;
std::list<NativeWindow*> child_windows_;
private:
static bool PlatformHasClientFrame();
std::unique_ptr<views::Widget> widget_ = std::make_unique<views::Widget>();
std::unique_ptr<views::Widget> widget_;
static inline int32_t next_id_ = 0;
const int32_t window_id_ = ++next_id_;
// The "titleBarStyle" option.
const TitleBarStyle title_bar_style_;
// Whether window has standard frame, but it's drawn by Electron (the client
// application) instead of the OS. Currently only has meaning on Linux for
// Wayland hosts.
const bool has_client_frame_ = PlatformHasClientFrame();
// Whether window is transparent.
const bool transparent_;
// Whether window can be resized larger than screen.
const bool enable_larger_than_screen_;
// Is this a modal window.
const bool is_modal_;
// Whether window has standard frame.
const bool has_frame_;
// The content view, weak ref.
raw_ptr<views::View> content_view_ = nullptr;
@@ -515,6 +490,20 @@ class NativeWindow : public base::SupportsUserData,
// "titleBarOverlay"
int titlebar_overlay_height_ = 0;
// Whether window has standard frame.
bool has_frame_ = true;
// Whether window has standard frame, but it's drawn by Electron (the client
// application) instead of the OS. Currently only has meaning on Linux for
// Wayland hosts.
bool has_client_frame_ = false;
// Whether window is transparent.
bool transparent_ = false;
// Whether window can be resized larger than screen.
bool enable_larger_than_screen_ = false;
// The windows has been closed.
bool is_closed_ = false;
@@ -531,6 +520,9 @@ class NativeWindow : public base::SupportsUserData,
// The parent window, it is guaranteed to be valid during this window's life.
raw_ptr<NativeWindow> parent_ = nullptr;
// Is this a modal window.
bool is_modal_ = false;
bool is_transitioning_fullscreen_ = false;
std::list<DraggableRegionProvider*> draggable_region_providers_;

View File

@@ -151,6 +151,10 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
const bool paint_when_initially_hidden =
options.ValueOrDefault(options::kPaintWhenInitiallyHidden, true);
// 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
@@ -248,20 +252,20 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
// https://github.com/electron/electron/issues/517.
[window_ setOpaque:NO];
// Show window buttons if titleBarStyle is not "normal".
if (title_bar_style() == TitleBarStyle::kNormal) {
if (title_bar_style_ == TitleBarStyle::kNormal) {
InternalSetWindowButtonVisibility(false);
} else {
buttons_proxy_ = [[WindowButtonsProxy alloc] initWithWindow:window_];
[buttons_proxy_ setHeight:titlebar_overlay_height()];
if (traffic_light_position_) {
[buttons_proxy_ setMargin:*traffic_light_position_];
} else if (title_bar_style() == TitleBarStyle::kHiddenInset) {
} else if (title_bar_style_ == TitleBarStyle::kHiddenInset) {
// For macOS >= 11, while this value does not match official macOS apps
// like Safari or Notes, it matches titleBarStyle's old implementation
// before Electron <= 12.
[buttons_proxy_ setMargin:gfx::Point(12, 11)];
}
if (title_bar_style() == TitleBarStyle::kCustomButtonsOnHover) {
if (title_bar_style_ == TitleBarStyle::kCustomButtonsOnHover) {
[buttons_proxy_ setShowOnHover:YES];
} else {
// customButtonsOnHover does not show buttons initially.
@@ -1049,7 +1053,7 @@ void NativeWindowMac::SetSimpleFullScreen(bool simple_fullscreen) {
if (has_frame())
visibility = true;
else
visibility = title_bar_style() != TitleBarStyle::kNormal;
visibility = title_bar_style_ != TitleBarStyle::kNormal;
InternalSetWindowButtonVisibility(visibility);
}
@@ -1477,7 +1481,7 @@ void NativeWindowMac::SetWindowButtonVisibility(bool visible) {
[buttons_proxy_ setVisible:visible];
}
if (title_bar_style() != TitleBarStyle::kCustomButtonsOnHover)
if (title_bar_style_ != TitleBarStyle::kCustomButtonsOnHover)
InternalSetWindowButtonVisibility(visible);
NotifyLayoutWindowControlsOverlay();

View File

@@ -20,7 +20,7 @@
#include <utility>
#include <vector>
#include "base/containers/fixed_flat_set.h"
#include "base/containers/contains.h"
#include "base/memory/raw_ref.h"
#include "base/numerics/ranges.h"
#include "base/strings/utf_string_conversions.h"
@@ -241,6 +241,10 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
}
}
// |hidden| is the only non-default titleBarStyle valid on Windows and Linux.
if (title_bar_style_ == TitleBarStyle::kHidden)
set_has_frame(false);
#if BUILDFLAG(IS_WIN)
// If the taskbar is re-created after we start up, we have to rebuild all of
// our buttons.
@@ -286,7 +290,7 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
if (parent)
params.parent = parent->GetNativeWindow();
params.native_widget = new ElectronDesktopNativeWidgetAura{this, widget()};
params.native_widget = new ElectronDesktopNativeWidgetAura(this);
#elif BUILDFLAG(IS_LINUX)
std::string name = Browser::Get()->GetName();
// Set WM_WINDOW_ROLE.
@@ -300,7 +304,7 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
auto* native_widget = new views::DesktopNativeWidgetAura(widget());
params.native_widget = native_widget;
params.desktop_window_tree_host =
new ElectronDesktopWindowTreeHostLinux{this, widget(), native_widget};
new ElectronDesktopWindowTreeHostLinux(this, native_widget);
#endif
widget()->Init(std::move(params));
@@ -1157,9 +1161,9 @@ void NativeWindowViews::SetAlwaysOnTop(ui::ZOrderLevel z_order,
if (z_order != ui::ZOrderLevel::kNormal) {
// On macOS the window is placed behind the Dock for the following levels.
// Re-use the same names on Windows to make it easier for the user.
static constexpr auto levels = base::MakeFixedFlatSet<std::string_view>(
{"floating", "torn-off-menu", "modal-panel", "main-menu", "status"});
behind_task_bar_ = levels.contains(level);
static const std::vector<std::string> levels = {
"floating", "torn-off-menu", "modal-panel", "main-menu", "status"};
behind_task_bar_ = base::Contains(levels, level);
}
#endif
MoveBehindTaskBarIfNeeded();
@@ -1198,11 +1202,6 @@ void NativeWindowViews::Invalidate() {
widget()->SchedulePaintInRect(gfx::Rect(GetBounds().size()));
}
bool NativeWindowViews::IsActive() const {
views::Widget* const widget = this->widget();
return widget && widget->IsActive();
}
void NativeWindowViews::FlashFrame(bool flash) {
#if BUILDFLAG(IS_WIN)
// The Chromium's implementation has a bug stopping flash.
@@ -1846,19 +1845,6 @@ NativeWindowViews::CreateNonClientFrameView(views::Widget* widget) {
#endif
}
#if BUILDFLAG(IS_LINUX)
electron::ClientFrameViewLinux* NativeWindowViews::GetClientFrameViewLinux() {
// Check to make sure this window's non-client frame view is a
// ClientFrameViewLinux. If either has_frame() or has_client_frame()
// are false, it will be an OpaqueFrameView or NativeFrameView instead.
// See NativeWindowViews::CreateNonClientFrameView.
if (!has_frame() || !has_client_frame())
return {};
return static_cast<ClientFrameViewLinux*>(
widget()->non_client_view()->frame_view());
}
#endif
void NativeWindowViews::OnWidgetMove() {
NotifyWindowMove();
}

View File

@@ -31,7 +31,6 @@ class Arguments;
namespace electron {
#if BUILDFLAG(IS_LINUX)
class ClientFrameViewLinux;
class GlobalMenuBarX11;
#endif
@@ -104,7 +103,6 @@ class NativeWindowViews : public NativeWindow,
ui::ZOrderLevel GetZOrderLevel() const override;
void Center() override;
void Invalidate() override;
[[nodiscard]] bool IsActive() const override;
void FlashFrame(bool flash) override;
void SetSkipTaskbar(bool skip) override;
void SetExcludedFromShownWindowsMenu(bool excluded) override {}
@@ -183,12 +181,6 @@ class NativeWindowViews : public NativeWindow,
SkColor overlay_button_color() const { return overlay_button_color_; }
SkColor overlay_symbol_color() const { return overlay_symbol_color_; }
#if BUILDFLAG(IS_LINUX)
// returns the ClientFrameViewLinux iff that is our NonClientFrameView type,
// nullptr otherwise.
ClientFrameViewLinux* GetClientFrameViewLinux();
#endif
private:
void set_overlay_button_color(SkColor color) {
overlay_button_color_ = color;

View File

@@ -5,10 +5,10 @@
#ifndef ELECTRON_SHELL_BROWSER_NET_RESOLVE_PROXY_HELPER_H_
#define ELECTRON_SHELL_BROWSER_NET_RESOLVE_PROXY_HELPER_H_
#include <deque>
#include <optional>
#include <string>
#include "base/containers/circular_deque.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "mojo/public/cpp/bindings/receiver.h"
@@ -66,7 +66,7 @@ class ResolveProxyHelper
// Self-reference. Owned as long as there's an outstanding proxy lookup.
scoped_refptr<ResolveProxyHelper> owned_self_;
base::circular_deque<PendingRequest> pending_requests_;
std::deque<PendingRequest> pending_requests_;
// Receiver for the currently in-progress request, if any.
mojo::Receiver<network::mojom::ProxyLookupClient> receiver_{this};

View File

@@ -33,10 +33,10 @@ namespace electron {
ElectronDesktopWindowTreeHostLinux::ElectronDesktopWindowTreeHostLinux(
NativeWindowViews* native_window_view,
views::Widget* widget,
views::DesktopNativeWidgetAura* desktop_native_widget_aura)
: views::DesktopWindowTreeHostLinux{widget, desktop_native_widget_aura},
native_window_view_{native_window_view} {}
: views::DesktopWindowTreeHostLinux(native_window_view->widget(),
desktop_native_widget_aura),
native_window_view_(native_window_view) {}
ElectronDesktopWindowTreeHostLinux::~ElectronDesktopWindowTreeHostLinux() =
default;
@@ -64,9 +64,13 @@ gfx::Insets ElectronDesktopWindowTreeHostLinux::CalculateInsetsInDIP(
return gfx::Insets();
}
auto* const view = native_window_view_->GetClientFrameViewLinux();
if (!view)
return {};
if (!native_window_view_->has_frame() ||
!native_window_view_->has_client_frame()) {
return gfx::Insets();
}
auto* view = static_cast<ClientFrameViewLinux*>(
native_window_view_->widget()->non_client_view()->frame_view());
gfx::Insets insets = view->RestoredMirroredFrameBorderInsets();
if (base::i18n::IsRTL())
@@ -98,12 +102,19 @@ void ElectronDesktopWindowTreeHostLinux::OnWindowStateChanged(
void ElectronDesktopWindowTreeHostLinux::OnWindowTiledStateChanged(
ui::WindowTiledEdges new_tiled_edges) {
if (auto* const view = native_window_view_->GetClientFrameViewLinux()) {
// CreateNonClientFrameView creates `ClientFrameViewLinux` only when both
// frame and client_frame booleans are set, otherwise it is a different type
// of view.
if (native_window_view_->has_frame() &&
native_window_view_->has_client_frame()) {
ClientFrameViewLinux* frame = static_cast<ClientFrameViewLinux*>(
native_window_view_->widget()->non_client_view()->frame_view());
bool maximized = new_tiled_edges.top && new_tiled_edges.left &&
new_tiled_edges.bottom && new_tiled_edges.right;
bool tiled = new_tiled_edges.top || new_tiled_edges.left ||
new_tiled_edges.bottom || new_tiled_edges.right;
view->set_tiled(tiled && !maximized);
frame->set_tiled(tiled && !maximized);
}
UpdateFrameHints();
}
@@ -155,13 +166,15 @@ void ElectronDesktopWindowTreeHostLinux::OnDeviceScaleFactorChanged() {
void ElectronDesktopWindowTreeHostLinux::UpdateFrameHints() {
if (base::FeatureList::IsEnabled(features::kWaylandWindowDecorations)) {
auto* const view = native_window_view_->GetClientFrameViewLinux();
if (!view)
if (!native_window_view_->has_frame() ||
!native_window_view_->has_client_frame())
return;
ui::PlatformWindow* window = platform_window();
auto window_state = window->GetPlatformWindowState();
float scale = device_scale_factor();
auto* view = static_cast<ClientFrameViewLinux*>(
native_window_view_->widget()->non_client_view()->frame_view());
const gfx::Size widget_size =
view->GetWidget()->GetWindowBoundsInScreen().size();

View File

@@ -29,7 +29,6 @@ class ElectronDesktopWindowTreeHostLinux
public:
ElectronDesktopWindowTreeHostLinux(
NativeWindowViews* native_window_view,
views::Widget* widget,
views::DesktopNativeWidgetAura* desktop_native_widget_aura);
~ElectronDesktopWindowTreeHostLinux() override;

View File

@@ -14,12 +14,9 @@
namespace electron {
ElectronDesktopNativeWidgetAura::ElectronDesktopNativeWidgetAura(
NativeWindowViews* native_window_view,
views::Widget* widget)
: views::DesktopNativeWidgetAura{widget},
native_window_view_{native_window_view},
desktop_window_tree_host_{new ElectronDesktopWindowTreeHostWin{
native_window_view, widget, this}} {
NativeWindowViews* native_window_view)
: views::DesktopNativeWidgetAura(native_window_view->widget()),
native_window_view_(native_window_view) {
GetNativeWindow()->SetName("ElectronDesktopNativeWidgetAura");
// This is to enable the override of OnWindowActivated
wm::SetActivationChangeObserver(GetNativeWindow(), this);
@@ -27,7 +24,9 @@ ElectronDesktopNativeWidgetAura::ElectronDesktopNativeWidgetAura(
void ElectronDesktopNativeWidgetAura::InitNativeWidget(
views::Widget::InitParams params) {
CHECK_EQ(params.native_widget, this);
desktop_window_tree_host_ = new ElectronDesktopWindowTreeHostWin(
native_window_view_,
static_cast<views::DesktopNativeWidgetAura*>(params.native_widget));
params.desktop_window_tree_host = desktop_window_tree_host_;
views::DesktopNativeWidgetAura::InitNativeWidget(std::move(params));
}

View File

@@ -18,8 +18,7 @@ class NativeWindowViews;
class ElectronDesktopNativeWidgetAura : public views::DesktopNativeWidgetAura {
public:
explicit ElectronDesktopNativeWidgetAura(
NativeWindowViews* native_window_view,
views::Widget* widget);
NativeWindowViews* native_window_view);
// disable copy
ElectronDesktopNativeWidgetAura(const ElectronDesktopNativeWidgetAura&) =
@@ -41,10 +40,10 @@ class ElectronDesktopNativeWidgetAura : public views::DesktopNativeWidgetAura {
aura::Window* gained_active,
aura::Window* lost_active) override;
const raw_ptr<NativeWindowViews> native_window_view_;
raw_ptr<NativeWindowViews> native_window_view_;
// Owned by DesktopNativeWidgetAura.
const raw_ptr<views::DesktopWindowTreeHost> desktop_window_tree_host_;
raw_ptr<views::DesktopWindowTreeHost> desktop_window_tree_host_;
};
} // namespace electron

View File

@@ -16,10 +16,10 @@ namespace electron {
ElectronDesktopWindowTreeHostWin::ElectronDesktopWindowTreeHostWin(
NativeWindowViews* native_window_view,
views::Widget* widget,
views::DesktopNativeWidgetAura* desktop_native_widget_aura)
: views::DesktopWindowTreeHostWin{widget, desktop_native_widget_aura},
native_window_view_{native_window_view} {}
: views::DesktopWindowTreeHostWin(native_window_view->widget(),
desktop_native_widget_aura),
native_window_view_(native_window_view) {}
ElectronDesktopWindowTreeHostWin::~ElectronDesktopWindowTreeHostWin() = default;

View File

@@ -20,7 +20,6 @@ class ElectronDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin,
public:
ElectronDesktopWindowTreeHostWin(
NativeWindowViews* native_window_view,
views::Widget* widget,
views::DesktopNativeWidgetAura* desktop_native_widget_aura);
~ElectronDesktopWindowTreeHostWin() override;

View File

@@ -5,11 +5,11 @@
#include "shell/common/crash_keys.h"
#include <cstdint>
#include <deque>
#include <map>
#include <string>
#include "base/command_line.h"
#include "base/containers/circular_deque.h"
#include "base/environment.h"
#include "base/no_destructor.h"
#include "base/strings/strcat.h"
@@ -28,17 +28,19 @@ namespace electron::crash_keys {
namespace {
auto& GetExtraCrashKeys() {
constexpr size_t kMaxCrashKeyValueSize = 20320;
static_assert(kMaxCrashKeyValueSize < crashpad::Annotation::kValueMaxSize,
"max crash key value length above what crashpad supports");
using CrashKeyString = crash_reporter::CrashKeyString<kMaxCrashKeyValueSize>;
static base::NoDestructor<base::circular_deque<CrashKeyString>> extra_keys;
constexpr size_t kMaxCrashKeyValueSize = 20320;
static_assert(kMaxCrashKeyValueSize < crashpad::Annotation::kValueMaxSize,
"max crash key value length above what crashpad supports");
using ExtraCrashKeys =
std::deque<crash_reporter::CrashKeyString<kMaxCrashKeyValueSize>>;
ExtraCrashKeys& GetExtraCrashKeys() {
static base::NoDestructor<ExtraCrashKeys> extra_keys;
return *extra_keys;
}
auto& GetExtraCrashKeyNames() {
static base::NoDestructor<base::circular_deque<std::string>> crash_key_names;
std::deque<std::string>& GetExtraCrashKeyNames() {
static base::NoDestructor<std::deque<std::string>> crash_key_names;
return *crash_key_names;
}

View File

@@ -143,21 +143,19 @@ v8::Local<v8::Value> Converter<electron::OffscreenSharedTextureValue>::ToV8(
// texture, output it in second pass callback.
data.SetSecondPassCallback([](const v8::WeakCallbackInfo<
OffscreenReleaseHolderMonitor>& data) {
auto* iso = data.GetIsolate();
// Emit warning only once
static std::once_flag flag;
std::call_once(flag, [=] {
base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE, base::BindOnce([] {
electron::util::EmitWarning(
"Offscreen rendering shared texture was garbage "
"collected before calling `release()`. When using OSR "
"with `useSharedTexture: true`, `texture.release()` "
"must be called explicitly as soon as the texture is "
"copied to your rendering system. Otherwise, it will "
"soon drain the underlying frame pool and prevent "
"future frames from being sent.",
"OSRSharedTextureNotReleased");
}));
electron::util::EmitWarning(
iso,
"[OSR TEXTURE LEAKED] When using OSR with "
"`useSharedTexture`, `texture.release()` "
"must be called explicitly as soon as the texture is "
"copied to your rendering system. "
"Otherwise, it will soon drain the underlying "
"framebuffer and prevent future frames from being generated.",
"SharedTextureOSRNotReleased");
});
});
}

View File

@@ -207,16 +207,9 @@ void ElectronRendererClient::WorkerScriptReadyForEvaluationOnWorkerThread(
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kNodeIntegrationInWorker)) {
auto* current = WebWorkerObserver::GetCurrent();
if (current) {
// With thread pooling, threads can be reused. Check if this context
// already has a Node.js environment before skipping.
if (node::Environment::GetCurrent(context))
return;
}
if (!current)
current = WebWorkerObserver::Create();
current->WorkerScriptReadyForEvaluation(context);
if (current)
return;
WebWorkerObserver::Create()->WorkerScriptReadyForEvaluation(context);
}
}

View File

@@ -7,7 +7,6 @@ import * as fs from 'node:fs';
import * as os from 'node:os';
import * as path from 'node:path';
import { pathToFileURL } from 'node:url';
import { stripVTControlCharacters } from 'node:util';
const runFixture = async (appPath: string, args: string[] = []) => {
const result = cp.spawn(process.execPath, [appPath, ...args], {
@@ -28,8 +27,8 @@ const runFixture = async (appPath: string, args: string[] = []) => {
return {
code,
signal,
stdout: stripVTControlCharacters(Buffer.concat(stdout).toString().trim()),
stderr: stripVTControlCharacters(Buffer.concat(stderr).toString().trim())
stdout: Buffer.concat(stdout).toString().trim(),
stderr: Buffer.concat(stderr).toString().trim()
};
};