Compare commits

...

1 Commits

Author SHA1 Message Date
Sam Attard
7c023d0127 chore: consolidate semantically-related Chromium patches
151 → 117 patches (-34). Merged 56 patches into 22 groups that share
the same intent and subsystem. Each merged patch's header lists its
constituent patches and preserves their original descriptions.

New consolidated patches:

  gin/V8
    gin_isolate_holder_customization.patch (3)
    gin_v8_snapshot_customization.patch (2)
    gin_cppgc_transition_support.patch (2)

  Blink/renderer
    add_script_lifecycle_observer_hooks.patch (3)
    add_electron_permission_types_to_blink.patch (2)
    expose_blink_esm_module_hooks.patch (2)
    disable_background_throttling.patch (3)

  Browser process
    window_open_full_params_plumbing.patch (2)
    service_process_launch_customization.patch (3)
    process_singleton_electron_extensions.patch (2)
    picture_in_picture_electron.patch (2)
    desktop_media_list_customization.patch (2)
    chore_stub_chrome_profile_dependencies.patch (3)

  Platform
    expose_gtk_apis_for_electron.patch (3)
    fix_linux_app_identity.patch (2)
    hwnd_aspect_ratio_fixes.patch (2)
    hwnd_frameless_window_style_fixes.patch (2)
    global_shortcuts_enhancements.patch (3)

  Feature
    offscreen_rendering_support.patch (5)
    webview_guest_behavior_fixes.patch (2)
    spellcheck_electron_customization.patch (3)

  Build
    build_electron_pak_resources.patch (3)

Side effect: patch apply time 28s → 22s.
2026-03-24 18:58:22 +00:00
64 changed files with 2499 additions and 3131 deletions

View File

@@ -1,47 +1,41 @@
build_gn.patch
accelerator.patch
blink_local_frame.patch
can_create_window.patch
disable_hidden.patch
window_open_full_params_plumbing.patch
disable_background_throttling.patch
dom_storage_limits.patch
render_widget_host_view_mac.patch
webview_cross_drag.patch
gin_enable_disable_v8_platform.patch
enable_reset_aspect_ratio.patch
webview_guest_behavior_fixes.patch
gin_isolate_holder_customization.patch
hwnd_aspect_ratio_fixes.patch
boringssl_build_gn.patch
gtk_visibility.patch
resource_file_conflict.patch
expose_gtk_apis_for_electron.patch
build_electron_pak_resources.patch
scroll_bounce_flag.patch
mas_avoid_private_macos_api_usage.patch.patch
add_didinstallconditionalfeatures.patch
desktop_media_list.patch
proxy_config_monitor.patch
gritsettings_resource_ids.patch
isolate_holder.patch
add_script_lifecycle_observer_hooks.patch
desktop_media_list_customization.patch
chore_stub_chrome_profile_dependencies.patch
notification_provenance.patch
dump_syms.patch
command-ismediakey.patch
global_shortcuts_enhancements.patch
printing.patch
support_mixed_sandbox_with_zygote.patch
build_add_electron_tracing_category.patch
worker_context_will_destroy.patch
frame_host_manager.patch
crashpad_pid_check.patch
network_service_allow_remote_certificate_verification_logic.patch
add_contentgpuclient_precreatemessageloop_callback.patch
picture-in-picture.patch
picture_in_picture_electron.patch
disable_compositor_recycling.patch
allow_new_privileges_in_unsandboxed_child_processes.patch
service_process_launch_customization.patch
expose_setuseragent_on_networkcontext.patch
feat_add_set_theme_source_to_allow_apps_to.patch
add_webmessageportconverter_entangleandinjectmessageportchannel.patch
ignore_rc_check.patch
remove_usage_of_incognito_apis_in_the_spellchecker.patch
allow_disabling_blink_scheduler_throttling_per_renderview.patch
hack_plugin_response_interceptor_to_point_to_electron.patch
feat_add_support_for_overriding_the_base_spellchecker_download_url.patch
feat_enable_offscreen_rendering_with_viz_compositor.patch
feat_allow_embedders_to_add_observers_on_created_hunspell.patch
spellcheck_electron_customization.patch
offscreen_rendering_support.patch
allow_in-process_windows_to_have_different_web_prefs.patch
refactor_expose_cursor_changes_to_the_webcontentsobserver.patch
crash_allow_setting_more_options.patch
@@ -49,28 +43,18 @@ upload_list_add_loadsync_method.patch
allow_setting_secondary_label_via_simplemenumodel.patch
feat_add_streaming-protocol_registry_to_multibuffer_data_source.patch
adjust_accessibility_ui_for_electron.patch
worker_feat_add_hook_to_notify_script_ready.patch
chore_provide_iswebcontentscreationoverridden_with_full_params.patch
fix_properly_honor_printing_page_ranges.patch
export_gin_v8platform_pageallocator_for_usage_outside_of_the_gin.patch
fix_export_zlib_symbols.patch
web_contents.patch
webview_fullscreen.patch
extend_apply_webpreferences.patch
build_libc_as_static_library.patch
build_do_not_depend_on_packed_resource_integrity.patch
logging_win32_only_create_a_console_if_logging_to_stderr.patch
fix_media_key_usage_with_globalshortcuts.patch
feat_expose_raw_response_headers_from_urlloader.patch
process_singleton.patch
process_singleton_electron_extensions.patch
add_ui_scopedcliboardwriter_writeunsaferawdata.patch
feat_add_data_parameter_to_processsingleton.patch
fix_adapt_exclusive_access_for_electron_needs.patch
fix_aspect_ratio_with_max_size.patch
port_autofill_colors_to_the_color_pipeline.patch
fix_non-client_mouse_tracking_and_message_bubbling_on_windows.patch
build_make_libcxx_abi_unstable_false_for_electron.patch
make_gtk_getlibgtk_public.patch
custom_protocols_plzserviceworker.patch
feat_filter_out_non-shareable_windows_in_the_current_application_in.patch
short-circuit_permissions_checks_in_mediastreamdevicescontroller.patch
@@ -78,26 +62,22 @@ chore_add_electron_deps_to_gitignores.patch
chore_modify_chromium_handling_of_mouse_events.patch
add_electron_deps_to_license_credits_file.patch
fix_crash_loading_non-standard_schemes_in_iframes.patch
create_browser_v8_snapshot_file_name_fuse.patch
feat_configure_launch_options_for_service_process.patch
gin_v8_snapshot_customization.patch
feat_ensure_mas_builds_of_the_same_application_can_use_safestorage.patch
fix_on-screen-keyboard_hides_on_input_blur_in_webview.patch
fix_remove_caption-removing_style_call.patch
hwnd_frameless_window_style_fixes.patch
build_allow_electron_to_use_exec_script.patch
chore_introduce_blocking_api_for_electron.patch
chore_patch_out_partition_attribute_dcheck_for_webviews.patch
chore_patch_out_profile_methods.patch
add_gin_converter_support_for_arraybufferview.patch
chore_defer_usb_service_getdevices_request_until_usb_service_is.patch
refactor_expose_hostimportmoduledynamically_and.patch
expose_blink_esm_module_hooks.patch
feat_expose_documentloader_setdefersloading_on_webdocumentloader.patch
fix_disabling_background_throttling_in_compositor.patch
fix_select_the_first_menu_item_when_opened_via_keyboard.patch
fix_return_v8_value_from_localframe_requestexecutescript.patch
fix_harden_blink_scriptstate_maybefrom.patch
fix_use_delegated_generic_capturer_when_available.patch
expose_webblob_path_to_allow_embedders_to_get_file_paths.patch
fix_move_autopipsettingshelper_behind_branding_buildflag.patch
revert_remove_the_allowaggressivethrottlingwithwebsocket_feature.patch
feat_allow_passing_of_objecttemplate_to_objecttemplatebuilder.patch
chore_remove_check_is_test_on_script_injection_tracker.patch
@@ -105,14 +85,11 @@ fix_restore_original_resize_performance_on_macos.patch
feat_allow_code_cache_in_custom_schemes.patch
build_run_reclient_cfg_generator_after_chrome.patch
fix_getcursorscreenpoint_wrongly_returns_0_0.patch
fix_add_support_for_skipping_first_2_no-op_refreshes_in_thumb_cap.patch
refactor_expose_file_system_access_blocklist.patch
feat_add_support_for_missing_dialog_features_to_shell_dialogs.patch
feat_enable_passing_exit_code_on_service_process_crash.patch
chore_remove_reference_to_chrome_browser_themes.patch
feat_enable_customizing_symbol_color_in_framecaptionbutton.patch
build_allow_electron_mojom_interfaces_to_depend_on_blink.patch
osr_shared_texture_remove_keyed_mutex_on_win_dxgi.patch
feat_allow_usage_of_sccontentsharingpicker_on_supported_platforms.patch
chore_partial_revert_of.patch
fix_adjust_headless_mode_handling_in_native_widget.patch
@@ -122,30 +99,19 @@ feat_corner_smoothing_css_rule_and_blink_painting.patch
build_add_public_config_simdutf_config.patch
fix_multiple_scopedpumpmessagesinprivatemodes_instances.patch
revert_code_health_clean_up_stale_macwebcontentsocclusion.patch
feat_add_signals_when_embedder_cleanup_callbacks_run_for.patch
feat_separate_content_settings_callback_for_sync_and_async_clipboard.patch
fix_win32_synchronous_spellcheck.patch
add_electron_permission_types_to_blink.patch
chore_grandfather_in_electron_views_and_delegates.patch
refactor_patch_electron_permissiontypes_into_blink.patch
revert_views_remove_desktopwindowtreehostwin_window_enlargement.patch
fix_add_macos_memory_query_fallback_to_avoid_crash.patch
fix_resolve_dynamic_background_material_update_issue_on_windows_11.patch
feat_add_support_for_embedder_snapshot_validation.patch
chore_restore_some_deprecated_wrapper_utility_in_gin.patch
chore_add_electron_objects_to_wrappablepointertag.patch
gin_cppgc_transition_support.patch
chore_expose_isolate_parameter_in_script_lifecycle_observers.patch
revert_partial_remove_unused_prehandlemouseevent.patch
allow_electron_to_depend_on_components_os_crypt_sync.patch
expose_referrerscriptinfo_hostdefinedoptionsindex.patch
chore_disable_protocol_handler_dcheck.patch
fix_check_for_file_existence_before_setting_mtime.patch
fix_linux_tray_id.patch
expose_gtk_ui_platform_field.patch
patch_osr_control_screen_info.patch
fix_linux_app_identity.patch
refactor_allow_customizing_config_in_freedesktopsecretkeyprovider.patch
fix_wayland_test_crash_on_teardown.patch
fix_set_correct_app_id_on_linux.patch
fix_pass_trigger_for_global_shortcuts_on_wayland.patch
feat_plumb_node_integration_in_worker_through_workersettings.patch
fix_restore_sdk_inputs_cross-toolchain_deps_for_macos.patch
fix_use_fresh_lazynow_for_onendworkitemimpl_after_didruntask.patch

View File

@@ -1,20 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Charles Kerr <charles@charleskerr.com>
Date: Thu, 17 Apr 2025 19:07:23 -0500
Subject: refactor: patch electron PermissionTypes into blink
From: deepak1556 <hop2deep@gmail.com>
Date: Thu, 30 Jan 2025 20:28:38 +0900
Subject: feat: add Electron permission types to blink::PermissionType
6387077: [PermissionOptions] Generalize PermissionRequestDescription | https://chromium-review.googlesource.com/c/chromium/src/+/6387077
Adds Electron-specific values (FILE_SYSTEM, HID, SERIAL, USB,
OPEN_EXTERNAL, ELECTRON_FULLSCREEN, DEPRECATED_SYNC_CLIPBOARD_READ) to
the blink::PermissionType and mojom PermissionName enums, and wires
them through the switch statements in content's permission layer.
These types back session.setPermissionRequestHandler; after CL 6387077
generalized PermissionRequestDescription, our extension enum in
WebContentsPermissionHelper can no longer flow through content, so the
values must live in blink directly.
Also adds WebContentSettingsClient::AllowReadFromClipboardSync() and
routes document.execCommand('paste') through it so Electron can run a
synchronous permission check distinct from the async Clipboard API.
Not upstreamable. The DEPRECATED_SYNC_CLIPBOARD_READ type and sync
clipboard callback can be removed when support for the deprecated sync
clipboard API is dropped.
diff --git a/components/permissions/permission_util.cc b/components/permissions/permission_util.cc
index 727b73a37a3258aa44643d66dceba79017d9dbc8..b3d872be603b68bb7aa2af267f05212ae7efd46c 100644
index 2f6fbe5270245ddb1ef82f097ac1258781acb66e..b3d872be603b68bb7aa2af267f05212ae7efd46c 100644
--- a/components/permissions/permission_util.cc
+++ b/components/permissions/permission_util.cc
@@ -554,9 +554,17 @@ ContentSettingsType PermissionUtil::PermissionTypeToContentSettingsTypeSafe(
@@ -554,8 +554,17 @@ ContentSettingsType PermissionUtil::PermissionTypeToContentSettingsTypeSafe(
return ContentSettingsType::LOCAL_NETWORK;
case PermissionType::LOOPBACK_NETWORK:
return ContentSettingsType::LOOPBACK_NETWORK;
- case PermissionType::GEOLOCATION_APPROXIMATE:
- case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ: case PermissionType::NUM:
- case PermissionType::NUM:
+ // Permissions added by Electron
+ case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
+ case PermissionType::ELECTRON_FULLSCREEN:
@@ -30,15 +44,14 @@ index 727b73a37a3258aa44643d66dceba79017d9dbc8..b3d872be603b68bb7aa2af267f05212a
return ContentSettingsType::DEFAULT;
diff --git a/content/browser/permissions/permission_controller_impl.cc b/content/browser/permissions/permission_controller_impl.cc
index cb07f1755e152f0f3cd11e1757b8aa203e29fcc0..944835cc4f315e9fb6845e7caaadf42f6cb606e6 100644
index 30cf63190284f0f7c5d9a7c8f6b2e6b0956d0ec5..944835cc4f315e9fb6845e7caaadf42f6cb606e6 100644
--- a/content/browser/permissions/permission_controller_impl.cc
+++ b/content/browser/permissions/permission_controller_impl.cc
@@ -98,9 +98,15 @@ PermissionToSchedulingFeature(PermissionType permission_name) {
@@ -98,8 +98,15 @@ PermissionToSchedulingFeature(PermissionType permission_name) {
case PermissionType::LOCAL_NETWORK_ACCESS:
case PermissionType::LOCAL_NETWORK:
case PermissionType::LOOPBACK_NETWORK:
- case PermissionType::GEOLOCATION_APPROXIMATE:
- case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ: return std::nullopt;
- return std::nullopt;
- }
+ // Permissions added by Electron
+ case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
@@ -53,21 +66,18 @@ index cb07f1755e152f0f3cd11e1757b8aa203e29fcc0..944835cc4f315e9fb6845e7caaadf42f
#if !BUILDFLAG(IS_ANDROID)
diff --git a/content/browser/permissions/permission_descriptor_util.cc b/content/browser/permissions/permission_descriptor_util.cc
index d2ea06fa66c07baaf741382af40de154068a7d6b..3397e741fbc52ce45cd62dd3fe12e73b8c010c4b 100644
index 8acf00d2618d9a0552750f0f8e1d734b52f790b1..3397e741fbc52ce45cd62dd3fe12e73b8c010c4b 100644
--- a/content/browser/permissions/permission_descriptor_util.cc
+++ b/content/browser/permissions/permission_descriptor_util.cc
@@ -180,13 +180,27 @@ content::PermissionDescriptorUtil::CreatePermissionDescriptorForPermissionType(
@@ -180,8 +180,27 @@ content::PermissionDescriptorUtil::CreatePermissionDescriptorForPermissionType(
case blink::PermissionType::LOOPBACK_NETWORK:
return CreatePermissionDescriptor(
blink::mojom::PermissionName::LOOPBACK_NETWORK);
- case blink::PermissionType::GEOLOCATION_APPROXIMATE:
- return CreatePermissionDescriptor(
- blink::mojom::PermissionName::GEOLOCATION_APPROXIMATE);
+ // Permissions added by Electron
case blink::PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
return CreatePermissionDescriptor(
- blink::mojom::PermissionName::DEPRECATED_SYNC_CLIPBOARD_READ); case blink::PermissionType::NUM:
- case blink::PermissionType::NUM:
- NOTREACHED();
+ // Permissions added by Electron
+ case blink::PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
+ return CreatePermissionDescriptor(
+ blink::mojom::PermissionName::DEPRECATED_SYNC_CLIPBOARD_READ);
+ case blink::PermissionType::FILE_SYSTEM:
+ return CreatePermissionDescriptor(
@@ -90,18 +100,16 @@ index d2ea06fa66c07baaf741382af40de154068a7d6b..3397e741fbc52ce45cd62dd3fe12e73b
NOTREACHED();
}
diff --git a/third_party/blink/common/permissions/permission_utils.cc b/third_party/blink/common/permissions/permission_utils.cc
index a818b0b9a0eb3efdf8b2d851a6b51fccbfdad0fe..de25e8cf94b84c1c0c7b353f49070603b0f78370 100644
index 9c1b4762fe932618ec85a86a8367dce706d23c0b..de25e8cf94b84c1c0c7b353f49070603b0f78370 100644
--- a/third_party/blink/common/permissions/permission_utils.cc
+++ b/third_party/blink/common/permissions/permission_utils.cc
@@ -110,11 +110,21 @@ std::string GetPermissionString(PermissionType permission) {
@@ -110,8 +110,21 @@ std::string GetPermissionString(PermissionType permission) {
return "LocalNetwork";
case PermissionType::LOOPBACK_NETWORK:
return "LoopbackNetwork";
- case PermissionType::GEOLOCATION_APPROXIMATE:
- return "GeolocationApproximate";
case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
- return "DeprecatedSyncClipboardRead"; case PermissionType::NUM:
- case PermissionType::NUM:
- NOTREACHED();
+ case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
+ return "DeprecatedSyncClipboardRead";
+ case PermissionType::FILE_SYSTEM:
+ return "FileSystem";
@@ -119,13 +127,13 @@ index a818b0b9a0eb3efdf8b2d851a6b51fccbfdad0fe..de25e8cf94b84c1c0c7b353f49070603
}
NOTREACHED();
}
@@ -194,7 +204,15 @@ PermissionTypeToPermissionsPolicyFeature(PermissionType permission) {
@@ -191,6 +204,15 @@ PermissionTypeToPermissionsPolicyFeature(PermissionType permission) {
case PermissionType::NOTIFICATIONS:
case PermissionType::KEYBOARD_LOCK:
case PermissionType::POINTER_LOCK:
+
+ // Permissions added by Electron
case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
+ case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
+ case PermissionType::ELECTRON_FULLSCREEN:
+ case PermissionType::FILE_SYSTEM:
+ case PermissionType::HID:
@@ -135,7 +143,7 @@ index a818b0b9a0eb3efdf8b2d851a6b51fccbfdad0fe..de25e8cf94b84c1c0c7b353f49070603
return std::nullopt;
case PermissionType::NUM:
@@ -372,6 +390,21 @@ std::optional<PermissionType> PermissionDescriptorInfoToPermissionType(
@@ -368,6 +390,21 @@ std::optional<PermissionType> PermissionDescriptorInfoToPermissionType(
return PermissionType::WEB_PRINTING;
case PermissionName::SMART_CARD:
return PermissionType::SMART_CARD;
@@ -158,16 +166,14 @@ index a818b0b9a0eb3efdf8b2d851a6b51fccbfdad0fe..de25e8cf94b84c1c0c7b353f49070603
}
diff --git a/third_party/blink/public/common/permissions/permission_utils.h b/third_party/blink/public/common/permissions/permission_utils.h
index 31158388db2df745af999adc9d07fc9272a2d6f8..fed5994c8563792405838d8923d3502aedbe85a2 100644
index b124d53fdd245f055f57ad00250112e2637e1cd1..fed5994c8563792405838d8923d3502aedbe85a2 100644
--- a/third_party/blink/public/common/permissions/permission_utils.h
+++ b/third_party/blink/public/common/permissions/permission_utils.h
@@ -69,8 +69,17 @@ enum class PermissionType {
LOCAL_NETWORK = 44,
@@ -70,7 +70,16 @@ enum class PermissionType {
LOOPBACK_NETWORK = 45,
GEOLOCATION_APPROXIMATE = 46,
- DEPRECATED_SYNC_CLIPBOARD_READ = 47,
- // Always keep this at the end.
+
+ // Permissions added by Electron
+ ELECTRON_FIRST = 47,
+ DEPRECATED_SYNC_CLIPBOARD_READ = ELECTRON_FIRST,
@@ -182,14 +188,14 @@ index 31158388db2df745af999adc9d07fc9272a2d6f8..fed5994c8563792405838d8923d3502a
MIN_VALUE = MIDI_SYSEX,
};
diff --git a/third_party/blink/public/mojom/permissions/permission.mojom b/third_party/blink/public/mojom/permissions/permission.mojom
index a25299b7222d43b6c4b4a5c18085171dbc322ec1..eb98bc0dad9a0448ef3f6222a604032d93a487bc 100644
index 7e5ab8bcc4756d3cf16594b69bd25d3df709e7cc..eb98bc0dad9a0448ef3f6222a604032d93a487bc 100644
--- a/third_party/blink/public/mojom/permissions/permission.mojom
+++ b/third_party/blink/public/mojom/permissions/permission.mojom
@@ -47,8 +47,16 @@ enum PermissionName {
WEB_PRINTING,
SMART_CARD,
GEOLOCATION_APPROXIMATE,
- DEPRECATED_SYNC_CLIPBOARD_READ};
-};
+ // Permissions added by Electron
+ DEPRECATED_SYNC_CLIPBOARD_READ,
@@ -203,18 +209,54 @@ index a25299b7222d43b6c4b4a5c18085171dbc322ec1..eb98bc0dad9a0448ef3f6222a604032d
struct MidiPermissionDescriptor {
bool sysex;
};
diff --git a/third_party/blink/public/platform/web_content_settings_client.h b/third_party/blink/public/platform/web_content_settings_client.h
index 36410ff29d9c82e59f93fbb82968064bd330dfde..6c3f994e0b184f78bd9442002bb4dfae66e50518 100644
--- a/third_party/blink/public/platform/web_content_settings_client.h
+++ b/third_party/blink/public/platform/web_content_settings_client.h
@@ -54,6 +54,9 @@ class WebContentSettingsClient {
// Controls whether access to write the clipboard is allowed for this frame.
virtual bool AllowWriteToClipboard() { return false; }
+ // Controls whether synchronous access to read the clipboard is allowed for this frame.
+ virtual bool AllowReadFromClipboardSync() { return false; }
+
// Reports that passive mixed content was found at the provided URL.
virtual void PassiveInsecureContentFound(const WebURL&) {}
diff --git a/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc b/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
index 8fded9303e74737d82ca6d54e00807ebabf6c1ac..c0b66eb9a62f8f75e3c4de43f467ddd09d8dc2d6 100644
--- a/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
+++ b/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
@@ -123,7 +123,7 @@ bool ClipboardCommands::CanReadClipboard(LocalFrame& frame,
return true;
}
return frame.GetContentSettingsClient() &&
- frame.GetContentSettingsClient()->AllowReadFromClipboard();
+ frame.GetContentSettingsClient()->AllowReadFromClipboardSync();
}
bool ClipboardCommands::CanWriteClipboard(LocalFrame& frame,
@@ -312,7 +312,7 @@ bool ClipboardCommands::PasteSupported(LocalFrame* frame) {
return true;
}
return frame->GetContentSettingsClient() &&
- frame->GetContentSettingsClient()->AllowReadFromClipboard();
+ frame->GetContentSettingsClient()->AllowReadFromClipboardSync();
}
bool ClipboardCommands::ExecuteCopy(LocalFrame& frame,
diff --git a/third_party/blink/renderer/modules/permissions/permission_utils.cc b/third_party/blink/renderer/modules/permissions/permission_utils.cc
index e9b7dcb070567580e8c6ad11b2bb943083e804f6..898efc336171ba6e33788dc754afaa47e3928f9e 100644
index 27cdc852f5974951f0a10157a0473e67791f6688..898efc336171ba6e33788dc754afaa47e3928f9e 100644
--- a/third_party/blink/renderer/modules/permissions/permission_utils.cc
+++ b/third_party/blink/renderer/modules/permissions/permission_utils.cc
@@ -151,8 +151,22 @@ String PermissionNameToString(PermissionName name) {
@@ -151,6 +151,22 @@ String PermissionNameToString(PermissionName name) {
return "web-printing";
case PermissionName::SMART_CARD:
return "smart-card";
+
+ // Permissions added by Electron
case PermissionName::DEPRECATED_SYNC_CLIPBOARD_READ:
return "deprecated-sync-clipboard-read";
+ case PermissionName::DEPRECATED_SYNC_CLIPBOARD_READ:
+ return "deprecated-sync-clipboard-read";
+ case PermissionName::FILE_SYSTEM:
+ return "file-system";
+ case PermissionName::ELECTRON_FULLSCREEN:

View File

@@ -1,14 +1,43 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Apthorp <nornagon@nornagon.net>
Date: Wed, 15 Jan 2020 16:35:18 -0800
Subject: add DidInstallConditionalFeatures
Subject: feat: add script lifecycle observer hooks for Node integration
This adds a hook on script context creation _after conditional features
have been installed_. Electron uses this to run preload scripts and
various other initialization. This is necessary because at the time
DidCreateScriptContext is called, not all JS APIs are available in the
context, which can cause some preload scripts to trip.
Adds script context lifecycle hooks in Blink and content/ that Electron
needs to set up and tear down Node.js integration at the correct moments.
DidInstallConditionalFeatures fires after a frame's conditional features
are installed; preload scripts run here instead of DidCreateScriptContext
since not all JS APIs exist at that earlier point.
WorkerScriptReadyForEvaluation fires once a worker scope is fully ready;
WorkerContextCreated fires too early under off-main-thread fetch, before
globals like `location` are safe to access.
WorkerContextWillDestroy fires before worker teardown for Node cleanup.
An attempt to upstream the worker-destroy hook was rejected:
https://chromium-review.googlesource.com/c/chromium/src/+/1954347
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h
index 1f6c015c361b3146db760643e3670a110634d75b..d64fef6bfc37264dcdc1bbea22eb5c4e099553dd 100644
--- a/content/public/renderer/content_renderer_client.h
+++ b/content/public/renderer/content_renderer_client.h
@@ -414,6 +414,16 @@ class CONTENT_EXPORT ContentRendererClient {
virtual void DidInitializeWorkerContextOnWorkerThread(
v8::Local<v8::Context> context) {}
+ // Notifies that a worker script has been downloaded, scope initialized and
+ // ready for evaluation. This function is called from the worker thread.
+ virtual void WorkerScriptReadyForEvaluationOnWorkerThread(
+ v8::Local<v8::Context> context) {}
+
+ // Notifies that a worker context will be destroyed. This function is called
+ // from the worker thread.
+ virtual void WillDestroyWorkerContextOnWorkerThread(
+ v8::Local<v8::Context> context) {}
+
// Overwrites the given URL to use an HTML5 embed if possible.
// An empty URL is returned if the URL is not overriden.
virtual GURL OverrideFlashEmbedWithHTML(const GURL& url);
diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h
index 8077ed85e45e56d6cccb691223216c1f6a94b5ee..dd4cee346f16df703d414bf206bbe6c9f4b1f796 100644
--- a/content/public/renderer/render_frame_observer.h
@@ -52,6 +81,63 @@ index c803bf1d93bb9aabf0f9098c4d58aa7528d18d79..ced097d57cec93b3d3062a6d7d9f7d03
void WillReleaseScriptContext(v8::Local<v8::Context> context,
int world_id) override;
void DidChangeScrollOffset() override;
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index 78f0ab75486f90ad9bda568cd28c20ec0c48f298..bfc88be930331b75be718fe3f7017f7ec477b086 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -922,12 +922,24 @@ void RendererBlinkPlatformImpl::WillStopWorkerThread() {
WorkerThreadRegistry::Instance()->WillStopCurrentWorkerThread();
}
+void RendererBlinkPlatformImpl::WorkerContextWillDestroy(
+ const v8::Local<v8::Context>& worker) {
+ GetContentClient()->renderer()->WillDestroyWorkerContextOnWorkerThread(
+ worker);
+}
+
void RendererBlinkPlatformImpl::WorkerContextCreated(
const v8::Local<v8::Context>& worker) {
GetContentClient()->renderer()->DidInitializeWorkerContextOnWorkerThread(
worker);
}
+void RendererBlinkPlatformImpl::WorkerScriptReadyForEvaluation(
+ const v8::Local<v8::Context>& worker) {
+ GetContentClient()->renderer()->WorkerScriptReadyForEvaluationOnWorkerThread(
+ worker);
+}
+
bool RendererBlinkPlatformImpl::AllowScriptExtensionForServiceWorker(
const blink::WebSecurityOrigin& script_origin) {
return GetContentClient()->renderer()->AllowScriptExtensionForServiceWorker(
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index 4535d0bf0328301f6ed1a602f6ff97a0243f7685..826134f19df305cb79598739174bc09808ea472e 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -209,6 +209,9 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
void DidStartWorkerThread() override;
void WillStopWorkerThread() override;
void WorkerContextCreated(const v8::Local<v8::Context>& worker) override;
+ void WorkerScriptReadyForEvaluation(
+ const v8::Local<v8::Context>& worker) override;
+ void WorkerContextWillDestroy(const v8::Local<v8::Context>& worker) override;
bool AllowScriptExtensionForServiceWorker(
const blink::WebSecurityOrigin& script_origin) override;
blink::ProtocolHandlerSecurityLevel GetProtocolHandlerSecurityLevel(
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h
index a26e45d64229f692efb4a218c653afc212788d1f..ae463faa3d16ab2697a4c20f3b038755205188f7 100644
--- a/third_party/blink/public/platform/platform.h
+++ b/third_party/blink/public/platform/platform.h
@@ -685,6 +685,9 @@ class BLINK_PLATFORM_EXPORT Platform {
virtual void DidStartWorkerThread() {}
virtual void WillStopWorkerThread() {}
virtual void WorkerContextCreated(const v8::Local<v8::Context>& worker) {}
+ virtual void WorkerScriptReadyForEvaluation(
+ const v8::Local<v8::Context>& worker) {}
+ virtual void WorkerContextWillDestroy(const v8::Local<v8::Context>& worker) {}
virtual bool AllowScriptExtensionForServiceWorker(
const WebSecurityOrigin& script_origin) {
return false;
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h
index 7e5f1d80ff5395ea11eb558acabe63ccc3e5a17e..d241042fc37ffe4a2afecbc3c02e89f18e990929 100644
--- a/third_party/blink/public/web/web_local_frame_client.h
@@ -78,6 +164,18 @@ index d293c49e6774de889fa9959234c82b41a4b1efe1..0787bc8a602c60e5b42933813baa6b9d
if (World().IsMainWorld()) {
probe::DidCreateMainWorldContext(GetFrame());
diff --git a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
index 7425989e1cef93269262a5c9468fd3b7bddac3ea..bbacc5da2399dbdc74c9b6f912482b2168168136 100644
--- a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
+++ b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
@@ -294,6 +294,7 @@ void WorkerOrWorkletScriptController::PrepareForEvaluation() {
V8PerContextData* per_context_data = script_state_->PerContextData();
std::ignore =
per_context_data->ConstructorForType(global_scope_->GetWrapperTypeInfo());
+ Platform::Current()->WorkerScriptReadyForEvaluation(script_state_->GetContext());
// Inform V8 that origin trial information is now connected with the context,
// and V8 can extend the context with origin trial features.
isolate_->InstallConditionalFeatures(script_state_->GetContext());
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h
index 52cc48e0099ded3686c6fc056514b6446afcae5d..a6331653b0aaf30cedba6ff6df787aa944142ac4 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -135,3 +233,20 @@ index 1f9061d660d7395a6a9e32d783228fc5ae85c898..f762722e2e2a27db2488aae25d78e795
void WillReleaseScriptContext(v8::Local<v8::Context>,
int32_t world_id) override {}
bool AllowScriptExtensions() override { return false; }
diff --git a/third_party/blink/renderer/core/workers/worker_thread.cc b/third_party/blink/renderer/core/workers/worker_thread.cc
index ef25707a97c4d7619da664fe5908681c8f659ad8..fa81395d6df143b31e4ae28dc9104a9149c0d91a 100644
--- a/third_party/blink/renderer/core/workers/worker_thread.cc
+++ b/third_party/blink/renderer/core/workers/worker_thread.cc
@@ -803,6 +803,12 @@ void WorkerThread::PrepareForShutdownOnWorkerThread() {
}
pause_handle_.reset();
+ {
+ v8::HandleScope handle_scope(GetIsolate());
+ Platform::Current()->WorkerContextWillDestroy(
+ GlobalScope()->ScriptController()->GetContext());
+ }
+
if (WorkerThreadDebugger* debugger = WorkerThreadDebugger::From(GetIsolate()))
debugger->WorkerThreadDestroyed(this);

View File

@@ -1,27 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Apthorp <nornagon@nornagon.net>
Date: Mon, 26 Aug 2019 12:02:51 -0700
Subject: allow new privileges in unsandboxed child processes
This allows unsandboxed child process to launch setuid processes on Linux.
diff --git a/content/browser/child_process_launcher_helper_linux.cc b/content/browser/child_process_launcher_helper_linux.cc
index b6f5667c86c3e74807728aa2dbb61fee87e6156a..492a0822181aebbede38f7783a457b820ce4f8d1 100644
--- a/content/browser/child_process_launcher_helper_linux.cc
+++ b/content/browser/child_process_launcher_helper_linux.cc
@@ -65,6 +65,15 @@ bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
options->fds_to_remap.emplace_back(sandbox_fd, GetSandboxFD());
}
+ // (For Electron), if we're launching without zygote, that means we're
+ // launching an unsandboxed process (since all sandboxed processes are
+ // forked from the zygote). Relax the allow_new_privs option to permit
+ // launching suid processes from unsandboxed child processes.
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoZygote) &&
+ delegate_->GetZygote() == nullptr) {
+ options->allow_new_privs = true;
+ }
+
options->environment = delegate_->GetEnvironment();
} else {
DCHECK(GetZygoteForLaunch());

View File

@@ -1,17 +1,21 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <sattard@slack-corp.com>
Date: Thu, 27 May 2021 17:21:07 -0700
Subject: build: do not depend on packed_resource_integrity
From: Jeremy Apthorp <nornagon@nornagon.net>
Date: Thu, 20 Sep 2018 17:48:59 -0700
Subject: build: configure resource packing for Electron's .pak layout
This ensures we do not depend on a target that does not exist when
building Electron, electron generates its own .pak files via
electron_repack and therefore this integrity target which is generated
by the chrome_paks target does not exist. This can not be upstreamed,
if we ever align our .pak file generation with Chrome we can remove this
patch.
Electron generates its own .pak files via //electron:packed_resources
rather than using chrome_paks(). This patch (1) swaps the //chrome
packed_resources target for a proxy group pointing at Electron's when
is_electron_build, avoiding GN duplicate-output errors on the hardcoded
chrome_*.pak paths on Win/Linux; (2) drops deps on the
packed_resources_integrity_header target, which is only produced by the
chrome_paks template we never invoke; and (3) registers
electron_resources.grd in resource_ids.spec so GRIT assigns Electron's
strings/includes non-colliding IDs. Not upstreamable; removable if we
ever align our .pak generation with Chrome's.
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index 74aadd24a27d31291bb42d452ff247bbf6dad14a..a0d74156745c0d22a332b2547c59b98d1ae8a7c5 100644
index d8f51269f5edb6fa698bc40abb3900a551f2ab0d..a0d74156745c0d22a332b2547c59b98d1ae8a7c5 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -201,11 +201,16 @@ if (!is_android && !is_mac) {
@@ -32,6 +36,28 @@ index 74aadd24a27d31291bb42d452ff247bbf6dad14a..a0d74156745c0d22a332b2547c59b98d
":visual_elements_resources",
"//base",
"//build:branding_buildflags",
@@ -1550,7 +1555,7 @@ if (is_chrome_branded && !is_android) {
}
}
-if (!is_android) {
+if (!is_android && !is_electron_build) {
chrome_paks("packed_resources") {
if (is_mac) {
output_dir = "$root_gen_dir/repack"
@@ -1596,6 +1601,12 @@ repack("browser_tests_pak") {
deps = [ "//chrome/test/data/webui:resources" ]
}
+if (is_electron_build) {
+ group("packed_resources") {
+ public_deps = [ "//electron:packed_resources" ]
+ }
+}
+
group("strings") {
public_deps = [
"//chrome/app:branded_strings",
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index f195e70c33b1a88e44f8ad51be6573d609d91b7f..a9195e0149385e7ffc95eb809bc30256683861d7 100644
--- a/chrome/browser/BUILD.gn
@@ -82,3 +108,19 @@ index cf7e31b7b1b8eab0e82a669902dc37020f74195a..dfeb9048a85ab2076259c01687d30c2c
"//chrome/browser/apps:icon_standardizer",
"//chrome/browser/apps/app_service",
"//chrome/browser/apps/app_service:app_registry_cache_waiter",
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
index bc4d99704dcdb1f2d688fb6d847304ac7a45d3a8..5087a431bb9bd1fba7779f01c738c9d19cbfb63c 100644
--- a/tools/gritsettings/resource_ids.spec
+++ b/tools/gritsettings/resource_ids.spec
@@ -1661,6 +1661,11 @@
"includes": [12000],
},
+ "electron/build/electron_resources.grd": {
+ "messages": [31750],
+ "includes": [31950],
+ }
+
# END "everything else" section.
# Everything but chrome/, components/, content/, and ios/

View File

@@ -1,238 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 20 Sep 2018 17:45:32 -0700
Subject: can_create_window.patch
This adds a hook to the window creation flow so that Electron can intercede and
potentially prevent a window from being created.
TODO(loc): this patch is currently broken.
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 4e7b516f145312e353f112499b2792b27207d84b..222cf1b2bbc98aa5e271426478a774f8a48e693d 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -10125,6 +10125,7 @@ void RenderFrameHostImpl::CreateNewWindow(
last_committed_origin_, params->window_container_type,
params->target_url, params->referrer.To<Referrer>(),
params->frame_name, params->disposition, *params->features,
+ params->raw_features, params->body,
effective_transient_activation_state, params->opener_suppressed,
&no_javascript_access);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index b0f3579f18f3b6dd5a9b328324348770319ccf67..1567ac2a65d222080430a47dce97b6d387ebe49d 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -5385,6 +5385,10 @@ FrameTree* WebContentsImpl::CreateNewWindow(
create_params.initially_hidden = renderer_started_hidden;
create_params.initial_popup_url = params.target_url;
+ // Potentially allow the delegate to override the create_params.
+ if (delegate_)
+ delegate_->MaybeOverrideCreateParamsForNewWindow(&create_params);
+
// Even though all codepaths leading here are in response to a renderer
// trying to open a new window, if the new window ends up in a different
// browsing instance, then the RenderViewHost, RenderWidgetHost,
@@ -5439,6 +5443,12 @@ FrameTree* WebContentsImpl::CreateNewWindow(
// Sets the newly created WebContents WindowOpenDisposition.
new_contents_impl->original_window_open_disposition_ = params.disposition;
+ if (delegate_) {
+ delegate_->WebContentsCreatedWithFullParams(this, render_process_id,
+ opener->GetRoutingID(),
+ params, new_contents_impl);
+ }
+
// If the new frame has a name, make sure any SiteInstances that can find
// this named frame have proxies for it. Must be called after
// SetSessionStorageNamespace, since this calls CreateRenderView, which uses
@@ -5480,12 +5490,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
AddWebContentsDestructionObserver(new_contents_impl);
}
- if (delegate_) {
- delegate_->WebContentsCreated(this, render_process_id,
- opener->GetRoutingID(), params.frame_name,
- params.target_url, new_contents_impl);
- }
-
observers_.NotifyObservers(&WebContentsObserver::DidOpenRequestedURL,
new_contents_impl, opener, params.target_url,
params.referrer.To<Referrer>(), params.disposition,
diff --git a/content/common/frame.mojom b/content/common/frame.mojom
index 19dbb921c9644522588ff74d0a1925f826736957..4e7b36729741a79cfdf04f89a8ec615d3148b294 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -658,6 +658,10 @@ struct CreateNewWindowParams {
pending_associated_remote<blink.mojom.Widget> widget;
pending_associated_receiver<blink.mojom.FrameWidgetHost> frame_widget_host;
pending_associated_remote<blink.mojom.FrameWidget> frame_widget;
+
+ // Extra fields added by Electron.
+ string raw_features;
+ network.mojom.URLRequestBody? body;
};
// Operation result when the renderer asks the browser to create a new window.
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index d2dccc29b0e13ab5c87b4c6803e79dc781e52ea2..be6639ef1a7eebb147afee483a35898d1ea5d95f 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -877,6 +877,8 @@ bool ContentBrowserClient::CanCreateWindow(
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
+ const std::string& raw_features,
+ const scoped_refptr<network::ResourceRequestBody>& body,
bool user_gesture,
bool opener_suppressed,
bool* no_javascript_access) {
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 3b6c42b2c4cd5d9e5753af25b27925ff0d933568..e6f51d39b4f2f6b162814996921958ca1252e1d7 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -205,6 +205,7 @@ class NetworkService;
class TrustedURLLoaderHeaderClient;
} // namespace mojom
struct ResourceRequest;
+class ResourceRequestBody;
} // namespace network
namespace sandbox {
@@ -1468,6 +1469,8 @@ class CONTENT_EXPORT ContentBrowserClient {
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
+ const std::string& raw_features,
+ const scoped_refptr<network::ResourceRequestBody>& body,
bool user_gesture,
bool opener_suppressed,
bool* no_javascript_access);
diff --git a/content/public/browser/web_contents_delegate.cc b/content/public/browser/web_contents_delegate.cc
index 0c0672e0a2d05d5dff31ae171f1a3af1d20b3019..51be0b86d083318f01a9ebe76fb7d1fb60cd72fd 100644
--- a/content/public/browser/web_contents_delegate.cc
+++ b/content/public/browser/web_contents_delegate.cc
@@ -34,6 +34,17 @@ namespace content {
WebContentsDelegate::WebContentsDelegate() = default;
+void WebContentsDelegate::WebContentsCreatedWithFullParams(
+ WebContents* source_contents,
+ int opener_render_process_id,
+ int opener_render_frame_id,
+ const mojom::CreateNewWindowParams& params,
+ WebContents* new_contents) {
+ WebContentsCreated(source_contents, opener_render_process_id,
+ opener_render_frame_id, params.frame_name,
+ params.target_url, new_contents);
+}
+
WebContents* WebContentsDelegate::OpenURLFromTab(
WebContents* source,
const OpenURLParams& params,
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h
index 0650197909d484b8a0f48ab61b22471c71bce0e8..29c380d7845aab1a7b3417e0d3940ea00460260b 100644
--- a/content/public/browser/web_contents_delegate.h
+++ b/content/public/browser/web_contents_delegate.h
@@ -18,6 +18,7 @@
#include "base/types/expected.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
+#include "content/common/frame.mojom.h"
#include "content/public/browser/eye_dropper.h"
#include "content/public/browser/fullscreen_types.h"
#include "content/public/browser/invalidate_type.h"
@@ -29,6 +30,7 @@
#include "content/public/browser/select_audio_output_request.h"
#include "content/public/browser/serial_chooser.h"
#include "content/public/browser/storage_partition_config.h"
+#include "content/public/browser/web_contents.h"
#include "content/public/common/window_container_type.mojom-forward.h"
#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/public/common/page/drag_operation.h"
@@ -402,6 +404,16 @@ class CONTENT_EXPORT WebContentsDelegate {
const StoragePartitionConfig& partition_config,
SessionStorageNamespace* session_storage_namespace);
+ virtual void WebContentsCreatedWithFullParams(
+ WebContents* source_contents,
+ int opener_render_process_id,
+ int opener_render_frame_id,
+ const mojom::CreateNewWindowParams& params,
+ WebContents* new_contents);
+
+ virtual void MaybeOverrideCreateParamsForNewWindow(
+ content::WebContents::CreateParams* create_params) {}
+
// Notifies the delegate about the creation of a new WebContents. This
// typically happens when popups are created.
virtual void WebContentsCreated(WebContents* source_contents,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 6ee766c52202804adc532b1585224b4e35239f9a..42a0a7e5be01fe346cc2ad83d3395425a41e1699 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -6879,6 +6879,10 @@ WebView* RenderFrameImpl::CreateNewWindow(
params->started_by_ad =
GetWebFrame()->IsAdFrame() || GetWebFrame()->IsAdScriptInStack();
+ params->raw_features = features.raw_features.Utf8(
+ WebString::UTF8ConversionMode::kStrictReplacingErrorsWithFFFD);
+ params->body = GetRequestBodyForWebURLRequest(request);
+
// We preserve this information before sending the message since |params| is
// moved on send.
bool is_background_tab =
diff --git a/content/web_test/browser/web_test_content_browser_client.cc b/content/web_test/browser/web_test_content_browser_client.cc
index 7a57cb3a1414a77704c42ae01a9dc89fae4ad4a3..769601c2749f0781317f668cf806042db626c348 100644
--- a/content/web_test/browser/web_test_content_browser_client.cc
+++ b/content/web_test/browser/web_test_content_browser_client.cc
@@ -539,6 +539,8 @@ bool WebTestContentBrowserClient::CanCreateWindow(
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
+ const std::string& raw_features,
+ const scoped_refptr<network::ResourceRequestBody>& body,
bool user_gesture,
bool opener_suppressed,
bool* no_javascript_access) {
diff --git a/content/web_test/browser/web_test_content_browser_client.h b/content/web_test/browser/web_test_content_browser_client.h
index 25e88c235485f75831bc67d72e9c10f67561ba99..f64dd47225c47407bef3a6d942903ee8b7a4cf20 100644
--- a/content/web_test/browser/web_test_content_browser_client.h
+++ b/content/web_test/browser/web_test_content_browser_client.h
@@ -101,6 +101,8 @@ class WebTestContentBrowserClient : public ShellContentBrowserClient {
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
+ const std::string& raw_features,
+ const scoped_refptr<network::ResourceRequestBody>& body,
bool user_gesture,
bool opener_suppressed,
bool* no_javascript_access) override;
diff --git a/third_party/blink/public/web/web_window_features.h b/third_party/blink/public/web/web_window_features.h
index d92bab531c12c62a5321a23f4a0cb89691668127..2060e04795ba8e7a923fd0fe3485b8c553ca4421 100644
--- a/third_party/blink/public/web/web_window_features.h
+++ b/third_party/blink/public/web/web_window_features.h
@@ -70,6 +70,8 @@ struct WebWindowFeatures {
// TODO(apaseltiner): Investigate moving this field to a non-public struct
// since it is only needed within //third_party/blink.
std::optional<std::vector<WebString>> attribution_srcs;
+
+ WebString raw_features;
};
} // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index 715ca6e188c7e821478fcbaa4496efd25a673c61..e58465eb936b2a8b3479201ec24580501f7fc2f3 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -2341,6 +2341,8 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
WebWindowFeatures window_features =
GetWindowFeaturesFromString(features, entered_window);
+ window_features.raw_features = features;
+
// In fenced frames, we should always use `noopener`.
if (GetFrame()->IsInFencedFrameTree()) {
window_features.noopener = true;

View File

@@ -1,35 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Wed, 20 Aug 2025 04:03:11 +0900
Subject: chore: add electron objects to WrappablePointerTag
Extends gin::WrappablePointerTag with tags needed for
electron objects that extend gin::Wrappable and gets
allocated on the cpp heap
diff --git a/gin/public/wrappable_pointer_tags.h b/gin/public/wrappable_pointer_tags.h
index fee622ebde42211de6f702b754cfa38595df5a1c..6b524632ebb405e473cf4fe8e253bd13bf7b67e5 100644
--- a/gin/public/wrappable_pointer_tags.h
+++ b/gin/public/wrappable_pointer_tags.h
@@ -77,7 +77,20 @@ enum WrappablePointerTag : uint16_t {
kWebAXObjectProxy, // content::WebAXObjectProxy
kWrappedExceptionHandler, // extensions::WrappedExceptionHandler
kIndigoContext, // indigo::IndigoContext
- kLastPointerTag = kIndigoContext,
+ kElectronApp, // electron::api::App
+ kElectronDataPipeHolder, // electron::api::DataPipeHolder
+ kElectronDebugger, // electron::api::Debugger
+ kElectronEvent, // gin_helper::internal::Event
+ kElectronMenu, // electron::api::Menu
+ kElectronNetLog, // electron::api::NetLog
+ kElectronPowerMonitor, // electron::api::PowerMonitor
+ kElectronPowerSaveBlocker, // electron::api::PowerSaveBlocker
+ kElectronReplyChannel, // gin_helper::internal::ReplyChannel
+ kElectronScreen, // electron::api::Screen
+ kElectronSession, // electron::api::Session
+ kElectronTray, // electron::api::Tray
+ kElectronWebRequest, // electron::api::WebRequest
+ kLastPointerTag = kElectronWebRequest,
};
static_assert(kLastPointerTag <

View File

@@ -1,11 +1,103 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Charles Kerr <charles@charleskerr.com>
Date: Wed, 17 May 2023 14:42:09 -0500
Subject: chore: patch out Profile methods
From: deepak1556 <hop2deep@gmail.com>
Date: Thu, 18 Oct 2018 17:07:12 -0700
Subject: chore: stub out //chrome Profile dependencies
Electron does not support Profiles, so we need to patch it out of any
code that we use.
Electron's BrowserContext does not derive from //chrome's Profile
class, so code we reuse from //chrome that calls
Profile::FromBrowserContext or queries Profile-type state (incognito,
guest, system profile) will not compile. This guards out those call
sites in ProxyConfigMonitor, ProfileKeyedServiceFactory,
ProfileSelections, the spellchecker service, PDF viewer utilities, and
the Windows titlebar config so Electron can link the surrounding code.
The long-term fix is to componentize the affected //chrome code so it
accepts a content::BrowserContext or PrefService directly.
diff --git a/chrome/browser/net/proxy_config_monitor.cc b/chrome/browser/net/proxy_config_monitor.cc
index 50e7a07af841ff55cd24c0a79eef5dcc68807933..ed40ecdb91ddd7139f8f463809594ddfca793fcc 100644
--- a/chrome/browser/net/proxy_config_monitor.cc
+++ b/chrome/browser/net/proxy_config_monitor.cc
@@ -11,7 +11,9 @@
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/net/proxy_service_factory.h"
+#if 0
#include "chrome/browser/profiles/profile.h"
+#endif
#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
@@ -21,12 +23,13 @@
#include "chrome/browser/ash/profiles/profile_helper.h"
#endif // BUILDFLAG(IS_CHROMEOS)
-#if BUILDFLAG(ENABLE_EXTENSIONS_CORE)
+#if 0
#include "chrome/browser/extensions/api/proxy/proxy_api.h"
#endif // BUILDFLAG(ENABLE_EXTENSIONS_CORE)
using content::BrowserThread;
+#if 0
ProxyConfigMonitor::ProxyConfigMonitor(Profile* profile) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(profile);
@@ -57,6 +60,7 @@ ProxyConfigMonitor::ProxyConfigMonitor(Profile* profile) {
proxy_config_service_->AddObserver(this);
}
+#endif
ProxyConfigMonitor::ProxyConfigMonitor(PrefService* local_state) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
@@ -135,8 +139,10 @@ void ProxyConfigMonitor::OnLazyProxyConfigPoll() {
void ProxyConfigMonitor::OnPACScriptError(int32_t line_number,
const std::string& details) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+#if 0
extensions::ProxyEventRouter::GetInstance()->OnPACScriptError(
profile_, line_number, base::UTF8ToUTF16(details));
+#endif
}
void ProxyConfigMonitor::OnRequestMaybeFailedDueToProxySettings(
@@ -151,7 +157,9 @@ void ProxyConfigMonitor::OnRequestMaybeFailedDueToProxySettings(
return;
}
+#if 0
extensions::ProxyEventRouter::GetInstance()->OnProxyError(profile_,
net_error);
+#endif
}
#endif // BUILDFLAG(ENABLE_EXTENSIONS_CORE)
diff --git a/chrome/browser/net/proxy_config_monitor.h b/chrome/browser/net/proxy_config_monitor.h
index 6c060b52d25799c6a7c4e4ee86ed7490060560d6..c81481a4451ff50b6ace5372a68b8615819affb3 100644
--- a/chrome/browser/net/proxy_config_monitor.h
+++ b/chrome/browser/net/proxy_config_monitor.h
@@ -40,11 +40,12 @@ class ProxyConfigMonitor : public net::ProxyConfigService::Observer,
{
public:
+#if 0
// Creates a ProxyConfigMonitor that gets proxy settings from |profile| and
// watches for changes. The created ProxyConfigMonitor must be destroyed
// before |profile|.
explicit ProxyConfigMonitor(Profile* profile);
-
+#endif
// Creates a ProxyConfigMonitor that gets proxy settings from the
// |local_state|, for use with NetworkContexts not
// associated with a profile. Must be destroyed before |local_state|.
@@ -94,7 +95,7 @@ class ProxyConfigMonitor : public net::ProxyConfigService::Observer,
#if BUILDFLAG(ENABLE_EXTENSIONS_CORE)
mojo::ReceiverSet<network::mojom::ProxyErrorClient> error_receiver_set_;
- raw_ptr<Profile> profile_ = nullptr;
+ // raw_ptr<Profile> profile_ = nullptr;
#endif // BUILDFLAG(ENABLE_EXTENSIONS_CORE)
};
diff --git a/chrome/browser/pdf/chrome_pdf_stream_delegate.cc b/chrome/browser/pdf/chrome_pdf_stream_delegate.cc
index 21d5ab99800c0830cc31ec4ebb24e3f05cd904d8..3f8f514519d6e4a0abe3690f5df35de8ffae6fd4 100644
--- a/chrome/browser/pdf/chrome_pdf_stream_delegate.cc
@@ -78,8 +170,22 @@ index 6f0d11aaf59d1f84b24a5cf33690035b84288f55..64d41eb402b0199d99ec6e37747a1a1a
}
} // namespace pdf_extension_util
diff --git a/chrome/browser/profiles/profile_keyed_service_factory.cc b/chrome/browser/profiles/profile_keyed_service_factory.cc
index 30a7e6a641e7b17a47fb5c66fb44d3d5899b9e78..85764a533585df0abe398758e4fd510c711de375 100644
--- a/chrome/browser/profiles/profile_keyed_service_factory.cc
+++ b/chrome/browser/profiles/profile_keyed_service_factory.cc
@@ -22,6 +22,9 @@ ProfileKeyedServiceFactory::~ProfileKeyedServiceFactory() = default;
content::BrowserContext* ProfileKeyedServiceFactory::GetBrowserContextToUse(
content::BrowserContext* context) const {
+ return context;
+#if 0
Profile* profile = Profile::FromBrowserContext(context);
return profile_selections_.ApplyProfileSelection(profile);
+#endif
}
diff --git a/chrome/browser/profiles/profile_selections.cc b/chrome/browser/profiles/profile_selections.cc
index bc0bad82ebcdceadc505e912ff27202b452fefab..6b77c57fccc4619a1df3b4ed661d2bdd60960228 100644
index 25b15408665dc95702e7f1382fb8e7c0bb493599..6b77c57fccc4619a1df3b4ed661d2bdd60960228 100644
--- a/chrome/browser/profiles/profile_selections.cc
+++ b/chrome/browser/profiles/profile_selections.cc
@@ -13,6 +13,7 @@
@@ -117,8 +223,25 @@ index bc0bad82ebcdceadc505e912ff27202b452fefab..6b77c57fccc4619a1df3b4ed661d2bdd
}
ProfileSelection ProfileSelections::GetProfileSelection(
@@ -132,6 +137,7 @@ ProfileSelection ProfileSelections::GetProfileSelection(
}
#endif // BUILDFLAG(IS_CHROMEOS)
+#if 0
// Treat other off the record profiles as Incognito (primary otr) Profiles.
if (profile->IsRegularProfile() || profile->IsIncognitoProfile() ||
profile_metrics::GetBrowserProfileType(profile) ==
@@ -148,6 +154,8 @@ ProfileSelection ProfileSelections::GetProfileSelection(
}
NOTREACHED();
+#endif
+ return ProfileSelection::kNone;
}
void ProfileSelections::SetProfileSelectionForRegular(
diff --git a/chrome/browser/spellchecker/spellcheck_service.cc b/chrome/browser/spellchecker/spellcheck_service.cc
index cf9cf84da456314804083c902859a0965425479f..779bdd17641c1808ff2c707b3de5f6c9b331ca2d 100644
index c138bc5b0021f323fbd842a0e6af35962e6037ce..8b781e4bf202481abb754b93d9b978c4f9294275 100644
--- a/chrome/browser/spellchecker/spellcheck_service.cc
+++ b/chrome/browser/spellchecker/spellcheck_service.cc
@@ -20,8 +20,10 @@

View File

@@ -1,14 +1,26 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Thu, 18 Oct 2018 17:07:01 -0700
Subject: desktop_media_list.patch
Subject: feat: customize DesktopMediaList for desktopCapturer API
* Use our grit resources instead of the chrome ones.
* Disabled WindowCaptureMacV2 feature for https://github.com/electron/electron/pull/30507
* Ensure "OnRefreshComplete()" even if there are no items in the list
Adapts DesktopMediaList for Electron's desktopCapturer.getSources(),
which does a one-shot Update() rather than Chrome's continuous
StartUpdating() picker flow:
* Adds refresh_thumbnails param to Update() so one-shot callers can
request thumbnails
* Adds skip_next_refresh_ counter to skip the initial no-op callbacks
from the macOS SCK thumbnail capturer
* Releases the capturer after thumbnail capture to free OS screen
capture resources held by the one-shot path
* Ensures the refresh callback fires even when the source list is empty
* Disables the remote_cocoa ScopedCGWindowID path on macOS pending
https://github.com/electron/electron/issues/30682
Long term, desktopCapturer should be rewritten to use StartUpdating and
handle events, which would remove most of this patch.
diff --git a/chrome/browser/media/webrtc/desktop_media_list.h b/chrome/browser/media/webrtc/desktop_media_list.h
index 9a4e06d24b829ba51bf5c925e7a7290da6fad4f0..09895ccfa99999e6e0ea24a3190d3f429ee40344 100644
index 9a4e06d24b829ba51bf5c925e7a7290da6fad4f0..b1189cebeabe49971c0d0d4d013e6fe26e7df5a5 100644
--- a/chrome/browser/media/webrtc/desktop_media_list.h
+++ b/chrome/browser/media/webrtc/desktop_media_list.h
@@ -108,7 +108,8 @@ class DesktopMediaList {
@@ -21,8 +33,17 @@ index 9a4e06d24b829ba51bf5c925e7a7290da6fad4f0..09895ccfa99999e6e0ea24a3190d3f42
virtual int GetSourceCount() const = 0;
virtual const Source& GetSource(int index) const = 0;
@@ -148,6 +149,8 @@ class DesktopMediaList {
// source lists that need to be displayed independently from when the
// DesktopMediaList gains focus.
virtual void ShowDelegatedList() = 0;
+
+ int skip_next_refresh_ = 0;
};
#endif // CHROME_BROWSER_MEDIA_WEBRTC_DESKTOP_MEDIA_LIST_H_
diff --git a/chrome/browser/media/webrtc/desktop_media_list_base.cc b/chrome/browser/media/webrtc/desktop_media_list_base.cc
index 1f25e8321301b0a5cd8703b8a4e9ec840fc0331b..f95b2230135dbcd6b19a31215d4f10be3481148c 100644
index 1f25e8321301b0a5cd8703b8a4e9ec840fc0331b..9e1eb8423969e75d5ece0056690f651c1bb901cd 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_base.cc
+++ b/chrome/browser/media/webrtc/desktop_media_list_base.cc
@@ -70,12 +70,12 @@ void DesktopMediaListBase::StartUpdating(DesktopMediaListObserver* observer) {
@@ -40,6 +61,19 @@ index 1f25e8321301b0a5cd8703b8a4e9ec840fc0331b..f95b2230135dbcd6b19a31215d4f10be
}
int DesktopMediaListBase::GetSourceCount() const {
@@ -232,7 +232,11 @@ uint32_t DesktopMediaListBase::GetImageHash(const gfx::Image& image) {
void DesktopMediaListBase::OnRefreshComplete() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(refresh_callback_);
- std::move(refresh_callback_).Run();
+ if (skip_next_refresh_ > 0) {
+ skip_next_refresh_--;
+ } else {
+ std::move(refresh_callback_).Run();
+ }
}
void DesktopMediaListBase::ScheduleNextRefresh() {
diff --git a/chrome/browser/media/webrtc/desktop_media_list_base.h b/chrome/browser/media/webrtc/desktop_media_list_base.h
index de56c9b94f92e9abf69b1d4894e5d386cad6d3cd..f8955ef7cc43b1854b29841ed65260a1966a4b19 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_base.h

View File

@@ -1,9 +1,26 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Mon, 18 May 2020 11:12:26 -0700
Subject: allow disabling blink scheduler throttling per RenderView
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 20 Sep 2018 17:45:47 -0700
Subject: feat: support disabling background throttling per-WebContents
This allows us to disable throttling for hidden windows.
Chromium throttles pages that become hidden or occluded: the
RenderWidgetHost drops frames, the Blink scheduler throttles timers,
and the viz::DisplayScheduler stops drawing and swapping frames.
This patch adds a disable_hidden_ flag on RenderWidgetHostImpl to
short-circuit WasHidden(), a SetSchedulerThrottling() IPC on the
PageBroadcast mojom interface to force Blink's PageScheduler to treat
the page as visible, and a SetBackgroundThrottling() method on
ui::Compositor to keep the viz display marked visible regardless of
the host's actual visibility.
Electron uses this to implement the webContents.backgroundThrottling
property and webPreferences.backgroundThrottling option, which let
apps opt out of throttling for hidden windows (e.g. media players,
offscreen renderers).
This patch is unlikely to be upstreamed as-is since Chromium has no
use case for per-WebContents throttling control.
diff --git a/content/browser/renderer_host/navigation_controller_impl_unittest.cc b/content/browser/renderer_host/navigation_controller_impl_unittest.cc
index c33775220e161d38e41efe8fea897815737341f8..e9636b69a8eb748aaa493466c3190ec602e16449 100644
@@ -50,8 +67,36 @@ index 89fed16c112d55c13a9f23695e2898d630f7d815..b7f486337f46daac015644525c9870f5
void SendWebPreferencesToRenderer();
void SendRendererPreferencesToRenderer(
const blink::RendererPreferences& preferences);
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index be97442111503ac8ca75171f2d195a0a18f9d7eb..5e7d992ba2144d32f8eb1c6fa5233c68954318e1 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -810,6 +810,10 @@ void RenderWidgetHostImpl::WasHidden() {
return;
}
+ if (disable_hidden_) {
+ return;
+ }
+
// Cancel pending pointer lock requests, unless there's an open user prompt.
// Prompts should remain open and functional across tab switches.
if (!delegate_ || !delegate_->IsWaitingForPointerLockPrompt(this)) {
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 8fc7d892a54e0890e86b01713f0cf6b75aa14ab0..d60b540934b290e9303b1dacfa990e85ce47b4e0 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -1042,6 +1042,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl
base::TimeDelta GetHungRendererDelayForTesting();
+ // Electron: Prevents the widget from getting hidden.
+ bool disable_hidden_ = false;
protected:
// |routing_id| must not be IPC::mojom::kRoutingIdNone.
// If this object outlives |delegate|, DetachDelegate() must be called when
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 79bd8d43a71731e5076196877448462656a04d48..b5d7f50817f503956f19fcea687b5b0751268b44 100644
index 95f75a24fa3e799dc4227e6438b1d0cc316ba4b9..b5d7f50817f503956f19fcea687b5b0751268b44 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -655,8 +655,8 @@ void RenderWidgetHostViewAura::ShowImpl(PageVisibilityState page_visibility) {
@@ -65,6 +110,15 @@ index 79bd8d43a71731e5076196877448462656a04d48..b5d7f50817f503956f19fcea687b5b07
}
void RenderWidgetHostViewAura::EnsurePlatformVisibility(
@@ -719,7 +719,7 @@ void RenderWidgetHostViewAura::HideImpl() {
CHECK(visibility_ == Visibility::HIDDEN ||
visibility_ == Visibility::OCCLUDED);
- if (!host()->IsHidden()) {
+ if (!host()->IsHidden() && !host()->disable_hidden_) {
host()->WasHidden();
aura::WindowTreeHost* host = window_->GetHost();
aura::Window* parent = window_->parent();
diff --git a/content/public/browser/render_view_host.h b/content/public/browser/render_view_host.h
index 782bed0fdc08d57eceb059f398f253fab9233b1b..f1ab5b981ea68af1b11313e67f2c5060f0a640b1 100644
--- a/content/public/browser/render_view_host.h
@@ -175,3 +229,72 @@ index 645ac2435db59cb76878de87cdd3e54d0958fce1..654f2ccfdff54742af06450aafe62cdf
// Whether the preferred size may have changed and |UpdatePreferredSize| needs
// to be called.
bool needs_preferred_size_update_ = true;
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
index e1d4c2dd4cf8c47ea555bf550f9c51bfd3a2e2fe..0a09e16571eeeb4ad8f2140f9a47b54da3d45e70 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -369,7 +369,8 @@ void Compositor::SetLayerTreeFrameSink(
if (display_private_) {
disabled_swap_until_resize_ = false;
display_private_->Resize(size());
- display_private_->SetDisplayVisible(host_->IsVisible());
+ // Invisible display is throttling itself.
+ display_private_->SetDisplayVisible(background_throttling_ ? host_->IsVisible() : true);
display_private_->SetDisplayColorSpaces(display_color_spaces_);
display_private_->SetDisplayColorMatrix(
gfx::SkM44ToTransform(display_color_matrix_));
@@ -620,7 +621,9 @@ void Compositor::SetVisible(bool visible) {
// updated then. We need to call this even if the visibility hasn't changed,
// for the same reason.
if (display_private_)
- display_private_->SetDisplayVisible(visible);
+ // Invisible display is throttling itself.
+ display_private_->SetDisplayVisible(
+ background_throttling_ ? visible : true);
if (changed) {
observer_list_.Notify(&CompositorObserver::OnCompositorVisibilityChanged,
@@ -1087,6 +1090,15 @@ void Compositor::MaybeUpdateObserveBeginFrame() {
host_begin_frame_observer_->GetBoundRemote());
}
+void Compositor::SetBackgroundThrottling(bool background_throttling_enabled) {
+ background_throttling_ = background_throttling_enabled;
+ if (display_private_) {
+ // Invisible display is throttling itself.
+ display_private_->SetDisplayVisible(
+ background_throttling_ ? host_->IsVisible() : true);
+ }
+}
+
#if BUILDFLAG(IS_CHROMEOS)
void Compositor::SetSeamlessRefreshRates(
const std::vector<float>& seamless_refresh_rates) {
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
index 97f26777528c3b21255b74ccf411ff2d3b243215..76354011ebcf4bce949af90c2301051626c357e3 100644
--- a/ui/compositor/compositor.h
+++ b/ui/compositor/compositor.h
@@ -503,6 +503,10 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver,
const cc::LayerTreeSettings& GetLayerTreeSettings() const;
+ // Sets |background_throttling_| responsible for suspending drawing
+ // and switching frames.
+ void SetBackgroundThrottling(bool background_throttling_enabled);
+
size_t saved_events_metrics_count_for_testing() const {
return host_->saved_events_metrics_count_for_testing();
}
@@ -717,6 +721,12 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver,
// See go/report-ux-metrics-at-painting for details.
bool animation_started_ = false;
+ // Background throttling is a default Chromium behaviour. It occurs
+ // when the |display_private_| is not visible by prevent drawing and swapping
+ // frames. When it is disabled we are keeping |display_private_| always
+ // visible in order to keep generating frames.
+ bool background_throttling_ = true;
+
TrackerId next_compositor_metrics_tracker_id_ = 1u;
struct TrackerState {
TrackerState();

View File

@@ -1,48 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 20 Sep 2018 17:45:47 -0700
Subject: disable_hidden.patch
Electron uses this to disable background throttling for hidden windows.
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index be97442111503ac8ca75171f2d195a0a18f9d7eb..5e7d992ba2144d32f8eb1c6fa5233c68954318e1 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -810,6 +810,10 @@ void RenderWidgetHostImpl::WasHidden() {
return;
}
+ if (disable_hidden_) {
+ return;
+ }
+
// Cancel pending pointer lock requests, unless there's an open user prompt.
// Prompts should remain open and functional across tab switches.
if (!delegate_ || !delegate_->IsWaitingForPointerLockPrompt(this)) {
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 8fc7d892a54e0890e86b01713f0cf6b75aa14ab0..d60b540934b290e9303b1dacfa990e85ce47b4e0 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -1042,6 +1042,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl
base::TimeDelta GetHungRendererDelayForTesting();
+ // Electron: Prevents the widget from getting hidden.
+ bool disable_hidden_ = false;
protected:
// |routing_id| must not be IPC::mojom::kRoutingIdNone.
// If this object outlives |delegate|, DetachDelegate() must be called when
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 95f75a24fa3e799dc4227e6438b1d0cc316ba4b9..79bd8d43a71731e5076196877448462656a04d48 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -719,7 +719,7 @@ void RenderWidgetHostViewAura::HideImpl() {
CHECK(visibility_ == Visibility::HIDDEN ||
visibility_ == Visibility::OCCLUDED);
- if (!host()->IsHidden()) {
+ if (!host()->IsHidden() && !host()->disable_hidden_) {
host()->WasHidden();
aura::WindowTreeHost* host = window_->GetHost();
aura::Window* parent = window_->parent();

View File

@@ -1,38 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 4 Oct 2018 14:57:02 -0700
Subject: feat: enable setting aspect ratio to 0
Make SetAspectRatio accept 0 as valid input, which would reset to null.
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index c9edcfeb4df4a52dd744b43f04ff1675f566a620..31060227432ab705c4f2c4c52233f2f23d860124 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -638,7 +638,7 @@ void DesktopWindowTreeHostWin::SetOpacity(float opacity) {
void DesktopWindowTreeHostWin::SetAspectRatio(
const gfx::SizeF& aspect_ratio,
const gfx::Size& excluded_margin) {
- DCHECK(!aspect_ratio.IsEmpty());
+ DCHECK_NE(aspect_ratio.height(), 0);
message_handler_->SetAspectRatio(aspect_ratio.width() / aspect_ratio.height(),
excluded_margin);
}
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index 6a4f780c6921d901e9f954d1f7ba18c40d8847b9..29560b1f244ba56018799eff1cf5d2eae3eb4e7c 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -1047,8 +1047,11 @@ void HWNDMessageHandler::SetFullscreen(bool fullscreen,
void HWNDMessageHandler::SetAspectRatio(float aspect_ratio,
const gfx::Size& excluded_margin) {
- // If the aspect ratio is not in the valid range, do nothing.
- DCHECK_GT(aspect_ratio, 0.0f);
+ // If the aspect ratio is 0, reset it to null.
+ if (aspect_ratio == 0.0f) {
+ aspect_ratio_.reset();
+ return;
+ }
aspect_ratio_ = aspect_ratio;
excluded_margin_dip_ = excluded_margin;

View File

@@ -1,11 +1,60 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <marshallofsound@electronjs.org>
Date: Wed, 8 Mar 2023 13:04:21 -0800
Subject: refactor: expose HostImportModuleDynamically and
HostGetImportMetaProperties to embedders
Subject: feat: expose Blink ESM module hooks for Node resolver integration
This is so that Electron can blend Blink's and Node's implementations of these isolate handlers.
Moves Blink's HostImportModuleWithPhaseDynamically and
HostGetImportMetaProperties from anonymous namespace to public static
methods on V8Initializer, and exposes the HostDefinedOptionsIndex enum
on ReferrerScriptInfo.
Electron installs its own isolate-level ESM callbacks that route dynamic
import() and import.meta to either Node.js or Blink depending on the
calling context. We need to call back into Blink's implementations for
web-origin scripts, and we compare host-defined-options array lengths
against HostDefinedOptionsIndex::kLength to detect whether a module was
loaded by Blink vs Node.
diff --git a/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc b/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc
index 1b797783987255622735047bd78ca0e8bb635d5e..b209c736bb80c186ed51999af1dac0a1d50fc232 100644
--- a/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc
+++ b/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc
@@ -12,15 +12,6 @@ namespace blink {
namespace {
-enum HostDefinedOptionsIndex : size_t {
- kBaseURL,
- kCredentialsMode,
- kNonce,
- kParserState,
- kReferrerPolicy,
- kLength
-};
-
// Omit storing base URL if it is same as ScriptOrigin::ResourceName().
// Note: This improves chance of getting into a fast path in
// ReferrerScriptInfo::ToV8HostDefinedOptions.
diff --git a/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h b/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h
index 0119624a028bec3e53e4e402938a98fe6def1483..743865839448748fe00e3e7d5027587cb65393c9 100644
--- a/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h
+++ b/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h
@@ -23,6 +23,15 @@ class CORE_EXPORT ReferrerScriptInfo {
STACK_ALLOCATED();
public:
+ enum HostDefinedOptionsIndex : size_t {
+ kBaseURL,
+ kCredentialsMode,
+ kNonce,
+ kParserState,
+ kReferrerPolicy,
+ kLength
+ };
+
ReferrerScriptInfo() {}
ReferrerScriptInfo(const KURL& base_url,
network::mojom::CredentialsMode credentials_mode,
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
index d2925a10c6242bff1de59fc681f549d3b0aa267e..97a49dd4904b7965ff716648d654e3464e2ebc58 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc

View File

@@ -0,0 +1,114 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Apthorp <nornagon@nornagon.net>
Date: Thu, 20 Sep 2018 17:48:38 -0700
Subject: feat: expose GTK internals for Electron Linux integration
Adds //electron to GN visibility for the GTK and X11 ozone build
targets, exposes gtk::GetLibGdkPixbuf() and gtk::GetLibGdk() so
embedders can obtain handles to the GDK libraries already loaded in
the process, and adds GtkUi::GetPlatform() to reach the GtkUiPlatform
instance (previously available via a global removed in
https://crrev.com/c/7237910).
Electron needs these hooks for its Linux native UI integration
(file dialogs, tray icons, window decorations).
diff --git a/build/config/linux/gtk/BUILD.gn b/build/config/linux/gtk/BUILD.gn
index fdc3442590bddda969681d49c451d32f086bd5d1..b6fd63c0c845e5d7648e8693f1639b1f0f39a779 100644
--- a/build/config/linux/gtk/BUILD.gn
+++ b/build/config/linux/gtk/BUILD.gn
@@ -27,6 +27,7 @@ pkg_config("gtk_internal_config") {
group("gtk") {
visibility = [
+ "//electron:*",
# These are allow-listed for WebRTC builds. Nothing in else should depend
# on GTK.
"//examples:peerconnection_client",
diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc
index b0b5f62156b35573d4109552ad63a79ac90a4596..a7d4dbcdcee9db4b7184753b1eaeffab85fc3eb5 100644
--- a/extensions/renderer/script_injection.cc
+++ b/extensions/renderer/script_injection.cc
@@ -9,6 +9,7 @@
#include "base/feature_list.h"
#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
#include "base/lazy_instance.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_macros.h"
diff --git a/ui/gtk/gtk_compat.cc b/ui/gtk/gtk_compat.cc
index e05b4f2eb1b22d5a647cb020bae4e4052a2e735c..86524a419606bea3e7d090415fda8f2d8ce24df2 100644
--- a/ui/gtk/gtk_compat.cc
+++ b/ui/gtk/gtk_compat.cc
@@ -78,11 +78,6 @@ void* GetLibGio() {
return libgio;
}
-void* GetLibGdkPixbuf() {
- static void* libgdk_pixbuf = DlOpen("libgdk_pixbuf-2.0.so.0");
- return libgdk_pixbuf;
-}
-
void* GetLibGdk3() {
static void* libgdk3 = DlOpen("libgdk-3.so.0");
return libgdk3;
@@ -175,6 +170,15 @@ gfx::Insets InsetsFromGtkBorder(const GtkBorder& border) {
} // namespace
+void* GetLibGdkPixbuf() {
+ static void* libgdk_pixbuf = DlOpen("libgdk_pixbuf-2.0.so.0");
+ return libgdk_pixbuf;
+}
+
+void* GetLibGdk() {
+ return GtkCheckVersion(4) ? GetLibGtk4() : GetLibGdk3();
+}
+
bool LoadGtk(ui::LinuxUiBackend backend) {
static bool loaded = LoadGtkImpl(backend);
return loaded;
diff --git a/ui/gtk/gtk_compat.h b/ui/gtk/gtk_compat.h
index 841e2e8fcdbe2da4aac487badd4d352476e461a2..043c3ab4dde02ca71798034e8cb2b3f2d2677af7 100644
--- a/ui/gtk/gtk_compat.h
+++ b/ui/gtk/gtk_compat.h
@@ -42,6 +42,12 @@ using SkColor = uint32_t;
namespace gtk {
+// Get handle to the currently loaded gdk_pixbuf library in the process.
+void* GetLibGdkPixbuf();
+
+// Get handle to the currently loaded gdk library in the process.
+void* GetLibGdk();
+
// Loads libgtk and related libraries and returns true on success.
bool LoadGtk(ui::LinuxUiBackend backend);
diff --git a/ui/gtk/gtk_ui.h b/ui/gtk/gtk_ui.h
index 40caafa5ce58104da7d5e96eb1efad1c99a77664..b388fc462e0c320170e5b35550e48b6b19079f40 100644
--- a/ui/gtk/gtk_ui.h
+++ b/ui/gtk/gtk_ui.h
@@ -53,6 +53,8 @@ class GtkUi : public ui::LinuxUiAndTheme {
~GtkUi() override;
+ GtkUiPlatform* GetPlatform() const { return platform_.get(); }
+
// Setters used by SettingsProvider:
void SetWindowButtonOrdering(
const std::vector<views::FrameButton>& leading_buttons,
diff --git a/ui/ozone/platform/x11/BUILD.gn b/ui/ozone/platform/x11/BUILD.gn
index 75a94f4deaec7b71fc54911e7dec6c90e42670db..a77cdc899faaf31ae403c0566f821b965e08b010 100644
--- a/ui/ozone/platform/x11/BUILD.gn
+++ b/ui/ozone/platform/x11/BUILD.gn
@@ -6,7 +6,7 @@ import("//build/config/chromeos/ui_mode.gni")
import("//gpu/vulkan/features.gni")
import("//ui/base/ui_features.gni")
-visibility = [ "//ui/ozone/*" ]
+visibility = [ "//ui/ozone/*", "//electron:*" ]
assert(is_linux || is_chromeos)

View File

@@ -1,36 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: clavin <clavin@electronjs.org>
Date: Sat, 13 Dec 2025 15:30:46 -0800
Subject: expose GTK UI platform field
Chromium used to expose this as a public static method, backed by global storage. In 7237910, these conveniences were removed.
This patch should be proposed upstream.
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7237910 "7237910: Remove g_gtk_ui global"
diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc
index ce94c80f7293ccc34994d79ab11cd09b479331b8..98defaaf3a8dc39f41df7f437073f3fba8a7115a 100644
--- a/extensions/renderer/script_injection.cc
+++ b/extensions/renderer/script_injection.cc
@@ -9,6 +9,7 @@
#include "base/feature_list.h"
#include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
#include "base/lazy_instance.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_macros.h"
diff --git a/ui/gtk/gtk_ui.h b/ui/gtk/gtk_ui.h
index 40caafa5ce58104da7d5e96eb1efad1c99a77664..b388fc462e0c320170e5b35550e48b6b19079f40 100644
--- a/ui/gtk/gtk_ui.h
+++ b/ui/gtk/gtk_ui.h
@@ -53,6 +53,8 @@ class GtkUi : public ui::LinuxUiAndTheme {
~GtkUi() override;
+ GtkUiPlatform* GetPlatform() const { return platform_.get(); }
+
// Setters used by SettingsProvider:
void SetWindowButtonOrdering(
const std::vector<views::FrameButton>& leading_buttons,

View File

@@ -1,53 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Fedor Indutny <indutny@signal.org>
Date: Wed, 24 Sep 2025 10:08:48 -0700
Subject: Expose ReferrerScriptInfo::HostDefinedOptionsIndex
In `shell/common/node_bindings.cc`'s
`HostImportModuleWithPhaseDynamically` we route dynamic imports to
either Node.js's or Blink's resolver based on presence of Node.js
environment, process type, etc. Exporting `HostDefinedOptionsIndex`
allows us to route based on the size of `v8_host_defined_options` data
which enables us to support dynamic imports in non-context-isolated
preload scripts.
diff --git a/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc b/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc
index 1b797783987255622735047bd78ca0e8bb635d5e..b209c736bb80c186ed51999af1dac0a1d50fc232 100644
--- a/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc
+++ b/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc
@@ -12,15 +12,6 @@ namespace blink {
namespace {
-enum HostDefinedOptionsIndex : size_t {
- kBaseURL,
- kCredentialsMode,
- kNonce,
- kParserState,
- kReferrerPolicy,
- kLength
-};
-
// Omit storing base URL if it is same as ScriptOrigin::ResourceName().
// Note: This improves chance of getting into a fast path in
// ReferrerScriptInfo::ToV8HostDefinedOptions.
diff --git a/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h b/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h
index 0119624a028bec3e53e4e402938a98fe6def1483..743865839448748fe00e3e7d5027587cb65393c9 100644
--- a/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h
+++ b/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h
@@ -23,6 +23,15 @@ class CORE_EXPORT ReferrerScriptInfo {
STACK_ALLOCATED();
public:
+ enum HostDefinedOptionsIndex : size_t {
+ kBaseURL,
+ kCredentialsMode,
+ kNonce,
+ kParserState,
+ kReferrerPolicy,
+ kLength
+ };
+
ReferrerScriptInfo() {}
ReferrerScriptInfo(const KURL& base_url,
network::mojom::CredentialsMode credentials_mode,

View File

@@ -1,29 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <sattard@slack-corp.com>
Date: Mon, 8 Mar 2021 16:27:39 -0800
Subject: extend ApplyWebPreferences with Electron-specific logic
On macOS, popup menus are rendered by the main process by default.
This causes problems in OSR, since when the popup is rendered separately,
it won't be captured in the rendered image.
Offscreen can be updated at runtime, as such we need to apply the
turn on/off ExternalPopupMenu in the ApplyPreferences method.
There is no current way to attach an observer to these prefs so patching
is our only option.
Ideally we could add an embedder observer pattern here but that can be
done in future work.
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 4aa7a851d7280411009ed8a50fd04c78f9cb41cd..d626e66d2059dc7172f28b95637516781ff3f754 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -1855,6 +1855,8 @@ void WebView::ApplyWebPreferences(const web_pref::WebPreferences& prefs,
#if BUILDFLAG(IS_MAC)
web_view_impl->SetMaximumLegibleScale(
prefs.default_maximum_page_scale_factor);
+ web_view_impl->GetChromeClient().SetUseExternalPopupMenus(
+ !prefs.offscreen);
#endif
#if BUILDFLAG(IS_WIN)

View File

@@ -1,80 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Wed, 29 Jan 2025 17:01:03 +0900
Subject: feat: add signals when embedder cleanup callbacks run for
gin::wrappable
Current setup of finalization callbacks does not work well with
gin_helper::CleanedUpAtExit for wrappables specifically on environment
shutdown leading to UAF in the second pass.
Details at https://github.com/microsoft/vscode/issues/192119#issuecomment-2375851531
This patch is more of a bandaid fix to improve the lifetime
management with existing finalizer callbacks. We should be able to
remove this patch once gin::Wrappable can be managed by V8 Oilpan
via https://github.com/electron/electron/issues/47922
diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc
index 64edf6fe78d2478cb9e12e8767a09e2b6c7c6ad2..7c640559dc7a09730f0053be8798d10bc8ac1a1c 100644
--- a/gin/isolate_holder.cc
+++ b/gin/isolate_holder.cc
@@ -35,6 +35,8 @@ v8::ArrayBuffer::Allocator* g_array_buffer_allocator = nullptr;
const intptr_t* g_reference_table = nullptr;
v8::FatalErrorCallback g_fatal_error_callback = nullptr;
v8::OOMErrorCallback g_oom_error_callback = nullptr;
+bool g_initialized_microtasks_runner = false;
+bool g_destroyed_microtasks_runner = false;
std::unique_ptr<v8::Isolate::CreateParams> getModifiedIsolateParams(
std::unique_ptr<v8::Isolate::CreateParams> params,
@@ -204,10 +206,26 @@ IsolateHolder::getDefaultIsolateParams() {
return params;
}
+// static
+bool IsolateHolder::DestroyedMicrotasksRunner() {
+ return g_initialized_microtasks_runner &&
+ g_destroyed_microtasks_runner;
+}
+
void IsolateHolder::EnableIdleTasks(
std::unique_ptr<V8IdleTaskRunner> idle_task_runner) {
DCHECK(isolate_data_.get());
isolate_data_->EnableIdleTasks(std::move(idle_task_runner));
}
+void IsolateHolder::WillCreateMicrotasksRunner() {
+ DCHECK(!g_initialized_microtasks_runner);
+ g_initialized_microtasks_runner = true;
+}
+
+void IsolateHolder::WillDestroyMicrotasksRunner() {
+ DCHECK(g_initialized_microtasks_runner);
+ g_destroyed_microtasks_runner = true;
+}
+
} // namespace gin
diff --git a/gin/public/isolate_holder.h b/gin/public/isolate_holder.h
index 902ad13dad8df57325f6c74ee3da9ec3148751cb..d0de06b55937d36848664c3817d098182c67f570 100644
--- a/gin/public/isolate_holder.h
+++ b/gin/public/isolate_holder.h
@@ -133,6 +133,8 @@ class GIN_EXPORT IsolateHolder {
// Should only be called after v8::IsolateHolder::Initialize() is invoked.
static std::unique_ptr<v8::Isolate::CreateParams> getDefaultIsolateParams();
+ static bool DestroyedMicrotasksRunner();
+
v8::Isolate* isolate() { return isolate_; }
// This method returns if v8::Locker is needed to access isolate.
@@ -146,6 +148,9 @@ class GIN_EXPORT IsolateHolder {
void EnableIdleTasks(std::unique_ptr<V8IdleTaskRunner> idle_task_runner);
+ void WillCreateMicrotasksRunner();
+ void WillDestroyMicrotasksRunner();
+
// This method returns V8IsolateMemoryDumpProvider of this isolate, used for
// testing.
V8IsolateMemoryDumpProvider* isolate_memory_dump_provider_for_testing()

View File

@@ -1,67 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <sattard@anthropic.com>
Date: Fri, 15 Aug 2025 14:58:12 -0700
Subject: feat: add support for embedder snapshot validation
IsValid is not exposed despite being commented as for embedders, this exposes something that works for us.
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
index aef4af8ce2a3352535a1ea2f4777e839c4811817..d5d861292c399a18ec0af66e2d726619c939875e 100644
--- a/gin/v8_initializer.cc
+++ b/gin/v8_initializer.cc
@@ -76,11 +76,23 @@ bool GenerateEntropy(unsigned char* buffer, size_t amount) {
return true;
}
+static base::RepeatingCallback<void(v8::StartupData*)>& SnapshotValidator() {
+ static base::NoDestructor<base::RepeatingCallback<void(v8::StartupData*)>>
+ validator(
+ base::BindRepeating([](v8::StartupData* data) -> void { /* empty */ }));
+ return *validator;
+}
+
+void SetV8SnapshotValidatorInner(const base::RepeatingCallback<void(v8::StartupData*)>& callback) {
+ SnapshotValidator() = std::move(callback);
+}
+
void GetMappedFileData(base::MemoryMappedFile* mapped_file,
v8::StartupData* data) {
if (mapped_file) {
data->data = reinterpret_cast<const char*>(mapped_file->data());
data->raw_size = static_cast<int>(mapped_file->length());
+ SnapshotValidator().Run(data);
} else {
data->data = nullptr;
data->raw_size = 0;
@@ -226,6 +238,10 @@ constexpr std::string_view kV8FlagParam = "V8FlagParam";
} // namespace
+void SetV8SnapshotValidator(const base::RepeatingCallback<void(v8::StartupData*)>& callback) {
+ SetV8SnapshotValidatorInner(std::move(callback));
+}
+
class V8FeatureVisitor : public base::FeatureVisitor {
public:
void Visit(const std::string& feature_name,
diff --git a/gin/v8_initializer.h b/gin/v8_initializer.h
index 6f7382cd600cd34916d9382878aee4b469dae5d0..61ed0f46437d2e1abbcebcfb64df06d17c8d9139 100644
--- a/gin/v8_initializer.h
+++ b/gin/v8_initializer.h
@@ -11,6 +11,7 @@
#include "base/files/file.h"
#include "base/files/memory_mapped_file.h"
+#include "base/functional/callback.h"
#include "build/build_config.h"
#include "gin/array_buffer.h"
#include "gin/gin_export.h"
@@ -28,6 +29,8 @@ class StartupData;
namespace gin {
+void SetV8SnapshotValidator(const base::RepeatingCallback<void(v8::StartupData*)>& callback);
+
class GIN_EXPORT V8Initializer {
public:
// This should be called by IsolateHolder::Initialize().

View File

@@ -1,57 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <sattard@slack-corp.com>
Date: Tue, 25 Feb 2020 13:28:30 -0800
Subject: feat: add support for overriding the base spellchecker download URL
This patch is required as the testing-only method we were using does not
take into account the dictionary name and therefore will not work for
production use cases. This is unlikely to be upstreamed as the change
is entirely in //chrome.
diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
index cf981e70ee4c43fd4f9a195c7839c9e3cb7fc956..c00068a963d66a07a726ec562e5f8327b2c3faeb 100644
--- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
+++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
@@ -55,6 +55,8 @@ GURL& GetDownloadUrlForTesting() {
return *download_url_for_testing;
}
+base::NoDestructor<GURL> g_base_download_url_override;
+
// Close the file.
void CloseDictionary(base::File file) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
@@ -269,6 +271,10 @@ void SpellcheckHunspellDictionary::SetDownloadURLForTesting(const GURL url) {
GetDownloadUrlForTesting() = url;
}
+void SpellcheckHunspellDictionary::SetBaseDownloadURL(const GURL url) {
+ *g_base_download_url_override = url;
+}
+
GURL SpellcheckHunspellDictionary::GetDictionaryURL() {
if (GetDownloadUrlForTesting() != GURL()) {
return GetDownloadUrlForTesting();
@@ -277,6 +283,9 @@ GURL SpellcheckHunspellDictionary::GetDictionaryURL() {
std::string bdict_file = dictionary_file_.path.BaseName().MaybeAsASCII();
DCHECK(!bdict_file.empty());
+ if (*g_base_download_url_override != GURL())
+ return GURL(g_base_download_url_override->spec() + base::ToLowerASCII(bdict_file));
+
static const char kDownloadServerUrl[] =
"https://redirector.gvt1.com/edgedl/chrome/dict/";
diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
index 4e608a6c0147c6f41e12f16fee7c87d0db2f1733..5962abf8dbd5998f11e828ec70b3a6a8b1758f65 100644
--- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
+++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
@@ -97,6 +97,8 @@ class SpellcheckHunspellDictionary : public SpellcheckDictionary {
// Tests use this method to set a custom URL for downloading dictionaries.
static void SetDownloadURLForTesting(const GURL url);
+ static void SetBaseDownloadURL(const GURL url);
+
private:
// Dictionary download status.
enum DownloadStatus {

View File

@@ -1,64 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <sattard@slack-corp.com>
Date: Sun, 1 Mar 2020 16:33:55 -0800
Subject: feat: allow embedders to add observers on created hunspell
dictionaries
This patch is used by Electron to implement spellchecker events.
diff --git a/chrome/browser/spellchecker/spellcheck_service.cc b/chrome/browser/spellchecker/spellcheck_service.cc
index c138bc5b0021f323fbd842a0e6af35962e6037ce..cf9cf84da456314804083c902859a0965425479f 100644
--- a/chrome/browser/spellchecker/spellcheck_service.cc
+++ b/chrome/browser/spellchecker/spellcheck_service.cc
@@ -479,6 +479,8 @@ void SpellcheckService::LoadDictionaries() {
std::make_unique<SpellcheckHunspellDictionary>(
dictionary, platform_spellcheck_language, context_, this));
hunspell_dictionaries_.back()->AddObserver(this);
+ if (hunspell_observer_)
+ hunspell_dictionaries_.back()->AddObserver(hunspell_observer_);
hunspell_dictionaries_.back()->Load();
}
@@ -529,6 +531,20 @@ bool SpellcheckService::IsSpellcheckEnabled() const {
(!hunspell_dictionaries_.empty() || enable_if_uninitialized);
}
+void SpellcheckService::SetHunspellObserver(SpellcheckHunspellDictionary::Observer* observer) {
+ if (hunspell_observer_) {
+ for (auto& dict : hunspell_dictionaries_) {
+ dict->RemoveObserver(hunspell_observer_);
+ }
+ }
+ if (observer) {
+ for (auto& dict : hunspell_dictionaries_) {
+ dict->AddObserver(observer);
+ }
+ }
+ hunspell_observer_ = observer;
+}
+
void SpellcheckService::OnRenderProcessHostCreated(
content::RenderProcessHost* host) {
InitForRenderer(host);
diff --git a/chrome/browser/spellchecker/spellcheck_service.h b/chrome/browser/spellchecker/spellcheck_service.h
index 00e613bb4ca4346eb0b0e65b9b818d817ac724d9..1b40931b8654b80e9a5fd0f170217b4b008eaae9 100644
--- a/chrome/browser/spellchecker/spellcheck_service.h
+++ b/chrome/browser/spellchecker/spellcheck_service.h
@@ -135,6 +135,8 @@ class SpellcheckService : public KeyedService,
// dictionaries available.
bool IsSpellcheckEnabled() const;
+ void SetHunspellObserver(SpellcheckHunspellDictionary::Observer* observer);
+
// content::RenderProcessHostCreationObserver implementation.
void OnRenderProcessHostCreated(content::RenderProcessHost* host) override;
@@ -299,6 +301,8 @@ class SpellcheckService : public KeyedService,
// A pointer to the BrowserContext which this service refers to.
raw_ptr<content::BrowserContext> context_;
+ raw_ptr<SpellcheckHunspellDictionary::Observer> hunspell_observer_ = nullptr;
+
std::unique_ptr<SpellCheckHostMetrics> metrics_;
std::unique_ptr<SpellcheckCustomDictionary> custom_dictionary_;

View File

@@ -1,129 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Tue, 28 May 2024 10:44:06 +0200
Subject: feat: enable passing exit code on service process crash
This patch enables plumbing the exit code of the service process to the
browser process when the service process crashes. The process can perform cleanup
after the message pipe disconnection, which previously led to racy and incorrect
exit codes in some crashing scenarios. To mitigate this, we can rely on
ServiceProcessHost::Observer functions, but we need to pass the exit code to
the observer.
diff --git a/content/browser/service_host/service_process_tracker.cc b/content/browser/service_host/service_process_tracker.cc
index fb41c8dfd147a90d7d581b49ad7f909d947cb214..ae0dce9d1dde14f1562adac7d324635983bb4c09 100644
--- a/content/browser/service_host/service_process_tracker.cc
+++ b/content/browser/service_host/service_process_tracker.cc
@@ -51,7 +51,8 @@ void ServiceProcessTracker::NotifyTerminated(ServiceProcessId id) {
void ServiceProcessTracker::NotifyCrashed(
ServiceProcessId id,
- UtilityProcessHost::Client::CrashType crash_type) {
+ UtilityProcessHost::Client::CrashType crash_type,
+ int exit_code) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto iter = processes_.find(id);
CHECK(iter != processes_.end());
@@ -65,7 +66,9 @@ void ServiceProcessTracker::NotifyCrashed(
break;
}
for (auto& observer : observers_) {
- observer.OnServiceProcessCrashed(iter->second.Duplicate());
+ auto params = iter->second.Duplicate();
+ params.set_exit_code(exit_code);
+ observer.OnServiceProcessCrashed(params);
}
processes_.erase(iter);
}
diff --git a/content/browser/service_host/service_process_tracker.h b/content/browser/service_host/service_process_tracker.h
index 9a5179c4eeacf8bbfb2d831b4301836df490f3a8..511fc9b9d5ce14a1b5ef457a1047e40d3bb64273 100644
--- a/content/browser/service_host/service_process_tracker.h
+++ b/content/browser/service_host/service_process_tracker.h
@@ -36,7 +36,8 @@ class ServiceProcessTracker {
void NotifyTerminated(ServiceProcessId id);
void NotifyCrashed(ServiceProcessId id,
- UtilityProcessHost::Client::CrashType type);
+ UtilityProcessHost::Client::CrashType type,
+ int exit_code);
void AddObserver(ServiceProcessHost::Observer* observer);
diff --git a/content/browser/service_host/utility_process_client.cc b/content/browser/service_host/utility_process_client.cc
index 99da7eee3cb1a09b984832211bceee385147aec2..5e4bd537d94ad26c8d309ebfb63845a8d3d11dae 100644
--- a/content/browser/service_host/utility_process_client.cc
+++ b/content/browser/service_host/utility_process_client.cc
@@ -40,7 +40,7 @@ void UtilityProcessClient::OnProcessTerminatedNormally() {
process_info_->service_process_id());
}
-void UtilityProcessClient::OnProcessCrashed(CrashType type) {
+void UtilityProcessClient::OnProcessCrashed(CrashType type, int exit_code) {
// TODO(crbug.com/40654042): It is unclear how we can observe
// |OnProcessCrashed()| without observing |OnProcessLaunched()| first, but
// it can happen on Android. Ignore the notification in this case.
@@ -49,6 +49,6 @@ void UtilityProcessClient::OnProcessCrashed(CrashType type) {
}
GetServiceProcessTracker().NotifyCrashed(process_info_->service_process_id(),
- type);
+ type, exit_code);
}
} // namespace content
diff --git a/content/browser/service_host/utility_process_client.h b/content/browser/service_host/utility_process_client.h
index 2648adb1cf38ab557b66ffd0e3034b26b04d76d6..98eab587f343f6ca472efc3d4e7b31b2b8821417 100644
--- a/content/browser/service_host/utility_process_client.h
+++ b/content/browser/service_host/utility_process_client.h
@@ -36,7 +36,7 @@ class UtilityProcessClient : public UtilityProcessHost::Client {
void OnProcessTerminatedNormally() override;
- void OnProcessCrashed(CrashType type) override;
+ void OnProcessCrashed(CrashType type, int exit_code) override;
private:
const std::string service_interface_name_;
diff --git a/content/browser/service_host/utility_process_host.cc b/content/browser/service_host/utility_process_host.cc
index 23731f8c98c50c3140867debba688c5720684444..234e822d265b09fcc338f0677e2135747699d70c 100644
--- a/content/browser/service_host/utility_process_host.cc
+++ b/content/browser/service_host/utility_process_host.cc
@@ -652,7 +652,7 @@ void UtilityProcessHost::OnProcessCrashed(int exit_code) {
: Client::CrashType::kPreIpcInitialization;
}
#endif // BUILDFLAG(IS_WIN)
- client->OnProcessCrashed(type);
+ client->OnProcessCrashed(type, exit_code);
}
std::optional<std::string> UtilityProcessHost::GetServiceName() {
diff --git a/content/browser/service_host/utility_process_host.h b/content/browser/service_host/utility_process_host.h
index 96c0cadf5caf5bf27f2a767c43f0f1da04298800..5a16fe5c01ae7777064168e8883ec8ec0b82a873 100644
--- a/content/browser/service_host/utility_process_host.h
+++ b/content/browser/service_host/utility_process_host.h
@@ -87,7 +87,7 @@ class CONTENT_EXPORT UtilityProcessHost final
virtual void OnProcessTerminatedNormally() {}
// Called when the process has terminated due to a crash. The `type` field
// indicates the type of crash. See above.
- virtual void OnProcessCrashed(CrashType type) {}
+ virtual void OnProcessCrashed(CrashType type, int exit_code) {}
};
struct CONTENT_EXPORT Options {
diff --git a/content/public/browser/service_process_info.h b/content/public/browser/service_process_info.h
index 21f2c71d2323a70491034678a4dc0029d8d53e63..ce76dc8cadd5cbee5114d7106389803c3d7e8238 100644
--- a/content/public/browser/service_process_info.h
+++ b/content/public/browser/service_process_info.h
@@ -68,7 +68,13 @@ class CONTENT_EXPORT ServiceProcessInfo {
crashed_pre_ipc_ = crashed_pre_ipc;
}
+ void set_exit_code(int exit_code) { exit_code_ = exit_code; }
+ int exit_code() const { return exit_code_; }
+
private:
+ // The exit code of the process, if it has exited.
+ int exit_code_ = 0;
+
// The name of the service interface for which the process was launched.
std::string service_interface_name_;

View File

@@ -1,166 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Thu, 30 Jan 2025 20:28:38 +0900
Subject: feat: separate content settings callback for sync and async clipboard
`AllowReadFromClipboard` is called from both the types without a way to differentiate.
[sync path] - third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
[async path] - third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
This patch adds a new callback to separate these two paths so that we
can have sync permission checks for the sync path.
Additionally, `blink::PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ`
has been added to support type conversion in permission policy checks. We have extended
`blink::PermissionType` in `electron::WebContentsPermissionHelper::PermissionType`
but it is hard to import the latter into the content permission layer checks.
This patch will be removed when the deprecated sync api support is
removed.
diff --git a/components/permissions/permission_util.cc b/components/permissions/permission_util.cc
index 2f6fbe5270245ddb1ef82f097ac1258781acb66e..727b73a37a3258aa44643d66dceba79017d9dbc8 100644
--- a/components/permissions/permission_util.cc
+++ b/components/permissions/permission_util.cc
@@ -554,7 +554,8 @@ ContentSettingsType PermissionUtil::PermissionTypeToContentSettingsTypeSafe(
return ContentSettingsType::LOCAL_NETWORK;
case PermissionType::LOOPBACK_NETWORK:
return ContentSettingsType::LOOPBACK_NETWORK;
- case PermissionType::NUM:
+ case PermissionType::GEOLOCATION_APPROXIMATE:
+ case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ: case PermissionType::NUM:
break;
}
diff --git a/content/browser/permissions/permission_controller_impl.cc b/content/browser/permissions/permission_controller_impl.cc
index 30cf63190284f0f7c5d9a7c8f6b2e6b0956d0ec5..cb07f1755e152f0f3cd11e1757b8aa203e29fcc0 100644
--- a/content/browser/permissions/permission_controller_impl.cc
+++ b/content/browser/permissions/permission_controller_impl.cc
@@ -98,7 +98,8 @@ PermissionToSchedulingFeature(PermissionType permission_name) {
case PermissionType::LOCAL_NETWORK_ACCESS:
case PermissionType::LOCAL_NETWORK:
case PermissionType::LOOPBACK_NETWORK:
- return std::nullopt;
+ case PermissionType::GEOLOCATION_APPROXIMATE:
+ case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ: return std::nullopt;
}
}
diff --git a/content/browser/permissions/permission_descriptor_util.cc b/content/browser/permissions/permission_descriptor_util.cc
index 8acf00d2618d9a0552750f0f8e1d734b52f790b1..d2ea06fa66c07baaf741382af40de154068a7d6b 100644
--- a/content/browser/permissions/permission_descriptor_util.cc
+++ b/content/browser/permissions/permission_descriptor_util.cc
@@ -180,7 +180,12 @@ content::PermissionDescriptorUtil::CreatePermissionDescriptorForPermissionType(
case blink::PermissionType::LOOPBACK_NETWORK:
return CreatePermissionDescriptor(
blink::mojom::PermissionName::LOOPBACK_NETWORK);
- case blink::PermissionType::NUM:
+ case blink::PermissionType::GEOLOCATION_APPROXIMATE:
+ return CreatePermissionDescriptor(
+ blink::mojom::PermissionName::GEOLOCATION_APPROXIMATE);
+ case blink::PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
+ return CreatePermissionDescriptor(
+ blink::mojom::PermissionName::DEPRECATED_SYNC_CLIPBOARD_READ); case blink::PermissionType::NUM:
NOTREACHED();
}
NOTREACHED();
diff --git a/third_party/blink/common/permissions/permission_utils.cc b/third_party/blink/common/permissions/permission_utils.cc
index 9c1b4762fe932618ec85a86a8367dce706d23c0b..a818b0b9a0eb3efdf8b2d851a6b51fccbfdad0fe 100644
--- a/third_party/blink/common/permissions/permission_utils.cc
+++ b/third_party/blink/common/permissions/permission_utils.cc
@@ -110,7 +110,10 @@ std::string GetPermissionString(PermissionType permission) {
return "LocalNetwork";
case PermissionType::LOOPBACK_NETWORK:
return "LoopbackNetwork";
- case PermissionType::NUM:
+ case PermissionType::GEOLOCATION_APPROXIMATE:
+ return "GeolocationApproximate";
+ case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
+ return "DeprecatedSyncClipboardRead"; case PermissionType::NUM:
NOTREACHED();
}
NOTREACHED();
@@ -191,6 +194,7 @@ PermissionTypeToPermissionsPolicyFeature(PermissionType permission) {
case PermissionType::NOTIFICATIONS:
case PermissionType::KEYBOARD_LOCK:
case PermissionType::POINTER_LOCK:
+ case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
return std::nullopt;
case PermissionType::NUM:
diff --git a/third_party/blink/public/common/permissions/permission_utils.h b/third_party/blink/public/common/permissions/permission_utils.h
index b124d53fdd245f055f57ad00250112e2637e1cd1..31158388db2df745af999adc9d07fc9272a2d6f8 100644
--- a/third_party/blink/public/common/permissions/permission_utils.h
+++ b/third_party/blink/public/common/permissions/permission_utils.h
@@ -69,7 +69,7 @@ enum class PermissionType {
LOCAL_NETWORK = 44,
LOOPBACK_NETWORK = 45,
GEOLOCATION_APPROXIMATE = 46,
-
+ DEPRECATED_SYNC_CLIPBOARD_READ = 47,
// Always keep this at the end.
NUM,
MIN_VALUE = MIDI_SYSEX,
diff --git a/third_party/blink/public/mojom/permissions/permission.mojom b/third_party/blink/public/mojom/permissions/permission.mojom
index 7e5ab8bcc4756d3cf16594b69bd25d3df709e7cc..a25299b7222d43b6c4b4a5c18085171dbc322ec1 100644
--- a/third_party/blink/public/mojom/permissions/permission.mojom
+++ b/third_party/blink/public/mojom/permissions/permission.mojom
@@ -47,7 +47,7 @@ enum PermissionName {
WEB_PRINTING,
SMART_CARD,
GEOLOCATION_APPROXIMATE,
-};
+ DEPRECATED_SYNC_CLIPBOARD_READ};
struct MidiPermissionDescriptor {
bool sysex;
diff --git a/third_party/blink/public/platform/web_content_settings_client.h b/third_party/blink/public/platform/web_content_settings_client.h
index 36410ff29d9c82e59f93fbb82968064bd330dfde..6c3f994e0b184f78bd9442002bb4dfae66e50518 100644
--- a/third_party/blink/public/platform/web_content_settings_client.h
+++ b/third_party/blink/public/platform/web_content_settings_client.h
@@ -54,6 +54,9 @@ class WebContentSettingsClient {
// Controls whether access to write the clipboard is allowed for this frame.
virtual bool AllowWriteToClipboard() { return false; }
+ // Controls whether synchronous access to read the clipboard is allowed for this frame.
+ virtual bool AllowReadFromClipboardSync() { return false; }
+
// Reports that passive mixed content was found at the provided URL.
virtual void PassiveInsecureContentFound(const WebURL&) {}
diff --git a/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc b/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
index 8fded9303e74737d82ca6d54e00807ebabf6c1ac..c0b66eb9a62f8f75e3c4de43f467ddd09d8dc2d6 100644
--- a/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
+++ b/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
@@ -123,7 +123,7 @@ bool ClipboardCommands::CanReadClipboard(LocalFrame& frame,
return true;
}
return frame.GetContentSettingsClient() &&
- frame.GetContentSettingsClient()->AllowReadFromClipboard();
+ frame.GetContentSettingsClient()->AllowReadFromClipboardSync();
}
bool ClipboardCommands::CanWriteClipboard(LocalFrame& frame,
@@ -312,7 +312,7 @@ bool ClipboardCommands::PasteSupported(LocalFrame* frame) {
return true;
}
return frame->GetContentSettingsClient() &&
- frame->GetContentSettingsClient()->AllowReadFromClipboard();
+ frame->GetContentSettingsClient()->AllowReadFromClipboardSync();
}
bool ClipboardCommands::ExecuteCopy(LocalFrame& frame,
diff --git a/third_party/blink/renderer/modules/permissions/permission_utils.cc b/third_party/blink/renderer/modules/permissions/permission_utils.cc
index 27cdc852f5974951f0a10157a0473e67791f6688..e9b7dcb070567580e8c6ad11b2bb943083e804f6 100644
--- a/third_party/blink/renderer/modules/permissions/permission_utils.cc
+++ b/third_party/blink/renderer/modules/permissions/permission_utils.cc
@@ -151,6 +151,8 @@ String PermissionNameToString(PermissionName name) {
return "web-printing";
case PermissionName::SMART_CARD:
return "smart-card";
+ case PermissionName::DEPRECATED_SYNC_CLIPBOARD_READ:
+ return "deprecated-sync-clipboard-read";
}
}

View File

@@ -1,45 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <marshallofsound@electronjs.org>
Date: Tue, 13 Feb 2024 17:40:15 -0800
Subject: fix: add support for skipping first 2 no-op refreshes in thumb cap
Fixes a bug in the SCK thumbnail capturer, will be reported upstream for a hopefully
less hacky fix.
The first refresh is "no windows yet, no thumbnails".
The second refresh is "we have windows, we queued the thumbnail requests"
The third refresh (the one we want) is "we have windows, and have thumbnail requests"
This really isn't ideal at all, we need to refactor desktopCapturer (read completely re-implement it)
to use StartUpdating and handle the events instead of using the "get the list once" method.
diff --git a/chrome/browser/media/webrtc/desktop_media_list.h b/chrome/browser/media/webrtc/desktop_media_list.h
index 09895ccfa99999e6e0ea24a3190d3f429ee40344..b1189cebeabe49971c0d0d4d013e6fe26e7df5a5 100644
--- a/chrome/browser/media/webrtc/desktop_media_list.h
+++ b/chrome/browser/media/webrtc/desktop_media_list.h
@@ -149,6 +149,8 @@ class DesktopMediaList {
// source lists that need to be displayed independently from when the
// DesktopMediaList gains focus.
virtual void ShowDelegatedList() = 0;
+
+ int skip_next_refresh_ = 0;
};
#endif // CHROME_BROWSER_MEDIA_WEBRTC_DESKTOP_MEDIA_LIST_H_
diff --git a/chrome/browser/media/webrtc/desktop_media_list_base.cc b/chrome/browser/media/webrtc/desktop_media_list_base.cc
index f95b2230135dbcd6b19a31215d4f10be3481148c..9e1eb8423969e75d5ece0056690f651c1bb901cd 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_base.cc
+++ b/chrome/browser/media/webrtc/desktop_media_list_base.cc
@@ -232,7 +232,11 @@ uint32_t DesktopMediaListBase::GetImageHash(const gfx::Image& image) {
void DesktopMediaListBase::OnRefreshComplete() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(refresh_callback_);
- std::move(refresh_callback_).Run();
+ if (skip_next_refresh_ > 0) {
+ skip_next_refresh_--;
+ } else {
+ std::move(refresh_callback_).Run();
+ }
}
void DesktopMediaListBase::ScheduleNextRefresh() {

View File

@@ -1,51 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cezary Kulakowski <cezary@openfin.co>
Date: Tue, 11 May 2021 11:14:06 +0200
Subject: fix: fix aspect ratio when max width/height is set
Add the native frame border size to the minimum and maximum size if
the view reports its size as the client size. It allows to enlarge
window to proper values when aspect ratio and max width/height are
set. It also fixes DCHECK which was triggered when user tried to
enlarge window above dimensions set during creation of the
BrowserWindow.
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index 29560b1f244ba56018799eff1cf5d2eae3eb4e7c..cc86c89d5670fd53eb3eea2aa31f054475b47b4b 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -3860,17 +3860,30 @@ void HWNDMessageHandler::SizeWindowToAspectRatio(UINT param,
delegate_->GetMinMaxSize(&min_window_size, &max_window_size);
min_window_size = delegate_->DIPToScreenSize(min_window_size);
max_window_size = delegate_->DIPToScreenSize(max_window_size);
+ // Add the native frame border size to the minimum and maximum size if the
+ // view reports its size as the client size.
+ if (delegate_->WidgetSizeIsClientSize()) {
+ RECT client_rect, rect;
+ GetClientRect(hwnd(), &client_rect);
+ GetWindowRect(hwnd(), &rect);
+ CR_DEFLATE_RECT(&rect, &client_rect);
+ min_window_size.Enlarge(rect.right - rect.left,
+ rect.bottom - rect.top);
+ // Either axis may be zero, so enlarge them independently.
+ if (max_window_size.width())
+ max_window_size.Enlarge(rect.right - rect.left, 0);
+ if (max_window_size.height())
+ max_window_size.Enlarge(0, rect.bottom - rect.top);
+ }
std::optional<gfx::Size> max_size_param;
if (!max_window_size.IsEmpty()) {
max_size_param = max_window_size;
}
- gfx::Size excluded_margin = delegate_->DIPToScreenSize(excluded_margin_dip_);
-
- gfx::SizeRectToAspectRatioWithExcludedMargin(
+ gfx::SizeRectToAspectRatio(
GetWindowResizeEdge(param), aspect_ratio_.value(), min_window_size,
- max_size_param, excluded_margin, *window_rect);
+ max_size_param, window_rect);
}
POINT HWNDMessageHandler::GetCursorPos() const {

View File

@@ -1,82 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michal Pichlinski <michal.pichlinski@openfin.co>
Date: Thu, 15 Jun 2023 23:04:48 +0200
Subject: allow disabling throttling in the `viz::DisplayScheduler` per
`ui::Compositor`
In Chromium when the `viz::DisplayScheduler` is invisible it throttles
its work by dropping frame draws and swaps.
This patch allows disbling this throttling by preventing transition to
invisible state of the `viz::DisplayScheduler` owned
by the `ui::Compositor`.
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
index e1d4c2dd4cf8c47ea555bf550f9c51bfd3a2e2fe..0a09e16571eeeb4ad8f2140f9a47b54da3d45e70 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -369,7 +369,8 @@ void Compositor::SetLayerTreeFrameSink(
if (display_private_) {
disabled_swap_until_resize_ = false;
display_private_->Resize(size());
- display_private_->SetDisplayVisible(host_->IsVisible());
+ // Invisible display is throttling itself.
+ display_private_->SetDisplayVisible(background_throttling_ ? host_->IsVisible() : true);
display_private_->SetDisplayColorSpaces(display_color_spaces_);
display_private_->SetDisplayColorMatrix(
gfx::SkM44ToTransform(display_color_matrix_));
@@ -620,7 +621,9 @@ void Compositor::SetVisible(bool visible) {
// updated then. We need to call this even if the visibility hasn't changed,
// for the same reason.
if (display_private_)
- display_private_->SetDisplayVisible(visible);
+ // Invisible display is throttling itself.
+ display_private_->SetDisplayVisible(
+ background_throttling_ ? visible : true);
if (changed) {
observer_list_.Notify(&CompositorObserver::OnCompositorVisibilityChanged,
@@ -1087,6 +1090,15 @@ void Compositor::MaybeUpdateObserveBeginFrame() {
host_begin_frame_observer_->GetBoundRemote());
}
+void Compositor::SetBackgroundThrottling(bool background_throttling_enabled) {
+ background_throttling_ = background_throttling_enabled;
+ if (display_private_) {
+ // Invisible display is throttling itself.
+ display_private_->SetDisplayVisible(
+ background_throttling_ ? host_->IsVisible() : true);
+ }
+}
+
#if BUILDFLAG(IS_CHROMEOS)
void Compositor::SetSeamlessRefreshRates(
const std::vector<float>& seamless_refresh_rates) {
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
index d45839ebc7b07ade2ca382e15b1d48dcf7d29106..2c24993f1a509856966bb4a1302db97d976ad4ba 100644
--- a/ui/compositor/compositor.h
+++ b/ui/compositor/compositor.h
@@ -516,6 +516,10 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver,
const cc::LayerTreeSettings& GetLayerTreeSettings() const;
+ // Sets |background_throttling_| responsible for suspending drawing
+ // and switching frames.
+ void SetBackgroundThrottling(bool background_throttling_enabled);
+
size_t saved_events_metrics_count_for_testing() const {
return host_->saved_events_metrics_count_for_testing();
}
@@ -732,6 +736,12 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver,
// See go/report-ux-metrics-at-painting for details.
bool animation_started_ = false;
+ // Background throttling is a default Chromium behaviour. It occurs
+ // when the |display_private_| is not visible by prevent drawing and swapping
+ // frames. When it is disabled we are keeping |display_private_| always
+ // visible in order to keep generating frames.
+ bool background_throttling_ = true;
+
TrackerId next_compositor_metrics_tracker_id_ = 1u;
struct TrackerState {
TrackerState();

View File

@@ -1,17 +1,80 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Damglador <vse.stopchanskyi@gmail.com>
Date: Mon, 27 Oct 2025 23:35:43 +0100
Subject: fix: allow setting tray id
Subject: fix: use app-specific identity instead of 'chrome' on Linux
This is needed to allow setting custom tray id when initializing a tray icon.
With current behaviour all programs get chrome_status_icon_1 as their id in tray.
So tray can't tell apart Electron apps,
which introduces issues like https://bugs.kde.org/show_bug.cgi?id=470840.
Derives the Linux app name, DBus session name prefix, and tray icon ID
from the CHROME_DESKTOP environment variable instead of hardcoded
"chrome"/"org.chromium.Chromium" values. Without this, all Electron apps
identify identically to the desktop environment, so portals (e.g. global
shortcuts) conflict and system trays cannot distinguish between apps
(https://bugs.kde.org/show_bug.cgi?id=470840).
This patch can be removed after being upstreamed. See discussion at
The tray ID portion can be removed once upstreamed; see discussion at
https://github.com/electron/electron/pull/48675#issuecomment-3452781711
for more info.
diff --git a/base/version_info/nix/version_extra_utils.cc b/base/version_info/nix/version_extra_utils.cc
index e48fbf29760fb0b6d759a82132a6693db4d09929..f6b658d01e0ddf31e8dc66b0922444ad16747ad0 100644
--- a/base/version_info/nix/version_extra_utils.cc
+++ b/base/version_info/nix/version_extra_utils.cc
@@ -10,8 +10,29 @@
#include "base/containers/fixed_flat_map.h"
#include "base/environment.h"
#include "base/strings/strcat.h"
+#include "base/strings/string_util.h"
#include "build/branding_buildflags.h"
+namespace {
+
+constexpr std::string_view kDesktopSuffix = ".desktop";
+std::optional<std::string> GetChromeDesktopBaseName(base::Environment& env) {
+ auto desktop = env.GetVar("CHROME_DESKTOP");
+ if (!desktop.has_value() || desktop->empty()) {
+ return std::nullopt;
+ }
+ std::string_view name = *desktop;
+ if (name.ends_with(kDesktopSuffix)) {
+ name.remove_suffix(kDesktopSuffix.size());
+ }
+ if (name.empty()) {
+ return std::nullopt;
+ }
+ return std::string(name);
+}
+
+} // namespace
+
namespace version_info::nix {
version_info::Channel GetChannel(base::Environment& env) {
@@ -36,6 +57,10 @@ bool IsExtendedStable(base::Environment& env) {
}
std::string GetAppName(base::Environment& env) {
+ if (auto name = GetChromeDesktopBaseName(env)) {
+ return *name;
+ }
+
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
static constexpr std::string_view kAppName = "com.google.Chrome";
#else
@@ -61,6 +86,16 @@ std::string GetAppName(base::Environment& env) {
}
std::string GetSessionNamePrefix(base::Environment& env) {
+ if (auto name = GetChromeDesktopBaseName(env)) {
+ // DBus object paths have stricter requirements than names.
+ for (char& c : *name) {
+ if (!base::IsAsciiAlphaNumeric(c) && c != '_') {
+ c = '_';
+ }
+ }
+ return base::ToLowerASCII(*name);
+ }
+
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
static constexpr std::string_view kSessionNamePrefix = "chrome";
#else
diff --git a/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc b/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc
index 72a61f80eb5dfafe2609ec9e3f8f34c7c84f7abe..af68cc7486c450f9b9765f562fab71855686cc2e 100644
--- a/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc

View File

@@ -1,99 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Mon, 16 Aug 2021 17:55:32 +0200
Subject: fix: media key usage with globalShortcuts
This patch enables media keys to work properly with Electron's globalShortcut
module. Chromium's default usage of RemoteCommandCenterDelegate on macOS falls
down into MPRemoteCommandCenter, which makes it such that an app will not
receive remote control events until it begins playing audio. This runs
counter to the design of globalShortcuts, and so we need to instead
use `ui::MediaKeysListener`.
diff --git a/content/browser/media/media_keys_listener_manager_impl.cc b/content/browser/media/media_keys_listener_manager_impl.cc
index 42e37564e585987d367921568f0f1d2b7507f953..9baf89efbade01e8b60c579255f10799914e144f 100644
--- a/content/browser/media/media_keys_listener_manager_impl.cc
+++ b/content/browser/media/media_keys_listener_manager_impl.cc
@@ -87,7 +87,11 @@ bool MediaKeysListenerManagerImpl::StartWatchingMediaKey(
CanActiveMediaSessionControllerReceiveEvents();
// Tell the underlying MediaKeysListener to listen for the key.
- if (should_start_watching && media_keys_listener_ &&
+ if (
+#if BUILDFLAG(IS_MAC)
+ !media_key_handling_enabled_ &&
+#endif // BUILDFLAG(IS_MAC)
+ should_start_watching && media_keys_listener_ &&
!media_keys_listener_->StartWatchingMediaKey(key_code)) {
return false;
}
@@ -361,6 +365,20 @@ void MediaKeysListenerManagerImpl::StartListeningForMediaKeysIfNecessary() {
this, ui::MediaKeysListener::Scope::kGlobal);
DCHECK(media_keys_listener_);
}
+
+#if BUILDFLAG(IS_MAC)
+ // Chromium's implementation of SystemMediaControls falls
+ // down into MPRemoteCommandCenter, which makes it such that an app will not
+ // will not receive remote control events until it begins playing audio.
+ // If there's not already a MediaKeysListener instance, create one so
+ // that globalShortcuts work correctly.
+ if (!media_keys_listener_) {
+ media_keys_listener_ = ui::MediaKeysListener::Create(
+ this, ui::MediaKeysListener::Scope::kGlobal);
+ DCHECK(media_keys_listener_);
+ }
+#endif
+
EnsureAuxiliaryServices();
}
diff --git a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.cc b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.cc
index 0e9bffaf0203d39d9fb82d717f36b449d5566181..5cf3d98f4679a252290a34c15491a8a4a619ac1c 100644
--- a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.cc
+++ b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.cc
@@ -62,6 +62,22 @@ void GlobalAcceleratorListener::UnregisterAccelerator(
}
}
+// static
+void GlobalAcceleratorListener::SetShouldUseInternalMediaKeyHandling(bool should_use) {
+ if (content::MediaKeysListenerManager::
+ IsMediaKeysListenerManagerEnabled()) {
+ content::MediaKeysListenerManager* media_keys_listener_manager =
+ content::MediaKeysListenerManager::GetInstance();
+ DCHECK(media_keys_listener_manager);
+
+ if (should_use) {
+ media_keys_listener_manager->EnableInternalMediaKeyHandling();
+ } else {
+ media_keys_listener_manager->DisableInternalMediaKeyHandling();
+ }
+ }
+}
+
void GlobalAcceleratorListener::UnregisterAccelerators(Observer* observer) {
auto it = accelerator_map_.begin();
while (it != accelerator_map_.end()) {
diff --git a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.h b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.h
index 4a343f4e701928644ff3f2a855cc04c3fea2932a..a48b7b73508942cc05e0dcf0fe108313f265c7c6 100644
--- a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.h
+++ b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.h
@@ -9,6 +9,7 @@
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
+#include "content/public/browser/media_keys_listener_manager.h"
#include "ui/base/accelerators/command.h"
#include "ui/gfx/native_ui_types.h"
@@ -43,6 +44,9 @@ class GlobalAcceleratorListener {
// The instance may be nullptr.
static GlobalAcceleratorListener* GetInstance();
+ // enables media keys to work with Electron's globalShortcut module.
+ static void SetShouldUseInternalMediaKeyHandling(bool should_use);
+
// Register an observer for when a certain `accelerator` is struck. Returns
// true if register successfully, or false if the specified `accelerator`
// has been registered by another caller or other native applications.

View File

@@ -1,102 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Wed, 30 Aug 2023 15:56:53 +0900
Subject: fix: move AutoPipSettingsHelper behind branding buildflag
The class was added in https://chromium-review.googlesource.com/c/chromium/src/+/4688277
which is primarily used for providing an overlay view in a PIP window
to support content settings UI. The support pulls in chrome content settings
and UI code which are not valid in the scope of Electron.
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc
index cccf164d978761dac8148d11fbddfbeb9ecfb048..295a16cd4f1e369c78d34b4da24ea3c830ce20e4 100644
--- a/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc
+++ b/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc
@@ -6,6 +6,7 @@
#include "base/memory/raw_ptr.h"
#include "base/numerics/safe_conversions.h"
+#include "build/branding_buildflags.h"
#include "chrome/browser/picture_in_picture/picture_in_picture_bounds_cache.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "content/public/browser/document_picture_in_picture_window_controller.h"
@@ -31,8 +32,10 @@
#include "base/task/sequenced_task_runner.h"
// TODO(crbug.com/421608904): include auto_picture_in_picture_tab_helper for
// Android when supporting document PiP.
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
#include "chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.h"
#include "chrome/browser/picture_in_picture/auto_pip_setting_overlay_view.h"
+#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
#include "chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.h"
#include "chrome/browser/picture_in_picture/picture_in_picture_window.h"
#include "media/base/media_switches.h"
@@ -71,6 +74,7 @@ constexpr double kMaxWindowSizeRatio = 0.8;
// `kMaxWindowSizeRatio`.
constexpr double kMaxSiteRequestedWindowSizeRatio = 0.25;
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
// Returns true if a document picture-in-picture window should be focused upon
// opening it.
bool ShouldFocusPictureInPictureWindow(const NavigateParams& params) {
@@ -87,6 +91,7 @@ bool ShouldFocusPictureInPictureWindow(const NavigateParams& params) {
// AutoPictureInPictureTabHelper.
return !auto_picture_in_picture_tab_helper->IsInAutoPictureInPicture();
}
+#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
// Returns the maximum area in pixels that the site can request a
// picture-in-picture window to be.
@@ -220,7 +225,7 @@ bool PictureInPictureWindowManager::ExitPictureInPictureViaWindowUi(
return false;
}
-#if !BUILDFLAG(IS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
// The user manually closed the pip window, so let the tab helper know in case
// the auto-pip permission dialog was visible.
if (auto* tab_helper = AutoPictureInPictureTabHelper::FromWebContents(
@@ -572,7 +577,7 @@ gfx::Size PictureInPictureWindowManager::GetMaximumWindowSize(
// static
void PictureInPictureWindowManager::SetWindowParams(NavigateParams& params) {
-#if !BUILDFLAG(IS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
// Always show document picture-in-picture in a new window. When this is
// not opened via the AutoPictureInPictureTabHelper, focus the window.
params.window_action =
@@ -681,6 +686,7 @@ PictureInPictureWindowManager::GetOverlayView(
return nullptr;
}
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
// It would be nice to create this in `EnterPictureInPicture*`, but detecting
// auto-pip while pip is in the process of opening doesn't work.
//
@@ -719,6 +725,8 @@ PictureInPictureWindowManager::GetOverlayView(
}
return overlay_view;
+#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
+ return nullptr;
}
PictureInPictureOcclusionTracker*
diff --git a/chrome/browser/ui/views/overlay/video_overlay_window_views.cc b/chrome/browser/ui/views/overlay/video_overlay_window_views.cc
index c9214d904f2ef51e42369b28a2055c5f2f3bcce1..7981a2517b9bd0b0863e7e2bb8511f40f45d9a21 100644
--- a/chrome/browser/ui/views/overlay/video_overlay_window_views.cc
+++ b/chrome/browser/ui/views/overlay/video_overlay_window_views.cc
@@ -444,11 +444,13 @@ std::unique_ptr<VideoOverlayWindowViews> VideoOverlayWindowViews::Create(
#endif // BUILDFLAG(IS_WIN)
+#if 0
PictureInPictureOcclusionTracker* tracker =
PictureInPictureWindowManager::GetInstance()->GetOcclusionTracker();
if (tracker) {
tracker->OnPictureInPictureWidgetOpened(overlay_window.get());
}
+#endif
return overlay_window;
}

View File

@@ -1,140 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mitchell Cohen <mitch.cohen@me.com>
Date: Sun, 1 Mar 2026 16:25:13 -0500
Subject: fix: pass trigger for global shortcuts on Wayland
Allows the global shortcut portal on Wayland to accept the trigger
values requested by Electron apps, instead of requiring user input.
This patch should be submitted upstream.
diff --git a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.cc b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.cc
index 37faffac6fbb00d356c7cc4e685441f7c4d32481..31bd60c4638e48e91c95b5df8c943ca13c3bc134 100644
--- a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.cc
+++ b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.cc
@@ -15,6 +15,7 @@
#include "base/logging.h"
#include "base/nix/xdg_util.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/dbus/thread_linux/dbus_thread_linux.h"
#include "components/dbus/xdg/portal.h"
@@ -49,6 +50,91 @@ std::string GetShortcutPrefix(const std::string& accelerator_group_id,
.substr(0, 32);
}
+// Converts a ui::Accelerator to an XDG shortcut string:
+// https://specifications.freedesktop.org/shortcuts-spec/latest/.
+std::string AcceleratorToXdgTrigger(const ui::Accelerator& accelerator) {
+ std::string trigger;
+
+ if (accelerator.IsCtrlDown()) {
+ trigger += "CTRL+";
+ }
+ if (accelerator.IsAltDown()) {
+ trigger += "ALT+";
+ }
+ if (accelerator.IsShiftDown()) {
+ trigger += "SHIFT+";
+ }
+ if (accelerator.IsCmdDown()) {
+ trigger += "LOGO+";
+ }
+
+ ui::KeyboardCode key = accelerator.key_code();
+ if (key >= ui::VKEY_A && key <= ui::VKEY_Z) {
+ trigger += base::ToLowerASCII(static_cast<char>(key));
+ } else if (key >= ui::VKEY_0 && key <= ui::VKEY_9) {
+ trigger += static_cast<char>(key);
+ } else if (key >= ui::VKEY_F1 && key <= ui::VKEY_F24) {
+ trigger += "F" + base::NumberToString(1 + (key - ui::VKEY_F1));
+ } else {
+ switch (key) {
+ case ui::VKEY_SPACE:
+ trigger += "space";
+ break;
+ case ui::VKEY_RETURN:
+ trigger += "Return";
+ break;
+ case ui::VKEY_TAB:
+ trigger += "Tab";
+ break;
+ case ui::VKEY_ESCAPE:
+ trigger += "Escape";
+ break;
+ case ui::VKEY_BACK:
+ trigger += "BackSpace";
+ break;
+ case ui::VKEY_DELETE:
+ trigger += "Delete";
+ break;
+ case ui::VKEY_INSERT:
+ trigger += "Insert";
+ break;
+ case ui::VKEY_HOME:
+ trigger += "Home";
+ break;
+ case ui::VKEY_END:
+ trigger += "End";
+ break;
+ case ui::VKEY_PRIOR:
+ trigger += "Page_Up";
+ break;
+ case ui::VKEY_NEXT:
+ trigger += "Page_Down";
+ break;
+ case ui::VKEY_UP:
+ trigger += "Up";
+ break;
+ case ui::VKEY_DOWN:
+ trigger += "Down";
+ break;
+ case ui::VKEY_LEFT:
+ trigger += "Left";
+ break;
+ case ui::VKEY_RIGHT:
+ trigger += "Right";
+ break;
+ case ui::VKEY_OEM_COMMA:
+ trigger += "comma";
+ break;
+ case ui::VKEY_OEM_PERIOD:
+ trigger += "period";
+ break;
+ default:
+ return "";
+ }
+ }
+ return trigger;
+}
+
} // namespace
GlobalAcceleratorListenerLinux::BoundCommand::BoundCommand() = default;
@@ -292,6 +378,12 @@ void GlobalAcceleratorListenerLinux::BindShortcuts(DbusShortcuts old_shortcuts,
new_props["description"] =
dbus_utils::Variant::Wrap<"s">(std::move(*description));
}
+ auto preferred_trigger =
+ TakeFromDict<std::string>(properties, "preferred_trigger");
+ if (preferred_trigger) {
+ new_props["preferred_trigger"] =
+ dbus_utils::Variant::Wrap<"s">(std::move(*preferred_trigger));
+ }
shortcuts.emplace_back(id, std::move(new_props));
}
@@ -299,6 +391,12 @@ void GlobalAcceleratorListenerLinux::BindShortcuts(DbusShortcuts old_shortcuts,
dbus_xdg::Dictionary props;
props["description"] = dbus_utils::Variant::Wrap<"s">(
base::UTF16ToUTF8(bound_cmd.command.description()));
+ std::string trigger =
+ AcceleratorToXdgTrigger(bound_cmd.command.accelerator());
+ if (!trigger.empty()) {
+ props["preferred_trigger"] =
+ dbus_utils::Variant::Wrap<"s">(std::move(trigger));
+ }
shortcuts.emplace_back(modified_id, std::move(props));
}

View File

@@ -1,48 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com>
Date: Wed, 17 Aug 2022 13:49:40 -0700
Subject: fix: Adjust caption-removing style call
There is a SetWindowLong call that removes WS_CAPTION for frameless
windows, but Electron uses WS_CAPTION even for frameless windows,
unless they are transparent.
Changing this call only affects frameless windows, and it fixes
a visual glitch where they showed a Windows 7 style frame
during startup.
The if statement was originally introduced by
https://codereview.chromium.org/9372053/, and it was there to fix
a visual glitch with the close button showing up during startup
or resizing, but Electron does not seem to run into that issue
for opaque frameless windows even with that block commented out.
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index b1950dade1cc98a82c75b4b242a34338b2ba741c..5f483e5271facd23f50ebda981a7bce9e7f20791 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -1857,7 +1857,23 @@ LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) {
::SendMessage(hwnd(), WM_CHANGEUISTATE, MAKELPARAM(UIS_CLEAR, UISF_HIDEFOCUS),
0);
- if (!delegate_->HasFrame()) {
+ LONG is_popup =
+ ::GetWindowLong(hwnd(), GWL_STYLE) & static_cast<LONG>(WS_POPUP);
+
+ // For transparent windows, Electron removes the WS_CAPTION style,
+ // so we continue to remove it here. If we didn't, an opaque rectangle
+ // would show up.
+ // For non-transparent windows, Electron keeps the WS_CAPTION style,
+ // so we don't remove it in that case. If we did, a Windows 7 frame
+ // would show up.
+ // We also need this block for frameless popup windows. When the user opens
+ // a dropdown in an Electron app, the internal popup menu from
+ // third_party/blink/renderer/core/html/forms/internal_popup_menu.h
+ // is rendered. That menu is actually an HTML page inside of a frameless popup window.
+ // A new popup window is created every time the user opens the dropdown,
+ // and this code path is run. The code block below runs SendFrameChanged,
+ // which gives the dropdown options the proper layout.
+ if (!delegate_->HasFrame() && (is_translucent_ || is_popup)) {
::SetWindowLong(hwnd(), GWL_STYLE,
::GetWindowLong(hwnd(), GWL_STYLE) & ~WS_CAPTION);
SendFrameChanged();

View File

@@ -8,10 +8,10 @@ v8::Value instead of base::Value.
Refs https://bugs.chromium.org/p/chromium/issues/detail?id=1323953
diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc
index b0b5f62156b35573d4109552ad63a79ac90a4596..ce94c80f7293ccc34994d79ab11cd09b479331b8 100644
index a7d4dbcdcee9db4b7184753b1eaeffab85fc3eb5..98defaaf3a8dc39f41df7f437073f3fba8a7115a 100644
--- a/extensions/renderer/script_injection.cc
+++ b/extensions/renderer/script_injection.cc
@@ -319,6 +319,7 @@ void ScriptInjection::InjectJs(std::set<std::string>* executing_scripts,
@@ -320,6 +320,7 @@ void ScriptInjection::InjectJs(std::set<std::string>* executing_scripts,
blink::mojom::LoadEventBlockingOption::kBlock,
base::BindOnce(&ScriptInjection::OnJsInjectionCompleted,
weak_ptr_factory_.GetWeakPtr()),

View File

@@ -1,70 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mitchell Cohen <mitch.cohen@me.com>
Date: Sun, 1 Mar 2026 16:22:00 -0500
Subject: fix: set correct app id on Linux
Sets the Electron app's actual XDG app ID and DBus path instead of org.chromium.Chromium..
This avoids conflicts with portals, e.g. the global shortcut portal.
diff --git a/base/version_info/nix/version_extra_utils.cc b/base/version_info/nix/version_extra_utils.cc
index e48fbf29760fb0b6d759a82132a6693db4d09929..f6b658d01e0ddf31e8dc66b0922444ad16747ad0 100644
--- a/base/version_info/nix/version_extra_utils.cc
+++ b/base/version_info/nix/version_extra_utils.cc
@@ -10,8 +10,29 @@
#include "base/containers/fixed_flat_map.h"
#include "base/environment.h"
#include "base/strings/strcat.h"
+#include "base/strings/string_util.h"
#include "build/branding_buildflags.h"
+namespace {
+
+constexpr std::string_view kDesktopSuffix = ".desktop";
+std::optional<std::string> GetChromeDesktopBaseName(base::Environment& env) {
+ auto desktop = env.GetVar("CHROME_DESKTOP");
+ if (!desktop.has_value() || desktop->empty()) {
+ return std::nullopt;
+ }
+ std::string_view name = *desktop;
+ if (name.ends_with(kDesktopSuffix)) {
+ name.remove_suffix(kDesktopSuffix.size());
+ }
+ if (name.empty()) {
+ return std::nullopt;
+ }
+ return std::string(name);
+}
+
+} // namespace
+
namespace version_info::nix {
version_info::Channel GetChannel(base::Environment& env) {
@@ -36,6 +57,10 @@ bool IsExtendedStable(base::Environment& env) {
}
std::string GetAppName(base::Environment& env) {
+ if (auto name = GetChromeDesktopBaseName(env)) {
+ return *name;
+ }
+
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
static constexpr std::string_view kAppName = "com.google.Chrome";
#else
@@ -61,6 +86,16 @@ std::string GetAppName(base::Environment& env) {
}
std::string GetSessionNamePrefix(base::Environment& env) {
+ if (auto name = GetChromeDesktopBaseName(env)) {
+ // DBus object paths have stricter requirements than names.
+ for (char& c : *name) {
+ if (!base::IsAsciiAlphaNumeric(c) && c != '_') {
+ c = '_';
+ }
+ }
+ return base::ToLowerASCII(*name);
+ }
+
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
static constexpr std::string_view kSessionNamePrefix = "chrome";
#else

View File

@@ -1,29 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Keeley Hammond <khammond@slack-corp.com>
Date: Wed, 19 Feb 2025 11:18:44 -0800
Subject: fix: re-enable synchronous spellcheck on Windows
This fix partially reverts 6109477: Code Health:
Clean up stale base::Feature "WinRetrieveSuggestionsOnlyOnDemand"
https://chromium-review.googlesource.com/c/chromium/src/+/6109477
by re-adding a synchronous call to FillSuggestionList.
This patch can be removed when an asynchronous spellcheck API
option is added to Electron.
diff --git a/components/spellcheck/browser/windows_spell_checker.cc b/components/spellcheck/browser/windows_spell_checker.cc
index 319029fc962eb73f0dcf8604ccd342b0e381496e..eff60d66c3762722e56743abba60e1aafa19b774 100644
--- a/components/spellcheck/browser/windows_spell_checker.cc
+++ b/components/spellcheck/browser/windows_spell_checker.cc
@@ -241,6 +241,11 @@ std::vector<SpellCheckResult> BackgroundHelper::RequestTextCheckForAllLanguages(
(action == CORRECTIVE_ACTION_GET_SUGGESTIONS ||
action == CORRECTIVE_ACTION_REPLACE)) {
std::vector<std::u16string> suggestions;
+ // TODO (vertedinde): Perform the synchronous operation of retrieving
+ // suggestions for all misspelled words while performing a text check.
+ FillSuggestionList(it->first,
+ text.substr(start_index, error_length),
+ &suggestions);
result_map[std::tuple<ULONG, ULONG>(start_index, error_length)]
.push_back(suggestions);
}

View File

@@ -1,11 +1,16 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Tue, 5 Aug 2025 02:26:29 +0900
Subject: chore: restore some deprecated wrapper utility in gin
Subject: chore: restore gin wrapper utilities pending cppgc migration
Restores part of https://chromium-review.googlesource.com/c/chromium/src/+/6799157
Restores gin wrapper utilities removed in https://crrev.com/c/6799157
(the OnBeforeMicrotasksRunnerDispose dispose observer hook and the
Deprecated/new WrapperInfo FunctionTemplate map variants in
PerIsolateData), and extends gin::WrappablePointerTag with entries for
Electron API objects that extend gin::Wrappable and are allocated on
the cpp heap.
Patch can be removed once cppgc migration is complete
This patch can be removed once Electron's cppgc migration is complete:
https://github.com/electron/electron/issues/47922
diff --git a/gin/function_template.h b/gin/function_template.h
@@ -159,3 +164,29 @@ index 9146df7ec5e65401771f452ed44c63369be1d31f..5ae71c795cc98a885090553177f57dec
FunctionTemplateMap function_templates_;
base::ObserverList<DisposeObserver> dispose_observers_;
std::shared_ptr<V8ForegroundTaskRunnerBase> task_runner_;
diff --git a/gin/public/wrappable_pointer_tags.h b/gin/public/wrappable_pointer_tags.h
index fee622ebde42211de6f702b754cfa38595df5a1c..6b524632ebb405e473cf4fe8e253bd13bf7b67e5 100644
--- a/gin/public/wrappable_pointer_tags.h
+++ b/gin/public/wrappable_pointer_tags.h
@@ -77,7 +77,20 @@ enum WrappablePointerTag : uint16_t {
kWebAXObjectProxy, // content::WebAXObjectProxy
kWrappedExceptionHandler, // extensions::WrappedExceptionHandler
kIndigoContext, // indigo::IndigoContext
- kLastPointerTag = kIndigoContext,
+ kElectronApp, // electron::api::App
+ kElectronDataPipeHolder, // electron::api::DataPipeHolder
+ kElectronDebugger, // electron::api::Debugger
+ kElectronEvent, // gin_helper::internal::Event
+ kElectronMenu, // electron::api::Menu
+ kElectronNetLog, // electron::api::NetLog
+ kElectronPowerMonitor, // electron::api::PowerMonitor
+ kElectronPowerSaveBlocker, // electron::api::PowerSaveBlocker
+ kElectronReplyChannel, // gin_helper::internal::ReplyChannel
+ kElectronScreen, // electron::api::Screen
+ kElectronSession, // electron::api::Session
+ kElectronTray, // electron::api::Tray
+ kElectronWebRequest, // electron::api::WebRequest
+ kLastPointerTag = kElectronWebRequest,
};
static_assert(kLastPointerTag <

View File

@@ -1,80 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 20 Sep 2018 17:47:44 -0700
Subject: gin_enable_disable_v8_platform.patch
We don't use gin to create the V8 platform, because we need to inject Node
things.
diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc
index 646647b6e257ecc5ff0934fe8204db74651c1510..15904644aa5451c6cb0fc2a46a67678824cd0bec 100644
--- a/gin/isolate_holder.cc
+++ b/gin/isolate_holder.cc
@@ -162,11 +162,13 @@ void IsolateHolder::Initialize(ScriptMode mode,
std::string js_command_line_flags,
bool disallow_v8_feature_flag_overrides,
v8::FatalErrorCallback fatal_error_callback,
- v8::OOMErrorCallback oom_error_callback) {
+ v8::OOMErrorCallback oom_error_callback,
+ bool create_v8_platform) {
CHECK(allocator);
V8Initializer::Initialize(mode, js_command_line_flags,
disallow_v8_feature_flag_overrides,
- oom_error_callback);
+ oom_error_callback,
+ create_v8_platform);
g_array_buffer_allocator = allocator;
g_reference_table = reference_table;
g_fatal_error_callback = fatal_error_callback;
diff --git a/gin/public/isolate_holder.h b/gin/public/isolate_holder.h
index 3909e70dc1425c2cb02624f4b3017784a2ae6c9d..a57b92f02085d6392e6d9d0cc037df6b972f3c31 100644
--- a/gin/public/isolate_holder.h
+++ b/gin/public/isolate_holder.h
@@ -120,7 +120,8 @@ class GIN_EXPORT IsolateHolder {
std::string js_command_line_flags = {},
bool disallow_v8_feature_flag_overrides = false,
v8::FatalErrorCallback fatal_error_callback = nullptr,
- v8::OOMErrorCallback oom_error_callback = nullptr);
+ v8::OOMErrorCallback oom_error_callback = nullptr,
+ bool create_v8_platform = true);
// Returns whether `Initialize` has already been invoked in the process.
// Initialization is a one-way operation (i.e., this method cannot return
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
index 6146bd47bf3203b97084438ab51f96d515c74b55..136e728c4c7981c9180304a43d75b2f003161664 100644
--- a/gin/v8_initializer.cc
+++ b/gin/v8_initializer.cc
@@ -529,7 +529,8 @@ void SetFeatureFlags() {
void V8Initializer::Initialize(IsolateHolder::ScriptMode mode,
const std::string& js_command_line_flags,
bool disallow_v8_feature_flag_overrides,
- v8::OOMErrorCallback oom_error_callback) {
+ v8::OOMErrorCallback oom_error_callback,
+ bool create_v8_platform) {
static bool v8_is_initialized = false;
if (v8_is_initialized)
return;
@@ -544,7 +545,8 @@ void V8Initializer::Initialize(IsolateHolder::ScriptMode mode,
}
SetFlags(mode, js_command_line_flags);
- v8::V8::InitializePlatform(V8Platform::Get());
+ if (create_v8_platform)
+ v8::V8::InitializePlatform(V8Platform::Get());
// Set this as early as possible in order to ensure OOM errors are reported
// correctly.
diff --git a/gin/v8_initializer.h b/gin/v8_initializer.h
index 1341b77198431e1c426bff043bdb2bbcf202c8ca..ec64afd9dd91b292604ca834a91b9cfbd52eb853 100644
--- a/gin/v8_initializer.h
+++ b/gin/v8_initializer.h
@@ -32,7 +32,8 @@ class GIN_EXPORT V8Initializer {
static void Initialize(IsolateHolder::ScriptMode mode,
const std::string& js_command_line_flags,
bool disallow_v8_feature_flag_overrides,
- v8::OOMErrorCallback oom_error_callback);
+ v8::OOMErrorCallback oom_error_callback,
+ bool create_v8_platform = true);
// Get address and size information for currently loaded snapshot.
// If no snapshot is loaded, the return values are null for addresses

View File

@@ -0,0 +1,201 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 20 Sep 2018 17:47:44 -0700
Subject: feat: customize gin::IsolateHolder for Node platform integration
Adds hooks to gin::IsolateHolder needed for Node.js integration:
a create_v8_platform flag to skip gin's V8 platform init (Electron
uses Node's platform instead); an optional pre-allocated isolate so
NodePlatform can register it between v8::Isolate::Allocate and
::Initialize (Initialize calls GetForegroundTaskRunner which requires
prior RegisterIsolate, but gin leaves no gap to do so); and
microtasks-runner lifecycle signals used to avoid UAF in second-pass
finalization callbacks on shutdown. The last can be removed once
gin::Wrappable migrates to Oilpan (electron/electron#47922).
diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc
index 646647b6e257ecc5ff0934fe8204db74651c1510..7c640559dc7a09730f0053be8798d10bc8ac1a1c 100644
--- a/gin/isolate_holder.cc
+++ b/gin/isolate_holder.cc
@@ -35,6 +35,8 @@ v8::ArrayBuffer::Allocator* g_array_buffer_allocator = nullptr;
const intptr_t* g_reference_table = nullptr;
v8::FatalErrorCallback g_fatal_error_callback = nullptr;
v8::OOMErrorCallback g_oom_error_callback = nullptr;
+bool g_initialized_microtasks_runner = false;
+bool g_destroyed_microtasks_runner = false;
std::unique_ptr<v8::Isolate::CreateParams> getModifiedIsolateParams(
std::unique_ptr<v8::Isolate::CreateParams> params,
@@ -81,7 +83,8 @@ IsolateHolder::IsolateHolder(
v8::AddHistogramSampleCallback add_histogram_sample_callback,
scoped_refptr<base::SingleThreadTaskRunner> user_visible_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> best_effort_task_runner,
- std::unique_ptr<v8::CppHeap> cpp_heap)
+ std::unique_ptr<v8::CppHeap> cpp_heap,
+ v8::Isolate* isolate)
: IsolateHolder(std::move(task_runner),
access_mode,
isolate_type,
@@ -92,7 +95,8 @@ IsolateHolder::IsolateHolder(
std::move(cpp_heap)),
isolate_creation_mode,
std::move(user_visible_task_runner),
- std::move(best_effort_task_runner)) {}
+ std::move(best_effort_task_runner),
+ isolate) {}
IsolateHolder::IsolateHolder(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
@@ -101,7 +105,8 @@ IsolateHolder::IsolateHolder(
std::unique_ptr<v8::Isolate::CreateParams> params,
IsolateCreationMode isolate_creation_mode,
scoped_refptr<base::SingleThreadTaskRunner> user_visible_task_runner,
- scoped_refptr<base::SingleThreadTaskRunner> best_effort_task_runner)
+ scoped_refptr<base::SingleThreadTaskRunner> best_effort_task_runner,
+ v8::Isolate* isolate)
: access_mode_(access_mode), isolate_type_(isolate_type) {
CHECK(Initialized())
<< "You need to invoke gin::IsolateHolder::Initialize first";
@@ -112,7 +117,7 @@ IsolateHolder::IsolateHolder(
v8::ArrayBuffer::Allocator* allocator = params->array_buffer_allocator;
DCHECK(allocator);
- isolate_ = v8::Isolate::Allocate();
+ isolate_ = isolate ? isolate : v8::Isolate::Allocate();
isolate_data_ = std::make_unique<PerIsolateData>(
isolate_, allocator, access_mode_, task_runner,
std::move(user_visible_task_runner), std::move(best_effort_task_runner));
@@ -162,11 +167,13 @@ void IsolateHolder::Initialize(ScriptMode mode,
std::string js_command_line_flags,
bool disallow_v8_feature_flag_overrides,
v8::FatalErrorCallback fatal_error_callback,
- v8::OOMErrorCallback oom_error_callback) {
+ v8::OOMErrorCallback oom_error_callback,
+ bool create_v8_platform) {
CHECK(allocator);
V8Initializer::Initialize(mode, js_command_line_flags,
disallow_v8_feature_flag_overrides,
- oom_error_callback);
+ oom_error_callback,
+ create_v8_platform);
g_array_buffer_allocator = allocator;
g_reference_table = reference_table;
g_fatal_error_callback = fatal_error_callback;
@@ -199,10 +206,26 @@ IsolateHolder::getDefaultIsolateParams() {
return params;
}
+// static
+bool IsolateHolder::DestroyedMicrotasksRunner() {
+ return g_initialized_microtasks_runner &&
+ g_destroyed_microtasks_runner;
+}
+
void IsolateHolder::EnableIdleTasks(
std::unique_ptr<V8IdleTaskRunner> idle_task_runner) {
DCHECK(isolate_data_.get());
isolate_data_->EnableIdleTasks(std::move(idle_task_runner));
}
+void IsolateHolder::WillCreateMicrotasksRunner() {
+ DCHECK(!g_initialized_microtasks_runner);
+ g_initialized_microtasks_runner = true;
+}
+
+void IsolateHolder::WillDestroyMicrotasksRunner() {
+ DCHECK(g_initialized_microtasks_runner);
+ g_destroyed_microtasks_runner = true;
+}
+
} // namespace gin
diff --git a/gin/public/isolate_holder.h b/gin/public/isolate_holder.h
index 3909e70dc1425c2cb02624f4b3017784a2ae6c9d..d0de06b55937d36848664c3817d098182c67f570 100644
--- a/gin/public/isolate_holder.h
+++ b/gin/public/isolate_holder.h
@@ -89,7 +89,8 @@ class GIN_EXPORT IsolateHolder {
nullptr,
scoped_refptr<base::SingleThreadTaskRunner> best_effort_task_runner =
nullptr,
- std::unique_ptr<v8::CppHeap> cpp_heap = {});
+ std::unique_ptr<v8::CppHeap> cpp_heap = {},
+ v8::Isolate* isolate = nullptr);
IsolateHolder(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
AccessMode access_mode,
@@ -99,7 +100,8 @@ class GIN_EXPORT IsolateHolder {
scoped_refptr<base::SingleThreadTaskRunner> user_visible_task_runner =
nullptr,
scoped_refptr<base::SingleThreadTaskRunner> best_effort_task_runner =
- nullptr);
+ nullptr,
+ v8::Isolate* isolate = nullptr);
IsolateHolder(const IsolateHolder&) = delete;
IsolateHolder& operator=(const IsolateHolder&) = delete;
~IsolateHolder();
@@ -120,7 +122,8 @@ class GIN_EXPORT IsolateHolder {
std::string js_command_line_flags = {},
bool disallow_v8_feature_flag_overrides = false,
v8::FatalErrorCallback fatal_error_callback = nullptr,
- v8::OOMErrorCallback oom_error_callback = nullptr);
+ v8::OOMErrorCallback oom_error_callback = nullptr,
+ bool create_v8_platform = true);
// Returns whether `Initialize` has already been invoked in the process.
// Initialization is a one-way operation (i.e., this method cannot return
@@ -130,6 +133,8 @@ class GIN_EXPORT IsolateHolder {
// Should only be called after v8::IsolateHolder::Initialize() is invoked.
static std::unique_ptr<v8::Isolate::CreateParams> getDefaultIsolateParams();
+ static bool DestroyedMicrotasksRunner();
+
v8::Isolate* isolate() { return isolate_; }
// This method returns if v8::Locker is needed to access isolate.
@@ -143,6 +148,9 @@ class GIN_EXPORT IsolateHolder {
void EnableIdleTasks(std::unique_ptr<V8IdleTaskRunner> idle_task_runner);
+ void WillCreateMicrotasksRunner();
+ void WillDestroyMicrotasksRunner();
+
// This method returns V8IsolateMemoryDumpProvider of this isolate, used for
// testing.
V8IsolateMemoryDumpProvider* isolate_memory_dump_provider_for_testing()
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
index 6146bd47bf3203b97084438ab51f96d515c74b55..136e728c4c7981c9180304a43d75b2f003161664 100644
--- a/gin/v8_initializer.cc
+++ b/gin/v8_initializer.cc
@@ -529,7 +529,8 @@ void SetFeatureFlags() {
void V8Initializer::Initialize(IsolateHolder::ScriptMode mode,
const std::string& js_command_line_flags,
bool disallow_v8_feature_flag_overrides,
- v8::OOMErrorCallback oom_error_callback) {
+ v8::OOMErrorCallback oom_error_callback,
+ bool create_v8_platform) {
static bool v8_is_initialized = false;
if (v8_is_initialized)
return;
@@ -544,7 +545,8 @@ void V8Initializer::Initialize(IsolateHolder::ScriptMode mode,
}
SetFlags(mode, js_command_line_flags);
- v8::V8::InitializePlatform(V8Platform::Get());
+ if (create_v8_platform)
+ v8::V8::InitializePlatform(V8Platform::Get());
// Set this as early as possible in order to ensure OOM errors are reported
// correctly.
diff --git a/gin/v8_initializer.h b/gin/v8_initializer.h
index 1341b77198431e1c426bff043bdb2bbcf202c8ca..ec64afd9dd91b292604ca834a91b9cfbd52eb853 100644
--- a/gin/v8_initializer.h
+++ b/gin/v8_initializer.h
@@ -32,7 +32,8 @@ class GIN_EXPORT V8Initializer {
static void Initialize(IsolateHolder::ScriptMode mode,
const std::string& js_command_line_flags,
bool disallow_v8_feature_flag_overrides,
- v8::OOMErrorCallback oom_error_callback);
+ v8::OOMErrorCallback oom_error_callback,
+ bool create_v8_platform = true);
// Get address and size information for currently loaded snapshot.
// If no snapshot is loaded, the return values are null for addresses

View File

@@ -1,10 +1,17 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ryan Manuel <ryanm@cypress.io>
Date: Thu, 4 Aug 2022 22:37:01 -0500
Subject: Create browser v8 snapshot file name fuse
Subject: feat: customize V8 snapshot loading for embedder validation
By default, chromium sets up one v8 snapshot to be used in all v8 contexts. This patch allows consumers
to have a dedicated browser process v8 snapshot defined by the file `browser_v8_context_snapshot.bin`.
By default, Chromium loads a single hardcoded V8 snapshot file for all
processes. This patch adds ContentMainDelegate::GetBrowserV8SnapshotFilename()
and V8Initializer::LoadV8SnapshotFromFileName() so embedders can supply a
custom snapshot path, enabling Electron's loadBrowserProcessSpecificV8Snapshot
fuse which loads a dedicated browser_v8_context_snapshot.bin in the main
process. It also adds a gin::SetV8SnapshotValidator() hook that invokes an
embedder callback on the mapped v8::StartupData, letting Electron validate
snapshot integrity at load time since V8's StartupData::IsValid is not
exposed through gin.
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc
index b795a9dbf898570a7cd8469ee386c4edf4bfa275..449940fe1b6969576f1b2c21d7719620e578e8a8 100644
@@ -79,10 +86,45 @@ index 8c318a31454c57b0e8db3770a36c45be427f053c..6f809c9672448ed9797e3c9da492ad2c
friend class ContentClientCreator;
friend class ContentClientInitializer;
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
index 136e728c4c7981c9180304a43d75b2f003161664..aef4af8ce2a3352535a1ea2f4777e839c4811817 100644
index 136e728c4c7981c9180304a43d75b2f003161664..d5d861292c399a18ec0af66e2d726619c939875e 100644
--- a/gin/v8_initializer.cc
+++ b/gin/v8_initializer.cc
@@ -634,8 +634,7 @@ void V8Initializer::GetV8ExternalSnapshotData(const char** snapshot_data_out,
@@ -76,11 +76,23 @@ bool GenerateEntropy(unsigned char* buffer, size_t amount) {
return true;
}
+static base::RepeatingCallback<void(v8::StartupData*)>& SnapshotValidator() {
+ static base::NoDestructor<base::RepeatingCallback<void(v8::StartupData*)>>
+ validator(
+ base::BindRepeating([](v8::StartupData* data) -> void { /* empty */ }));
+ return *validator;
+}
+
+void SetV8SnapshotValidatorInner(const base::RepeatingCallback<void(v8::StartupData*)>& callback) {
+ SnapshotValidator() = std::move(callback);
+}
+
void GetMappedFileData(base::MemoryMappedFile* mapped_file,
v8::StartupData* data) {
if (mapped_file) {
data->data = reinterpret_cast<const char*>(mapped_file->data());
data->raw_size = static_cast<int>(mapped_file->length());
+ SnapshotValidator().Run(data);
} else {
data->data = nullptr;
data->raw_size = 0;
@@ -226,6 +238,10 @@ constexpr std::string_view kV8FlagParam = "V8FlagParam";
} // namespace
+void SetV8SnapshotValidator(const base::RepeatingCallback<void(v8::StartupData*)>& callback) {
+ SetV8SnapshotValidatorInner(std::move(callback));
+}
+
class V8FeatureVisitor : public base::FeatureVisitor {
public:
void Visit(const std::string& feature_name,
@@ -634,8 +650,7 @@ void V8Initializer::GetV8ExternalSnapshotData(const char** snapshot_data_out,
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
@@ -92,7 +134,7 @@ index 136e728c4c7981c9180304a43d75b2f003161664..aef4af8ce2a3352535a1ea2f4777e839
if (g_mapped_snapshot) {
// TODO(crbug.com/40558459): Confirm not loading different type of snapshot
// files in a process.
@@ -644,10 +643,17 @@ void V8Initializer::LoadV8Snapshot(V8SnapshotFileType snapshot_file_type) {
@@ -644,10 +659,17 @@ void V8Initializer::LoadV8Snapshot(V8SnapshotFileType snapshot_file_type) {
base::MemoryMappedFile::Region file_region;
base::File file =
@@ -112,10 +154,10 @@ index 136e728c4c7981c9180304a43d75b2f003161664..aef4af8ce2a3352535a1ea2f4777e839
void V8Initializer::LoadV8SnapshotFromFile(
base::File snapshot_file,
diff --git a/gin/v8_initializer.h b/gin/v8_initializer.h
index ec64afd9dd91b292604ca834a91b9cfbd52eb853..6f7382cd600cd34916d9382878aee4b469dae5d0 100644
index ec64afd9dd91b292604ca834a91b9cfbd52eb853..61ed0f46437d2e1abbcebcfb64df06d17c8d9139 100644
--- a/gin/v8_initializer.h
+++ b/gin/v8_initializer.h
@@ -7,6 +7,8 @@
@@ -7,8 +7,11 @@
#include <stdint.h>
@@ -123,8 +165,20 @@ index ec64afd9dd91b292604ca834a91b9cfbd52eb853..6f7382cd600cd34916d9382878aee4b4
+
#include "base/files/file.h"
#include "base/files/memory_mapped_file.h"
+#include "base/functional/callback.h"
#include "build/build_config.h"
@@ -43,6 +45,7 @@ class GIN_EXPORT V8Initializer {
#include "gin/array_buffer.h"
#include "gin/gin_export.h"
@@ -26,6 +29,8 @@ class StartupData;
namespace gin {
+void SetV8SnapshotValidator(const base::RepeatingCallback<void(v8::StartupData*)>& callback);
+
class GIN_EXPORT V8Initializer {
public:
// This should be called by IsolateHolder::Initialize().
@@ -43,6 +48,7 @@ class GIN_EXPORT V8Initializer {
int* snapshot_size_out);
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)

View File

@@ -1,20 +1,59 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Apthorp <jeremya@chromium.org>
Date: Wed, 10 Oct 2018 15:07:34 -0700
Subject: command-ismediakey.patch
Subject: feat: extend globalShortcut for media keys and Wayland
Override MediaKeysListener::IsMediaKeycode and associated functions to also listen for
Volume Up, Volume Down, and Mute.
Also apply electron/electron@0f67b1866a9f00b852370e721affa4efda623f3a
and electron/electron@d2368d2d3b3de9eec4cc32b6aaf035cc89921bf1 as
patches.
Extends Chromium's global accelerator infrastructure to support
Electron's globalShortcut API. Recognizes volume up/down/mute as media
keys so they can be registered as shortcuts. On macOS, forces use of
ui::MediaKeysListener instead of MPRemoteCommandCenter so media keys
fire without the app first playing audio. Plumbs the Super/Meta/Win
modifier through the X11, Ozone and Windows listeners so shortcuts
using that key work on Linux and Windows. On Wayland, converts
accelerators to XDG shortcut-spec strings and passes them as
preferred_trigger to the global shortcuts portal so registration
doesn't require manual user input. The Wayland portion is a candidate
for upstreaming.
diff --git a/content/browser/media/media_keys_listener_manager_impl.cc b/content/browser/media/media_keys_listener_manager_impl.cc
index e87c180342b967756efeb701c73207fcee8754f1..42e37564e585987d367921568f0f1d2b7507f953 100644
index e87c180342b967756efeb701c73207fcee8754f1..9baf89efbade01e8b60c579255f10799914e144f 100644
--- a/content/browser/media/media_keys_listener_manager_impl.cc
+++ b/content/browser/media/media_keys_listener_manager_impl.cc
@@ -412,6 +412,11 @@ void MediaKeysListenerManagerImpl::UpdateSystemMediaControlsEnabledControls() {
@@ -87,7 +87,11 @@ bool MediaKeysListenerManagerImpl::StartWatchingMediaKey(
CanActiveMediaSessionControllerReceiveEvents();
// Tell the underlying MediaKeysListener to listen for the key.
- if (should_start_watching && media_keys_listener_ &&
+ if (
+#if BUILDFLAG(IS_MAC)
+ !media_key_handling_enabled_ &&
+#endif // BUILDFLAG(IS_MAC)
+ should_start_watching && media_keys_listener_ &&
!media_keys_listener_->StartWatchingMediaKey(key_code)) {
return false;
}
@@ -361,6 +365,20 @@ void MediaKeysListenerManagerImpl::StartListeningForMediaKeysIfNecessary() {
this, ui::MediaKeysListener::Scope::kGlobal);
DCHECK(media_keys_listener_);
}
+
+#if BUILDFLAG(IS_MAC)
+ // Chromium's implementation of SystemMediaControls falls
+ // down into MPRemoteCommandCenter, which makes it such that an app will not
+ // will not receive remote control events until it begins playing audio.
+ // If there's not already a MediaKeysListener instance, create one so
+ // that globalShortcuts work correctly.
+ if (!media_keys_listener_) {
+ media_keys_listener_ = ui::MediaKeysListener::Create(
+ this, ui::MediaKeysListener::Scope::kGlobal);
+ DCHECK(media_keys_listener_);
+ }
+#endif
+
EnsureAuxiliaryServices();
}
@@ -412,6 +430,11 @@ void MediaKeysListenerManagerImpl::UpdateSystemMediaControlsEnabledControls() {
case ui::VKEY_MEDIA_STOP:
browser_system_media_controls_->SetIsStopEnabled(should_enable);
break;
@@ -26,7 +65,7 @@ index e87c180342b967756efeb701c73207fcee8754f1..42e37564e585987d367921568f0f1d2b
default:
NOTREACHED();
}
@@ -454,6 +459,11 @@ void MediaKeysListenerManagerImpl::UpdateSystemMediaControlsEnabledControls() {
@@ -454,6 +477,11 @@ void MediaKeysListenerManagerImpl::UpdateSystemMediaControlsEnabledControls() {
case ui::VKEY_MEDIA_STOP:
smc->SetIsStopEnabled(should_enable);
break;
@@ -38,6 +77,185 @@ index e87c180342b967756efeb701c73207fcee8754f1..42e37564e585987d367921568f0f1d2b
default:
NOTREACHED();
}
diff --git a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.cc b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.cc
index 0e9bffaf0203d39d9fb82d717f36b449d5566181..5cf3d98f4679a252290a34c15491a8a4a619ac1c 100644
--- a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.cc
+++ b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.cc
@@ -62,6 +62,22 @@ void GlobalAcceleratorListener::UnregisterAccelerator(
}
}
+// static
+void GlobalAcceleratorListener::SetShouldUseInternalMediaKeyHandling(bool should_use) {
+ if (content::MediaKeysListenerManager::
+ IsMediaKeysListenerManagerEnabled()) {
+ content::MediaKeysListenerManager* media_keys_listener_manager =
+ content::MediaKeysListenerManager::GetInstance();
+ DCHECK(media_keys_listener_manager);
+
+ if (should_use) {
+ media_keys_listener_manager->EnableInternalMediaKeyHandling();
+ } else {
+ media_keys_listener_manager->DisableInternalMediaKeyHandling();
+ }
+ }
+}
+
void GlobalAcceleratorListener::UnregisterAccelerators(Observer* observer) {
auto it = accelerator_map_.begin();
while (it != accelerator_map_.end()) {
diff --git a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.h b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.h
index 4a343f4e701928644ff3f2a855cc04c3fea2932a..a48b7b73508942cc05e0dcf0fe108313f265c7c6 100644
--- a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.h
+++ b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.h
@@ -9,6 +9,7 @@
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
+#include "content/public/browser/media_keys_listener_manager.h"
#include "ui/base/accelerators/command.h"
#include "ui/gfx/native_ui_types.h"
@@ -43,6 +44,9 @@ class GlobalAcceleratorListener {
// The instance may be nullptr.
static GlobalAcceleratorListener* GetInstance();
+ // enables media keys to work with Electron's globalShortcut module.
+ static void SetShouldUseInternalMediaKeyHandling(bool should_use);
+
// Register an observer for when a certain `accelerator` is struck. Returns
// true if register successfully, or false if the specified `accelerator`
// has been registered by another caller or other native applications.
diff --git a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.cc b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.cc
index 37faffac6fbb00d356c7cc4e685441f7c4d32481..31bd60c4638e48e91c95b5df8c943ca13c3bc134 100644
--- a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.cc
+++ b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_linux.cc
@@ -15,6 +15,7 @@
#include "base/logging.h"
#include "base/nix/xdg_util.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/dbus/thread_linux/dbus_thread_linux.h"
#include "components/dbus/xdg/portal.h"
@@ -49,6 +50,91 @@ std::string GetShortcutPrefix(const std::string& accelerator_group_id,
.substr(0, 32);
}
+// Converts a ui::Accelerator to an XDG shortcut string:
+// https://specifications.freedesktop.org/shortcuts-spec/latest/.
+std::string AcceleratorToXdgTrigger(const ui::Accelerator& accelerator) {
+ std::string trigger;
+
+ if (accelerator.IsCtrlDown()) {
+ trigger += "CTRL+";
+ }
+ if (accelerator.IsAltDown()) {
+ trigger += "ALT+";
+ }
+ if (accelerator.IsShiftDown()) {
+ trigger += "SHIFT+";
+ }
+ if (accelerator.IsCmdDown()) {
+ trigger += "LOGO+";
+ }
+
+ ui::KeyboardCode key = accelerator.key_code();
+ if (key >= ui::VKEY_A && key <= ui::VKEY_Z) {
+ trigger += base::ToLowerASCII(static_cast<char>(key));
+ } else if (key >= ui::VKEY_0 && key <= ui::VKEY_9) {
+ trigger += static_cast<char>(key);
+ } else if (key >= ui::VKEY_F1 && key <= ui::VKEY_F24) {
+ trigger += "F" + base::NumberToString(1 + (key - ui::VKEY_F1));
+ } else {
+ switch (key) {
+ case ui::VKEY_SPACE:
+ trigger += "space";
+ break;
+ case ui::VKEY_RETURN:
+ trigger += "Return";
+ break;
+ case ui::VKEY_TAB:
+ trigger += "Tab";
+ break;
+ case ui::VKEY_ESCAPE:
+ trigger += "Escape";
+ break;
+ case ui::VKEY_BACK:
+ trigger += "BackSpace";
+ break;
+ case ui::VKEY_DELETE:
+ trigger += "Delete";
+ break;
+ case ui::VKEY_INSERT:
+ trigger += "Insert";
+ break;
+ case ui::VKEY_HOME:
+ trigger += "Home";
+ break;
+ case ui::VKEY_END:
+ trigger += "End";
+ break;
+ case ui::VKEY_PRIOR:
+ trigger += "Page_Up";
+ break;
+ case ui::VKEY_NEXT:
+ trigger += "Page_Down";
+ break;
+ case ui::VKEY_UP:
+ trigger += "Up";
+ break;
+ case ui::VKEY_DOWN:
+ trigger += "Down";
+ break;
+ case ui::VKEY_LEFT:
+ trigger += "Left";
+ break;
+ case ui::VKEY_RIGHT:
+ trigger += "Right";
+ break;
+ case ui::VKEY_OEM_COMMA:
+ trigger += "comma";
+ break;
+ case ui::VKEY_OEM_PERIOD:
+ trigger += "period";
+ break;
+ default:
+ return "";
+ }
+ }
+ return trigger;
+}
+
} // namespace
GlobalAcceleratorListenerLinux::BoundCommand::BoundCommand() = default;
@@ -292,6 +378,12 @@ void GlobalAcceleratorListenerLinux::BindShortcuts(DbusShortcuts old_shortcuts,
new_props["description"] =
dbus_utils::Variant::Wrap<"s">(std::move(*description));
}
+ auto preferred_trigger =
+ TakeFromDict<std::string>(properties, "preferred_trigger");
+ if (preferred_trigger) {
+ new_props["preferred_trigger"] =
+ dbus_utils::Variant::Wrap<"s">(std::move(*preferred_trigger));
+ }
shortcuts.emplace_back(id, std::move(new_props));
}
@@ -299,6 +391,12 @@ void GlobalAcceleratorListenerLinux::BindShortcuts(DbusShortcuts old_shortcuts,
dbus_xdg::Dictionary props;
props["description"] = dbus_utils::Variant::Wrap<"s">(
base::UTF16ToUTF8(bound_cmd.command.description()));
+ std::string trigger =
+ AcceleratorToXdgTrigger(bound_cmd.command.accelerator());
+ if (!trigger.empty()) {
+ props["preferred_trigger"] =
+ dbus_utils::Variant::Wrap<"s">(std::move(trigger));
+ }
shortcuts.emplace_back(modified_id, std::move(props));
}
diff --git a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_ozone.cc b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_ozone.cc
index 0e85d30f7015b48a92fe33cea2bb4ec0fe7e6b19..0c9978710079bbdbf55f89bf7966f3ad4c1c4845 100644
--- a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener_ozone.cc

View File

@@ -1,23 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Thu, 18 Oct 2018 17:07:17 -0700
Subject: gritsettings_resource_ids.patch
Add electron resources file to the list of resource ids generation.
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
index bc4d99704dcdb1f2d688fb6d847304ac7a45d3a8..5087a431bb9bd1fba7779f01c738c9d19cbfb63c 100644
--- a/tools/gritsettings/resource_ids.spec
+++ b/tools/gritsettings/resource_ids.spec
@@ -1661,6 +1661,11 @@
"includes": [12000],
},
+ "electron/build/electron_resources.grd": {
+ "messages": [31750],
+ "includes": [31950],
+ }
+
# END "everything else" section.
# Everything but chrome/, components/, content/, and ios/

View File

@@ -1,32 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Apthorp <nornagon@nornagon.net>
Date: Thu, 20 Sep 2018 17:48:38 -0700
Subject: gtk_visibility.patch
Allow electron to depend on GTK in the GN build.
diff --git a/build/config/linux/gtk/BUILD.gn b/build/config/linux/gtk/BUILD.gn
index fdc3442590bddda969681d49c451d32f086bd5d1..b6fd63c0c845e5d7648e8693f1639b1f0f39a779 100644
--- a/build/config/linux/gtk/BUILD.gn
+++ b/build/config/linux/gtk/BUILD.gn
@@ -27,6 +27,7 @@ pkg_config("gtk_internal_config") {
group("gtk") {
visibility = [
+ "//electron:*",
# These are allow-listed for WebRTC builds. Nothing in else should depend
# on GTK.
"//examples:peerconnection_client",
diff --git a/ui/ozone/platform/x11/BUILD.gn b/ui/ozone/platform/x11/BUILD.gn
index 75a94f4deaec7b71fc54911e7dec6c90e42670db..a77cdc899faaf31ae403c0566f821b965e08b010 100644
--- a/ui/ozone/platform/x11/BUILD.gn
+++ b/ui/ozone/platform/x11/BUILD.gn
@@ -6,7 +6,7 @@ import("//build/config/chromeos/ui_mode.gni")
import("//gpu/vulkan/features.gni")
import("//ui/base/ui_features.gni")
-visibility = [ "//ui/ozone/*" ]
+visibility = [ "//ui/ozone/*", "//electron:*" ]
assert(is_linux || is_chromeos)

View File

@@ -0,0 +1,81 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 4 Oct 2018 14:57:02 -0700
Subject: fix: HWND aspect ratio handling for resizable windows
Allows SetAspectRatio to accept 0 as valid input, which resets the
stored aspect ratio to null. Electron's BrowserWindow.setAspectRatio(0)
relies on this to clear a previously-set ratio constraint.
Also adds the native frame border size to the min/max window sizes in
SizeWindowToAspectRatio when the widget reports its size as client
size. Without this adjustment, windows with both an aspect ratio and a
max width/height cannot be enlarged to the correct dimensions and
trigger a DCHECK on resize.
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index c9edcfeb4df4a52dd744b43f04ff1675f566a620..31060227432ab705c4f2c4c52233f2f23d860124 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -638,7 +638,7 @@ void DesktopWindowTreeHostWin::SetOpacity(float opacity) {
void DesktopWindowTreeHostWin::SetAspectRatio(
const gfx::SizeF& aspect_ratio,
const gfx::Size& excluded_margin) {
- DCHECK(!aspect_ratio.IsEmpty());
+ DCHECK_NE(aspect_ratio.height(), 0);
message_handler_->SetAspectRatio(aspect_ratio.width() / aspect_ratio.height(),
excluded_margin);
}
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index 6a4f780c6921d901e9f954d1f7ba18c40d8847b9..cc86c89d5670fd53eb3eea2aa31f054475b47b4b 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -1047,8 +1047,11 @@ void HWNDMessageHandler::SetFullscreen(bool fullscreen,
void HWNDMessageHandler::SetAspectRatio(float aspect_ratio,
const gfx::Size& excluded_margin) {
- // If the aspect ratio is not in the valid range, do nothing.
- DCHECK_GT(aspect_ratio, 0.0f);
+ // If the aspect ratio is 0, reset it to null.
+ if (aspect_ratio == 0.0f) {
+ aspect_ratio_.reset();
+ return;
+ }
aspect_ratio_ = aspect_ratio;
excluded_margin_dip_ = excluded_margin;
@@ -3857,17 +3860,30 @@ void HWNDMessageHandler::SizeWindowToAspectRatio(UINT param,
delegate_->GetMinMaxSize(&min_window_size, &max_window_size);
min_window_size = delegate_->DIPToScreenSize(min_window_size);
max_window_size = delegate_->DIPToScreenSize(max_window_size);
+ // Add the native frame border size to the minimum and maximum size if the
+ // view reports its size as the client size.
+ if (delegate_->WidgetSizeIsClientSize()) {
+ RECT client_rect, rect;
+ GetClientRect(hwnd(), &client_rect);
+ GetWindowRect(hwnd(), &rect);
+ CR_DEFLATE_RECT(&rect, &client_rect);
+ min_window_size.Enlarge(rect.right - rect.left,
+ rect.bottom - rect.top);
+ // Either axis may be zero, so enlarge them independently.
+ if (max_window_size.width())
+ max_window_size.Enlarge(rect.right - rect.left, 0);
+ if (max_window_size.height())
+ max_window_size.Enlarge(0, rect.bottom - rect.top);
+ }
std::optional<gfx::Size> max_size_param;
if (!max_window_size.IsEmpty()) {
max_size_param = max_window_size;
}
- gfx::Size excluded_margin = delegate_->DIPToScreenSize(excluded_margin_dip_);
-
- gfx::SizeRectToAspectRatioWithExcludedMargin(
+ gfx::SizeRectToAspectRatio(
GetWindowResizeEdge(param), aspect_ratio_.value(), min_window_size,
- max_size_param, excluded_margin, *window_rect);
+ max_size_param, window_rect);
}
POINT HWNDMessageHandler::GetCursorPos() const {

View File

@@ -1,17 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: zoy <zoy-l@outlook.com>
Date: Mon, 5 May 2025 23:28:53 +0800
Subject: fix: resolve dynamic background material update issue on Windows 11
From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com>
Date: Wed, 17 Aug 2022 13:49:40 -0700
Subject: fix: HWND style handling for frameless and Mica windows
This patch addresses issues with background materials on Windows 11,
such as the background turning black when maximizing the window and
dynamic background material settings not taking effect.
Adjusts HWNDMessageHandler's window style and NC-message handling to
support Electron's frameless, transparent, and Mica/Acrylic windows.
Electron retains WS_CAPTION on opaque frameless windows (removing it
causes a Windows 7 frame glitch on startup) but must strip it for
transparent and popup windows, so OnCreate conditions the removal on
is_translucent_/WS_POPUP rather than !HasFrame(). For translucent
windows using Windows 11 backdrop materials, WM_NCACTIVATE must reach
DefWindowProc (with lParam=-1 to suppress NC painting), the Glic-
specific !is_translucent_ resize restriction is dropped so these
windows can maximize, and ResetWindowRegion skips the custom region
path to avoid a white title bar when maximized. A SetIsTranslucent
accessor is added to DesktopWindowTreeHostWin so backgroundMaterial
can be changed at runtime.
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index 1f66f36c028b97f018e116ae41a8d9b078620757..e19955df73a287fcade8e6c90ed02558e45d210b 100644
index ceb6e3ad0e60b1aaee47c24564ca9fd8b3c2e71f..35433949e2933e0c886c1e05dd54ce4b5b6cbe71 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -184,6 +184,10 @@ void DesktopWindowTreeHostWin::FinishTouchDrag(gfx::Point screen_point) {
@@ -167,6 +167,10 @@ void DesktopWindowTreeHostWin::FinishTouchDrag(gfx::Point screen_point) {
}
}
@@ -23,7 +34,7 @@ index 1f66f36c028b97f018e116ae41a8d9b078620757..e19955df73a287fcade8e6c90ed02558
void DesktopWindowTreeHostWin::Init(const Widget::InitParams& params) {
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
index 0cd07fd5fb55dcc0d972de4c027fcb895d156592..0f4d335e1d54b5e92fc217080d86513db94d4122 100644
index e8acd2828ed05deefa335ce2bb461f0c3be8d7b7..32377f112337e4f2f9dd17410eaffe089fda1368 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
@@ -93,6 +93,8 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
@@ -36,7 +47,7 @@ index 0cd07fd5fb55dcc0d972de4c027fcb895d156592..0f4d335e1d54b5e92fc217080d86513d
// Overridden from DesktopWindowTreeHost:
void Init(const Widget::InitParams& params) override;
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index 5f483e5271facd23f50ebda981a7bce9e7f20791..43132e8040059296373f121b6fb2863023eb3a57 100644
index b1950dade1cc98a82c75b4b242a34338b2ba741c..43132e8040059296373f121b6fb2863023eb3a57 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -986,13 +986,13 @@ void HWNDMessageHandler::FrameTypeChanged() {
@@ -89,7 +100,32 @@ index 5f483e5271facd23f50ebda981a7bce9e7f20791..43132e8040059296373f121b6fb28630
return;
}
@@ -2436,17 +2448,18 @@ LRESULT HWNDMessageHandler::OnNCActivate(UINT message,
@@ -1857,7 +1869,23 @@ LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) {
::SendMessage(hwnd(), WM_CHANGEUISTATE, MAKELPARAM(UIS_CLEAR, UISF_HIDEFOCUS),
0);
- if (!delegate_->HasFrame()) {
+ LONG is_popup =
+ ::GetWindowLong(hwnd(), GWL_STYLE) & static_cast<LONG>(WS_POPUP);
+
+ // For transparent windows, Electron removes the WS_CAPTION style,
+ // so we continue to remove it here. If we didn't, an opaque rectangle
+ // would show up.
+ // For non-transparent windows, Electron keeps the WS_CAPTION style,
+ // so we don't remove it in that case. If we did, a Windows 7 frame
+ // would show up.
+ // We also need this block for frameless popup windows. When the user opens
+ // a dropdown in an Electron app, the internal popup menu from
+ // third_party/blink/renderer/core/html/forms/internal_popup_menu.h
+ // is rendered. That menu is actually an HTML page inside of a frameless popup window.
+ // A new popup window is created every time the user opens the dropdown,
+ // and this code path is run. The code block below runs SendFrameChanged,
+ // which gives the dropdown options the proper layout.
+ if (!delegate_->HasFrame() && (is_translucent_ || is_popup)) {
::SetWindowLong(hwnd(), GWL_STYLE,
::GetWindowLong(hwnd(), GWL_STYLE) & ~WS_CAPTION);
SendFrameChanged();
@@ -2420,17 +2448,18 @@ LRESULT HWNDMessageHandler::OnNCActivate(UINT message,
delegate_->SchedulePaint();
}

View File

@@ -1,83 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <samuel.r.attard@gmail.com>
Date: Thu, 18 Oct 2018 17:07:27 -0700
Subject: isolate_holder.patch
Pass pre allocated isolate for initialization, node platform
needs to register on an isolate so that it can be used later
down in the initialization process of an isolate.
Specifically, v8::Isolate::Initialize ends up calling
NodePlatform::GetForegroundTaskRunner, which requires that the
isolate has previously been registered with NodePlatform::RegisterIsolate.
However, if we let gin allocate the isolate, there's no opportunity
for us to register the isolate in between Isolate::Allocate and
Isolate::Initialize.
diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc
index 15904644aa5451c6cb0fc2a46a67678824cd0bec..64edf6fe78d2478cb9e12e8767a09e2b6c7c6ad2 100644
--- a/gin/isolate_holder.cc
+++ b/gin/isolate_holder.cc
@@ -81,7 +81,8 @@ IsolateHolder::IsolateHolder(
v8::AddHistogramSampleCallback add_histogram_sample_callback,
scoped_refptr<base::SingleThreadTaskRunner> user_visible_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> best_effort_task_runner,
- std::unique_ptr<v8::CppHeap> cpp_heap)
+ std::unique_ptr<v8::CppHeap> cpp_heap,
+ v8::Isolate* isolate)
: IsolateHolder(std::move(task_runner),
access_mode,
isolate_type,
@@ -92,7 +93,8 @@ IsolateHolder::IsolateHolder(
std::move(cpp_heap)),
isolate_creation_mode,
std::move(user_visible_task_runner),
- std::move(best_effort_task_runner)) {}
+ std::move(best_effort_task_runner),
+ isolate) {}
IsolateHolder::IsolateHolder(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
@@ -101,7 +103,8 @@ IsolateHolder::IsolateHolder(
std::unique_ptr<v8::Isolate::CreateParams> params,
IsolateCreationMode isolate_creation_mode,
scoped_refptr<base::SingleThreadTaskRunner> user_visible_task_runner,
- scoped_refptr<base::SingleThreadTaskRunner> best_effort_task_runner)
+ scoped_refptr<base::SingleThreadTaskRunner> best_effort_task_runner,
+ v8::Isolate* isolate)
: access_mode_(access_mode), isolate_type_(isolate_type) {
CHECK(Initialized())
<< "You need to invoke gin::IsolateHolder::Initialize first";
@@ -112,7 +115,7 @@ IsolateHolder::IsolateHolder(
v8::ArrayBuffer::Allocator* allocator = params->array_buffer_allocator;
DCHECK(allocator);
- isolate_ = v8::Isolate::Allocate();
+ isolate_ = isolate ? isolate : v8::Isolate::Allocate();
isolate_data_ = std::make_unique<PerIsolateData>(
isolate_, allocator, access_mode_, task_runner,
std::move(user_visible_task_runner), std::move(best_effort_task_runner));
diff --git a/gin/public/isolate_holder.h b/gin/public/isolate_holder.h
index a57b92f02085d6392e6d9d0cc037df6b972f3c31..902ad13dad8df57325f6c74ee3da9ec3148751cb 100644
--- a/gin/public/isolate_holder.h
+++ b/gin/public/isolate_holder.h
@@ -89,7 +89,8 @@ class GIN_EXPORT IsolateHolder {
nullptr,
scoped_refptr<base::SingleThreadTaskRunner> best_effort_task_runner =
nullptr,
- std::unique_ptr<v8::CppHeap> cpp_heap = {});
+ std::unique_ptr<v8::CppHeap> cpp_heap = {},
+ v8::Isolate* isolate = nullptr);
IsolateHolder(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
AccessMode access_mode,
@@ -99,7 +100,8 @@ class GIN_EXPORT IsolateHolder {
scoped_refptr<base::SingleThreadTaskRunner> user_visible_task_runner =
nullptr,
scoped_refptr<base::SingleThreadTaskRunner> best_effort_task_runner =
- nullptr);
+ nullptr,
+ v8::Isolate* isolate = nullptr);
IsolateHolder(const IsolateHolder&) = delete;
IsolateHolder& operator=(const IsolateHolder&) = delete;
~IsolateHolder();

View File

@@ -1,57 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Thu, 7 Apr 2022 20:30:16 +0900
Subject: Make gtk::GetLibGdkPixbuf and gtk::GetLibGdk public
Allows embedders to get handles to the gdk_pixbuf
and gdk libraries already loaded in the process.
diff --git a/ui/gtk/gtk_compat.cc b/ui/gtk/gtk_compat.cc
index e05b4f2eb1b22d5a647cb020bae4e4052a2e735c..86524a419606bea3e7d090415fda8f2d8ce24df2 100644
--- a/ui/gtk/gtk_compat.cc
+++ b/ui/gtk/gtk_compat.cc
@@ -78,11 +78,6 @@ void* GetLibGio() {
return libgio;
}
-void* GetLibGdkPixbuf() {
- static void* libgdk_pixbuf = DlOpen("libgdk_pixbuf-2.0.so.0");
- return libgdk_pixbuf;
-}
-
void* GetLibGdk3() {
static void* libgdk3 = DlOpen("libgdk-3.so.0");
return libgdk3;
@@ -175,6 +170,15 @@ gfx::Insets InsetsFromGtkBorder(const GtkBorder& border) {
} // namespace
+void* GetLibGdkPixbuf() {
+ static void* libgdk_pixbuf = DlOpen("libgdk_pixbuf-2.0.so.0");
+ return libgdk_pixbuf;
+}
+
+void* GetLibGdk() {
+ return GtkCheckVersion(4) ? GetLibGtk4() : GetLibGdk3();
+}
+
bool LoadGtk(ui::LinuxUiBackend backend) {
static bool loaded = LoadGtkImpl(backend);
return loaded;
diff --git a/ui/gtk/gtk_compat.h b/ui/gtk/gtk_compat.h
index 841e2e8fcdbe2da4aac487badd4d352476e461a2..043c3ab4dde02ca71798034e8cb2b3f2d2677af7 100644
--- a/ui/gtk/gtk_compat.h
+++ b/ui/gtk/gtk_compat.h
@@ -42,6 +42,12 @@ using SkColor = uint32_t;
namespace gtk {
+// Get handle to the currently loaded gdk_pixbuf library in the process.
+void* GetLibGdkPixbuf();
+
+// Get handle to the currently loaded gdk library in the process.
+void* GetLibGdk();
+
// Loads libgtk and related libraries and returns true on success.
bool LoadGtk(ui::LinuxUiBackend backend);

View File

@@ -1,11 +1,22 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andy Dill <andy.dill@gmail.com>
Date: Thu, 30 Jan 2020 09:36:07 -0800
Subject: feat: enable off-screen rendering with viz compositor
Subject: feat: enable offscreen rendering with viz compositor
This patch adds hooks in the relevant places that allow for off-screen
rendering with the viz compositor by way of a custom HostDisplayClient
and LayeredWindowUpdater.
Adds the hooks Electron's offscreen-rendering API needs to receive
composited frames from the viz display compositor: a CompositorDelegate
on ui::Compositor that supplies a custom HostDisplayClient, a new
SoftwareOutputDeviceProxy that ships frames (with damage rects) over the
LayeredWindowUpdater mojo interface on every platform, and view/
delegate_view fields on WebContents::CreateParams so Electron can inject
its OSR WebContentsView. Also disables native popup menus on macOS when
offscreen so they appear in the captured frame, makes
GetNewScreenInfosForUpdate virtual so OSR can report its own screen
info, and drops the D3D11 keyed mutex on Windows OSR shared textures to
avoid the performance cost when there is no concurrent access.
Not upstreamable in this form; embedder hooks in viz/content would need
to be designed to fit Chromium's headless/capture paths.
diff --git a/components/viz/host/host_display_client.cc b/components/viz/host/host_display_client.cc
index b153c538488b7b77af0630a454604d9fb7eba487..1b97bfae745d3aeaa4ebd3d3a0dfc64f48da0d70 100644
@@ -583,6 +594,129 @@ index 59a7d48453bc4d317c5760f57ad3bf84d5a81106..6b03be074cfd1ef113394debbfeeb646
root_params->display_client =
compositor_data.display_client->GetBoundRemote(resize_task_runner_);
mojo::AssociatedRemote<viz::mojom::ExternalBeginFrameController>
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h
index 1a18bdda39f76cfae36adc0ffde136e788a98262..1062bada30908399f5429b51031e245f4d010f84 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -680,7 +680,7 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
// Generates the most current set of ScreenInfos from the current set of
// displays in the system for use in UpdateScreenInfo.
- display::ScreenInfos GetNewScreenInfosForUpdate();
+ virtual display::ScreenInfos GetNewScreenInfosForUpdate();
// Called when display properties that need to be synchronized with the
// renderer process changes. This method is called before notifying
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index afb060d27384204565995d10d3f44ca46b4a301b..ae601ef503f0e721544273a03695ef31259787d8 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -4203,6 +4203,13 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
params.main_frame_name, GetOpener(), primary_main_frame_policy,
base::UnguessableToken::Create());
+ if (params.view && params.delegate_view) {
+ view_.reset(params.view);
+ render_view_host_delegate_view_ = params.delegate_view;
+ }
+
+ if (!view_) {
+
std::unique_ptr<WebContentsViewDelegate> delegate =
GetContentClient()->browser()->GetWebContentsViewDelegate(this);
@@ -4213,6 +4220,7 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
view_ = CreateWebContentsView(this, std::move(delegate),
&render_view_host_delegate_view_);
}
+ } // !view_
CHECK(render_view_host_delegate_view_);
CHECK(view_.get());
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
index a02a9134feae75d4fe95f2d8163983bdec447b2b..055302c00a625f4570c57243be3bd0ae02a73347 100644
--- a/content/public/browser/web_contents.h
+++ b/content/public/browser/web_contents.h
@@ -130,11 +130,14 @@ class PrerenderHandle;
class RenderFrameHost;
class RenderViewHost;
class RenderWidgetHost;
+class RenderViewHostDelegateView;
class RenderWidgetHostView;
+class RenderWidgetHostViewBase;
class ScreenOrientationDelegate;
class SiteInstance;
class UnownedInnerWebContentsClient;
class WebContentsDelegate;
+class WebContentsView;
class WebUI;
struct DropData;
struct GlobalRenderFrameHostId;
@@ -296,6 +299,10 @@ class WebContents : public PageNavigator, public base::SupportsUserData {
network::mojom::WebSandboxFlags starting_sandbox_flags =
network::mojom::WebSandboxFlags::kNone;
+ // Optionally specify the view and delegate view.
+ raw_ptr<content::WebContentsView> view = nullptr;
+ raw_ptr<content::RenderViewHostDelegateView> delegate_view = nullptr;
+
// Value used to set the last time the WebContents was made active, this is
// the value that'll be returned by GetLastActiveTimeTicks(). If this is
// left default initialized then the value is not passed on to the
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc
index 6f31a20329a7bc7cafb6384c3b8ec9ed7a11e64e..3bf92efa5c0ad0212096e61383b53095867aa62e 100644
--- a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc
@@ -379,7 +379,8 @@ gfx::GpuMemoryBufferHandle D3DImageBackingFactory::CreateGpuMemoryBufferHandle(
// so make sure that the usage is one that we support.
DCHECK(usage == gfx::BufferUsage::GPU_READ ||
usage == gfx::BufferUsage::SCANOUT ||
- usage == gfx::BufferUsage::SCANOUT_CPU_READ_WRITE)
+ usage == gfx::BufferUsage::SCANOUT_CPU_READ_WRITE ||
+ usage == gfx::BufferUsage::SCANOUT_VEA_CPU_READ)
<< "Incorrect usage, usage=" << gfx::BufferUsageToString(usage);
D3D11_TEXTURE2D_DESC desc = {
@@ -393,7 +394,9 @@ gfx::GpuMemoryBufferHandle D3DImageBackingFactory::CreateGpuMemoryBufferHandle(
D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET,
0,
D3D11_RESOURCE_MISC_SHARED_NTHANDLE |
- D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX};
+ static_cast<UINT>(usage == gfx::BufferUsage::SCANOUT_VEA_CPU_READ
+ ? D3D11_RESOURCE_MISC_SHARED
+ : D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX)};
Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture;
diff --git a/media/video/renderable_mappable_shared_image_video_frame_pool.cc b/media/video/renderable_mappable_shared_image_video_frame_pool.cc
index 36ed797edc58a6cf094a0b720bf949b3f6379890..36a4a080da38cddad645d42e5c53c840e211105e 100644
--- a/media/video/renderable_mappable_shared_image_video_frame_pool.cc
+++ b/media/video/renderable_mappable_shared_image_video_frame_pool.cc
@@ -211,6 +211,24 @@ bool FrameResources::Initialize(VideoPixelFormat format,
const gfx::Size coded_size =
GetCodedSizeForVideoPixelFormat(format, visible_size_);
+#if BUILDFLAG(IS_WIN)
+ // For CEF OSR feature, currently there's no other place in chromium use RGBA.
+ // If the format is RGBA, currently CEF do not write to the texture anymore
+ // once the GMB is returned from CopyRequest. So there will be no race
+ // condition on that texture. We can request a GMB without a keyed mutex to
+ // accelerate and probably prevent some driver deadlock.
+ if (format == PIXEL_FORMAT_ARGB || format == PIXEL_FORMAT_ABGR ||
+ format == PIXEL_FORMAT_RGBAF16) {
+ // This value is 'borrowed', SCANOUT_VEA_CPU_READ is probably invalid
+ // cause there's no real SCANOUT on Windows. We simply use this enum as a
+ // flag to disable mutex in the GMBFactoryDXGI because this enum is also
+ // used above in macOS and CrOS for similar usage (claim no other one will
+ // concurrently use the resource).
+ // https://chromium-review.googlesource.com/c/chromium/src/+/5302103
+ buffer_usage = gfx::BufferUsage::SCANOUT_VEA_CPU_READ;
+ }
+#endif
+
gpu::SharedImageUsageSet usage =
#if BUILDFLAG(IS_MAC)
gpu::SHARED_IMAGE_USAGE_MACOS_VIDEO_TOOLBOX |
diff --git a/services/viz/privileged/mojom/compositing/display_private.mojom b/services/viz/privileged/mojom/compositing/display_private.mojom
index 00bd84b857fbd5915edf9e45c805e06a3a76a467..18c4391ba498f0379a1ce4204f72c35baa3dd4ec 100644
--- a/services/viz/privileged/mojom/compositing/display_private.mojom
@@ -618,8 +752,21 @@ index 2f462f0deb5fc8a637457243fb5d5849fc214d14..695869b83cefaa24af93a2e11b39de05
- Draw() => ();
+ Draw(gfx.mojom.Rect damage_rect) => ();
};
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 4aa7a851d7280411009ed8a50fd04c78f9cb41cd..d626e66d2059dc7172f28b95637516781ff3f754 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -1855,6 +1855,8 @@ void WebView::ApplyWebPreferences(const web_pref::WebPreferences& prefs,
#if BUILDFLAG(IS_MAC)
web_view_impl->SetMaximumLegibleScale(
prefs.default_maximum_page_scale_factor);
+ web_view_impl->GetChromeClient().SetUseExternalPopupMenus(
+ !prefs.offscreen);
#endif
#if BUILDFLAG(IS_WIN)
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
index 97f26777528c3b21255b74ccf411ff2d3b243215..d45839ebc7b07ade2ca382e15b1d48dcf7d29106 100644
index 76354011ebcf4bce949af90c2301051626c357e3..2c24993f1a509856966bb4a1302db97d976ad4ba 100644
--- a/ui/compositor/compositor.h
+++ b/ui/compositor/compositor.h
@@ -89,6 +89,7 @@ class DisplayPrivate;
@@ -656,7 +803,7 @@ index 97f26777528c3b21255b74ccf411ff2d3b243215..d45839ebc7b07ade2ca382e15b1d48dc
// Sets the root of the layer tree drawn by this Compositor. The root layer
// must have no parent. The compositor's root layer is reset if the root layer
// is destroyed. NULL can be passed to reset the root layer, in which case the
@@ -632,6 +645,8 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver,
@@ -636,6 +649,8 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver,
simple_begin_frame_observers_;
std::unique_ptr<ui::HostBeginFrameObserver> host_begin_frame_observer_;

View File

@@ -1,66 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: reito <cnschwarzer@qq.com>
Date: Thu, 15 Aug 2024 14:05:52 +0800
Subject: Remove DXGI GMB keyed-mutex
This patch removes the keyed mutex of the d3d11 texture only when the texture is requested by offscreen rendering and on Windows.
The keyed mutex introduce extra performance cost and spikes. However, at offscreen rendering scenario, the shared resources will not be simultaneously read from & written to, typically just one reader, so it doesn't need such exclusive guarantee, and it's safe to remove this mutex for extra performance gain.
For resolving complex conflict please pin @reitowo
For more reason please see: https://crrev.com/c/5465148
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc
index 6f31a20329a7bc7cafb6384c3b8ec9ed7a11e64e..3bf92efa5c0ad0212096e61383b53095867aa62e 100644
--- a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc
@@ -379,7 +379,8 @@ gfx::GpuMemoryBufferHandle D3DImageBackingFactory::CreateGpuMemoryBufferHandle(
// so make sure that the usage is one that we support.
DCHECK(usage == gfx::BufferUsage::GPU_READ ||
usage == gfx::BufferUsage::SCANOUT ||
- usage == gfx::BufferUsage::SCANOUT_CPU_READ_WRITE)
+ usage == gfx::BufferUsage::SCANOUT_CPU_READ_WRITE ||
+ usage == gfx::BufferUsage::SCANOUT_VEA_CPU_READ)
<< "Incorrect usage, usage=" << gfx::BufferUsageToString(usage);
D3D11_TEXTURE2D_DESC desc = {
@@ -393,7 +394,9 @@ gfx::GpuMemoryBufferHandle D3DImageBackingFactory::CreateGpuMemoryBufferHandle(
D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET,
0,
D3D11_RESOURCE_MISC_SHARED_NTHANDLE |
- D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX};
+ static_cast<UINT>(usage == gfx::BufferUsage::SCANOUT_VEA_CPU_READ
+ ? D3D11_RESOURCE_MISC_SHARED
+ : D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX)};
Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture;
diff --git a/media/video/renderable_mappable_shared_image_video_frame_pool.cc b/media/video/renderable_mappable_shared_image_video_frame_pool.cc
index 36ed797edc58a6cf094a0b720bf949b3f6379890..36a4a080da38cddad645d42e5c53c840e211105e 100644
--- a/media/video/renderable_mappable_shared_image_video_frame_pool.cc
+++ b/media/video/renderable_mappable_shared_image_video_frame_pool.cc
@@ -211,6 +211,24 @@ bool FrameResources::Initialize(VideoPixelFormat format,
const gfx::Size coded_size =
GetCodedSizeForVideoPixelFormat(format, visible_size_);
+#if BUILDFLAG(IS_WIN)
+ // For CEF OSR feature, currently there's no other place in chromium use RGBA.
+ // If the format is RGBA, currently CEF do not write to the texture anymore
+ // once the GMB is returned from CopyRequest. So there will be no race
+ // condition on that texture. We can request a GMB without a keyed mutex to
+ // accelerate and probably prevent some driver deadlock.
+ if (format == PIXEL_FORMAT_ARGB || format == PIXEL_FORMAT_ABGR ||
+ format == PIXEL_FORMAT_RGBAF16) {
+ // This value is 'borrowed', SCANOUT_VEA_CPU_READ is probably invalid
+ // cause there's no real SCANOUT on Windows. We simply use this enum as a
+ // flag to disable mutex in the GMBFactoryDXGI because this enum is also
+ // used above in macOS and CrOS for similar usage (claim no other one will
+ // concurrently use the resource).
+ // https://chromium-review.googlesource.com/c/chromium/src/+/5302103
+ buffer_usage = gfx::BufferUsage::SCANOUT_VEA_CPU_READ;
+ }
+#endif
+
gpu::SharedImageUsageSet usage =
#if BUILDFLAG(IS_MAC)
gpu::SHARED_IMAGE_USAGE_MACOS_VIDEO_TOOLBOX |

View File

@@ -1,22 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: reito <reito@chromium.org>
Date: Wed, 29 Oct 2025 00:50:03 +0800
Subject: patch: osr control screen info
We need to override GetNewScreenInfosForUpdate to ensure the screen info
is updated correctly, instead of overriding GetScreenInfo which seems not
working.
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h
index 1a18bdda39f76cfae36adc0ffde136e788a98262..1062bada30908399f5429b51031e245f4d010f84 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -680,7 +680,7 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
// Generates the most current set of ScreenInfos from the current set of
// displays in the system for use in UpdateScreenInfo.
- display::ScreenInfos GetNewScreenInfosForUpdate();
+ virtual display::ScreenInfos GetNewScreenInfosForUpdate();
// Called when display properties that need to be synchronized with the
// renderer process changes. This method is called before notifying

View File

@@ -1,13 +1,91 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Heilig Benedek <benecene@gmail.com>
Date: Sat, 10 Aug 2019 00:41:50 +0200
Subject: feat: enable picture in picture mode for video players
Subject: feat: adapt Picture-in-Picture for Electron (no //chrome deps)
These files are needed to implement PiP, but the Electron build patches out
chrome's generated resources for our own. This updates the #include so that we
don't get errors for Chrome's generated resources, which are non-existent
because we don't generate them in our build.
Electron reuses Chromium's Picture-in-Picture overlay window
implementation from //chrome, but must excise dependencies on
Chrome-only infrastructure that does not exist in our build:
Profile, Browser, MediaEngagementService, live caption UI, the
auto-PiP content-settings helper, and Chrome-branded vector icons.
This patch guards those pieces behind GOOGLE_CHROME_BRANDING or
#if 0 and swaps in a generic views close icon so the PiP window
compiles and functions without pulling in //chrome UI layers.
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc
index cccf164d978761dac8148d11fbddfbeb9ecfb048..295a16cd4f1e369c78d34b4da24ea3c830ce20e4 100644
--- a/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc
+++ b/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc
@@ -6,6 +6,7 @@
#include "base/memory/raw_ptr.h"
#include "base/numerics/safe_conversions.h"
+#include "build/branding_buildflags.h"
#include "chrome/browser/picture_in_picture/picture_in_picture_bounds_cache.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "content/public/browser/document_picture_in_picture_window_controller.h"
@@ -31,8 +32,10 @@
#include "base/task/sequenced_task_runner.h"
// TODO(crbug.com/421608904): include auto_picture_in_picture_tab_helper for
// Android when supporting document PiP.
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
#include "chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.h"
#include "chrome/browser/picture_in_picture/auto_pip_setting_overlay_view.h"
+#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
#include "chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.h"
#include "chrome/browser/picture_in_picture/picture_in_picture_window.h"
#include "media/base/media_switches.h"
@@ -71,6 +74,7 @@ constexpr double kMaxWindowSizeRatio = 0.8;
// `kMaxWindowSizeRatio`.
constexpr double kMaxSiteRequestedWindowSizeRatio = 0.25;
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
// Returns true if a document picture-in-picture window should be focused upon
// opening it.
bool ShouldFocusPictureInPictureWindow(const NavigateParams& params) {
@@ -87,6 +91,7 @@ bool ShouldFocusPictureInPictureWindow(const NavigateParams& params) {
// AutoPictureInPictureTabHelper.
return !auto_picture_in_picture_tab_helper->IsInAutoPictureInPicture();
}
+#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
// Returns the maximum area in pixels that the site can request a
// picture-in-picture window to be.
@@ -220,7 +225,7 @@ bool PictureInPictureWindowManager::ExitPictureInPictureViaWindowUi(
return false;
}
-#if !BUILDFLAG(IS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
// The user manually closed the pip window, so let the tab helper know in case
// the auto-pip permission dialog was visible.
if (auto* tab_helper = AutoPictureInPictureTabHelper::FromWebContents(
@@ -572,7 +577,7 @@ gfx::Size PictureInPictureWindowManager::GetMaximumWindowSize(
// static
void PictureInPictureWindowManager::SetWindowParams(NavigateParams& params) {
-#if !BUILDFLAG(IS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
// Always show document picture-in-picture in a new window. When this is
// not opened via the AutoPictureInPictureTabHelper, focus the window.
params.window_action =
@@ -681,6 +686,7 @@ PictureInPictureWindowManager::GetOverlayView(
return nullptr;
}
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
// It would be nice to create this in `EnterPictureInPicture*`, but detecting
// auto-pip while pip is in the process of opening doesn't work.
//
@@ -719,6 +725,8 @@ PictureInPictureWindowManager::GetOverlayView(
}
return overlay_view;
+#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
+ return nullptr;
}
PictureInPictureOcclusionTracker*
diff --git a/chrome/browser/ui/views/overlay/close_image_button.cc b/chrome/browser/ui/views/overlay/close_image_button.cc
index a7a637438116a1c7846194dea4412100a45c9331..bb3877d546bfea141d3d6ebb396b88faab6ee34e 100644
--- a/chrome/browser/ui/views/overlay/close_image_button.cc
@@ -38,7 +116,7 @@ index a7a637438116a1c7846194dea4412100a45c9331..bb3877d546bfea141d3d6ebb396b88fa
ui::ImageModel::FromVectorIcon(*icon, kColorPipWindowForeground,
kCloseButtonIconSize));
diff --git a/chrome/browser/ui/views/overlay/video_overlay_window_views.cc b/chrome/browser/ui/views/overlay/video_overlay_window_views.cc
index 69b2fbfbcbabda336021c5b4935f6d6e4cdd1a7e..c9214d904f2ef51e42369b28a2055c5f2f3bcce1 100644
index 69b2fbfbcbabda336021c5b4935f6d6e4cdd1a7e..7981a2517b9bd0b0863e7e2bb8511f40f45d9a21 100644
--- a/chrome/browser/ui/views/overlay/video_overlay_window_views.cc
+++ b/chrome/browser/ui/views/overlay/video_overlay_window_views.cc
@@ -18,12 +18,16 @@
@@ -87,7 +165,21 @@ index 69b2fbfbcbabda336021c5b4935f6d6e4cdd1a7e..c9214d904f2ef51e42369b28a2055c5f
std::wstring app_user_model_id;
Browser* browser = chrome::FindBrowserWithTab(controller->GetWebContents());
if (browser) {
@@ -704,6 +710,7 @@ void VideoOverlayWindowViews::OnMouseEvent(ui::MouseEvent* event) {
@@ -438,11 +444,13 @@ std::unique_ptr<VideoOverlayWindowViews> VideoOverlayWindowViews::Create(
#endif // BUILDFLAG(IS_WIN)
+#if 0
PictureInPictureOcclusionTracker* tracker =
PictureInPictureWindowManager::GetInstance()->GetOcclusionTracker();
if (tracker) {
tracker->OnPictureInPictureWidgetOpened(overlay_window.get());
}
+#endif
return overlay_window;
}
@@ -704,6 +712,7 @@ void VideoOverlayWindowViews::OnMouseEvent(ui::MouseEvent* event) {
}
case ui::EventType::kMousePressed:
@@ -95,7 +187,7 @@ index 69b2fbfbcbabda336021c5b4935f6d6e4cdd1a7e..c9214d904f2ef51e42369b28a2055c5f
// Hide the live caption dialog if it's visible and the user clicks
// outside of it.
if (live_caption_dialog_ && live_caption_dialog_->GetVisible() &&
@@ -712,6 +719,7 @@ void VideoOverlayWindowViews::OnMouseEvent(ui::MouseEvent* event) {
@@ -712,6 +721,7 @@ void VideoOverlayWindowViews::OnMouseEvent(ui::MouseEvent* event) {
SetLiveCaptionDialogVisibility(false);
return;
}
@@ -103,7 +195,7 @@ index 69b2fbfbcbabda336021c5b4935f6d6e4cdd1a7e..c9214d904f2ef51e42369b28a2055c5f
break;
default:
@@ -747,11 +755,11 @@ bool VideoOverlayWindowViews::HideLiveCaptionDialogForGestureIfNecessary(
@@ -747,11 +757,11 @@ bool VideoOverlayWindowViews::HideLiveCaptionDialogForGestureIfNecessary(
if (event->type() != ui::EventType::kGestureTap) {
return false;
}
@@ -117,7 +209,7 @@ index 69b2fbfbcbabda336021c5b4935f6d6e4cdd1a7e..c9214d904f2ef51e42369b28a2055c5f
if (!GetLiveCaptionDialogBounds().Contains(event->location())) {
SetLiveCaptionDialogVisibility(false);
event->SetHandled();
@@ -1237,6 +1245,7 @@ void VideoOverlayWindowViews::SetUpViews() {
@@ -1237,6 +1247,7 @@ void VideoOverlayWindowViews::SetUpViews() {
timestamp->SetBackgroundColor(SK_ColorTRANSPARENT);
timestamp->SetHorizontalAlignment(gfx::ALIGN_LEFT);
@@ -125,7 +217,7 @@ index 69b2fbfbcbabda336021c5b4935f6d6e4cdd1a7e..c9214d904f2ef51e42369b28a2055c5f
auto live_status = std::make_unique<views::Label>(
l10n_util::GetStringUTF16(IDS_PICTURE_IN_PICTURE_LIVE_STATUS_TEXT),
views::style::CONTEXT_LABEL, views::style::STYLE_CAPTION_BOLD);
@@ -1256,6 +1265,7 @@ void VideoOverlayWindowViews::SetUpViews() {
@@ -1256,6 +1267,7 @@ void VideoOverlayWindowViews::SetUpViews() {
Profile::FromBrowserContext(
controller_->GetWebContents()->GetBrowserContext()));
live_caption_dialog->SetVisible(false);
@@ -133,7 +225,7 @@ index 69b2fbfbcbabda336021c5b4935f6d6e4cdd1a7e..c9214d904f2ef51e42369b28a2055c5f
auto toggle_microphone_button =
std::make_unique<ToggleMicrophoneButton>(base::BindRepeating(
@@ -1378,13 +1388,15 @@ void VideoOverlayWindowViews::SetUpViews() {
@@ -1378,13 +1390,15 @@ void VideoOverlayWindowViews::SetUpViews() {
timestamp_ =
playback_controls_container_view_->AddChildView(std::move(timestamp));
@@ -150,7 +242,7 @@ index 69b2fbfbcbabda336021c5b4935f6d6e4cdd1a7e..c9214d904f2ef51e42369b28a2055c5f
toggle_camera_button_ = vc_controls_container_view_->AddChildView(
std::move(toggle_camera_button));
@@ -1663,6 +1675,7 @@ void VideoOverlayWindowViews::OnUpdateControlsBounds() {
@@ -1663,6 +1677,7 @@ void VideoOverlayWindowViews::OnUpdateControlsBounds() {
timestamp_->SetSize({max_timestamp_width, kTimestampHeight});
timestamp_->SetVisible(!is_live_);
@@ -158,7 +250,7 @@ index 69b2fbfbcbabda336021c5b4935f6d6e4cdd1a7e..c9214d904f2ef51e42369b28a2055c5f
live_status_->SetPosition(timestamp_position);
live_status_->SetMaximumWidthSingleLine(max_timestamp_width);
live_status_->SetSize(
@@ -1670,7 +1683,6 @@ void VideoOverlayWindowViews::OnUpdateControlsBounds() {
@@ -1670,7 +1685,6 @@ void VideoOverlayWindowViews::OnUpdateControlsBounds() {
.width(),
kTimestampHeight});
live_status_->SetVisible(is_live_);
@@ -166,7 +258,7 @@ index 69b2fbfbcbabda336021c5b4935f6d6e4cdd1a7e..c9214d904f2ef51e42369b28a2055c5f
gfx::Rect live_caption_button_bounds(
bottom_controls_bounds.right() - kBottomControlsHorizontalMargin -
kActionButtonSize.width(),
@@ -1683,7 +1695,7 @@ void VideoOverlayWindowViews::OnUpdateControlsBounds() {
@@ -1683,7 +1697,7 @@ void VideoOverlayWindowViews::OnUpdateControlsBounds() {
live_caption_dialog_->SetPosition(
{live_caption_button_bounds.right() - live_caption_dialog_->width(),
live_caption_button_bounds.y() - live_caption_dialog_->height()});
@@ -175,7 +267,7 @@ index 69b2fbfbcbabda336021c5b4935f6d6e4cdd1a7e..c9214d904f2ef51e42369b28a2055c5f
// The play/pause button and replay/forward 10 seconds buttons should not be
// visible while dragging the progress bar or for live media.
const bool is_dragging_progress_bar =
@@ -2096,18 +2108,25 @@ gfx::Rect VideoOverlayWindowViews::GetProgressViewBounds() {
@@ -2096,18 +2110,25 @@ gfx::Rect VideoOverlayWindowViews::GetProgressViewBounds() {
}
gfx::Rect VideoOverlayWindowViews::GetLiveCaptionButtonBounds() {
@@ -201,7 +293,7 @@ index 69b2fbfbcbabda336021c5b4935f6d6e4cdd1a7e..c9214d904f2ef51e42369b28a2055c5f
MediaEngagementService* service =
MediaEngagementService::Get(Profile::FromBrowserContext(
GetController()->GetWebContents()->GetBrowserContext()));
@@ -2116,6 +2135,8 @@ bool VideoOverlayWindowViews::HasHighMediaEngagement(
@@ -2116,6 +2137,8 @@ bool VideoOverlayWindowViews::HasHighMediaEngagement(
}
return service->HasHighEngagement(origin);
@@ -210,7 +302,7 @@ index 69b2fbfbcbabda336021c5b4935f6d6e4cdd1a7e..c9214d904f2ef51e42369b28a2055c5f
}
bool VideoOverlayWindowViews::IsTrustedForMediaPlayback() const {
@@ -2377,11 +2398,14 @@ void VideoOverlayWindowViews::UpdateTimestampLabel(base::TimeDelta current_time,
@@ -2377,11 +2400,14 @@ void VideoOverlayWindowViews::UpdateTimestampLabel(base::TimeDelta current_time,
}
void VideoOverlayWindowViews::OnLiveCaptionButtonPressed() {
@@ -225,7 +317,7 @@ index 69b2fbfbcbabda336021c5b4935f6d6e4cdd1a7e..c9214d904f2ef51e42369b28a2055c5f
if (wanted_visibility == live_caption_dialog_->GetVisible()) {
return;
}
@@ -2404,6 +2428,7 @@ void VideoOverlayWindowViews::SetLiveCaptionDialogVisibility(
@@ -2404,6 +2430,7 @@ void VideoOverlayWindowViews::SetLiveCaptionDialogVisibility(
for (auto* control : controls_to_be_disabled_when_live_caption_is_open) {
control->SetEnabled(!wanted_visibility);
}

View File

@@ -1,249 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Raymond Zhao <raymondzhao@microsoft.com>
Date: Wed, 18 Aug 2021 08:24:10 -0700
Subject: extend ProcessSingleton
This patch applies Electron ProcessSingleton changes onto the Chromium
files.
This patch adds a few changes to the Chromium code:
1. It adds a parameter `program_name` to the Windows constructor, making
the generated mutex name on the Windows-side program-dependent,
rather than shared between all Electron applications.
2. It adds an `IsAppSandboxed` check for macOS so that
sandboxed applications generate shorter temp paths.
3. It adds a `ChangeWindowMessageFilterEx` call to the Windows
implementation, along with a parameter `is_app_sandboxed` in the
constructor, to handle the case when the primary app is run with
admin permissions.
diff --git a/chrome/browser/process_singleton.h b/chrome/browser/process_singleton.h
index e11ccd361a0837eef71869b65f510830171c3a29..f076d0f783e2c0f6b5444002f756001adf2729bd 100644
--- a/chrome/browser/process_singleton.h
+++ b/chrome/browser/process_singleton.h
@@ -101,12 +101,19 @@ class ProcessSingleton {
base::RepeatingCallback<bool(base::CommandLine command_line,
const base::FilePath& current_directory)>;
+#if BUILDFLAG(IS_WIN)
+ ProcessSingleton(const std::string& program_name,
+ const base::FilePath& user_data_dir,
+ bool is_sandboxed,
+ const NotificationCallback& notification_callback);
+#else
ProcessSingleton(const base::FilePath& user_data_dir,
const NotificationCallback& notification_callback);
ProcessSingleton(const ProcessSingleton&) = delete;
ProcessSingleton& operator=(const ProcessSingleton&) = delete;
+#endif
~ProcessSingleton();
// Notify another process, if available. Otherwise sets ourselves as the
@@ -175,6 +182,8 @@ class ProcessSingleton {
#if BUILDFLAG(IS_WIN)
bool EscapeVirtualization(const base::FilePath& user_data_dir);
+ std::string program_name_; // Used for mutexName.
+ bool is_app_sandboxed_; // Whether the Electron app is sandboxed.
HWND remote_window_; // The HWND_MESSAGE of another browser.
base::win::MessageWindow window_; // The message-only window.
bool is_virtualized_; // Stuck inside Microsoft Softricity VM environment.
diff --git a/chrome/browser/process_singleton_posix.cc b/chrome/browser/process_singleton_posix.cc
index f36983753ab7bdf2ecd332408f1f3d9c01f87a62..5a88dfda5eb2c4bf5b547a76eef81b530f3ea96e 100644
--- a/chrome/browser/process_singleton_posix.cc
+++ b/chrome/browser/process_singleton_posix.cc
@@ -55,6 +55,7 @@
#include <memory>
#include <set>
#include <string>
+#include <tuple>
#include <type_traits>
#include "base/base_paths.h"
@@ -86,6 +87,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/task/sequenced_task_runner_helpers.h"
#include "base/task/single_thread_task_runner.h"
+#include "base/threading/thread_restrictions.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
@@ -102,7 +104,7 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/scoped_startup_resource_bundle.h"
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+#if 0
#include "chrome/browser/ui/process_singleton_dialog_linux.h"
#endif
@@ -353,6 +355,8 @@ bool SymlinkPath(const base::FilePath& target, const base::FilePath& path) {
bool DisplayProfileInUseError(const base::FilePath& lock_path,
const std::string& hostname,
int pid) {
+ return true;
+#if 0
// Ensure there is an instance of ResourceBundle that is initialized for
// localized string resource accesses.
ui::ScopedStartupResourceBundle ensure_startup_resource_bundle;
@@ -375,6 +379,7 @@ bool DisplayProfileInUseError(const base::FilePath& lock_path,
#else
NOTREACHED();
#endif
+#endif
}
bool IsChromeProcess(pid_t pid) {
@@ -387,6 +392,21 @@ bool IsChromeProcess(pid_t pid) {
base::FilePath(chrome::kBrowserProcessExecutableName));
}
+bool IsAppSandboxed() {
+#if BUILDFLAG(IS_MAC)
+ // NB: There is no sane API for this, we have to just guess by
+ // reading tea leaves
+ base::FilePath home_dir;
+ if (!base::PathService::Get(base::DIR_HOME, &home_dir)) {
+ return false;
+ }
+
+ return home_dir.value().find("Library/Containers") != std::string::npos;
+#else
+ return false;
+#endif // BUILDFLAG(IS_MAC)
+}
+
// A helper class to hold onto a socket.
class ScopedSocket {
public:
@@ -773,6 +793,10 @@ ProcessSingleton::~ProcessSingleton() {
if (watcher_) {
watcher_->OnEminentProcessSingletonDestruction();
}
+ // Manually free resources with IO explicitly allowed.
+ base::ScopedAllowBlocking allow_blocking;
+ watcher_ = nullptr;
+ std::ignore = socket_dir_.Delete();
}
ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
@@ -1045,11 +1069,32 @@ bool ProcessSingleton::Create() {
// Create the socket file somewhere in /tmp which is usually mounted as a
// normal filesystem. Some network filesystems (notably AFS) are screwy and
// do not support Unix domain sockets.
- if (!socket_dir_.CreateUniqueTempDir(/*prefix=*/FILE_PATH_LITERAL(""))) {
- LOG(ERROR) << "Failed to create socket directory.";
+ base::FilePath tmp_dir;
+ if (!base::GetTempDir(&tmp_dir)) {
+ LOG(ERROR) << "Failed to get temporary directory.";
return false;
}
+ if (IsAppSandboxed()) {
+ // For sandboxed applications, the tmp dir could be too long to fit
+ // addr->sun_path, so we need to make it as short as possible.
+ if (!socket_dir_.Set(tmp_dir.Append("S"))) {
+ LOG(ERROR) << "Failed to set socket directory.";
+ return false;
+ }
+ } else {
+ // Create the socket file somewhere in /tmp which is usually mounted as a
+ // normal filesystem. Some network filesystems (notably AFS) are screwy and
+ // do not support Unix domain sockets.
+ // Prefer CreateUniqueTempDirUnderPath rather than CreateUniqueTempDir as
+ // the latter will calculate unique paths based on bundle ids which can
+ // increase the socket path length than what is allowed.
+ if (!socket_dir_.CreateUniqueTempDirUnderPath(tmp_dir)) {
+ LOG(ERROR) << "Failed to create socket directory.";
+ return false;
+ }
+ }
+
// Check that the directory was created with the correct permissions.
int dir_mode = 0;
CHECK(base::GetPosixFilePermissions(socket_dir_.GetPath(), &dir_mode) &&
diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc
index ff44618efa8f8082b5da2c416802b781290c6cac..ae659d84a5ae2f2e87ce288477506575f8d86839 100644
--- a/chrome/browser/process_singleton_win.cc
+++ b/chrome/browser/process_singleton_win.cc
@@ -29,7 +29,9 @@
#include "base/win/wmi.h"
#include "chrome/browser/process_singleton_internal.h"
#include "chrome/browser/shell_integration.h"
+#if 0
#include "chrome/browser/ui/simple_message_box.h"
+#endif
#include "chrome/browser/win/chrome_process_finder.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
@@ -164,6 +166,7 @@ bool ProcessLaunchNotification(
}
bool DisplayShouldKillMessageBox() {
+#if 0
TRACE_EVENT0("startup", "ProcessSingleton:DisplayShouldKillMessageBox");
// Ensure there is an instance of ResourceBundle that is initialized for
@@ -174,6 +177,10 @@ bool DisplayShouldKillMessageBox() {
NULL, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
l10n_util::GetStringUTF16(IDS_BROWSER_HUNGBROWSER_MESSAGE)) !=
chrome::MESSAGE_BOX_RESULT_NO;
+#endif
+ // This is called when the secondary process can't ping the primary
+ // process.
+ return false;
}
// Function was copied from Process::Terminate.
@@ -256,9 +263,13 @@ bool ProcessSingleton::EscapeVirtualization(
}
ProcessSingleton::ProcessSingleton(
+ const std::string& program_name,
const base::FilePath& user_data_dir,
+ bool is_app_sandboxed,
const NotificationCallback& notification_callback)
: notification_callback_(notification_callback),
+ program_name_(program_name),
+ is_app_sandboxed_(is_app_sandboxed),
is_virtualized_(false),
lock_file_(INVALID_HANDLE_VALUE),
user_data_dir_(user_data_dir),
@@ -381,7 +392,7 @@ ProcessSingleton::NotifyOtherProcessOrCreate() {
bool ProcessSingleton::Create() {
TRACE_EVENT0("startup", "ProcessSingleton::Create");
- static const wchar_t kMutexName[] = L"Local\\ChromeProcessSingletonStartup!";
+ std::wstring mutexName = base::UTF8ToWide("Local\\" + program_name_ + "ProcessSingletonStartup");
remote_window_ = FindRunningChromeWindow(user_data_dir_);
if (!remote_window_ && !EscapeVirtualization(user_data_dir_)) {
@@ -390,7 +401,7 @@ bool ProcessSingleton::Create() {
// access. As documented, it's clearer to NOT request ownership on creation
// since it isn't guaranteed we will get it. It is better to create it
// without ownership and explicitly get the ownership afterward.
- base::win::ScopedHandle only_me(::CreateMutex(NULL, FALSE, kMutexName));
+ base::win::ScopedHandle only_me(::CreateMutex(NULL, FALSE, mutexName.c_str()));
if (!only_me.is_valid()) {
DPLOG(FATAL) << "CreateMutex failed";
return false;
@@ -429,6 +440,17 @@ bool ProcessSingleton::Create() {
window_.CreateNamed(base::BindRepeating(&ProcessLaunchNotification,
notification_callback_),
user_data_dir_.value());
+
+ // When the app is sandboxed, firstly, the app should not be in
+ // admin mode, and even if it somehow is, messages from an unelevated
+ // instance should not be able to be sent to it.
+ if (!is_app_sandboxed_) {
+ // NB: Ensure that if the primary app gets started as elevated
+ // admin inadvertently, secondary windows running not as elevated
+ // will still be able to send messages.
+ ::ChangeWindowMessageFilterEx(window_.hwnd(), WM_COPYDATA, MSGFLT_ALLOW,
+ NULL);
+ }
CHECK(result && window_.hwnd());
}
}

View File

@@ -1,19 +1,22 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Raymond Zhao <raymondzhao@microsoft.com>
Date: Tue, 7 Sep 2021 14:54:25 -0700
Subject: feat: Add data parameter to ProcessSingleton
Date: Wed, 18 Aug 2021 08:24:10 -0700
Subject: feat: extend ProcessSingleton for app.requestSingleInstanceLock
This patch adds an additional_data parameter to the constructor of
ProcessSingleton, so that the second instance can send additional
data over to the first instance while requesting the ProcessSingleton
lock.
Extends ProcessSingleton to support app.requestSingleInstanceLock:
On the Electron side, we then expose an extra parameter to the
app.requestSingleInstanceLock API so that users can pass in a JSON
object for the second instance to send to the first instance.
1. Adds an additional_data parameter so a second instance can pass
arbitrary serialized data to the first instance, surfaced to apps
via the 'second-instance' event.
2. Makes the Windows mutex name program-dependent so separate Electron
apps don't share a single-instance lock.
3. Shortens the socket path on sandboxed macOS apps to fit sun_path.
4. Calls ChangeWindowMessageFilterEx on Windows so unelevated second
instances can notify a primary instance running elevated.
5. Disables Chrome's profile-in-use/hung-browser dialogs.
diff --git a/chrome/browser/process_singleton.h b/chrome/browser/process_singleton.h
index f076d0f783e2c0f6b5444002f756001adf2729bd..a03d99f929e2d354cdba969567d781561656261d 100644
index e11ccd361a0837eef71869b65f510830171c3a29..a03d99f929e2d354cdba969567d781561656261d 100644
--- a/chrome/browser/process_singleton.h
+++ b/chrome/browser/process_singleton.h
@@ -18,7 +18,8 @@
@@ -26,7 +29,7 @@ index f076d0f783e2c0f6b5444002f756001adf2729bd..a03d99f929e2d354cdba969567d78156
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
#include "base/files/scoped_temp_dir.h"
#endif
@@ -99,21 +100,24 @@ class ProcessSingleton {
@@ -99,10 +100,20 @@ class ProcessSingleton {
// should handle it (i.e., because the current process is shutting down).
using NotificationCallback =
base::RepeatingCallback<bool(base::CommandLine command_line,
@@ -34,13 +37,13 @@ index f076d0f783e2c0f6b5444002f756001adf2729bd..a03d99f929e2d354cdba969567d78156
+ const base::FilePath& current_directory,
+ const std::vector<uint8_t> additional_data)>;
#if BUILDFLAG(IS_WIN)
ProcessSingleton(const std::string& program_name,
const base::FilePath& user_data_dir,
+#if BUILDFLAG(IS_WIN)
+ ProcessSingleton(const std::string& program_name,
+ const base::FilePath& user_data_dir,
+ const base::raw_span<const uint8_t> additional_data,
bool is_sandboxed,
const NotificationCallback& notification_callback);
#else
+ bool is_sandboxed,
+ const NotificationCallback& notification_callback);
+#else
ProcessSingleton(const base::FilePath& user_data_dir,
+ const base::raw_span<const uint8_t> additional_data,
const NotificationCallback& notification_callback);
@@ -48,12 +51,7 @@ index f076d0f783e2c0f6b5444002f756001adf2729bd..a03d99f929e2d354cdba969567d78156
ProcessSingleton(const ProcessSingleton&) = delete;
ProcessSingleton& operator=(const ProcessSingleton&) = delete;
-#endif
~ProcessSingleton();
// Notify another process, if available. Otherwise sets ourselves as the
@@ -177,7 +181,10 @@ class ProcessSingleton {
@@ -170,11 +181,16 @@ class ProcessSingleton {
#endif
private:
@@ -64,11 +62,81 @@ index f076d0f783e2c0f6b5444002f756001adf2729bd..a03d99f929e2d354cdba969567d78156
#if BUILDFLAG(IS_WIN)
bool EscapeVirtualization(const base::FilePath& user_data_dir);
+ std::string program_name_; // Used for mutexName.
+ bool is_app_sandboxed_; // Whether the Electron app is sandboxed.
HWND remote_window_; // The HWND_MESSAGE of another browser.
base::win::MessageWindow window_; // The message-only window.
bool is_virtualized_; // Stuck inside Microsoft Softricity VM environment.
diff --git a/chrome/browser/process_singleton_posix.cc b/chrome/browser/process_singleton_posix.cc
index 5a88dfda5eb2c4bf5b547a76eef81b530f3ea96e..1204affca14f73d84b57c1b3092079464a4d5430 100644
index f36983753ab7bdf2ecd332408f1f3d9c01f87a62..1204affca14f73d84b57c1b3092079464a4d5430 100644
--- a/chrome/browser/process_singleton_posix.cc
+++ b/chrome/browser/process_singleton_posix.cc
@@ -619,6 +619,7 @@ class ProcessSingleton::LinuxWatcher
@@ -55,6 +55,7 @@
#include <memory>
#include <set>
#include <string>
+#include <tuple>
#include <type_traits>
#include "base/base_paths.h"
@@ -86,6 +87,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/task/sequenced_task_runner_helpers.h"
#include "base/task/single_thread_task_runner.h"
+#include "base/threading/thread_restrictions.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
@@ -102,7 +104,7 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/scoped_startup_resource_bundle.h"
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+#if 0
#include "chrome/browser/ui/process_singleton_dialog_linux.h"
#endif
@@ -353,6 +355,8 @@ bool SymlinkPath(const base::FilePath& target, const base::FilePath& path) {
bool DisplayProfileInUseError(const base::FilePath& lock_path,
const std::string& hostname,
int pid) {
+ return true;
+#if 0
// Ensure there is an instance of ResourceBundle that is initialized for
// localized string resource accesses.
ui::ScopedStartupResourceBundle ensure_startup_resource_bundle;
@@ -375,6 +379,7 @@ bool DisplayProfileInUseError(const base::FilePath& lock_path,
#else
NOTREACHED();
#endif
+#endif
}
bool IsChromeProcess(pid_t pid) {
@@ -387,6 +392,21 @@ bool IsChromeProcess(pid_t pid) {
base::FilePath(chrome::kBrowserProcessExecutableName));
}
+bool IsAppSandboxed() {
+#if BUILDFLAG(IS_MAC)
+ // NB: There is no sane API for this, we have to just guess by
+ // reading tea leaves
+ base::FilePath home_dir;
+ if (!base::PathService::Get(base::DIR_HOME, &home_dir)) {
+ return false;
+ }
+
+ return home_dir.value().find("Library/Containers") != std::string::npos;
+#else
+ return false;
+#endif // BUILDFLAG(IS_MAC)
+}
+
// A helper class to hold onto a socket.
class ScopedSocket {
public:
@@ -599,6 +619,7 @@ class ProcessSingleton::LinuxWatcher
// |reader| is for sending back ACK message.
void HandleMessage(const std::string& current_dir,
const std::vector<std::string>& argv,
@@ -76,7 +144,7 @@ index 5a88dfda5eb2c4bf5b547a76eef81b530f3ea96e..1204affca14f73d84b57c1b309207946
SocketReader* reader);
// Called when the ProcessSingleton that owns this class is about to be
@@ -678,13 +679,17 @@ void ProcessSingleton::LinuxWatcher::StartListening(int socket) {
@@ -658,13 +679,17 @@ void ProcessSingleton::LinuxWatcher::StartListening(int socket) {
}
void ProcessSingleton::LinuxWatcher::HandleMessage(
@@ -96,7 +164,7 @@ index 5a88dfda5eb2c4bf5b547a76eef81b530f3ea96e..1204affca14f73d84b57c1b309207946
// Send back "ACK" message to prevent the client process from starting up.
reader->FinishWithACK(kACKToken);
} else {
@@ -714,7 +719,8 @@ void ProcessSingleton::LinuxWatcher::SocketReader::
@@ -694,7 +719,8 @@ void ProcessSingleton::LinuxWatcher::SocketReader::
bytes_read_ += ReadFromSocketWithTimeout(
fd_, base::span(buf_).subspan(bytes_read_), base::Seconds(0));
@@ -106,7 +174,7 @@ index 5a88dfda5eb2c4bf5b547a76eef81b530f3ea96e..1204affca14f73d84b57c1b309207946
const size_t kMinMessageLength = kStartToken.length() + 4;
if (bytes_read_ < kMinMessageLength) {
buf_[bytes_read_] = 0;
@@ -745,10 +751,45 @@ void ProcessSingleton::LinuxWatcher::SocketReader::
@@ -725,10 +751,45 @@ void ProcessSingleton::LinuxWatcher::SocketReader::
tokens.erase(tokens.begin());
tokens.erase(tokens.begin());
@@ -153,7 +221,7 @@ index 5a88dfda5eb2c4bf5b547a76eef81b530f3ea96e..1204affca14f73d84b57c1b309207946
fd_watch_controller_.reset();
// LinuxWatcher::HandleMessage() is in charge of destroying this SocketReader
@@ -777,8 +818,10 @@ void ProcessSingleton::LinuxWatcher::SocketReader::FinishWithACK(
@@ -757,8 +818,10 @@ void ProcessSingleton::LinuxWatcher::SocketReader::FinishWithACK(
//
ProcessSingleton::ProcessSingleton(
const base::FilePath& user_data_dir,
@@ -164,7 +232,18 @@ index 5a88dfda5eb2c4bf5b547a76eef81b530f3ea96e..1204affca14f73d84b57c1b309207946
current_pid_(base::GetCurrentProcId()) {
socket_path_ = user_data_dir.Append(chrome::kSingletonSocketFilename);
lock_path_ = user_data_dir.Append(chrome::kSingletonLockFilename);
@@ -899,7 +942,8 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
@@ -773,6 +836,10 @@ ProcessSingleton::~ProcessSingleton() {
if (watcher_) {
watcher_->OnEminentProcessSingletonDestruction();
}
+ // Manually free resources with IO explicitly allowed.
+ base::ScopedAllowBlocking allow_blocking;
+ watcher_ = nullptr;
+ std::ignore = socket_dir_.Delete();
}
ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
@@ -875,7 +942,8 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
sizeof(socket_timeout));
// Found another process, prepare our command line
@@ -174,7 +253,7 @@ index 5a88dfda5eb2c4bf5b547a76eef81b530f3ea96e..1204affca14f73d84b57c1b309207946
std::string to_send(kStartToken);
to_send.push_back(kTokenDelimiter);
@@ -909,11 +953,21 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
@@ -885,11 +953,21 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
to_send.append(current_dir.value());
const std::vector<std::string>& argv = cmd_line.argv();
@@ -196,8 +275,43 @@ index 5a88dfda5eb2c4bf5b547a76eef81b530f3ea96e..1204affca14f73d84b57c1b309207946
// Send the message
if (!WriteToSocket(socket.fd(), to_send)) {
// Try to kill the other process, because it might have been dead.
@@ -1045,11 +1123,32 @@ bool ProcessSingleton::Create() {
// Create the socket file somewhere in /tmp which is usually mounted as a
// normal filesystem. Some network filesystems (notably AFS) are screwy and
// do not support Unix domain sockets.
- if (!socket_dir_.CreateUniqueTempDir(/*prefix=*/FILE_PATH_LITERAL(""))) {
- LOG(ERROR) << "Failed to create socket directory.";
+ base::FilePath tmp_dir;
+ if (!base::GetTempDir(&tmp_dir)) {
+ LOG(ERROR) << "Failed to get temporary directory.";
return false;
}
+ if (IsAppSandboxed()) {
+ // For sandboxed applications, the tmp dir could be too long to fit
+ // addr->sun_path, so we need to make it as short as possible.
+ if (!socket_dir_.Set(tmp_dir.Append("S"))) {
+ LOG(ERROR) << "Failed to set socket directory.";
+ return false;
+ }
+ } else {
+ // Create the socket file somewhere in /tmp which is usually mounted as a
+ // normal filesystem. Some network filesystems (notably AFS) are screwy and
+ // do not support Unix domain sockets.
+ // Prefer CreateUniqueTempDirUnderPath rather than CreateUniqueTempDir as
+ // the latter will calculate unique paths based on bundle ids which can
+ // increase the socket path length than what is allowed.
+ if (!socket_dir_.CreateUniqueTempDirUnderPath(tmp_dir)) {
+ LOG(ERROR) << "Failed to create socket directory.";
+ return false;
+ }
+ }
+
// Check that the directory was created with the correct permissions.
int dir_mode = 0;
CHECK(base::GetPosixFilePermissions(socket_dir_.GetPath(), &dir_mode) &&
diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc
index ae659d84a5ae2f2e87ce288477506575f8d86839..274887d62ff8d008bb86815a11205fcaa5f2c2ff 100644
index ff44618efa8f8082b5da2c416802b781290c6cac..274887d62ff8d008bb86815a11205fcaa5f2c2ff 100644
--- a/chrome/browser/process_singleton_win.cc
+++ b/chrome/browser/process_singleton_win.cc
@@ -9,6 +9,7 @@
@@ -208,7 +322,17 @@ index ae659d84a5ae2f2e87ce288477506575f8d86839..274887d62ff8d008bb86815a11205fca
#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
@@ -81,10 +82,12 @@ BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) {
@@ -29,7 +30,9 @@
#include "base/win/wmi.h"
#include "chrome/browser/process_singleton_internal.h"
#include "chrome/browser/shell_integration.h"
+#if 0
#include "chrome/browser/ui/simple_message_box.h"
+#endif
#include "chrome/browser/win/chrome_process_finder.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
@@ -79,10 +82,12 @@ BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) {
bool ParseCommandLine(const COPYDATASTRUCT* cds,
base::CommandLine* parsed_command_line,
@@ -223,7 +347,7 @@ index ae659d84a5ae2f2e87ce288477506575f8d86839..274887d62ff8d008bb86815a11205fca
static const int min_message_size = 7;
if (cds->cbData < min_message_size * sizeof(wchar_t) ||
cds->cbData % sizeof(wchar_t) != 0) {
@@ -134,6 +137,25 @@ bool ParseCommandLine(const COPYDATASTRUCT* cds,
@@ -132,6 +137,25 @@ bool ParseCommandLine(const COPYDATASTRUCT* cds,
const std::wstring cmd_line =
msg.substr(second_null + 1, third_null - second_null);
*parsed_command_line = base::CommandLine::FromString(cmd_line);
@@ -249,7 +373,7 @@ index ae659d84a5ae2f2e87ce288477506575f8d86839..274887d62ff8d008bb86815a11205fca
return true;
}
return false;
@@ -155,13 +177,14 @@ bool ProcessLaunchNotification(
@@ -153,17 +177,19 @@ bool ProcessLaunchNotification(
base::CommandLine parsed_command_line(base::CommandLine::NO_PROGRAM);
base::FilePath current_directory;
@@ -267,19 +391,39 @@ index ae659d84a5ae2f2e87ce288477506575f8d86839..274887d62ff8d008bb86815a11205fca
return true;
}
@@ -265,9 +288,11 @@ bool ProcessSingleton::EscapeVirtualization(
bool DisplayShouldKillMessageBox() {
+#if 0
TRACE_EVENT0("startup", "ProcessSingleton:DisplayShouldKillMessageBox");
// Ensure there is an instance of ResourceBundle that is initialized for
@@ -174,6 +200,10 @@ bool DisplayShouldKillMessageBox() {
NULL, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
l10n_util::GetStringUTF16(IDS_BROWSER_HUNGBROWSER_MESSAGE)) !=
chrome::MESSAGE_BOX_RESULT_NO;
+#endif
+ // This is called when the secondary process can't ping the primary
+ // process.
+ return false;
}
// Function was copied from Process::Terminate.
@@ -256,9 +286,15 @@ bool ProcessSingleton::EscapeVirtualization(
}
ProcessSingleton::ProcessSingleton(
const std::string& program_name,
+ const std::string& program_name,
const base::FilePath& user_data_dir,
+ const base::raw_span<const uint8_t> additional_data,
bool is_app_sandboxed,
+ bool is_app_sandboxed,
const NotificationCallback& notification_callback)
: notification_callback_(notification_callback),
+ additional_data_(additional_data),
program_name_(program_name),
is_app_sandboxed_(is_app_sandboxed),
+ program_name_(program_name),
+ is_app_sandboxed_(is_app_sandboxed),
is_virtualized_(false),
@@ -294,7 +319,7 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
lock_file_(INVALID_HANDLE_VALUE),
user_data_dir_(user_data_dir),
@@ -283,7 +319,7 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
return PROCESS_NONE;
}
@@ -288,6 +432,42 @@ index ae659d84a5ae2f2e87ce288477506575f8d86839..274887d62ff8d008bb86815a11205fca
case NotifyChromeResult::kSuccess:
return PROCESS_NOTIFIED;
case NotifyChromeResult::kFailed:
@@ -381,7 +417,7 @@ ProcessSingleton::NotifyOtherProcessOrCreate() {
bool ProcessSingleton::Create() {
TRACE_EVENT0("startup", "ProcessSingleton::Create");
- static const wchar_t kMutexName[] = L"Local\\ChromeProcessSingletonStartup!";
+ std::wstring mutexName = base::UTF8ToWide("Local\\" + program_name_ + "ProcessSingletonStartup");
remote_window_ = FindRunningChromeWindow(user_data_dir_);
if (!remote_window_ && !EscapeVirtualization(user_data_dir_)) {
@@ -390,7 +426,7 @@ bool ProcessSingleton::Create() {
// access. As documented, it's clearer to NOT request ownership on creation
// since it isn't guaranteed we will get it. It is better to create it
// without ownership and explicitly get the ownership afterward.
- base::win::ScopedHandle only_me(::CreateMutex(NULL, FALSE, kMutexName));
+ base::win::ScopedHandle only_me(::CreateMutex(NULL, FALSE, mutexName.c_str()));
if (!only_me.is_valid()) {
DPLOG(FATAL) << "CreateMutex failed";
return false;
@@ -429,6 +465,17 @@ bool ProcessSingleton::Create() {
window_.CreateNamed(base::BindRepeating(&ProcessLaunchNotification,
notification_callback_),
user_data_dir_.value());
+
+ // When the app is sandboxed, firstly, the app should not be in
+ // admin mode, and even if it somehow is, messages from an unelevated
+ // instance should not be able to be sent to it.
+ if (!is_app_sandboxed_) {
+ // NB: Ensure that if the primary app gets started as elevated
+ // admin inadvertently, secondary windows running not as elevated
+ // will still be able to send messages.
+ ::ChangeWindowMessageFilterEx(window_.hwnd(), WM_COPYDATA, MSGFLT_ALLOW,
+ NULL);
+ }
CHECK(result && window_.hwnd());
}
}
diff --git a/chrome/browser/win/chrome_process_finder.cc b/chrome/browser/win/chrome_process_finder.cc
index 594f3bc08a4385c177fb488123cef79448e94850..28e5a18a19718b2e748ada6882341413a1ab0705 100644
--- a/chrome/browser/win/chrome_process_finder.cc

View File

@@ -1,92 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Thu, 18 Oct 2018 17:07:12 -0700
Subject: proxy_config_monitor.patch
Allow monitoring proxy config changes for a pref service.
diff --git a/chrome/browser/net/proxy_config_monitor.cc b/chrome/browser/net/proxy_config_monitor.cc
index 50e7a07af841ff55cd24c0a79eef5dcc68807933..ed40ecdb91ddd7139f8f463809594ddfca793fcc 100644
--- a/chrome/browser/net/proxy_config_monitor.cc
+++ b/chrome/browser/net/proxy_config_monitor.cc
@@ -11,7 +11,9 @@
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/net/proxy_service_factory.h"
+#if 0
#include "chrome/browser/profiles/profile.h"
+#endif
#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
@@ -21,12 +23,13 @@
#include "chrome/browser/ash/profiles/profile_helper.h"
#endif // BUILDFLAG(IS_CHROMEOS)
-#if BUILDFLAG(ENABLE_EXTENSIONS_CORE)
+#if 0
#include "chrome/browser/extensions/api/proxy/proxy_api.h"
#endif // BUILDFLAG(ENABLE_EXTENSIONS_CORE)
using content::BrowserThread;
+#if 0
ProxyConfigMonitor::ProxyConfigMonitor(Profile* profile) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(profile);
@@ -57,6 +60,7 @@ ProxyConfigMonitor::ProxyConfigMonitor(Profile* profile) {
proxy_config_service_->AddObserver(this);
}
+#endif
ProxyConfigMonitor::ProxyConfigMonitor(PrefService* local_state) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
@@ -135,8 +139,10 @@ void ProxyConfigMonitor::OnLazyProxyConfigPoll() {
void ProxyConfigMonitor::OnPACScriptError(int32_t line_number,
const std::string& details) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+#if 0
extensions::ProxyEventRouter::GetInstance()->OnPACScriptError(
profile_, line_number, base::UTF8ToUTF16(details));
+#endif
}
void ProxyConfigMonitor::OnRequestMaybeFailedDueToProxySettings(
@@ -151,7 +157,9 @@ void ProxyConfigMonitor::OnRequestMaybeFailedDueToProxySettings(
return;
}
+#if 0
extensions::ProxyEventRouter::GetInstance()->OnProxyError(profile_,
net_error);
+#endif
}
#endif // BUILDFLAG(ENABLE_EXTENSIONS_CORE)
diff --git a/chrome/browser/net/proxy_config_monitor.h b/chrome/browser/net/proxy_config_monitor.h
index 6c060b52d25799c6a7c4e4ee86ed7490060560d6..c81481a4451ff50b6ace5372a68b8615819affb3 100644
--- a/chrome/browser/net/proxy_config_monitor.h
+++ b/chrome/browser/net/proxy_config_monitor.h
@@ -40,11 +40,12 @@ class ProxyConfigMonitor : public net::ProxyConfigService::Observer,
{
public:
+#if 0
// Creates a ProxyConfigMonitor that gets proxy settings from |profile| and
// watches for changes. The created ProxyConfigMonitor must be destroyed
// before |profile|.
explicit ProxyConfigMonitor(Profile* profile);
-
+#endif
// Creates a ProxyConfigMonitor that gets proxy settings from the
// |local_state|, for use with NetworkContexts not
// associated with a profile. Must be destroyed before |local_state|.
@@ -94,7 +95,7 @@ class ProxyConfigMonitor : public net::ProxyConfigService::Observer,
#if BUILDFLAG(ENABLE_EXTENSIONS_CORE)
mojo::ReceiverSet<network::mojom::ProxyErrorClient> error_receiver_set_;
- raw_ptr<Profile> profile_ = nullptr;
+ // raw_ptr<Profile> profile_ = nullptr;
#endif // BUILDFLAG(ENABLE_EXTENSIONS_CORE)
};

View File

@@ -44,10 +44,10 @@ index 5e7d992ba2144d32f8eb1c6fa5233c68954318e1..4ff55ddc2286fff096a7e2bcdfb87d87
void RenderWidgetHostImpl::ShowContextMenuAtPoint(
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 1567ac2a65d222080430a47dce97b6d387ebe49d..f605f46115cda0f8f06e5274a26e3b997ca4c62e 100644
index ae601ef503f0e721544273a03695ef31259787d8..76def190aabe280bb8e0971dc5c72643bbce8f53 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -6212,6 +6212,11 @@ TextInputManager* WebContentsImpl::GetTextInputManager() {
@@ -6223,6 +6223,11 @@ TextInputManager* WebContentsImpl::GetTextInputManager() {
return text_input_manager_.get();
}

View File

@@ -1,45 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <sattard@slack-corp.com>
Date: Wed, 23 Oct 2019 11:43:58 -0700
Subject: remove usage of incognito APIs in the spellchecker
chrome::GetBrowserContextRedirectedInIncognito is not available in
Electron nor do we want it to be. We could potentially upstream a
change to move more of //chrome spellchecker logic into //components so
that we can further separate our dependency from //chrome.
diff --git a/chrome/browser/profiles/profile_keyed_service_factory.cc b/chrome/browser/profiles/profile_keyed_service_factory.cc
index 30a7e6a641e7b17a47fb5c66fb44d3d5899b9e78..85764a533585df0abe398758e4fd510c711de375 100644
--- a/chrome/browser/profiles/profile_keyed_service_factory.cc
+++ b/chrome/browser/profiles/profile_keyed_service_factory.cc
@@ -22,6 +22,9 @@ ProfileKeyedServiceFactory::~ProfileKeyedServiceFactory() = default;
content::BrowserContext* ProfileKeyedServiceFactory::GetBrowserContextToUse(
content::BrowserContext* context) const {
+ return context;
+#if 0
Profile* profile = Profile::FromBrowserContext(context);
return profile_selections_.ApplyProfileSelection(profile);
+#endif
}
diff --git a/chrome/browser/profiles/profile_selections.cc b/chrome/browser/profiles/profile_selections.cc
index 25b15408665dc95702e7f1382fb8e7c0bb493599..bc0bad82ebcdceadc505e912ff27202b452fefab 100644
--- a/chrome/browser/profiles/profile_selections.cc
+++ b/chrome/browser/profiles/profile_selections.cc
@@ -132,6 +132,7 @@ ProfileSelection ProfileSelections::GetProfileSelection(
}
#endif // BUILDFLAG(IS_CHROMEOS)
+#if 0
// Treat other off the record profiles as Incognito (primary otr) Profiles.
if (profile->IsRegularProfile() || profile->IsIncognitoProfile() ||
profile_metrics::GetBrowserProfileType(profile) ==
@@ -148,6 +149,8 @@ ProfileSelection ProfileSelections::GetProfileSelection(
}
NOTREACHED();
+#endif
+ return ProfileSelection::kNone;
}
void ProfileSelections::SetProfileSelectionForRegular(

View File

@@ -1,79 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Apthorp <nornagon@nornagon.net>
Date: Thu, 20 Sep 2018 17:48:59 -0700
Subject: resource_file_conflict.patch
Resolve conflict between //chrome's .pak files and //electron's. The paths
that chrome code hardcodes require that we generate resources at these
paths, but GN throws errors if there are multiple targets that generate the
same files.
This is due to the hardcoded names here:
https://chromium.googlesource.com/chromium/src/+/69.0.3497.106/ui/base/resource/resource_bundle.cc#780
and here:
https://chromium.googlesource.com/chromium/src/+/69.0.3497.106/ui/base/resource/resource_bundle_mac.mm#50
This isn't needed on Mac because resource files are copied into the app bundle,
and are built in `$root_out_dir/electron_repack` (while Chromium's resources
target `$root_out_dir/repack`), but on Windows and Linux, the resource files go
directly in `$root_out_dir`, and so they conflict.
We don't actually ever generate Chromium's resource paks, but without this
patch, GN refuses to generate the ninja files:
ERROR at //tools/grit/repack.gni:35:3: Duplicate output file.
action(_repack_target_name) {
^----------------------------
Two or more targets generate the same output:
chrome_100_percent.pak
This is can often be fixed by changing one of the target names, or by
setting an output_name on one of them.
Collisions:
//chrome:packed_resources_100_percent
//electron:packed_resources_100_percent
See //tools/grit/repack.gni:35:3: Collision.
action(_repack_target_name) {
^----------------------------
Some alternatives to this patch:
1. Refactor upstream in such a way that the "chrome" pak names were
configurable, for instance by adding a method to ResourceBundle::Delegate that
LoadChromeResources would check.
2. Pass a Delegate that overrides `GetPathForResourcePack`, check for the
`chrome_{100,200}_percent.pak` filenames, and rewrite them to
`electron_{100,200}_percent.pak`.
3. Initialize the resource bundle with DO_NOT_LOAD_COMMON_RESOURCES and load
the paks ourselves.
None of these options seems like a substantial maintainability win over this patch to me (@nornagon).
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index d8f51269f5edb6fa698bc40abb3900a551f2ab0d..74aadd24a27d31291bb42d452ff247bbf6dad14a 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -1550,7 +1550,7 @@ if (is_chrome_branded && !is_android) {
}
}
-if (!is_android) {
+if (!is_android && !is_electron_build) {
chrome_paks("packed_resources") {
if (is_mac) {
output_dir = "$root_gen_dir/repack"
@@ -1596,6 +1596,12 @@ repack("browser_tests_pak") {
deps = [ "//chrome/test/data/webui:resources" ]
}
+if (is_electron_build) {
+ group("packed_resources") {
+ public_deps = [ "//electron:packed_resources" ]
+ }
+}
+
group("strings") {
public_deps = [
"//chrome/app:branded_strings",

View File

@@ -67,7 +67,7 @@ index 78d8585e83bb12acb9e95867dfb586299c511277..838b40eb0aa31e12d6527f39a673f71a
} // namespace views::features
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index ceb6e3ad0e60b1aaee47c24564ca9fd8b3c2e71f..1f66f36c028b97f018e116ae41a8d9b078620757 100644
index 35433949e2933e0c886c1e05dd54ce4b5b6cbe71..e19955df73a287fcade8e6c90ed02558e45d210b 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -85,6 +85,23 @@ namespace {
@@ -94,7 +94,7 @@ index ceb6e3ad0e60b1aaee47c24564ca9fd8b3c2e71f..1f66f36c028b97f018e116ae41a8d9b0
// Updates the cursor clip region. Used for mouse locking.
void UpdateMouseLockRegion(aura::Window* window, bool locked) {
if (!locked) {
@@ -342,9 +359,14 @@ bool DesktopWindowTreeHostWin::IsVisible() const {
@@ -346,9 +363,14 @@ bool DesktopWindowTreeHostWin::IsVisible() const {
}
void DesktopWindowTreeHostWin::SetSize(const gfx::Size& size) {
@@ -111,7 +111,7 @@ index ceb6e3ad0e60b1aaee47c24564ca9fd8b3c2e71f..1f66f36c028b97f018e116ae41a8d9b0
}
void DesktopWindowTreeHostWin::StackAbove(aura::Window* window) {
@@ -359,30 +381,40 @@ void DesktopWindowTreeHostWin::StackAtTop() {
@@ -363,30 +385,40 @@ void DesktopWindowTreeHostWin::StackAtTop() {
}
void DesktopWindowTreeHostWin::CenterWindow(const gfx::Size& size) {
@@ -154,7 +154,7 @@ index ceb6e3ad0e60b1aaee47c24564ca9fd8b3c2e71f..1f66f36c028b97f018e116ae41a8d9b0
return display::win::GetScreenWin()->ScreenToDIPRect(GetHWND(), pixel_bounds);
}
@@ -701,37 +733,44 @@ void DesktopWindowTreeHostWin::HideImpl() {
@@ -705,37 +737,44 @@ void DesktopWindowTreeHostWin::HideImpl() {
// other get/set methods work in DIP.
gfx::Rect DesktopWindowTreeHostWin::GetBoundsInPixels() const {
@@ -219,7 +219,7 @@ index ceb6e3ad0e60b1aaee47c24564ca9fd8b3c2e71f..1f66f36c028b97f018e116ae41a8d9b0
}
gfx::Rect
@@ -943,18 +982,26 @@ int DesktopWindowTreeHostWin::GetNonClientComponent(
@@ -947,18 +986,26 @@ int DesktopWindowTreeHostWin::GetNonClientComponent(
void DesktopWindowTreeHostWin::GetWindowMask(const gfx::Size& size_px,
SkPath* path) {
@@ -258,10 +258,10 @@ index ceb6e3ad0e60b1aaee47c24564ca9fd8b3c2e71f..1f66f36c028b97f018e116ae41a8d9b0
}
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
index e8acd2828ed05deefa335ce2bb461f0c3be8d7b7..0cd07fd5fb55dcc0d972de4c027fcb895d156592 100644
index 32377f112337e4f2f9dd17410eaffe089fda1368..0f4d335e1d54b5e92fc217080d86513db94d4122 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
@@ -175,7 +175,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
@@ -177,7 +177,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
void ShowImpl() override;
void HideImpl() override;
gfx::Rect GetBoundsInPixels() const override;
@@ -270,7 +270,7 @@ index e8acd2828ed05deefa335ce2bb461f0c3be8d7b7..0cd07fd5fb55dcc0d972de4c027fcb89
gfx::Rect GetBoundsInAcceleratedWidgetPixelCoordinates() override;
gfx::Point GetLocationOnScreenInPixels() const override;
void SetCapture() override;
@@ -328,6 +328,12 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
@@ -330,6 +330,12 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
gfx::Vector2d window_expansion_top_left_delta_;
gfx::Vector2d window_expansion_bottom_right_delta_;

View File

@@ -1,24 +1,16 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Wed, 17 Aug 2022 22:04:47 +0900
Subject: feat: configure launch options for service process
From: Jeremy Apthorp <nornagon@nornagon.net>
Date: Mon, 26 Aug 2019 12:02:51 -0700
Subject: feat: customize service process launch for utilityProcess API
- POSIX:
Allows configuring base::LaunchOptions::fds_to_remap when launching the child process.
- Win:
Allows configuring base::LaunchOptions::handles_to_inherit, base::LaunchOptions::stdout_handle,
base::LaunchOptions::stderr_handle and base::LaunchOptions::feedback_cursor_off when launching
the child process.
- Mac:
Allows configuring base::LaunchOptions::disclaim_responsibility when launching the child process.
- All:
Allows configuring base::LauncOptions::current_directory, base::LaunchOptions::enviroment
and base::LaunchOptions::clear_environment.
An example use of this option, UtilityProcess API allows reading the output From
stdout and stderr of child process by creating a pipe, whose write end is remapped
to STDOUT_FILENO/STD_OUTPUT_HANDLE and STDERR_FILENO/STD_ERROR_HANDLE allowing the
parent process to read from the pipe.
Extends UtilityProcessHost and ServiceProcessHost with configurable
launch options needed by Electron's utilityProcess API: stdio
redirection (Win handles / POSIX fd remapping), working directory,
environment inheritance control, Win feedback-cursor suppression, and
Mac TCC responsibility disclaim. Also sets allow_new_privs for
unsandboxed Linux children so they can spawn setuid processes, and
plumbs the crash exit code through ServiceProcessHost::Observer so apps
receive accurate exit codes when a service process crashes.
diff --git a/content/browser/child_process_launcher.h b/content/browser/child_process_launcher.h
index 1b42600b2d240c1215c1b7223ac2aaa7c90794fc..65ffcb9491176722bb573be78ed15e81a9047c29 100644
@@ -61,10 +53,10 @@ index 1b42600b2d240c1215c1b7223ac2aaa7c90794fc..65ffcb9491176722bb573be78ed15e81
// Launches a process asynchronously and notifies the client of the process
diff --git a/content/browser/child_process_launcher_helper_linux.cc b/content/browser/child_process_launcher_helper_linux.cc
index 492a0822181aebbede38f7783a457b820ce4f8d1..878e5245266cfd4ea96bdbf8ca20c7ae0ac9a80e 100644
index b6f5667c86c3e74807728aa2dbb61fee87e6156a..878e5245266cfd4ea96bdbf8ca20c7ae0ac9a80e 100644
--- a/content/browser/child_process_launcher_helper_linux.cc
+++ b/content/browser/child_process_launcher_helper_linux.cc
@@ -65,6 +65,11 @@ bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
@@ -65,7 +65,23 @@ bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
options->fds_to_remap.emplace_back(sandbox_fd, GetSandboxFD());
}
@@ -73,13 +65,15 @@ index 492a0822181aebbede38f7783a457b820ce4f8d1..878e5245266cfd4ea96bdbf8ca20c7ae
+ remapped_fd.first);
+ }
+
// (For Electron), if we're launching without zygote, that means we're
// launching an unsandboxed process (since all sandboxed processes are
// forked from the zygote). Relax the allow_new_privs option to permit
@@ -74,7 +79,9 @@ bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
options->allow_new_privs = true;
}
+ // (For Electron), if we're launching without zygote, that means we're
+ // launching an unsandboxed process (since all sandboxed processes are
+ // forked from the zygote). Relax the allow_new_privs option to permit
+ // launching suid processes from unsandboxed child processes.
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoZygote) &&
+ delegate_->GetZygote() == nullptr) {
+ options->allow_new_privs = true;
+ }
+
+ options->current_directory = delegate_->GetCurrentDirectory();
options->environment = delegate_->GetEnvironment();
+ options->clear_environment = !delegate_->ShouldInheritEnvironment();
@@ -192,8 +186,81 @@ index d9c14f91747bde0e76056d7f2f2ada166e67f994..09335acac17f526fb8d8e42e4b2d993b
utility_options.WithBoundServiceInterfaceOnChildProcess(std::move(receiver));
UtilityProcessHost::Start(std::move(utility_options),
diff --git a/content/browser/service_host/service_process_tracker.cc b/content/browser/service_host/service_process_tracker.cc
index fb41c8dfd147a90d7d581b49ad7f909d947cb214..ae0dce9d1dde14f1562adac7d324635983bb4c09 100644
--- a/content/browser/service_host/service_process_tracker.cc
+++ b/content/browser/service_host/service_process_tracker.cc
@@ -51,7 +51,8 @@ void ServiceProcessTracker::NotifyTerminated(ServiceProcessId id) {
void ServiceProcessTracker::NotifyCrashed(
ServiceProcessId id,
- UtilityProcessHost::Client::CrashType crash_type) {
+ UtilityProcessHost::Client::CrashType crash_type,
+ int exit_code) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto iter = processes_.find(id);
CHECK(iter != processes_.end());
@@ -65,7 +66,9 @@ void ServiceProcessTracker::NotifyCrashed(
break;
}
for (auto& observer : observers_) {
- observer.OnServiceProcessCrashed(iter->second.Duplicate());
+ auto params = iter->second.Duplicate();
+ params.set_exit_code(exit_code);
+ observer.OnServiceProcessCrashed(params);
}
processes_.erase(iter);
}
diff --git a/content/browser/service_host/service_process_tracker.h b/content/browser/service_host/service_process_tracker.h
index 9a5179c4eeacf8bbfb2d831b4301836df490f3a8..511fc9b9d5ce14a1b5ef457a1047e40d3bb64273 100644
--- a/content/browser/service_host/service_process_tracker.h
+++ b/content/browser/service_host/service_process_tracker.h
@@ -36,7 +36,8 @@ class ServiceProcessTracker {
void NotifyTerminated(ServiceProcessId id);
void NotifyCrashed(ServiceProcessId id,
- UtilityProcessHost::Client::CrashType type);
+ UtilityProcessHost::Client::CrashType type,
+ int exit_code);
void AddObserver(ServiceProcessHost::Observer* observer);
diff --git a/content/browser/service_host/utility_process_client.cc b/content/browser/service_host/utility_process_client.cc
index 99da7eee3cb1a09b984832211bceee385147aec2..5e4bd537d94ad26c8d309ebfb63845a8d3d11dae 100644
--- a/content/browser/service_host/utility_process_client.cc
+++ b/content/browser/service_host/utility_process_client.cc
@@ -40,7 +40,7 @@ void UtilityProcessClient::OnProcessTerminatedNormally() {
process_info_->service_process_id());
}
-void UtilityProcessClient::OnProcessCrashed(CrashType type) {
+void UtilityProcessClient::OnProcessCrashed(CrashType type, int exit_code) {
// TODO(crbug.com/40654042): It is unclear how we can observe
// |OnProcessCrashed()| without observing |OnProcessLaunched()| first, but
// it can happen on Android. Ignore the notification in this case.
@@ -49,6 +49,6 @@ void UtilityProcessClient::OnProcessCrashed(CrashType type) {
}
GetServiceProcessTracker().NotifyCrashed(process_info_->service_process_id(),
- type);
+ type, exit_code);
}
} // namespace content
diff --git a/content/browser/service_host/utility_process_client.h b/content/browser/service_host/utility_process_client.h
index 2648adb1cf38ab557b66ffd0e3034b26b04d76d6..98eab587f343f6ca472efc3d4e7b31b2b8821417 100644
--- a/content/browser/service_host/utility_process_client.h
+++ b/content/browser/service_host/utility_process_client.h
@@ -36,7 +36,7 @@ class UtilityProcessClient : public UtilityProcessHost::Client {
void OnProcessTerminatedNormally() override;
- void OnProcessCrashed(CrashType type) override;
+ void OnProcessCrashed(CrashType type, int exit_code) override;
private:
const std::string service_interface_name_;
diff --git a/content/browser/service_host/utility_process_host.cc b/content/browser/service_host/utility_process_host.cc
index 1b6c5d15eaf06224d40bee70b2da2a6b9c623f9a..23731f8c98c50c3140867debba688c5720684444 100644
index 1b6c5d15eaf06224d40bee70b2da2a6b9c623f9a..234e822d265b09fcc338f0677e2135747699d70c 100644
--- a/content/browser/service_host/utility_process_host.cc
+++ b/content/browser/service_host/utility_process_host.cc
@@ -242,13 +242,13 @@ UtilityProcessHost::Options& UtilityProcessHost::Options::WithFileToPreload(
@@ -291,8 +358,17 @@ index 1b6c5d15eaf06224d40bee70b2da2a6b9c623f9a..23731f8c98c50c3140867debba688c57
#if BUILDFLAG(IS_WIN)
if (!options_.preload_libraries_.empty()) {
@@ -592,7 +652,7 @@ void UtilityProcessHost::OnProcessCrashed(int exit_code) {
: Client::CrashType::kPreIpcInitialization;
}
#endif // BUILDFLAG(IS_WIN)
- client->OnProcessCrashed(type);
+ client->OnProcessCrashed(type, exit_code);
}
std::optional<std::string> UtilityProcessHost::GetServiceName() {
diff --git a/content/browser/service_host/utility_process_host.h b/content/browser/service_host/utility_process_host.h
index dfdcb66d65f07f4543703396eb529a6ec02b3f4a..96c0cadf5caf5bf27f2a767c43f0f1da04298800 100644
index dfdcb66d65f07f4543703396eb529a6ec02b3f4a..5a16fe5c01ae7777064168e8883ec8ec0b82a873 100644
--- a/content/browser/service_host/utility_process_host.h
+++ b/content/browser/service_host/utility_process_host.h
@@ -30,6 +30,7 @@
@@ -303,6 +379,15 @@ index dfdcb66d65f07f4543703396eb529a6ec02b3f4a..96c0cadf5caf5bf27f2a767c43f0f1da
#endif // BUILDFLAG(IS_WIN)
namespace base {
@@ -86,7 +87,7 @@ class CONTENT_EXPORT UtilityProcessHost final
virtual void OnProcessTerminatedNormally() {}
// Called when the process has terminated due to a crash. The `type` field
// indicates the type of crash. See above.
- virtual void OnProcessCrashed(CrashType type) {}
+ virtual void OnProcessCrashed(CrashType type, int exit_code) {}
};
struct CONTENT_EXPORT Options {
@@ -133,14 +134,36 @@ class CONTENT_EXPORT UtilityProcessHost final
std::variant<base::FilePath, base::ScopedFD> file);
#endif
@@ -741,6 +826,24 @@ index 0062d2cb6634b8b29977a0312516b1b13936b40a..888ff36d70c83010f1f45e9eeb2dd6b5
};
// An interface which can be implemented and registered/unregistered with
diff --git a/content/public/browser/service_process_info.h b/content/public/browser/service_process_info.h
index 21f2c71d2323a70491034678a4dc0029d8d53e63..ce76dc8cadd5cbee5114d7106389803c3d7e8238 100644
--- a/content/public/browser/service_process_info.h
+++ b/content/public/browser/service_process_info.h
@@ -68,7 +68,13 @@ class CONTENT_EXPORT ServiceProcessInfo {
crashed_pre_ipc_ = crashed_pre_ipc;
}
+ void set_exit_code(int exit_code) { exit_code_ = exit_code; }
+ int exit_code() const { return exit_code_; }
+
private:
+ // The exit code of the process, if it has exited.
+ int exit_code_ = 0;
+
// The name of the service interface for which the process was launched.
std::string service_interface_name_;
diff --git a/sandbox/policy/win/sandbox_win.cc b/sandbox/policy/win/sandbox_win.cc
index 5c92eec064e36fa4be5a57a769a4091a18e3396d..b705450708560c0ae8b386d7efdb5c526964c629 100644
--- a/sandbox/policy/win/sandbox_win.cc

View File

@@ -0,0 +1,136 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <sattard@slack-corp.com>
Date: Tue, 25 Feb 2020 13:28:30 -0800
Subject: feat: customize spellchecker for Electron (URL override, observers,
sync)
Adds SpellcheckHunspellDictionary::SetBaseDownloadURL so embedders can
override the Hunspell dictionary download host (the existing
testing-only setter does not append the dictionary filename and is
unsuitable for production). Adds SpellcheckService::SetHunspellObserver
so embedders can receive dictionary load/download events, used to
implement Electron's spellcheck-dictionary-* session events. Also
re-adds a synchronous FillSuggestionList call on Windows that was
removed upstream in CL 6109477; this hunk can be dropped once Electron
exposes an async spellcheck API. Unlikely to be upstreamed as the
changes live in //chrome.
diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
index cf981e70ee4c43fd4f9a195c7839c9e3cb7fc956..c00068a963d66a07a726ec562e5f8327b2c3faeb 100644
--- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
+++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
@@ -55,6 +55,8 @@ GURL& GetDownloadUrlForTesting() {
return *download_url_for_testing;
}
+base::NoDestructor<GURL> g_base_download_url_override;
+
// Close the file.
void CloseDictionary(base::File file) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
@@ -269,6 +271,10 @@ void SpellcheckHunspellDictionary::SetDownloadURLForTesting(const GURL url) {
GetDownloadUrlForTesting() = url;
}
+void SpellcheckHunspellDictionary::SetBaseDownloadURL(const GURL url) {
+ *g_base_download_url_override = url;
+}
+
GURL SpellcheckHunspellDictionary::GetDictionaryURL() {
if (GetDownloadUrlForTesting() != GURL()) {
return GetDownloadUrlForTesting();
@@ -277,6 +283,9 @@ GURL SpellcheckHunspellDictionary::GetDictionaryURL() {
std::string bdict_file = dictionary_file_.path.BaseName().MaybeAsASCII();
DCHECK(!bdict_file.empty());
+ if (*g_base_download_url_override != GURL())
+ return GURL(g_base_download_url_override->spec() + base::ToLowerASCII(bdict_file));
+
static const char kDownloadServerUrl[] =
"https://redirector.gvt1.com/edgedl/chrome/dict/";
diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
index 4e608a6c0147c6f41e12f16fee7c87d0db2f1733..5962abf8dbd5998f11e828ec70b3a6a8b1758f65 100644
--- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
+++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
@@ -97,6 +97,8 @@ class SpellcheckHunspellDictionary : public SpellcheckDictionary {
// Tests use this method to set a custom URL for downloading dictionaries.
static void SetDownloadURLForTesting(const GURL url);
+ static void SetBaseDownloadURL(const GURL url);
+
private:
// Dictionary download status.
enum DownloadStatus {
diff --git a/chrome/browser/spellchecker/spellcheck_service.cc b/chrome/browser/spellchecker/spellcheck_service.cc
index 8b781e4bf202481abb754b93d9b978c4f9294275..779bdd17641c1808ff2c707b3de5f6c9b331ca2d 100644
--- a/chrome/browser/spellchecker/spellcheck_service.cc
+++ b/chrome/browser/spellchecker/spellcheck_service.cc
@@ -484,6 +484,8 @@ void SpellcheckService::LoadDictionaries() {
std::make_unique<SpellcheckHunspellDictionary>(
dictionary, platform_spellcheck_language, context_, this));
hunspell_dictionaries_.back()->AddObserver(this);
+ if (hunspell_observer_)
+ hunspell_dictionaries_.back()->AddObserver(hunspell_observer_);
hunspell_dictionaries_.back()->Load();
}
@@ -534,6 +536,20 @@ bool SpellcheckService::IsSpellcheckEnabled() const {
(!hunspell_dictionaries_.empty() || enable_if_uninitialized);
}
+void SpellcheckService::SetHunspellObserver(SpellcheckHunspellDictionary::Observer* observer) {
+ if (hunspell_observer_) {
+ for (auto& dict : hunspell_dictionaries_) {
+ dict->RemoveObserver(hunspell_observer_);
+ }
+ }
+ if (observer) {
+ for (auto& dict : hunspell_dictionaries_) {
+ dict->AddObserver(observer);
+ }
+ }
+ hunspell_observer_ = observer;
+}
+
void SpellcheckService::OnRenderProcessHostCreated(
content::RenderProcessHost* host) {
InitForRenderer(host);
diff --git a/chrome/browser/spellchecker/spellcheck_service.h b/chrome/browser/spellchecker/spellcheck_service.h
index 00e613bb4ca4346eb0b0e65b9b818d817ac724d9..1b40931b8654b80e9a5fd0f170217b4b008eaae9 100644
--- a/chrome/browser/spellchecker/spellcheck_service.h
+++ b/chrome/browser/spellchecker/spellcheck_service.h
@@ -135,6 +135,8 @@ class SpellcheckService : public KeyedService,
// dictionaries available.
bool IsSpellcheckEnabled() const;
+ void SetHunspellObserver(SpellcheckHunspellDictionary::Observer* observer);
+
// content::RenderProcessHostCreationObserver implementation.
void OnRenderProcessHostCreated(content::RenderProcessHost* host) override;
@@ -299,6 +301,8 @@ class SpellcheckService : public KeyedService,
// A pointer to the BrowserContext which this service refers to.
raw_ptr<content::BrowserContext> context_;
+ raw_ptr<SpellcheckHunspellDictionary::Observer> hunspell_observer_ = nullptr;
+
std::unique_ptr<SpellCheckHostMetrics> metrics_;
std::unique_ptr<SpellcheckCustomDictionary> custom_dictionary_;
diff --git a/components/spellcheck/browser/windows_spell_checker.cc b/components/spellcheck/browser/windows_spell_checker.cc
index 319029fc962eb73f0dcf8604ccd342b0e381496e..eff60d66c3762722e56743abba60e1aafa19b774 100644
--- a/components/spellcheck/browser/windows_spell_checker.cc
+++ b/components/spellcheck/browser/windows_spell_checker.cc
@@ -241,6 +241,11 @@ std::vector<SpellCheckResult> BackgroundHelper::RequestTextCheckForAllLanguages(
(action == CORRECTIVE_ACTION_GET_SUGGESTIONS ||
action == CORRECTIVE_ACTION_REPLACE)) {
std::vector<std::u16string> suggestions;
+ // TODO (vertedinde): Perform the synchronous operation of retrieving
+ // suggestions for all misspelled words while performing a text check.
+ FillSuggestionList(it->first,
+ text.substr(start_index, error_length),
+ &suggestions);
result_map[std::tuple<ULONG, ULONG>(start_index, error_length)]
.push_back(suggestions);
}

View File

@@ -1,66 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Sat, 24 Apr 2021 18:07:09 -0700
Subject: web_contents.patch
This allows overriding the RenderViewHostDelegateView of a WebContents, which
is needed for OSR.
Originally landed in https://github.com/electron/libchromiumcontent/pull/226.
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 16c4c2f73643314a9b8287e13a6472dff2671652..859643e7796440bf1966007c598effffba7e47c9 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -4203,6 +4203,13 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
params.main_frame_name, GetOpener(), primary_main_frame_policy,
base::UnguessableToken::Create());
+ if (params.view && params.delegate_view) {
+ view_.reset(params.view);
+ render_view_host_delegate_view_ = params.delegate_view;
+ }
+
+ if (!view_) {
+
std::unique_ptr<WebContentsViewDelegate> delegate =
GetContentClient()->browser()->GetWebContentsViewDelegate(this);
@@ -4213,6 +4220,7 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
view_ = CreateWebContentsView(this, std::move(delegate),
&render_view_host_delegate_view_);
}
+ } // !view_
CHECK(render_view_host_delegate_view_);
CHECK(view_.get());
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
index a02a9134feae75d4fe95f2d8163983bdec447b2b..055302c00a625f4570c57243be3bd0ae02a73347 100644
--- a/content/public/browser/web_contents.h
+++ b/content/public/browser/web_contents.h
@@ -130,11 +130,14 @@ class PrerenderHandle;
class RenderFrameHost;
class RenderViewHost;
class RenderWidgetHost;
+class RenderViewHostDelegateView;
class RenderWidgetHostView;
+class RenderWidgetHostViewBase;
class ScreenOrientationDelegate;
class SiteInstance;
class UnownedInnerWebContentsClient;
class WebContentsDelegate;
+class WebContentsView;
class WebUI;
struct DropData;
struct GlobalRenderFrameHostId;
@@ -296,6 +299,10 @@ class WebContents : public PageNavigator, public base::SupportsUserData {
network::mojom::WebSandboxFlags starting_sandbox_flags =
network::mojom::WebSandboxFlags::kNone;
+ // Optionally specify the view and delegate view.
+ raw_ptr<content::WebContentsView> view = nullptr;
+ raw_ptr<content::RenderViewHostDelegateView> delegate_view = nullptr;
+
// Value used to set the last time the WebContents was made active, this is
// the value that'll be returned by GetLastActiveTimeTicks(). If this is
// left default initialized then the value is not passed on to the

View File

@@ -1,22 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Anonymous <anonymous@electronjs.org>
Date: Thu, 20 Sep 2018 17:47:04 -0700
Subject: feat: allow dragging and dropping between <webview>s.
This allows dragging and dropping between <webview>s.
Originally landed in https://github.com/electron/libchromiumcontent/pull/267
diff --git a/content/browser/web_contents/web_contents_view_drag_security_info.cc b/content/browser/web_contents/web_contents_view_drag_security_info.cc
index bf24f4e2ccff56a2a92c4f11c9318644ea59daff..c54e6717144e618b3034e8f5a96fd6d85d207f30 100644
--- a/content/browser/web_contents/web_contents_view_drag_security_info.cc
+++ b/content/browser/web_contents/web_contents_view_drag_security_info.cc
@@ -66,7 +66,7 @@ bool WebContentsViewDragSecurityInfo::IsValidDragTarget(
// browser-side checks only have local tree fragment (potentially with
// multiple origins) granularity at best, but a drag operation eventually
// targets one single frame in that local tree fragment.
- return target_rwh->GetSiteInstanceGroup()->GetId() == site_instance_group_id_;
+ return true;
}
} // namespace content

View File

@@ -1,18 +1,22 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 4 Oct 2018 14:57:02 -0700
Subject: fix: also propagate fullscreen state for outer frame
From: Anonymous <anonymous@electronjs.org>
Date: Thu, 20 Sep 2018 17:47:04 -0700
Subject: fix: adapt guest view behavior for Electron <webview>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When entering fullscreen with Element.requestFullscreen in child frames,
the parent frame should also enter fullscreen mode too. Chromium handles
this for iframes, but not for webviews as they are essentially main
frames instead of child frames.
Adapts Chromium's guest view handling for Electron's <webview> tag.
This patch makes webviews propagate the fullscreen state to embedder.It also handles a
DCHECK preventing guest webcontents from becoming the focused webContents.
Propagates fullscreen state from a <webview> to its embedder frame
when Element.requestFullscreen() is called — Chromium does this for
iframes but not for inner-delegate main frames. Also routes the ESC
key through the chain of outer WebContents so fullscreen can be
exited, and relaxes DCHECKs that assume the fullscreen element is an
<iframe> or that the guest WebContents is focused.
Note that we also need to manually update embedder's
`api::WebContents::IsFullscreenForTabOrPending` value.
Additionally bypasses the SiteInstanceGroup check in IsValidDragTarget
to allow drag-and-drop between separate <webview> tags.
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 222cf1b2bbc98aa5e271426478a774f8a48e693d..865df1914009165ef0b0ea0e812e9e53535551bb 100644
@@ -37,10 +41,10 @@ index 222cf1b2bbc98aa5e271426478a774f8a48e693d..865df1914009165ef0b0ea0e812e9e53
if (had_fullscreen_token && !GetView()->HasFocus()) {
GetView()->Focus();
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 859643e7796440bf1966007c598effffba7e47c9..76def190aabe280bb8e0971dc5c72643bbce8f53 100644
index 68128b098d5b195ca34746bfd77290b0fc6c14ee..afb060d27384204565995d10d3f44ca46b4a301b 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -4503,21 +4503,25 @@ KeyboardEventProcessingResult WebContentsImpl::PreHandleKeyboardEvent(
@@ -4495,21 +4495,25 @@ KeyboardEventProcessingResult WebContentsImpl::PreHandleKeyboardEvent(
const input::NativeWebKeyboardEvent& event) {
OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
"WebContentsImpl::PreHandleKeyboardEvent");
@@ -80,7 +84,7 @@ index 859643e7796440bf1966007c598effffba7e47c9..76def190aabe280bb8e0971dc5c72643
}
bool WebContentsImpl::HandleMouseEvent(const blink::WebMouseEvent& event) {
@@ -4690,7 +4694,7 @@ void WebContentsImpl::EnterFullscreenMode(
@@ -4682,7 +4686,7 @@ void WebContentsImpl::EnterFullscreenMode(
OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::EnterFullscreenMode");
DCHECK(CanEnterFullscreenMode(requesting_frame));
DCHECK(requesting_frame->IsActive());
@@ -89,6 +93,19 @@ index 859643e7796440bf1966007c598effffba7e47c9..76def190aabe280bb8e0971dc5c72643
// Ensure the window is made active to take input focus. The window may be
// inactive when sites request fullscreen via capability delegation, consume
// transient activation from a gesture made before another window was focused,
diff --git a/content/browser/web_contents/web_contents_view_drag_security_info.cc b/content/browser/web_contents/web_contents_view_drag_security_info.cc
index bf24f4e2ccff56a2a92c4f11c9318644ea59daff..c54e6717144e618b3034e8f5a96fd6d85d207f30 100644
--- a/content/browser/web_contents/web_contents_view_drag_security_info.cc
+++ b/content/browser/web_contents/web_contents_view_drag_security_info.cc
@@ -66,7 +66,7 @@ bool WebContentsViewDragSecurityInfo::IsValidDragTarget(
// browser-side checks only have local tree fragment (potentially with
// multiple origins) granularity at best, but a drag operation eventually
// targets one single frame in that local tree fragment.
- return target_rwh->GetSiteInstanceGroup()->GetId() == site_instance_group_id_;
+ return true;
}
} // namespace content
diff --git a/third_party/blink/renderer/core/fullscreen/fullscreen.cc b/third_party/blink/renderer/core/fullscreen/fullscreen.cc
index c533c80eb4eea180a2ef89a225d7c75390d40225..4c81dea15346b35a9a43c92fb3b778367888a6ca 100644
--- a/third_party/blink/renderer/core/fullscreen/fullscreen.cc

View File

@@ -1,10 +1,20 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andy Locascio <andy@slack-corp.com>
Date: Wed, 9 Sep 2020 16:56:06 -0700
Subject: chore: provide IsWebContentsCreationOverridden with full params
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 20 Sep 2018 17:45:32 -0700
Subject: feat: plumb full window.open params for setWindowOpenHandler
Pending upstream patch, this gives us fuller access to the window.open params
so that we will be able to decide whether to cancel it or not.
Plumbs the raw window.open() features string and POST body through
CreateNewWindowParams (frame.mojom) from Blink to the browser, adding
them as parameters to ContentBrowserClient::CanCreateWindow. Also
widens WebContentsDelegate::IsWebContentsCreationOverridden to receive
the full CreateNewWindowParams struct instead of just frame_name and
target_url, updating all Chromium implementers accordingly.
Electron needs this to power webContents.setWindowOpenHandler(), which
lets apps inspect the full features string and request body to decide
whether to allow, deny, or override child windows. Upstreaming is
difficult because it changes a widely-implemented public delegate
interface for an embedder-specific use case.
diff --git a/chrome/browser/media/offscreen_tab.cc b/chrome/browser/media/offscreen_tab.cc
index 047f1258f951f763df2ca0ba355b19d19337826b..9fc7114312212fbe38ddec740b4aebbcd72cb0f8 100644
@@ -222,8 +232,20 @@ index b969f1d97b7e3396119b579cfbe61e19ff7d2dd4..b8d6169652da28266a514938b45b39c5
content::WebContents* AddNewContents(
content::WebContents* source,
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 4e7b516f145312e353f112499b2792b27207d84b..222cf1b2bbc98aa5e271426478a774f8a48e693d 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -10125,6 +10125,7 @@ void RenderFrameHostImpl::CreateNewWindow(
last_committed_origin_, params->window_container_type,
params->target_url, params->referrer.To<Referrer>(),
params->frame_name, params->disposition, *params->features,
+ params->raw_features, params->body,
effective_transient_activation_state, params->opener_suppressed,
&no_javascript_access);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index f605f46115cda0f8f06e5274a26e3b997ca4c62e..16c4c2f73643314a9b8287e13a6472dff2671652 100644
index b0f3579f18f3b6dd5a9b328324348770319ccf67..68128b098d5b195ca34746bfd77290b0fc6c14ee 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -5320,8 +5320,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
@@ -236,11 +258,115 @@ index f605f46115cda0f8f06e5274a26e3b997ca4c62e..16c4c2f73643314a9b8287e13a6472df
auto* web_contents_impl =
static_cast<WebContentsImpl*>(delegate_->CreateCustomWebContents(
opener, source_site_instance, is_new_browsing_instance,
@@ -5385,6 +5384,10 @@ FrameTree* WebContentsImpl::CreateNewWindow(
create_params.initially_hidden = renderer_started_hidden;
create_params.initial_popup_url = params.target_url;
+ // Potentially allow the delegate to override the create_params.
+ if (delegate_)
+ delegate_->MaybeOverrideCreateParamsForNewWindow(&create_params);
+
// Even though all codepaths leading here are in response to a renderer
// trying to open a new window, if the new window ends up in a different
// browsing instance, then the RenderViewHost, RenderWidgetHost,
@@ -5439,6 +5442,12 @@ FrameTree* WebContentsImpl::CreateNewWindow(
// Sets the newly created WebContents WindowOpenDisposition.
new_contents_impl->original_window_open_disposition_ = params.disposition;
+ if (delegate_) {
+ delegate_->WebContentsCreatedWithFullParams(this, render_process_id,
+ opener->GetRoutingID(),
+ params, new_contents_impl);
+ }
+
// If the new frame has a name, make sure any SiteInstances that can find
// this named frame have proxies for it. Must be called after
// SetSessionStorageNamespace, since this calls CreateRenderView, which uses
@@ -5480,12 +5489,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
AddWebContentsDestructionObserver(new_contents_impl);
}
- if (delegate_) {
- delegate_->WebContentsCreated(this, render_process_id,
- opener->GetRoutingID(), params.frame_name,
- params.target_url, new_contents_impl);
- }
-
observers_.NotifyObservers(&WebContentsObserver::DidOpenRequestedURL,
new_contents_impl, opener, params.target_url,
params.referrer.To<Referrer>(), params.disposition,
diff --git a/content/common/frame.mojom b/content/common/frame.mojom
index 19dbb921c9644522588ff74d0a1925f826736957..4e7b36729741a79cfdf04f89a8ec615d3148b294 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -658,6 +658,10 @@ struct CreateNewWindowParams {
pending_associated_remote<blink.mojom.Widget> widget;
pending_associated_receiver<blink.mojom.FrameWidgetHost> frame_widget_host;
pending_associated_remote<blink.mojom.FrameWidget> frame_widget;
+
+ // Extra fields added by Electron.
+ string raw_features;
+ network.mojom.URLRequestBody? body;
};
// Operation result when the renderer asks the browser to create a new window.
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index d2dccc29b0e13ab5c87b4c6803e79dc781e52ea2..be6639ef1a7eebb147afee483a35898d1ea5d95f 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -877,6 +877,8 @@ bool ContentBrowserClient::CanCreateWindow(
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
+ const std::string& raw_features,
+ const scoped_refptr<network::ResourceRequestBody>& body,
bool user_gesture,
bool opener_suppressed,
bool* no_javascript_access) {
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 3b6c42b2c4cd5d9e5753af25b27925ff0d933568..e6f51d39b4f2f6b162814996921958ca1252e1d7 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -205,6 +205,7 @@ class NetworkService;
class TrustedURLLoaderHeaderClient;
} // namespace mojom
struct ResourceRequest;
+class ResourceRequestBody;
} // namespace network
namespace sandbox {
@@ -1468,6 +1469,8 @@ class CONTENT_EXPORT ContentBrowserClient {
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
+ const std::string& raw_features,
+ const scoped_refptr<network::ResourceRequestBody>& body,
bool user_gesture,
bool opener_suppressed,
bool* no_javascript_access);
diff --git a/content/public/browser/web_contents_delegate.cc b/content/public/browser/web_contents_delegate.cc
index 51be0b86d083318f01a9ebe76fb7d1fb60cd72fd..02ec57eeb67dd5e5e0ff250853599c88c2a75ed0 100644
index 0c0672e0a2d05d5dff31ae171f1a3af1d20b3019..02ec57eeb67dd5e5e0ff250853599c88c2a75ed0 100644
--- a/content/public/browser/web_contents_delegate.cc
+++ b/content/public/browser/web_contents_delegate.cc
@@ -160,8 +160,7 @@ bool WebContentsDelegate::IsWebContentsCreationOverridden(
@@ -34,6 +34,17 @@ namespace content {
WebContentsDelegate::WebContentsDelegate() = default;
+void WebContentsDelegate::WebContentsCreatedWithFullParams(
+ WebContents* source_contents,
+ int opener_render_process_id,
+ int opener_render_frame_id,
+ const mojom::CreateNewWindowParams& params,
+ WebContents* new_contents) {
+ WebContentsCreated(source_contents, opener_render_process_id,
+ opener_render_frame_id, params.frame_name,
+ params.target_url, new_contents);
+}
+
WebContents* WebContentsDelegate::OpenURLFromTab(
WebContents* source,
const OpenURLParams& params,
@@ -149,8 +160,7 @@ bool WebContentsDelegate::IsWebContentsCreationOverridden(
SiteInstance* source_site_instance,
mojom::WindowContainerType window_container_type,
const GURL& opener_url,
@@ -251,10 +377,26 @@ index 51be0b86d083318f01a9ebe76fb7d1fb60cd72fd..02ec57eeb67dd5e5e0ff250853599c88
}
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h
index 29c380d7845aab1a7b3417e0d3940ea00460260b..234d6d89d1c8c7f333b96f35dacb73daeecf7b17 100644
index 0650197909d484b8a0f48ab61b22471c71bce0e8..234d6d89d1c8c7f333b96f35dacb73daeecf7b17 100644
--- a/content/public/browser/web_contents_delegate.h
+++ b/content/public/browser/web_contents_delegate.h
@@ -380,8 +380,7 @@ class CONTENT_EXPORT WebContentsDelegate {
@@ -18,6 +18,7 @@
#include "base/types/expected.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
+#include "content/common/frame.mojom.h"
#include "content/public/browser/eye_dropper.h"
#include "content/public/browser/fullscreen_types.h"
#include "content/public/browser/invalidate_type.h"
@@ -29,6 +30,7 @@
#include "content/public/browser/select_audio_output_request.h"
#include "content/public/browser/serial_chooser.h"
#include "content/public/browser/storage_partition_config.h"
+#include "content/public/browser/web_contents.h"
#include "content/public/common/window_container_type.mojom-forward.h"
#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/public/common/page/drag_operation.h"
@@ -378,8 +380,7 @@ class CONTENT_EXPORT WebContentsDelegate {
SiteInstance* source_site_instance,
mojom::WindowContainerType window_container_type,
const GURL& opener_url,
@@ -264,6 +406,64 @@ index 29c380d7845aab1a7b3417e0d3940ea00460260b..234d6d89d1c8c7f333b96f35dacb73da
// Allow delegate to creates a custom WebContents when
// WebContents::CreateNewWindow() is called. This function is only called
@@ -402,6 +403,16 @@ class CONTENT_EXPORT WebContentsDelegate {
const StoragePartitionConfig& partition_config,
SessionStorageNamespace* session_storage_namespace);
+ virtual void WebContentsCreatedWithFullParams(
+ WebContents* source_contents,
+ int opener_render_process_id,
+ int opener_render_frame_id,
+ const mojom::CreateNewWindowParams& params,
+ WebContents* new_contents);
+
+ virtual void MaybeOverrideCreateParamsForNewWindow(
+ content::WebContents::CreateParams* create_params) {}
+
// Notifies the delegate about the creation of a new WebContents. This
// typically happens when popups are created.
virtual void WebContentsCreated(WebContents* source_contents,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 6ee766c52202804adc532b1585224b4e35239f9a..42a0a7e5be01fe346cc2ad83d3395425a41e1699 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -6879,6 +6879,10 @@ WebView* RenderFrameImpl::CreateNewWindow(
params->started_by_ad =
GetWebFrame()->IsAdFrame() || GetWebFrame()->IsAdScriptInStack();
+ params->raw_features = features.raw_features.Utf8(
+ WebString::UTF8ConversionMode::kStrictReplacingErrorsWithFFFD);
+ params->body = GetRequestBodyForWebURLRequest(request);
+
// We preserve this information before sending the message since |params| is
// moved on send.
bool is_background_tab =
diff --git a/content/web_test/browser/web_test_content_browser_client.cc b/content/web_test/browser/web_test_content_browser_client.cc
index 7a57cb3a1414a77704c42ae01a9dc89fae4ad4a3..769601c2749f0781317f668cf806042db626c348 100644
--- a/content/web_test/browser/web_test_content_browser_client.cc
+++ b/content/web_test/browser/web_test_content_browser_client.cc
@@ -539,6 +539,8 @@ bool WebTestContentBrowserClient::CanCreateWindow(
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
+ const std::string& raw_features,
+ const scoped_refptr<network::ResourceRequestBody>& body,
bool user_gesture,
bool opener_suppressed,
bool* no_javascript_access) {
diff --git a/content/web_test/browser/web_test_content_browser_client.h b/content/web_test/browser/web_test_content_browser_client.h
index 25e88c235485f75831bc67d72e9c10f67561ba99..f64dd47225c47407bef3a6d942903ee8b7a4cf20 100644
--- a/content/web_test/browser/web_test_content_browser_client.h
+++ b/content/web_test/browser/web_test_content_browser_client.h
@@ -101,6 +101,8 @@ class WebTestContentBrowserClient : public ShellContentBrowserClient {
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
+ const std::string& raw_features,
+ const scoped_refptr<network::ResourceRequestBody>& body,
bool user_gesture,
bool opener_suppressed,
bool* no_javascript_access) override;
diff --git a/extensions/browser/guest_view/app_view/app_view_guest.cc b/extensions/browser/guest_view/app_view/app_view_guest.cc
index f51ac6c6493c78c1eafcae5abbd303563b56665d..0719a104bb2073e1ca3e25a661c86b8f5e747b17 100644
--- a/extensions/browser/guest_view/app_view/app_view_guest.cc
@@ -398,6 +598,32 @@ index ae616fa9c352413e23fb509b3e12e0e4fab5a094..0efa65f7d4346cfe78d2f27ba55a0526
return headless_web_contents_->browser_context()
->options()
->block_new_web_contents();
diff --git a/third_party/blink/public/web/web_window_features.h b/third_party/blink/public/web/web_window_features.h
index d92bab531c12c62a5321a23f4a0cb89691668127..2060e04795ba8e7a923fd0fe3485b8c553ca4421 100644
--- a/third_party/blink/public/web/web_window_features.h
+++ b/third_party/blink/public/web/web_window_features.h
@@ -70,6 +70,8 @@ struct WebWindowFeatures {
// TODO(apaseltiner): Investigate moving this field to a non-public struct
// since it is only needed within //third_party/blink.
std::optional<std::vector<WebString>> attribution_srcs;
+
+ WebString raw_features;
};
} // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index 715ca6e188c7e821478fcbaa4496efd25a673c61..e58465eb936b2a8b3479201ec24580501f7fc2f3 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -2341,6 +2341,8 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
WebWindowFeatures window_features =
GetWindowFeaturesFromString(features, entered_window);
+ window_features.raw_features = features;
+
// In fenced frames, we should always use `noopener`.
if (GetFrame()->IsInFencedFrameTree()) {
window_features.noopener = true;
diff --git a/ui/views/controls/webview/web_dialog_view.cc b/ui/views/controls/webview/web_dialog_view.cc
index 20555af0857f1e8ea8227d71245fb95c5e95679a..a6df69bc877046214bf693ceff3c60036e8767ed 100644
--- a/ui/views/controls/webview/web_dialog_view.cc

View File

@@ -1,85 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 20 Sep 2018 17:47:12 -0700
Subject: worker_context_will_destroy.patch
This adds a hook for worker context destruction, which we use in Electron to
shutdown node integration in the worker if relevant.
An attempt to upstream this was made, but rejected:
https://chromium-review.googlesource.com/c/chromium/src/+/1954347
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h
index 1f6c015c361b3146db760643e3670a110634d75b..d4d9c10d3420a5ff998aeb593ea6a25556d1215e 100644
--- a/content/public/renderer/content_renderer_client.h
+++ b/content/public/renderer/content_renderer_client.h
@@ -414,6 +414,11 @@ class CONTENT_EXPORT ContentRendererClient {
virtual void DidInitializeWorkerContextOnWorkerThread(
v8::Local<v8::Context> context) {}
+ // Notifies that a worker context will be destroyed. This function is called
+ // from the worker thread.
+ virtual void WillDestroyWorkerContextOnWorkerThread(
+ v8::Local<v8::Context> context) {}
+
// Overwrites the given URL to use an HTML5 embed if possible.
// An empty URL is returned if the URL is not overriden.
virtual GURL OverrideFlashEmbedWithHTML(const GURL& url);
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index 78f0ab75486f90ad9bda568cd28c20ec0c48f298..5e2fff57b0a4e08d4263546a8914575501fc9082 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -922,6 +922,12 @@ void RendererBlinkPlatformImpl::WillStopWorkerThread() {
WorkerThreadRegistry::Instance()->WillStopCurrentWorkerThread();
}
+void RendererBlinkPlatformImpl::WorkerContextWillDestroy(
+ const v8::Local<v8::Context>& worker) {
+ GetContentClient()->renderer()->WillDestroyWorkerContextOnWorkerThread(
+ worker);
+}
+
void RendererBlinkPlatformImpl::WorkerContextCreated(
const v8::Local<v8::Context>& worker) {
GetContentClient()->renderer()->DidInitializeWorkerContextOnWorkerThread(
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index 4535d0bf0328301f6ed1a602f6ff97a0243f7685..e191b4ef4185a6cb745c50e949ce6281719e0265 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -209,6 +209,7 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
void DidStartWorkerThread() override;
void WillStopWorkerThread() override;
void WorkerContextCreated(const v8::Local<v8::Context>& worker) override;
+ void WorkerContextWillDestroy(const v8::Local<v8::Context>& worker) override;
bool AllowScriptExtensionForServiceWorker(
const blink::WebSecurityOrigin& script_origin) override;
blink::ProtocolHandlerSecurityLevel GetProtocolHandlerSecurityLevel(
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h
index a26e45d64229f692efb4a218c653afc212788d1f..4c797975567026268ea107f42e47f6411c5b7311 100644
--- a/third_party/blink/public/platform/platform.h
+++ b/third_party/blink/public/platform/platform.h
@@ -685,6 +685,7 @@ class BLINK_PLATFORM_EXPORT Platform {
virtual void DidStartWorkerThread() {}
virtual void WillStopWorkerThread() {}
virtual void WorkerContextCreated(const v8::Local<v8::Context>& worker) {}
+ virtual void WorkerContextWillDestroy(const v8::Local<v8::Context>& worker) {}
virtual bool AllowScriptExtensionForServiceWorker(
const WebSecurityOrigin& script_origin) {
return false;
diff --git a/third_party/blink/renderer/core/workers/worker_thread.cc b/third_party/blink/renderer/core/workers/worker_thread.cc
index ef25707a97c4d7619da664fe5908681c8f659ad8..fa81395d6df143b31e4ae28dc9104a9149c0d91a 100644
--- a/third_party/blink/renderer/core/workers/worker_thread.cc
+++ b/third_party/blink/renderer/core/workers/worker_thread.cc
@@ -803,6 +803,12 @@ void WorkerThread::PrepareForShutdownOnWorkerThread() {
}
pause_handle_.reset();
+ {
+ v8::HandleScope handle_scope(GetIsolate());
+ Platform::Current()->WorkerContextWillDestroy(
+ GlobalScope()->ScriptController()->GetContext());
+ }
+
if (WorkerThreadDebugger* debugger = WorkerThreadDebugger::From(GetIsolate()))
debugger->WorkerThreadDestroyed(this);

View File

@@ -1,91 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Thu, 17 Oct 2019 18:00:32 -0700
Subject: feat: add hook to notify script ready from WorkerScriptController
In Off-the-main-thread fetch, the WorkerGlobalScope will be in a half
initialized state until the script is finished downloading.
Doc: https://docs.google.com/document/d/1JCv8TD2nPLNC2iRCp_D1OM4I3uTS0HoEobuTymaMqgw/edit
During this stage if the global object is transformed for ex: copying properties
in DidInitializeWorkerContextOnWorkerThread hook then an access to property like
location will result in a crash WorkerGlobalScope::Url() because the script has
not been set with response URL yet.
This issue cannot happen in chromium with existing usage, but can surface when an
embedder tries to integrate Node.js in the worker. Hence, this new hook is proposed
that clearly establishes the worker script is ready for evaluation with the scope
initialized.
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h
index d4d9c10d3420a5ff998aeb593ea6a25556d1215e..d64fef6bfc37264dcdc1bbea22eb5c4e099553dd 100644
--- a/content/public/renderer/content_renderer_client.h
+++ b/content/public/renderer/content_renderer_client.h
@@ -414,6 +414,11 @@ class CONTENT_EXPORT ContentRendererClient {
virtual void DidInitializeWorkerContextOnWorkerThread(
v8::Local<v8::Context> context) {}
+ // Notifies that a worker script has been downloaded, scope initialized and
+ // ready for evaluation. This function is called from the worker thread.
+ virtual void WorkerScriptReadyForEvaluationOnWorkerThread(
+ v8::Local<v8::Context> context) {}
+
// Notifies that a worker context will be destroyed. This function is called
// from the worker thread.
virtual void WillDestroyWorkerContextOnWorkerThread(
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index 5e2fff57b0a4e08d4263546a8914575501fc9082..bfc88be930331b75be718fe3f7017f7ec477b086 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -934,6 +934,12 @@ void RendererBlinkPlatformImpl::WorkerContextCreated(
worker);
}
+void RendererBlinkPlatformImpl::WorkerScriptReadyForEvaluation(
+ const v8::Local<v8::Context>& worker) {
+ GetContentClient()->renderer()->WorkerScriptReadyForEvaluationOnWorkerThread(
+ worker);
+}
+
bool RendererBlinkPlatformImpl::AllowScriptExtensionForServiceWorker(
const blink::WebSecurityOrigin& script_origin) {
return GetContentClient()->renderer()->AllowScriptExtensionForServiceWorker(
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index e191b4ef4185a6cb745c50e949ce6281719e0265..826134f19df305cb79598739174bc09808ea472e 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -209,6 +209,8 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
void DidStartWorkerThread() override;
void WillStopWorkerThread() override;
void WorkerContextCreated(const v8::Local<v8::Context>& worker) override;
+ void WorkerScriptReadyForEvaluation(
+ const v8::Local<v8::Context>& worker) override;
void WorkerContextWillDestroy(const v8::Local<v8::Context>& worker) override;
bool AllowScriptExtensionForServiceWorker(
const blink::WebSecurityOrigin& script_origin) override;
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h
index 4c797975567026268ea107f42e47f6411c5b7311..ae463faa3d16ab2697a4c20f3b038755205188f7 100644
--- a/third_party/blink/public/platform/platform.h
+++ b/third_party/blink/public/platform/platform.h
@@ -685,6 +685,8 @@ class BLINK_PLATFORM_EXPORT Platform {
virtual void DidStartWorkerThread() {}
virtual void WillStopWorkerThread() {}
virtual void WorkerContextCreated(const v8::Local<v8::Context>& worker) {}
+ virtual void WorkerScriptReadyForEvaluation(
+ const v8::Local<v8::Context>& worker) {}
virtual void WorkerContextWillDestroy(const v8::Local<v8::Context>& worker) {}
virtual bool AllowScriptExtensionForServiceWorker(
const WebSecurityOrigin& script_origin) {
diff --git a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
index 7425989e1cef93269262a5c9468fd3b7bddac3ea..bbacc5da2399dbdc74c9b6f912482b2168168136 100644
--- a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
+++ b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
@@ -294,6 +294,7 @@ void WorkerOrWorkletScriptController::PrepareForEvaluation() {
V8PerContextData* per_context_data = script_state_->PerContextData();
std::ignore =
per_context_data->ConstructorForType(global_scope_->GetWrapperTypeInfo());
+ Platform::Current()->WorkerScriptReadyForEvaluation(script_state_->GetContext());
// Inform V8 that origin trial information is now connected with the context,
// and V8 can extend the context with origin trial features.
isolate_->InstallConditionalFeatures(script_state_->GetContext());