Browse Source

Merge branch 'main' into pdf-tests

Jeremy Rose 3 years ago
parent
commit
af9168f6b2
100 changed files with 1607 additions and 650 deletions
  1. 25 11
      .circleci/build_config.yml
  2. 2 5
      BUILD.gn
  3. 1 1
      DEPS
  4. 1 1
      ELECTRON_VERSION
  5. 16 12
      appveyor.yml
  6. 1 2
      build/args/all.gn
  7. 7 12
      chromium_src/BUILD.gn
  8. 4 1
      docs/api/app.md
  9. 66 57
      docs/api/browser-window.md
  10. 3 3
      docs/api/system-preferences.md
  11. 1 1
      docs/api/web-frame.md
  12. 4 8
      docs/breaking-changes.md
  13. 7 7
      docs/tutorial/electron-timelines.md
  14. 3 2
      docs/tutorial/security.md
  15. 0 2
      filenames.gni
  16. 4 1
      lib/browser/api/browser-window.ts
  17. 1 1
      lib/common/webpack-provider.ts
  18. 1 1
      npm/package.json
  19. 7 6
      package.json
  20. 1 0
      patches/chromium/.patches
  21. 5 5
      patches/chromium/add_didinstallconditionalfeatures.patch
  22. 5 5
      patches/chromium/allow_disabling_blink_scheduler_throttling_per_renderview.patch
  23. 1 1
      patches/chromium/allow_setting_secondary_label_via_simplemenumodel.patch
  24. 3 3
      patches/chromium/blink_local_frame.patch
  25. 1 1
      patches/chromium/build_add_electron_tracing_category.patch
  26. 11 11
      patches/chromium/build_do_not_depend_on_packed_resource_integrity.patch
  27. 15 15
      patches/chromium/can_create_window.patch
  28. 1 1
      patches/chromium/chore_expose_v8_initialization_isolate_callbacks.patch
  29. 6 6
      patches/chromium/chore_provide_iswebcontentscreationoverridden_with_full_params.patch
  30. 2 2
      patches/chromium/chore_use_electron_resources_not_chrome_for_spellchecker.patch
  31. 2 2
      patches/chromium/dcheck.patch
  32. 3 3
      patches/chromium/disable_color_correct_rendering.patch
  33. 1 1
      patches/chromium/don_t_use_potentially_null_getwebframe_-_view_when_get_blink.patch
  34. 1 1
      patches/chromium/extend_apply_webpreferences.patch
  35. 5 5
      patches/chromium/feat_enable_offscreen_rendering_with_viz_compositor.patch
  36. 3 3
      patches/chromium/fix_crash_when_saving_edited_pdf_files.patch
  37. 78 4
      patches/chromium/fix_patch_out_permissions_checks_in_exclusive_access.patch
  38. 2 2
      patches/chromium/fix_properly_honor_printing_page_ranges.patch
  39. 4 4
      patches/chromium/frame_host_manager.patch
  40. 2 2
      patches/chromium/gritsettings_resource_ids.patch
  41. 1 1
      patches/chromium/hack_to_allow_gclient_sync_with_host_os_mac_on_linux_in_ci.patch
  42. 37 0
      patches/chromium/introduce_ozoneplatform_electron_can_call_x11_property.patch
  43. 1 1
      patches/chromium/load_v8_snapshot_in_browser_process.patch
  44. 1 1
      patches/chromium/notification_provenance.patch
  45. 18 18
      patches/chromium/picture-in-picture.patch
  46. 64 56
      patches/chromium/printing.patch
  47. 2 2
      patches/chromium/refactor_expose_cursor_changes_to_the_webcontentsobserver.patch
  48. 3 3
      patches/chromium/resource_file_conflict.patch
  49. 1 1
      patches/chromium/support_mixed_sandbox_with_zygote.patch
  50. 15 5
      patches/chromium/ui_gtk_public_header.patch
  51. 3 3
      patches/chromium/web_contents.patch
  52. 2 2
      patches/chromium/webview_cross_drag.patch
  53. 2 2
      patches/chromium/webview_fullscreen.patch
  54. 4 4
      patches/chromium/worker_context_will_destroy.patch
  55. 2 2
      patches/chromium/worker_feat_add_hook_to_notify_script_ready.patch
  56. 1 1
      patches/node/.patches
  57. 11 2
      patches/node/build_add_gn_build_files.patch
  58. 503 0
      patches/node/feat_add_uv_loop_interrupt_on_io_change_option_to_uv_loop_configure.patch
  59. 0 59
      patches/node/feat_add_uv_loop_watcher_queue_code.patch
  60. 1 1
      patches/node/unix_remove_uv_cloexec_ioctl_3515.patch
  61. 1 1
      patches/node/unix_simplify_uv_cloexec_fcntl_3492.patch
  62. 2 0
      patches/squirrel.mac/.patches
  63. 128 0
      patches/squirrel.mac/feat_add_new_squirrel_mac_bundle_installation_method_behind_flag.patch
  64. 101 0
      patches/squirrel.mac/refactor_use_posix_spawn_instead_of_nstask_so_we_can_disclaim_the.patch
  65. 3 3
      patches/v8/build_gn.patch
  66. 1 1
      patches/v8/do_not_export_private_v8_symbols_on_windows.patch
  67. 2 2
      patches/v8/export_symbols_needed_for_windows_build.patch
  68. 2 2
      patches/v8/expose_mksnapshot.patch
  69. 48 0
      script/lib/azput.js
  70. 19 2
      script/lib/util.py
  71. 0 4
      script/node-disabled-tests.json
  72. 47 45
      script/release/release.js
  73. 3 5
      script/release/uploaders/upload-index-json.py
  74. 3 5
      script/release/uploaders/upload-node-checksums.py
  75. 14 16
      script/release/uploaders/upload-node-headers.py
  76. 5 6
      script/release/uploaders/upload-symbols.py
  77. 4 10
      script/release/uploaders/upload.py
  78. 6 6
      shell/app/electron_content_client.cc
  79. 3 0
      shell/browser/api/electron_api_app.cc
  80. 18 1
      shell/browser/api/electron_api_browser_view.cc
  81. 6 4
      shell/browser/api/electron_api_web_contents.cc
  82. 2 2
      shell/browser/api/electron_api_web_request.cc
  83. 1 0
      shell/browser/browser.h
  84. 4 0
      shell/browser/browser_mac.mm
  85. 1 0
      shell/browser/electron_api_ipc_handler_impl.h
  86. 8 9
      shell/browser/electron_browser_client.cc
  87. 2 2
      shell/browser/electron_browser_main_parts.cc
  88. 0 6
      shell/browser/electron_browser_main_parts.h
  89. 1 0
      shell/browser/electron_web_contents_utility_handler_impl.h
  90. 7 0
      shell/browser/media/media_stream_devices_controller.cc
  91. 1 1
      shell/browser/native_window.cc
  92. 2 0
      shell/browser/native_window_mac.h
  93. 26 2
      shell/browser/native_window_mac.mm
  94. 140 115
      shell/browser/native_window_views.cc
  95. 11 4
      shell/browser/native_window_views.h
  96. 3 8
      shell/browser/net/proxying_url_loader_factory.cc
  97. 0 4
      shell/browser/net/proxying_url_loader_factory.h
  98. 0 1
      shell/browser/net/proxying_websocket.cc
  99. 0 4
      shell/browser/net/system_network_context_manager.cc
  100. 4 4
      shell/browser/resources/win/electron.rc

+ 25 - 11
.circleci/build_config.yml

@@ -59,7 +59,7 @@ executors:
         description: "xcode version"
         default: "12.4.0"
         type: enum
-        enum: ["12.4.0", "13.2.1"]
+        enum: ["12.4.0", "13.3.0"]
 
     macos:
       xcode: << parameters.xcode >>
@@ -470,6 +470,8 @@ step-fix-sync: &step-fix-sync
 
         # Fix esbuild (wrong binary)
         echo 'infra/3pp/tools/esbuild/${platform}' `gclient getdep --deps-file=src/third_party/devtools-frontend/src/DEPS -r 'third_party/esbuild:infra/3pp/tools/esbuild/${platform}'` > esbuild_ensure_file
+        # Remove extra output from calling gclient getdep which always calls update_depot_tools
+        sed -i '' "s/Updating depot_tools... //g" esbuild_ensure_file
         cipd ensure --root src/third_party/devtools-frontend/src/third_party/esbuild -ensure-file esbuild_ensure_file
       fi
 
@@ -672,6 +674,7 @@ step-persist-data-for-tests: &step-persist-data-for-tests
       - src/out/Default/chromedriver.zip
       - src/out/Default/shell_browser_ui_unittests
       - src/out/Default/gen/node_headers
+      - src/out/Default/overlapped-checker
       - src/out/ffmpeg/ffmpeg.zip
       - src/electron
       - src/third_party/electron_node
@@ -809,6 +812,13 @@ step-mksnapshot-build: &step-mksnapshot-build
         (cd out/Default; zip mksnapshot.zip mksnapshot_args gen/v8/embedded.S)
       fi
 
+step-nodejs-build-test-executable: &step-nodejs-build-test-executable
+  run:
+    name: Build Node.js Test Executables
+    command: |
+      cd src
+      ninja -C out/Default third_party/electron_node:overlapped-checker
+
 step-hunspell-build: &step-hunspell-build
   run:
     name: hunspell build
@@ -1270,6 +1280,7 @@ commands:
             mv_if_exist src/out/Default/hunspell_dictionaries.zip
             mv_if_exist src/cross-arch-snapshots
             mv_if_exist src/out/electron_ninja_log
+            mv_if_exist src/out/Default/.ninja_log
           when: always
       - store_artifacts:
           path: generated_artifacts
@@ -1430,6 +1441,9 @@ commands:
             # Node.js headers
             - *step-nodejs-headers-build
 
+            # Node.js test executable
+            - *step-nodejs-build-test-executable
+
             - *step-show-goma-stats
 
             # mksnapshot
@@ -1909,7 +1923,7 @@ jobs:
   osx-testing-x64:
     executor:
       name: macos
-      xcode: "13.2.1"
+      xcode: "13.3.0"
     environment:
       <<: *env-mac-large
       <<: *env-testing-build
@@ -1926,7 +1940,7 @@ jobs:
   osx-testing-x64-gn-check:
     executor:
       name: macos
-      xcode: "13.2.1"
+      xcode: "13.3.0"
     environment:
       <<: *env-machine-mac
       <<: *env-testing-build
@@ -1935,7 +1949,7 @@ jobs:
   osx-publish-x64-skip-checkout:
     executor:
       name: macos
-      xcode: "13.2.1"
+      xcode: "13.3.0"
     environment:
       <<: *env-mac-large-release
       <<: *env-release-build
@@ -1956,7 +1970,7 @@ jobs:
   osx-publish-arm64-skip-checkout:
     executor:
       name: macos
-      xcode: "13.2.1"
+      xcode: "13.3.0"
     environment:
       <<: *env-mac-large-release
       <<: *env-release-build
@@ -1978,7 +1992,7 @@ jobs:
   osx-testing-arm64:
     executor:
       name: macos
-      xcode: "13.2.1"
+      xcode: "13.3.0"
     environment:
       <<: *env-mac-large
       <<: *env-testing-build
@@ -1997,7 +2011,7 @@ jobs:
   mas-testing-x64:
     executor:
       name: macos
-      xcode: "13.2.1"
+      xcode: "13.3.0"
     environment:
       <<: *env-mac-large
       <<: *env-mas
@@ -2015,7 +2029,7 @@ jobs:
   mas-testing-x64-gn-check:
     executor:
       name: macos
-      xcode: "13.2.1"
+      xcode: "13.3.0"
     environment:
       <<: *env-machine-mac
       <<: *env-mas
@@ -2025,7 +2039,7 @@ jobs:
   mas-publish-x64-skip-checkout:
     executor:
       name: macos
-      xcode: "13.2.1"
+      xcode: "13.3.0"
     environment:
       <<: *env-mac-large-release
       <<: *env-mas
@@ -2046,7 +2060,7 @@ jobs:
   mas-publish-arm64-skip-checkout:
     executor:
       name: macos
-      xcode: "13.2.1"
+      xcode: "13.3.0"
     environment:
       <<: *env-mac-large-release
       <<: *env-mas-apple-silicon
@@ -2068,7 +2082,7 @@ jobs:
   mas-testing-arm64:
     executor:
       name: macos
-      xcode: "13.2.1"
+      xcode: "13.3.0"
     environment:
       <<: *env-mac-large
       <<: *env-testing-build

+ 2 - 5
BUILD.gn

@@ -363,10 +363,6 @@ source_set("electron_lib") {
     "//components/network_session_configurator/common",
     "//components/omnibox/browser:buildflags",
     "//components/os_crypt",
-    "//components/pdf/browser",
-    "//components/pdf/browser:interceptors",
-    "//components/pdf/common",
-    "//components/pdf/renderer",
     "//components/pref_registry",
     "//components/prefs",
     "//components/security_state/content",
@@ -563,7 +559,6 @@ source_set("electron_lib") {
     defines += [
       # Disable warnings for g_settings_list_schemas.
       "GLIB_DISABLE_DEPRECATION_WARNINGS",
-      "USE_X11=1",
     ]
 
     sources += [
@@ -701,6 +696,8 @@ source_set("electron_lib") {
     deps += [
       "//chrome/browser/resources/pdf:resources",
       "//components/pdf/browser",
+      "//components/pdf/browser:interceptors",
+      "//components/pdf/common",
       "//components/pdf/renderer",
       "//pdf",
     ]

+ 1 - 1
DEPS

@@ -2,7 +2,7 @@ gclient_gn_args_from = 'src'
 
 vars = {
   'chromium_version':
-    '102.0.4962.3',
+    '102.0.4971.0',
   'node_version':
     'v16.14.2',
   'nan_version':

+ 1 - 1
ELECTRON_VERSION

@@ -1 +1 @@
-19.0.0-nightly.20220325
+20.0.0-nightly.20220330

+ 16 - 12
appveyor.yml

@@ -177,16 +177,7 @@ build_script:
   - ninja -C out/Default third_party/electron_node:headers
   - python %LOCAL_GOMA_DIR%\goma_ctl.py stat
   - python electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
-  - appveyor PushArtifact out/Default/windows_toolchain_profile.json
-  - appveyor PushArtifact out/Default/dist.zip
-  - appveyor PushArtifact out/Default/shell_browser_ui_unittests.exe
-  - appveyor PushArtifact out/Default/chromedriver.zip
-  - appveyor PushArtifact out/ffmpeg/ffmpeg.zip
   - 7z a node_headers.zip out\Default\gen\node_headers
-  - appveyor PushArtifact node_headers.zip
-  - appveyor PushArtifact out/Default/mksnapshot.zip
-  - appveyor PushArtifact out/Default/hunspell_dictionaries.zip
-  - appveyor PushArtifact out/Default/electron.lib
   - ps: >-
       if ($env:GN_CONFIG -eq 'release') {
         # Needed for msdia140.dll on 64-bit windows
@@ -201,7 +192,6 @@ build_script:
         # It's useful to have pdb files when debugging testing builds that are
         # built on CI.
         7z a pdb.zip out\Default\*.pdb
-        appveyor-retry appveyor PushArtifact pdb.zip
       }
   - python electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
 test_script:
@@ -230,7 +220,6 @@ test_script:
   - echo "Done verifying mksnapshot"
   - if "%RUN_TESTS%"=="true" ( echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd% )
   - echo "Done verifying chromedriver"
-  - if exist %cd%\electron.log ( appveyor-retry appveyor PushArtifact %cd%\electron.log )
 deploy_script:
   - cd electron
   - ps: >-
@@ -246,4 +235,19 @@ deploy_script:
         node script/release/ci-release-build.js --job=electron-woa-testing --ci=VSTS --armTest --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
       }
 on_finish:
-  - if exist src\electron\electron.log ( appveyor-retry appveyor PushArtifact src\electron\electron.log )
+  - cd ..
+  - if exist out\Default\windows_toolchain_profile.json ( appveyor-retry appveyor PushArtifact out\Default\windows_toolchain_profile.json )
+  - if exist out\Default\dist.zip (appveyor-retry appveyor PushArtifact out\Default\dist.zip)
+  - if exist out\Default\shell_browser_ui_unittests.exe (appveyor-retry appveyor PushArtifact out\Default\shell_browser_ui_unittests.exe)
+  - if exist out\Default\chromedriver.zip (appveyor-retry appveyor PushArtifact out\Default\chromedriver.zip)
+  - if exist out\ffmpeg\ffmpeg.zip (appveyor-retry appveyor PushArtifact out\ffmpeg\ffmpeg.zip)
+  - if exist node_headers.zip (appveyor-retry appveyor PushArtifact node_headers.zip)
+  - if exist out\Default\mksnapshot.zip (appveyor-retry appveyor PushArtifact out\Default\mksnapshot.zip)
+  - if exist out\Default\hunspell_dictionaries.zip (appveyor-retry appveyor PushArtifact out\Default\hunspell_dictionaries.zip)
+  - if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
+  - ps: >-
+      if ((Test-Path "pdb.zip") -And ($env:GN_CONFIG -ne 'release')) {
+        appveyor-retry appveyor PushArtifact pdb.zip
+      }
+
+  - if exist electron\electron.log ( appveyor-retry appveyor PushArtifact electron\electron.log )

+ 1 - 2
build/args/all.gn

@@ -2,10 +2,9 @@ is_electron_build = true
 root_extra_deps = [ "//electron" ]
 
 # Registry of NMVs --> https://github.com/nodejs/node/blob/master/doc/abi_version_registry.json
-node_module_version = 106
+node_module_version = 107
 
 v8_promise_internal_field_count = 1
-v8_typed_array_max_size_in_heap = 0
 v8_embedder_string = "-electron.0"
 
 # TODO: this breaks mksnapshot

+ 7 - 12
chromium_src/BUILD.gn

@@ -307,6 +307,10 @@ static_library("chrome") {
         "//chrome/browser/plugins/pdf_iframe_navigation_throttle.cc",
         "//chrome/browser/plugins/pdf_iframe_navigation_throttle.h",
       ]
+      deps += [
+        "//components/pdf/browser",
+        "//components/pdf/renderer",
+      ]
     }
   }
 
@@ -334,15 +338,6 @@ source_set("plugins") {
     "//chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc",
     "//chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h",
   ]
-  deps += [
-    "//media:media_buildflags",
-    "//ppapi/buildflags",
-    "//ppapi/proxy:ipc",
-    "//services/device/public/mojom",
-  ]
-  if (enable_pdf_viewer) {
-    deps += [ "//components/pdf/browser" ]
-  }
 
   # renderer side
   sources += [
@@ -351,16 +346,16 @@ source_set("plugins") {
     "//chrome/renderer/pepper/pepper_shared_memory_message_filter.cc",
     "//chrome/renderer/pepper/pepper_shared_memory_message_filter.h",
   ]
-  if (enable_pdf_viewer) {
-    deps += [ "//components/pdf/renderer" ]
-  }
+
   deps += [
     "//components/strings",
     "//media:media_buildflags",
+    "//ppapi/buildflags",
     "//ppapi/host",
     "//ppapi/proxy",
     "//ppapi/proxy:ipc",
     "//ppapi/shared_impl",
+    "//services/device/public/mojom",
     "//skia",
   ]
 }

+ 4 - 1
docs/api/app.md

@@ -606,6 +606,10 @@ You should seek to use the `steal` option as sparingly as possible.
 
 Hides all application windows without minimizing them.
 
+### `app.isHidden()` _macOS_
+
+Returns `boolean` - `true` if the application—including all of its windows—is hidden (e.g. with `Command-H`), `false` otherwise.
+
 ### `app.show()` _macOS_
 
 Shows application windows after they were hidden. Does not automatically focus
@@ -633,7 +637,6 @@ Returns `string` - The current application directory.
     * `~/Library/Application Support` on macOS
   * `userData` The directory for storing your app's configuration files, which by
     default it is the `appData` directory appended with your app's name.
-  * `cache`
   * `temp` Temporary directory.
   * `exe` The current executable file.
   * `module` The `libchromiumcontent` library.

+ 66 - 57
docs/api/browser-window.md

@@ -164,14 +164,14 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
   * `maxWidth` Integer (optional) - Window's maximum width. Default is no limit.
   * `maxHeight` Integer (optional) - Window's maximum height. Default is no limit.
   * `resizable` boolean (optional) - Whether window is resizable. Default is `true`.
-  * `movable` boolean (optional) - Whether window is movable. This is not implemented
-    on Linux. Default is `true`.
-  * `minimizable` boolean (optional) - Whether window is minimizable. This is not
-    implemented on Linux. Default is `true`.
-  * `maximizable` boolean (optional) - Whether window is maximizable. This is not
-    implemented on Linux. Default is `true`.
-  * `closable` boolean (optional) - Whether window is closable. This is not implemented
-    on Linux. Default is `true`.
+  * `movable` boolean (optional) _macOS_ _Windows_ - Whether window is
+    movable. This is not implemented on Linux. Default is `true`.
+  * `minimizable` boolean (optional) _macOS_ _Windows_ - Whether window is
+    minimizable. This is not implemented on Linux. Default is `true`.
+  * `maximizable` boolean (optional) _macOS_ _Windows_ - Whether window is
+    maximizable. This is not implemented on Linux. Default is `true`.
+  * `closable` boolean (optional) _macOS_ _Windows_ - Whether window is
+    closable. This is not implemented on Linux. Default is `true`.
   * `focusable` boolean (optional) - Whether the window can be focused. Default is
     `true`. On Windows setting `focusable: false` also implies setting
     `skipTaskbar: true`. On Linux setting `focusable: false` makes the window
@@ -185,7 +185,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
   * `fullscreenable` boolean (optional) - Whether the window can be put into fullscreen
     mode. On macOS, also whether the maximize/zoom button should toggle full
     screen mode or maximize window. Default is `true`.
-  * `simpleFullscreen` boolean (optional) - Use pre-Lion fullscreen on macOS. Default is `false`.
+  * `simpleFullscreen` boolean (optional) _macOS_ - Use pre-Lion fullscreen on
+    macOS. Default is `false`.
   * `skipTaskbar` boolean (optional) _macOS_ _Windows_ - Whether to show the window in taskbar.
     Default is `false`.
   * `kiosk` boolean (optional) - Whether the window is in kiosk mode. Default is `false`.
@@ -201,27 +202,30 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
   * `parent` BrowserWindow (optional) - Specify parent window. Default is `null`.
   * `modal` boolean (optional) - Whether this is a modal window. This only works when the
     window is a child window. Default is `false`.
-  * `acceptFirstMouse` boolean (optional) - Whether clicking an inactive window will also
-  click through to the web contents. Default is `false` on macOS. This option is not
-  configurable on other platforms.
+  * `acceptFirstMouse` boolean (optional) _macOS_ - Whether clicking an
+    inactive window will also click through to the web contents. Default is
+    `false` on macOS. This option is not configurable on other platforms.
   * `disableAutoHideCursor` boolean (optional) - Whether to hide cursor when typing.
     Default is `false`.
   * `autoHideMenuBar` boolean (optional) - Auto hide the menu bar unless the `Alt`
     key is pressed. Default is `false`.
-  * `enableLargerThanScreen` boolean (optional) - Enable the window to be resized larger
-    than screen. Only relevant for macOS, as other OSes allow
-    larger-than-screen windows by default. Default is `false`.
+  * `enableLargerThanScreen` boolean (optional) _macOS_ - Enable the window to
+    be resized larger than screen. Only relevant for macOS, as other OSes
+    allow larger-than-screen windows by default. Default is `false`.
   * `backgroundColor` string (optional) - The window's background color in Hex, RGB, RGBA, HSL, HSLA or named CSS color format. Alpha in #AARRGGBB format is supported if `transparent` is set to `true`. Default is `#FFF` (white). See [win.setBackgroundColor](browser-window.md#winsetbackgroundcolorbackgroundcolor) for more information.
   * `hasShadow` boolean (optional) - Whether window should have a shadow. Default is `true`.
-  * `opacity` number (optional) - Set the initial opacity of the window, between 0.0 (fully
-    transparent) and 1.0 (fully opaque). This is only implemented on Windows and macOS.
+  * `opacity` number (optional) _macOS_ _Windows_ - Set the initial opacity of
+    the window, between 0.0 (fully transparent) and 1.0 (fully opaque). This
+    is only implemented on Windows and macOS.
   * `darkTheme` boolean (optional) - Forces using dark theme for the window, only works on
     some GTK+3 desktop environments. Default is `false`.
   * `transparent` boolean (optional) - Makes the window [transparent](../tutorial/window-customization.md#create-transparent-windows).
     Default is `false`. On Windows, does not work unless the window is frameless.
   * `type` string (optional) - The type of window, default is normal window. See more about
     this below.
-  * `visualEffectState` string (optional) - Specify how the material appearance should reflect window activity state on macOS. Must be used with the `vibrancy` property. Possible values are:
+  * `visualEffectState` string (optional) _macOS_ - Specify how the material
+    appearance should reflect window activity state on macOS. Must be used
+    with the `vibrancy` property. Possible values are:
     * `followWindow` - The backdrop should automatically appear active when the window is active, and inactive when it is not. This is the default.
     * `active` - The backdrop should always appear active.
     * `inactive` - The backdrop should always appear inactive.
@@ -229,36 +233,41 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
     Default is `default`. Possible values are:
     * `default` - Results in the standard title bar for macOS or Windows respectively.
     * `hidden` - Results in a hidden title bar and a full size content window. On macOS, the window still has the standard window controls (“traffic lights”) in the top left. On Windows, when combined with `titleBarOverlay: true` it will activate the Window Controls Overlay (see `titleBarOverlay` for more information), otherwise no window controls will be shown.
-    * `hiddenInset` - Only on macOS, results in a hidden title bar with an alternative look
-      where the traffic light buttons are slightly more inset from the window edge.
-    * `customButtonsOnHover` - Only on macOS, results in a hidden title bar and a full size
-      content window, the traffic light buttons will display when being hovered
-      over in the top left of the window.  **Note:** This option is currently
-      experimental.
-  * `trafficLightPosition` [Point](structures/point.md) (optional) - Set a
-    custom position for the traffic light buttons in frameless windows.
-  * `roundedCorners` boolean (optional) - Whether frameless window should have
-    rounded corners on macOS. Default is `true`.
-  * `fullscreenWindowTitle` boolean (optional) _Deprecated_ - Shows the title in
-    the title bar in full screen mode on macOS for `hiddenInset` titleBarStyle.
-    Default is `false`.
+    * `hiddenInset` _macOS_ - Only on macOS, results in a hidden title bar
+      with an alternative look where the traffic light buttons are slightly
+      more inset from the window edge.
+    * `customButtonsOnHover` _macOS_ - Only on macOS, results in a hidden
+      title bar and a full size content window, the traffic light buttons will
+      display when being hovered over in the top left of the window.
+      **Note:** This option is currently experimental.
+  * `trafficLightPosition` [Point](structures/point.md) (optional) _macOS_ -
+    Set a custom position for the traffic light buttons in frameless windows.
+  * `roundedCorners` boolean (optional) _macOS_ - Whether frameless window
+    should have rounded corners on macOS. Default is `true`.
+  * `fullscreenWindowTitle` boolean (optional) _macOS_ _Deprecated_ - Shows
+    the title in the title bar in full screen mode on macOS for `hiddenInset`
+    titleBarStyle. Default is `false`.
   * `thickFrame` boolean (optional) - Use `WS_THICKFRAME` style for frameless windows on
     Windows, which adds standard window frame. Setting it to `false` will remove
     window shadow and window animations. Default is `true`.
-  * `vibrancy` string (optional) - Add a type of vibrancy effect to the window, only on
-    macOS. Can be `appearance-based`, `light`, `dark`, `titlebar`, `selection`,
-    `menu`, `popover`, `sidebar`, `medium-light`, `ultra-dark`, `header`, `sheet`, `window`, `hud`, `fullscreen-ui`, `tooltip`, `content`, `under-window`, or `under-page`. Please note that `appearance-based`, `light`, `dark`, `medium-light`, and `ultra-dark` are deprecated and have been removed in macOS Catalina (10.15).
-  * `zoomToPageWidth` boolean (optional) - Controls the behavior on macOS when
-    option-clicking the green stoplight button on the toolbar or by clicking the
-    Window > Zoom menu item. If `true`, the window will grow to the preferred
-    width of the web page when zoomed, `false` will cause it to zoom to the
-    width of the screen. This will also affect the behavior when calling
-    `maximize()` directly. Default is `false`.
-  * `tabbingIdentifier` string (optional) - Tab group name, allows opening the
-    window as a native tab on macOS 10.12+. Windows with the same tabbing
-    identifier will be grouped together. This also adds a native new tab button
-    to your window's tab bar and allows your `app` and window to receive the
-    `new-window-for-tab` event.
+  * `vibrancy` string (optional) _macOS_ - Add a type of vibrancy effect to
+    the window, only on macOS. Can be `appearance-based`, `light`, `dark`,
+    `titlebar`, `selection`, `menu`, `popover`, `sidebar`, `medium-light`,
+    `ultra-dark`, `header`, `sheet`, `window`, `hud`, `fullscreen-ui`,
+    `tooltip`, `content`, `under-window`, or `under-page`. Please note that
+    `appearance-based`, `light`, `dark`, `medium-light`, and `ultra-dark` are
+    deprecated and have been removed in macOS Catalina (10.15).
+  * `zoomToPageWidth` boolean (optional) _macOS_ - Controls the behavior on
+    macOS when option-clicking the green stoplight button on the toolbar or by
+    clicking the Window > Zoom menu item. If `true`, the window will grow to
+    the preferred width of the web page when zoomed, `false` will cause it to
+    zoom to the width of the screen. This will also affect the behavior when
+    calling `maximize()` directly. Default is `false`.
+  * `tabbingIdentifier` string (optional) _macOS_ - Tab group name, allows
+    opening the window as a native tab on macOS 10.12+. Windows with the same
+    tabbing identifier will be grouped together. This also adds a native new
+    tab button to your window's tab bar and allows your `app` and window to
+    receive the `new-window-for-tab` event.
   * `webPreferences` Object (optional) - Settings of web page's features.
     * `devTools` boolean (optional) - Whether to enable DevTools. If it is set to `false`, can not use `BrowserWindow.webContents.openDevTools()` to open DevTools. Default is `true`.
     * `nodeIntegration` boolean (optional) - Whether node integration is enabled.
@@ -310,8 +319,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
     * `plugins` boolean (optional) - Whether plugins should be enabled. Default is `false`.
     * `experimentalFeatures` boolean (optional) - Enables Chromium's experimental features.
       Default is `false`.
-    * `scrollBounce` boolean (optional) - Enables scroll bounce (rubber banding) effect on
-      macOS. Default is `false`.
+    * `scrollBounce` boolean (optional) _macOS_ - Enables scroll bounce
+      (rubber banding) effect on macOS. Default is `false`.
     * `enableBlinkFeatures` string (optional) - A list of feature strings separated by `,`, like
       `CSSVariables,KeyboardEventKey` to enable. The full list of supported feature
       strings can be found in the [RuntimeEnabledFeatures.json5][runtime-enabled-features]
@@ -774,7 +783,7 @@ A `boolean` property that determines whether the window is in fullscreen mode.
 
 A `boolean` property that determines whether the window is focusable.
 
-#### `win.visibleOnAllWorkspaces`
+#### `win.visibleOnAllWorkspaces` _macOS_ _Linux_
 
 A `boolean` property that determines whether the window is visible on all workspaces.
 
@@ -811,13 +820,13 @@ A `string` property that determines the title of the native window.
 
 **Note:** The title of the web page can be different from the title of the native window.
 
-#### `win.minimizable`
+#### `win.minimizable` _macOS_ _Windows_
 
 A `boolean` property that determines whether the window can be manually minimized by user.
 
 On Linux the setter is a no-op, although the getter returns `true`.
 
-#### `win.maximizable`
+#### `win.maximizable` _macOS_ _Windows_
 
 A `boolean` property that determines whether the window can be manually maximized by user.
 
@@ -832,13 +841,13 @@ maximizes the window.
 
 A `boolean` property that determines whether the window can be manually resized by user.
 
-#### `win.closable`
+#### `win.closable` _macOS_ _Windows_
 
 A `boolean` property that determines whether the window can be manually closed by user.
 
 On Linux the setter is a no-op, although the getter returns `true`.
 
-#### `win.movable`
+#### `win.movable` _macOS_ _Windows_
 
 A `boolean` property that determines Whether the window can be moved by user.
 
@@ -1635,7 +1644,7 @@ Changes window icon.
 
 Sets whether the window traffic light buttons should be visible.
 
-#### `win.setAutoHideMenuBar(hide)`
+#### `win.setAutoHideMenuBar(hide)` _Windows_ _Linux_
 
 * `hide` boolean
 
@@ -1644,7 +1653,7 @@ menu bar will only show when users press the single `Alt` key.
 
 If the menu bar is already visible, calling `setAutoHideMenuBar(true)` won't hide it immediately.
 
-#### `win.isMenuBarAutoHide()`
+#### `win.isMenuBarAutoHide()` _Windows_ _Linux_
 
 Returns `boolean` - Whether menu bar automatically hides itself.
 
@@ -1654,11 +1663,11 @@ Returns `boolean` - Whether menu bar automatically hides itself.
 
 Sets whether the menu bar should be visible. If the menu bar is auto-hide, users can still bring up the menu bar by pressing the single `Alt` key.
 
-#### `win.isMenuBarVisible()`
+#### `win.isMenuBarVisible()` _Windows_ _Linux_
 
 Returns `boolean` - Whether the menu bar is visible.
 
-#### `win.setVisibleOnAllWorkspaces(visible[, options])`
+#### `win.setVisibleOnAllWorkspaces(visible[, options])` _macOS_ _Linux_
 
 * `visible` boolean
 * `options` Object (optional)
@@ -1676,7 +1685,7 @@ Sets whether the window should be visible on all workspaces.
 
 **Note:** This API does nothing on Windows.
 
-#### `win.isVisibleOnAllWorkspaces()`
+#### `win.isVisibleOnAllWorkspaces()` _macOS_ _Linux_
 
 Returns `boolean` - Whether the window is visible on all workspaces.
 

+ 3 - 3
docs/api/system-preferences.md

@@ -177,11 +177,11 @@ Some popular `key` and `type`s are:
 * `NSPreferredWebServices`: `dictionary`
 * `NSUserDictionaryReplacementItems`: `array`
 
-### `systemPreferences.setUserDefault(key, type, value)` _macOS_
+### `systemPreferences.setUserDefault<Type extends keyof UserDefaultTypes>(key, type, value)` _macOS_
 
 * `key` string
-* `type` string - Can be `string`, `boolean`, `integer`, `float`, `double`, `url`, `array` or `dictionary`.
-* `value` string
+* `type` Type - Can be `string`, `boolean`, `integer`, `float`, `double`, `url`, `array` or `dictionary`.
+* `value` UserDefaultTypes[Type]
 
 Set the value of `key` in `NSUserDefaults`.
 

+ 1 - 1
docs/api/web-frame.md

@@ -110,7 +110,7 @@ webFrame.setSpellCheckProvider('en-US', {
 })
 ```
 
-#### `webFrame.insertCSS(css[, options])`
+### `webFrame.insertCSS(css[, options])`
 
 * `css` string
 * `options` Object (optional)

+ 4 - 8
docs/breaking-changes.md

@@ -29,19 +29,15 @@ renderers.
 
 ### Removed: `skipTaskbar` on Linux
 
-See `skipTaskbar` discussion in 19.0 below. This feature is not available on
-Wayland. Since most modern Linux desktops are transitioning to Wayland, this
-feature will be removed for Linux.
-
-## Planned Breaking API Changes (19.0)
-
-### Unsupported: `skipTaskbar` on Linux
-
 On X11, `skipTaskbar` sends a `_NET_WM_STATE_SKIP_TASKBAR` message to the X11
 window manager. There is not a direct equivalent for Wayland, and the known
 workarounds have unacceptable tradeoffs (e.g. Window.is_skip_taskbar in GNOME
 requires unsafe mode), so Electron is unable to support this feature on Linux.
 
+## Planned Breaking API Changes (19.0)
+
+None
+
 ## Planned Breaking API Changes (18.0)
 
 ### Removed: `nativeWindowOpen`

+ 7 - 7
docs/tutorial/electron-timelines.md

@@ -22,23 +22,23 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
 | 12.0.0 | -- | 2020-Nov-19 | 2021-Mar-02 | M89 | v14.16 | 🚫 |
 | 13.0.0 | -- | 2021-Mar-04 | 2021-May-25 | M91 | v14.16 | 🚫 |
 | 14.0.0 | -- | 2021-May-27 | 2021-Aug-31 | M93 | v14.17 | 🚫 |
-| 15.0.0 | 2021-Jul-20 | 2021-Sep-01 | 2021-Sep-21 | M94 | v16.5 | 🚫 |
+| 15.0.0 | 2021-Jul-20 | 2021-Sep-01 | 2021-Sep-21 | M94 | v16.5 |  |
 | 16.0.0 | 2021-Sep-23 | 2021-Oct-20 | 2021-Nov-16 | M96 | v16.9 | ✅ |
 | 17.0.0 | 2021-Nov-18 | 2022-Jan-06 | 2022-Feb-01 | M98 | v16.13 | ✅ |
-| 18.0.0 | 2022-Feb-03 | 2022-Mar-03 | 2022-Mar-29 | M100 | TBD | ✅ |
-| 19.0.0 | 2022-Mar-31 | 2022-Apr-30 | 2022-May-24 | M102 | TBD | ✅ |
+| 18.0.0 | 2022-Feb-03 | 2022-Mar-03 | 2022-Mar-29 | M100 | v16.13 | ✅ |
+| 19.0.0 | 2022-Mar-31 | 2022-Apr-26 | 2022-May-24 | M102 | TBD | ✅ |
 
 **Notes:**
 
-* The `-beta.1` and `stable` dates are our solid release dates.
-* We strive for weekly beta releases, but we often release more betas than scheduled.
+* The `-alpha.1`, `-beta.1`, and `stable` dates are our solid release dates.
+* We strive for weekly alpha/beta releases, but we often release more than scheduled.
 * All dates are our goals but there may be reasons for adjusting the stable deadline, such as security bugs.
 
 **Historical changes:**
 
 * Since Electron 5, Electron has been publicizing its release dates ([see blog post](https://electronjs.org/blog/electron-5-0-timeline)).
-* Since Electron 6, Electron major versions have been targeting every other Chromium major version. Each Electron stable should happen on the same day as Chrome stable ([see blog post](https://www.electronjs.org/blog/12-week-cadence)). When this was announced
-* Since Electron 16, Electron has been releasing major versions on an 8-week cadence in accordance to Chrome's change to a 4-week release cadence ([see blog post](https://www.electronjs.org/blog/8-week-cadence).
+* Since Electron 6, Electron major versions have been targeting every other Chromium major version. Each Electron stable should happen on the same day as Chrome stable ([see blog post](https://www.electronjs.org/blog/12-week-cadence)).
+* Since Electron 16, Electron has been releasing major versions on an 8-week cadence in accordance to Chrome's change to a 4-week release cadence ([see blog post](https://www.electronjs.org/blog/8-week-cadence)).
 
 :::info Chrome release dates
 

+ 3 - 2
docs/tutorial/security.md

@@ -279,11 +279,12 @@ security-conscious developers might want to assume the very opposite.
 
 ```js title='main.js (Main Process)'
 const { session } = require('electron')
+const URL = require('url').URL
 
 session
   .fromPartition('some-partition')
   .setPermissionRequestHandler((webContents, permission, callback) => {
-    const url = webContents.getURL()
+    const parsedUrl = new URL(webContents.getURL())
 
     if (permission === 'notifications') {
       // Approves the permissions request
@@ -291,7 +292,7 @@ session
     }
 
     // Verify URL
-    if (!url.startsWith('https://example.com/')) {
+    if (parsedUrl.protocol !== 'https:' || parsedUrl.host !== 'example.com') {
       // Denies the permissions request
       return callback(false)
     }

+ 0 - 2
filenames.gni

@@ -53,8 +53,6 @@ filenames = {
     "shell/browser/ui/views/global_menu_bar_x11.h",
     "shell/browser/ui/x/event_disabler.cc",
     "shell/browser/ui/x/event_disabler.h",
-    "shell/browser/ui/x/window_state_watcher.cc",
-    "shell/browser/ui/x/window_state_watcher.h",
     "shell/browser/ui/x/x_window_utils.cc",
     "shell/browser/ui/x/x_window_utils.h",
   ]

+ 4 - 1
lib/browser/api/browser-window.ts

@@ -72,7 +72,10 @@ BrowserWindow.getAllWindows = () => {
 
 BrowserWindow.getFocusedWindow = () => {
   for (const window of BrowserWindow.getAllWindows()) {
-    if (window.isFocused() || window.isDevToolsFocused()) return window;
+    const hasWC = window.webContents && !window.webContents.isDestroyed();
+    if (!window.isDestroyed() && hasWC) {
+      if (window.isFocused() || window.isDevToolsFocused()) return window;
+    }
   }
   return null;
 };

+ 1 - 1
lib/common/webpack-provider.ts

@@ -7,7 +7,7 @@
 
 // Rip global off of window (which is also global) so that webpack doesn't
 // auto replace it with a looped reference to this file
-const _global = typeof globalThis !== 'undefined' ? globalThis.global : (self as any || window as any).global as NodeJS.Global;
+const _global = typeof globalThis !== 'undefined' ? globalThis.global : (self || window).global;
 const process = _global.process;
 const Buffer = _global.Buffer;
 

+ 1 - 1
npm/package.json

@@ -9,7 +9,7 @@
   },
   "dependencies": {
     "@electron/get": "^1.14.1",
-    "@types/node": "^14.6.2",
+    "@types/node": "^16.11.26",
     "extract-zip": "^1.0.3"
   },
   "engines": {

+ 7 - 6
package.json

@@ -1,9 +1,10 @@
 {
   "name": "electron",
-  "version": "19.0.0-nightly.20220325",
+  "version": "20.0.0-nightly.20220330",
   "repository": "https://github.com/electron/electron",
   "description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
   "devDependencies": {
+    "@azure/storage-blob": "^12.9.0",
     "@electron/docs-parser": "^0.12.4",
     "@electron/typescript-definitions": "^8.9.5",
     "@octokit/auth-app": "^2.10.0",
@@ -14,12 +15,12 @@
     "@types/chai": "^4.2.12",
     "@types/chai-as-promised": "^7.1.3",
     "@types/dirty-chai": "^2.0.2",
-    "@types/express": "^4.17.7",
+    "@types/express": "^4.17.13",
     "@types/fs-extra": "^9.0.1",
     "@types/klaw": "^3.0.1",
     "@types/minimist": "^1.2.0",
     "@types/mocha": "^7.0.2",
-    "@types/node": "^14.6.2",
+    "@types/node": "^16.11.26",
     "@types/semver": "^7.3.3",
     "@types/send": "^0.14.5",
     "@types/split": "^1.0.0",
@@ -27,7 +28,7 @@
     "@types/temp": "^0.8.34",
     "@types/uuid": "^3.4.6",
     "@types/webpack": "^4.41.21",
-    "@types/webpack-env": "^1.15.2",
+    "@types/webpack-env": "^1.16.3",
     "@typescript-eslint/eslint-plugin": "^4.4.1",
     "@typescript-eslint/parser": "^4.4.1",
     "asar": "^3.1.0",
@@ -53,7 +54,7 @@
     "lint-staged": "^10.2.11",
     "markdownlint": "^0.21.1",
     "markdownlint-cli": "^0.25.0",
-    "minimist": "^1.2.5",
+    "minimist": "^1.2.6",
     "null-loader": "^4.0.0",
     "pre-flight": "^1.1.0",
     "remark-cli": "^10.0.0",
@@ -141,4 +142,4 @@
       "node script/gen-hunspell-filenames.js"
     ]
   }
-}
+}

+ 1 - 0
patches/chromium/.patches

@@ -114,3 +114,4 @@ port_autofill_colors_to_the_color_pipeline.patch
 build_disable_partition_alloc_on_mac.patch
 fix_non-client_mouse_tracking_and_message_bubbling_on_windows.patch
 build_make_libcxx_abi_unstable_false_for_electron.patch
+introduce_ozoneplatform_electron_can_call_x11_property.patch

+ 5 - 5
patches/chromium/add_didinstallconditionalfeatures.patch

@@ -10,10 +10,10 @@ DidCreateScriptContext is called, not all JS APIs are available in the
 context, which can cause some preload scripts to trip.
 
 diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h
-index 19c936be477f944d62e85cec81359a71bbcfa45d..b02bb1cd67488f996b6142058c52c34dfe523fff 100644
+index d55a1b4f71224a2156eb5f3b0b32f41643b3dc28..f41c8f3d74f72d6e2220af527500749ef7409d77 100644
 --- a/content/public/renderer/render_frame_observer.h
 +++ b/content/public/renderer/render_frame_observer.h
-@@ -132,6 +132,8 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener,
+@@ -131,6 +131,8 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener,
    virtual void DidHandleOnloadEvents() {}
    virtual void DidCreateScriptContext(v8::Local<v8::Context> context,
                                        int32_t world_id) {}
@@ -23,10 +23,10 @@ index 19c936be477f944d62e85cec81359a71bbcfa45d..b02bb1cd67488f996b6142058c52c34d
                                          int32_t world_id) {}
    virtual void DidClearWindowObject() {}
 diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
-index c9296960c76e34646bf7cb3195b80c0cbc483b58..bc8bdba3facba81c572d43b85881ec02ad7d2f00 100644
+index e0d4faf86b7afe7f29da5e5c8babc78a40e72ae1..1fbf6abed9c7d1bbec4478d022e1763ea8bfed8e 100644
 --- a/content/renderer/render_frame_impl.cc
 +++ b/content/renderer/render_frame_impl.cc
-@@ -4423,6 +4423,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
+@@ -4444,6 +4444,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
      observer.DidCreateScriptContext(context, world_id);
  }
  
@@ -92,7 +92,7 @@ index bca4cbb2b2ba84fe58b5cfeaf190add5803e27c9..b6c9dd3a2a1c9b6667c563d5da86ccb4
                                          int32_t world_id) = 0;
    virtual bool AllowScriptExtensions() = 0;
 diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
-index e06c96c068139e829af7bd99ebb111507b2bddb0..a98bc22fc5c96ad1fd2071ea1c9e1aab2fb4d5ff 100644
+index b690ada2d46146b6da38cbb2c688f249ae558464..b03774140883c5bb7de6358f3df95ab8774b9dc7 100644
 --- a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
 +++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
 @@ -275,6 +275,13 @@ void LocalFrameClientImpl::DidCreateScriptContext(

+ 5 - 5
patches/chromium/allow_disabling_blink_scheduler_throttling_per_renderview.patch

@@ -6,10 +6,10 @@ Subject: allow disabling blink scheduler throttling per RenderView
 This allows us to disable throttling for hidden windows.
 
 diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
-index 84044606fb0644b2b6053c72a9750bae3729f666..995c5dfc49a392669f73d85a92fbdb54cf0e11ca 100644
+index 8ee02135efb64c57d0779faa96640aa8e7775b58..66007d67da1230740eb00e31b220ddb02fbf37d9 100644
 --- a/content/browser/renderer_host/render_view_host_impl.cc
 +++ b/content/browser/renderer_host/render_view_host_impl.cc
-@@ -649,6 +649,11 @@ void RenderViewHostImpl::SetBackgroundOpaque(bool opaque) {
+@@ -650,6 +650,11 @@ void RenderViewHostImpl::SetBackgroundOpaque(bool opaque) {
    GetWidget()->GetAssociatedFrameWidget()->SetBackgroundOpaque(opaque);
  }
  
@@ -85,10 +85,10 @@ index 560b72dfbc70172bc668229b29fe0c9da139f320..13ec73b9d627259625d64f5b97838033
    // Visibility -----------------------------------------------------------
  
 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 daab024ee0e2010e177eabeb7e0fb964c631dd17..06d8ca44fb1dc3748d81b5c5a407dfdf7183f845 100644
+index dc63c0ba0cc8625ed5efb961a1c7f1d07fc72f5d..13a16ae577130d7520b47eb046b504ccd6796979 100644
 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc
 +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
-@@ -3666,6 +3666,13 @@ PageScheduler* WebViewImpl::Scheduler() const {
+@@ -3669,6 +3669,13 @@ PageScheduler* WebViewImpl::Scheduler() const {
    return GetPage()->GetPageScheduler();
  }
  
@@ -102,7 +102,7 @@ index daab024ee0e2010e177eabeb7e0fb964c631dd17..06d8ca44fb1dc3748d81b5c5a407dfdf
  void WebViewImpl::SetVisibilityState(
      mojom::blink::PageVisibilityState visibility_state,
      bool is_initial_state) {
-@@ -3677,7 +3684,8 @@ void WebViewImpl::SetVisibilityState(
+@@ -3680,7 +3687,8 @@ void WebViewImpl::SetVisibilityState(
    }
    GetPage()->SetVisibilityState(visibility_state, is_initial_state);
    GetPage()->GetPageScheduler()->SetPageVisible(

+ 1 - 1
patches/chromium/allow_setting_secondary_label_via_simplemenumodel.patch

@@ -6,7 +6,7 @@ Subject: Allow setting secondary label via SimpleMenuModel
 Builds on https://chromium-review.googlesource.com/c/chromium/src/+/2208976
 
 diff --git a/ui/base/models/simple_menu_model.cc b/ui/base/models/simple_menu_model.cc
-index 746dffb1defec9d776f681d41325a65b02cbdd0f..05a7f20f10e3ff514aa3b3b5386980ddfcc586eb 100644
+index a787411f89e2d95e2fa636a7cc6723bdd227e563..f8c67d10957c26fbcd21fa1fe05507efd78f1c29 100644
 --- a/ui/base/models/simple_menu_model.cc
 +++ b/ui/base/models/simple_menu_model.cc
 @@ -53,6 +53,11 @@ std::u16string SimpleMenuModel::Delegate::GetLabelForCommandId(

+ 3 - 3
patches/chromium/blink_local_frame.patch

@@ -49,10 +49,10 @@ index da12f2f47f97628f1adeabc8900ffd16132afd7e..61d373f78520a063c7f86bde6869af9d
    // its owning reference back to our owning LocalFrame.
    client_->Detached(type);
 diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
-index 1efaff0e92061bc97dcbf3105f6b6c1dcefff17c..ec2e19c3ccf60f01b73259e1e6eff405ebf15f07 100644
+index ae445a52314d8581909f05a06442954f39b6b6d0..857715ca74b0f3a50953095d15237292e2a05510 100644
 --- a/third_party/blink/renderer/core/frame/local_frame.cc
 +++ b/third_party/blink/renderer/core/frame/local_frame.cc
-@@ -545,10 +545,6 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
+@@ -543,10 +543,6 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
    }
    DCHECK(!view_ || !view_->IsAttached());
  
@@ -63,7 +63,7 @@ index 1efaff0e92061bc97dcbf3105f6b6c1dcefff17c..ec2e19c3ccf60f01b73259e1e6eff405
    if (!Client())
      return false;
  
-@@ -594,6 +590,11 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
+@@ -592,6 +588,11 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
    DCHECK(!view_->IsAttached());
    Client()->WillBeDetached();
  

+ 1 - 1
patches/chromium/build_add_electron_tracing_category.patch

@@ -8,7 +8,7 @@ categories in use are known / declared.  This patch is required for us
 to introduce a new Electron category for Electron-specific tracing.
 
 diff --git a/base/trace_event/builtin_categories.h b/base/trace_event/builtin_categories.h
-index 083a46a96bf969a075ef05cfe4837c4cce784191..22f18293e65035cc3b9af322520b102eb6b24a76 100644
+index 0736e7021761e6019e1b52448d21ffdb73b964fc..571b553e9aaa98739851d0ff312eefe9f6a75596 100644
 --- a/base/trace_event/builtin_categories.h
 +++ b/base/trace_event/builtin_categories.h
 @@ -80,6 +80,7 @@

+ 11 - 11
patches/chromium/build_do_not_depend_on_packed_resource_integrity.patch

@@ -11,7 +11,7 @@ if we ever align our .pak file generation with Chrome we can remove this
 patch.
 
 diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
-index a6e0a53d4ebbd585114bc0cda2e2d1caaab4a015..95a7e70eee0303471702b81c68f46a0fea2b6f0e 100644
+index 1f86073736f849e797e029678bc212ce96ba0bd9..b8abc10e48bdff0f4e6c3f8e1c4927bc6e0c2f79 100644
 --- a/chrome/BUILD.gn
 +++ b/chrome/BUILD.gn
 @@ -171,11 +171,16 @@ if (!is_android && !is_mac) {
@@ -33,10 +33,10 @@ index a6e0a53d4ebbd585114bc0cda2e2d1caaab4a015..95a7e70eee0303471702b81c68f46a0f
          "//base",
          "//build:branding_buildflags",
 diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
-index 5bbb64d83e2024feeb7a2eae45f6b8e937fc927c..20004fb890e726d11dc672894cdba4645b0a3606 100644
+index a99ce094addf69f21f3c42690defc445eff8fa05..797c8add1af6df1142179388ef1b7a5bf977d527 100644
 --- a/chrome/browser/BUILD.gn
 +++ b/chrome/browser/BUILD.gn
-@@ -4508,7 +4508,7 @@ static_library("browser") {
+@@ -4518,7 +4518,7 @@ static_library("browser") {
  
      # On Windows, the hashes are embedded in //chrome:chrome_initial rather
      # than here in :chrome_dll.
@@ -46,10 +46,10 @@ index 5bbb64d83e2024feeb7a2eae45f6b8e937fc927c..20004fb890e726d11dc672894cdba464
        sources += [ "certificate_viewer_stub.cc" ]
      }
 diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
-index 3d7606b8d7d5f1ec61c9c00be0cc530967985e4b..044b52e00d8b334e90a9f1126b5bc3df916a1af3 100644
+index 4f088ea7cfbb7aaa3ed15607608dd9cafc6a2981..8df44262c079c96a1a81167a769d426aab23bef0 100644
 --- a/chrome/test/BUILD.gn
 +++ b/chrome/test/BUILD.gn
-@@ -5907,7 +5907,6 @@ test("unit_tests") {
+@@ -5943,7 +5943,6 @@ test("unit_tests") {
  
      deps += [
        "//chrome:other_version",
@@ -57,7 +57,7 @@ index 3d7606b8d7d5f1ec61c9c00be0cc530967985e4b..044b52e00d8b334e90a9f1126b5bc3df
        "//chrome//services/util_win:unit_tests",
        "//chrome/app:chrome_dll_resources",
        "//chrome/browser:chrome_process_finder",
-@@ -5930,6 +5929,10 @@ test("unit_tests") {
+@@ -5966,6 +5965,10 @@ test("unit_tests") {
        "//ui/resources",
      ]
  
@@ -68,7 +68,7 @@ index 3d7606b8d7d5f1ec61c9c00be0cc530967985e4b..044b52e00d8b334e90a9f1126b5bc3df
      ldflags = [
        "/DELAYLOAD:api-ms-win-core-winrt-error-l1-1-0.dll",
        "/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll",
-@@ -6619,7 +6622,6 @@ test("unit_tests") {
+@@ -6656,7 +6659,6 @@ test("unit_tests") {
      }
  
      deps += [
@@ -76,10 +76,10 @@ index 3d7606b8d7d5f1ec61c9c00be0cc530967985e4b..044b52e00d8b334e90a9f1126b5bc3df
        "//chrome/browser:cart_db_content_proto",
        "//chrome/browser:coupon_db_content_proto",
        "//chrome/browser/media/router:test_support",
-@@ -6664,6 +6666,11 @@ test("unit_tests") {
-       "//ui/native_theme:test_support",
-       "//ui/webui/resources/js/browser_command:mojo_bindings",
-     ]
+@@ -6704,6 +6706,11 @@ test("unit_tests") {
+     if (is_chromeos) {
+       deps += [ "//ui/chromeos" ]
+     }
 +
 +    if (!is_electron_build) {
 +      deps += [ "//chrome:packed_resources_integrity_hash" ]

+ 15 - 15
patches/chromium/can_create_window.patch

@@ -9,10 +9,10 @@ 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 dc75ab59ff7af972c950a9be682ebd9cddce2627..a969bbaaecb4b589808413d40299b68f3bc1fd3e 100644
+index be7895586d64b0f8e7f122561d86f49479400a2b..5ad53ce87d8757b18e5ecedbd7ec9aec54bea165 100644
 --- a/content/browser/renderer_host/render_frame_host_impl.cc
 +++ b/content/browser/renderer_host/render_frame_host_impl.cc
-@@ -6880,6 +6880,7 @@ void RenderFrameHostImpl::CreateNewWindow(
+@@ -6908,6 +6908,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,
@@ -21,10 +21,10 @@ index dc75ab59ff7af972c950a9be682ebd9cddce2627..a969bbaaecb4b589808413d40299b68f
            &no_javascript_access);
  
 diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
-index 2afbf96abef912bf483d08f6c011aa4a2e515e25..92dcf2308842ce8922426b0cafdd5a3e83f4bd52 100644
+index 88266830511440e51e47166c66f80e9956bcef5a..3fa51ecee644055db44bd4dd54c27ec224ff46d6 100644
 --- a/content/browser/web_contents/web_contents_impl.cc
 +++ b/content/browser/web_contents/web_contents_impl.cc
-@@ -3931,6 +3931,14 @@ FrameTree* WebContentsImpl::CreateNewWindow(
+@@ -3937,6 +3937,14 @@ FrameTree* WebContentsImpl::CreateNewWindow(
    }
    auto* new_contents_impl = new_contents.get();
  
@@ -39,7 +39,7 @@ index 2afbf96abef912bf483d08f6c011aa4a2e515e25..92dcf2308842ce8922426b0cafdd5a3e
    new_contents_impl->GetController().SetSessionStorageNamespace(
        partition_config, session_storage_namespace);
  
-@@ -3975,12 +3983,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
+@@ -3981,12 +3989,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
      AddWebContentsDestructionObserver(new_contents_impl);
    }
  
@@ -53,7 +53,7 @@ index 2afbf96abef912bf483d08f6c011aa4a2e515e25..92dcf2308842ce8922426b0cafdd5a3e
                               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 afc0dc34e4a1f6c06e96d7fa09922e8aaf4bab28..f3d13fc719324e064f70077deb5d95cb9e467820 100644
+index ec594f27e94bf0b95967c4d816c9b1e159e4a08d..de908becd59392db284c60f61d97f8b2210aa888 100644
 --- a/content/common/frame.mojom
 +++ b/content/common/frame.mojom
 @@ -550,6 +550,10 @@ struct CreateNewWindowParams {
@@ -68,10 +68,10 @@ index afc0dc34e4a1f6c06e96d7fa09922e8aaf4bab28..f3d13fc719324e064f70077deb5d95cb
  
  // 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 d832c0c37554dafad0c44c78f6dc9233015b152f..654abc174a237a90225ad7be7f1180e929b9829b 100644
+index fbf6817479cace0ca06065eef3aa70aae2a0ebe1..cef6a18df7cfb8528ea07e808c3e539726ea815d 100644
 --- a/content/public/browser/content_browser_client.cc
 +++ b/content/public/browser/content_browser_client.cc
-@@ -576,6 +576,8 @@ bool ContentBrowserClient::CanCreateWindow(
+@@ -577,6 +577,8 @@ bool ContentBrowserClient::CanCreateWindow(
      const std::string& frame_name,
      WindowOpenDisposition disposition,
      const blink::mojom::WindowFeatures& features,
@@ -81,10 +81,10 @@ index d832c0c37554dafad0c44c78f6dc9233015b152f..654abc174a237a90225ad7be7f1180e9
      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 e142bc65c2a0fe06a1cf59621c424170dc2d641c..8573ea54135e363f83bd786db3483d1c539e4bb1 100644
+index a0f2f002b51c6061fe509d13b2286faaec721936..1b7e71e12d01929b8bfacf8c7c8950922bdd3d59 100644
 --- a/content/public/browser/content_browser_client.h
 +++ b/content/public/browser/content_browser_client.h
-@@ -169,6 +169,7 @@ class NetworkService;
+@@ -170,6 +170,7 @@ class NetworkService;
  class TrustedURLLoaderHeaderClient;
  }  // namespace mojom
  struct ResourceRequest;
@@ -92,7 +92,7 @@ index e142bc65c2a0fe06a1cf59621c424170dc2d641c..8573ea54135e363f83bd786db3483d1c
  }  // namespace network
  
  namespace sandbox {
-@@ -958,6 +959,8 @@ class CONTENT_EXPORT ContentBrowserClient {
+@@ -959,6 +960,8 @@ class CONTENT_EXPORT ContentBrowserClient {
        const std::string& frame_name,
        WindowOpenDisposition disposition,
        const blink::mojom::WindowFeatures& features,
@@ -124,7 +124,7 @@ index f132199113778f6b50972419b61a187e6272300c..7bb1680553c405a9016cfd67eca5fa3c
                                                   const OpenURLParams& params) {
    return nullptr;
 diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h
-index 9c70cc90402dd1541b2b58b3be2fa7ff215f8f57..a998c64237a7ffd6583a33cd54fe3229196300a6 100644
+index 85335ff06c87ea3986360fad18df6cf01a4a7cca..eeafde1fa6067804665954525eafdd482d8eb3f3 100644
 --- a/content/public/browser/web_contents_delegate.h
 +++ b/content/public/browser/web_contents_delegate.h
 @@ -16,6 +16,7 @@
@@ -135,7 +135,7 @@ index 9c70cc90402dd1541b2b58b3be2fa7ff215f8f57..a998c64237a7ffd6583a33cd54fe3229
  #include "content/public/browser/eye_dropper.h"
  #include "content/public/browser/invalidate_type.h"
  #include "content/public/browser/media_stream_request.h"
-@@ -339,6 +340,13 @@ class CONTENT_EXPORT WebContentsDelegate {
+@@ -338,6 +339,13 @@ class CONTENT_EXPORT WebContentsDelegate {
        const StoragePartitionConfig& partition_config,
        SessionStorageNamespace* session_storage_namespace);
  
@@ -220,10 +220,10 @@ index 84d32491a56528a84b4395fba1d54cdbb38d522b..09998a83c449ef8cd9f360fbcdcf7edc
  
  }  // 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 c18012a217bfc492ac2cdef5776bb23099df57ae..b96bd45cfee98c8177b3ac5979273d1f9ba47388 100644
+index dcacde03e5889d7347aadb2cfde10da767c9f9ca..3ccb2700c97d1297b8482e1b7b324cfa4002e21e 100644
 --- a/third_party/blink/renderer/core/frame/local_dom_window.cc
 +++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
-@@ -2069,6 +2069,7 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
+@@ -2068,6 +2068,7 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
  
    WebWindowFeatures window_features =
        GetWindowFeaturesFromString(features, incumbent_window);

+ 1 - 1
patches/chromium/chore_expose_v8_initialization_isolate_callbacks.patch

@@ -9,7 +9,7 @@ we're running with contextIsolation enabled, we should be falling back
 to Blink's logic. This will be upstreamed in some form.
 
 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 5040ec838c64ffa8aa58ba43f51df649443b2f81..7a7a87d00fa392b7bd07267d9059664d5d472252 100644
+index 66dddc124ca48024cb9539529b787f6e9aa1fd5c..fd6dc712df185724ae88a40e643a26126e54d712 100644
 --- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
 +++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
 @@ -446,8 +446,9 @@ CodeGenerationCheckCallbackInMainThread(v8::Local<v8::Context> context,

+ 6 - 6
patches/chromium/chore_provide_iswebcontentscreationoverridden_with_full_params.patch

@@ -108,10 +108,10 @@ index 6688ba8ba2fb7d930773144cdbc43f1f6fa2b685..22015c7b9b50e1264551ce226757f90e
    }
  
 diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
-index ace0c593debb46c9238e5708634fc6088a1bc715..31d5c0f00ae43706f16fc8615761e96eab31f1f3 100644
+index 70ee9049e3cb73f55bed81c3e08037df2f4c9e07..8d230826aaf867d9046a6b9ac93a60f4750e52be 100644
 --- a/chrome/browser/ui/browser.cc
 +++ b/chrome/browser/ui/browser.cc
-@@ -1770,12 +1770,11 @@ bool Browser::IsWebContentsCreationOverridden(
+@@ -1786,12 +1786,11 @@ bool Browser::IsWebContentsCreationOverridden(
      content::SiteInstance* source_site_instance,
      content::mojom::WindowContainerType window_container_type,
      const GURL& opener_url,
@@ -246,10 +246,10 @@ index c6bd5c19f8a7ceec17c9e32af5296a9617f3a619..02199b439fba7fdc617b7f7980d958b7
    void AddNewContents(content::WebContents* source,
                        std::unique_ptr<content::WebContents> new_contents,
 diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
-index d69e028b34ab4407abcdea3ece93db39926c587e..a82b571fdabe90771bc8f8ed4ae40df3085592c7 100644
+index cc6afdef869470136c2cec392911742a289f6339..2033877b86eddbc9baac6a603587e631021f6819 100644
 --- a/content/browser/web_contents/web_contents_impl.cc
 +++ b/content/browser/web_contents/web_contents_impl.cc
-@@ -3879,8 +3879,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
+@@ -3885,8 +3885,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
  
    if (delegate_ && delegate_->IsWebContentsCreationOverridden(
                         source_site_instance, params.window_container_type,
@@ -274,10 +274,10 @@ index 7bb1680553c405a9016cfd67eca5fa3c6439b692..3aa2cca04340098859e1072eaa80a46a
  }
  
 diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h
-index a998c64237a7ffd6583a33cd54fe3229196300a6..4f57227a9033f905be13bc5166d0324d495a6531 100644
+index eeafde1fa6067804665954525eafdd482d8eb3f3..b17f371aa489a5b61c28fbcd316b19815f072df9 100644
 --- a/content/public/browser/web_contents_delegate.h
 +++ b/content/public/browser/web_contents_delegate.h
-@@ -318,8 +318,7 @@ class CONTENT_EXPORT WebContentsDelegate {
+@@ -317,8 +317,7 @@ class CONTENT_EXPORT WebContentsDelegate {
        SiteInstance* source_site_instance,
        content::mojom::WindowContainerType window_container_type,
        const GURL& opener_url,

+ 2 - 2
patches/chromium/chore_use_electron_resources_not_chrome_for_spellchecker.patch

@@ -7,10 +7,10 @@ spellchecker uses a few IDS_ resources.  We need to load these from
 Electrons grit header instead of Chromes
 
 diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
-index 5f43b35aab6c2f277f0d021b378bee55f97572aa..5bbb64d83e2024feeb7a2eae45f6b8e937fc927c 100644
+index 72c3a67361eaecbe7349db00bbd3b7c1deaced69..a99ce094addf69f21f3c42690defc445eff8fa05 100644
 --- a/chrome/browser/BUILD.gn
 +++ b/chrome/browser/BUILD.gn
-@@ -7126,6 +7126,7 @@ static_library("browser") {
+@@ -7135,6 +7135,7 @@ static_library("browser") {
      deps += [
        "//components/spellcheck/browser",
        "//components/spellcheck/common",

+ 2 - 2
patches/chromium/dcheck.patch

@@ -17,10 +17,10 @@ only one or two specific checks fail. Then it's better to simply comment out the
 failing checks and allow the rest of the target to have them enabled.
 
 diff --git a/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.cc b/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.cc
-index 7a6503d4a4ad33290d97078336c18d81839a8675..0f162b8e681ebb67c5f3b23a40fe3b6ec97cec49 100644
+index a4d74f8e59673d4734ef338235c027bd1c77e92e..6969d1c69ee215055bd49a2bf830416c9e8b62c8 100644
 --- a/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.cc
 +++ b/third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.cc
-@@ -506,8 +506,7 @@ void MobileFriendlinessChecker::NotifyInvalidatePaint(
+@@ -515,8 +515,7 @@ void MobileFriendlinessChecker::NotifyInvalidatePaint(
                                 ->GetPageScaleConstraintsSet()
                                 .FinalConstraints()
                                 .initial_scale;

+ 3 - 3
patches/chromium/disable_color_correct_rendering.patch

@@ -80,7 +80,7 @@ index 6a830ec9f29b9764cd425f0681dafbb18d90b457..a7a095ceb9e626c79db21e0d16c8ef47
        !command_line->HasSwitch(switches::kUIDisablePartialSwap);
  
 diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc
-index 553c3be2562e836e2ce6d6f44997cebf3cba7466..fbe38d97a8d1861ecfb5ccb583d050a28b9ab108 100644
+index 23eed6772dd7edd77378f3bf4cff9d6bb5274894..69056d1121eb833393aba362d71c52cc9c51c6d3 100644
 --- a/components/viz/service/display/gl_renderer.cc
 +++ b/components/viz/service/display/gl_renderer.cc
 @@ -86,6 +86,9 @@
@@ -228,7 +228,7 @@ index 553c3be2562e836e2ce6d6f44997cebf3cba7466..fbe38d97a8d1861ecfb5ccb583d050a2
 +
 +#undef PATCH_CS
 diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
-index 90c7ace352fe909e3f521403c2a7fbf030ccc31e..f011183e21921f38ce5062079e8430a030159bc1 100644
+index 8b32bf5455183ff7bb6295d7922e76a6593b8ee0..041ffe9d26ef3401179eb57917f5585497500689 100644
 --- a/content/browser/gpu/gpu_process_host.cc
 +++ b/content/browser/gpu/gpu_process_host.cc
 @@ -227,6 +227,7 @@ GpuTerminationStatus ConvertToGpuTerminationStatus(
@@ -240,7 +240,7 @@ index 90c7ace352fe909e3f521403c2a7fbf030ccc31e..f011183e21921f38ce5062079e8430a0
      sandbox::policy::switches::kGpuSandboxAllowSysVShm,
      sandbox::policy::switches::kGpuSandboxFailuresFatal,
 diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
-index d8939c1936830b101d6bb4079cd99e6015b481c4..366f801cbe84a28ef462037a26da47c9f65057b4 100644
+index ca056c66af681548ba01bd07db7dadc5ce2a5280..f5025422ebdb9fe35ee5e4e1ed647bc05028d4a8 100644
 --- a/content/browser/renderer_host/render_process_host_impl.cc
 +++ b/content/browser/renderer_host/render_process_host_impl.cc
 @@ -197,6 +197,7 @@

+ 1 - 1
patches/chromium/don_t_use_potentially_null_getwebframe_-_view_when_get_blink.patch

@@ -11,7 +11,7 @@ This regressed in https://chromium-review.googlesource.com/c/chromium/src/+/2572
 Upstream: https://chromium-review.googlesource.com/c/chromium/src/+/2598393
 
 diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
-index bc8bdba3facba81c572d43b85881ec02ad7d2f00..3b12ab113f7c159beb74a09f95335977b4ee2b4f 100644
+index 1fbf6abed9c7d1bbec4478d022e1763ea8bfed8e..e0d7367135abb08f9f303cc528a55d8ba026fa56 100644
 --- a/content/renderer/render_frame_impl.cc
 +++ b/content/renderer/render_frame_impl.cc
 @@ -2367,7 +2367,7 @@ const blink::WebView* RenderFrameImpl::GetWebView() const {

+ 1 - 1
patches/chromium/extend_apply_webpreferences.patch

@@ -12,7 +12,7 @@ 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 06d8ca44fb1dc3748d81b5c5a407dfdf7183f845..85e1772fbcbb190e32dd30996541cc2e9d19d057 100644
+index 13a16ae577130d7520b47eb046b504ccd6796979..6987c81cd9f6b774ec15605c0ea64ca34ba84d22 100644
 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc
 +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
 @@ -159,6 +159,7 @@

+ 5 - 5
patches/chromium/feat_enable_offscreen_rendering_with_viz_compositor.patch

@@ -573,10 +573,10 @@ index 6b7fbb6cf13dc8ee6ade0878a9a2c1efc5d4d3f1..e2af75168cb914a7b3b4a6c9b6a28549
 +  Draw(gfx.mojom.Rect damage_rect) => ();
  };
 diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
-index b30b9460889b9bb3862f4e28b5f1292a118f2a09..d8f1f921d3e6e74c99d6a22c902f81dfc5bb646e 100644
+index 2696c864d5e32e4b87834ced1035a7b1742639b4..ff663b4e75399898daaa3e77339deec03b43a28a 100644
 --- a/ui/compositor/compositor.h
 +++ b/ui/compositor/compositor.h
-@@ -81,6 +81,7 @@ class DisplayPrivate;
+@@ -82,6 +82,7 @@ class DisplayPrivate;
  class ExternalBeginFrameController;
  }  // namespace mojom
  class ContextProvider;
@@ -584,7 +584,7 @@ index b30b9460889b9bb3862f4e28b5f1292a118f2a09..d8f1f921d3e6e74c99d6a22c902f81df
  class HostFrameSinkManager;
  class LocalSurfaceId;
  class RasterContextProvider;
-@@ -137,6 +138,16 @@ class COMPOSITOR_EXPORT ContextFactory {
+@@ -138,6 +139,16 @@ class COMPOSITOR_EXPORT ContextFactory {
    virtual viz::HostFrameSinkManager* GetHostFrameSinkManager() = 0;
  };
  
@@ -601,7 +601,7 @@ index b30b9460889b9bb3862f4e28b5f1292a118f2a09..d8f1f921d3e6e74c99d6a22c902f81df
  // Compositor object to take care of GPU painting.
  // A Browser compositor object is responsible for generating the final
  // displayable form of pixels comprising a single widget's contents. It draws an
-@@ -178,6 +189,9 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver,
+@@ -179,6 +190,9 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver,
    // Schedules a redraw of the layer tree associated with this compositor.
    void ScheduleDraw();
  
@@ -611,7 +611,7 @@ index b30b9460889b9bb3862f4e28b5f1292a118f2a09..d8f1f921d3e6e74c99d6a22c902f81df
    // 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
-@@ -466,6 +480,8 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver,
+@@ -469,6 +483,8 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver,
  
    std::unique_ptr<PendingBeginFrameArgs> pending_begin_frame_args_;
  

+ 3 - 3
patches/chromium/fix_crash_when_saving_edited_pdf_files.patch

@@ -13,10 +13,10 @@ This patch can be removed should we choose to support chrome.fileSystem
 or support it enough to fix the crash.
 
 diff --git a/chrome/browser/resources/pdf/pdf_viewer.ts b/chrome/browser/resources/pdf/pdf_viewer.ts
-index 2e370bf7fd61d75677cfc84798ba543a48f3bc19..fc8f471745c8daf30679df1ffb994febe62cfbea 100644
+index 22f7a86817fe4a2dc39913db349e81d93eef4874..c9509d84e25fd88d6ef13933099d582561fe5660 100644
 --- a/chrome/browser/resources/pdf/pdf_viewer.ts
 +++ b/chrome/browser/resources/pdf/pdf_viewer.ts
-@@ -855,26 +855,12 @@ export class PDFViewerElement extends PDFViewerBaseElement {
+@@ -858,26 +858,12 @@ export class PDFViewerElement extends PDFViewerBaseElement {
        dataArray = [result.dataToSave];
      }
  
@@ -48,7 +48,7 @@ index 2e370bf7fd61d75677cfc84798ba543a48f3bc19..fc8f471745c8daf30679df1ffb994feb
    }
  
    /**
-@@ -982,30 +968,12 @@ export class PDFViewerElement extends PDFViewerBaseElement {
+@@ -985,30 +971,12 @@ export class PDFViewerElement extends PDFViewerBaseElement {
        fileName = fileName + '.pdf';
      }
  

+ 78 - 4
patches/chromium/fix_patch_out_permissions_checks_in_exclusive_access.patch

@@ -14,10 +14,67 @@ but it's not strictly necessary for this API to work to spec.
 Profile check has been upstreamed at https://chromium-review.googlesource.com/c/chromium/src/+/3247196
 
 diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
-index 8d6f8aedab475c1a553949bfcba3753ebed87778..e379e4995b0812be5970cf9741a00e4f99dea3f1 100644
+index f1b9597ea5070ac1847355833a751c72abc0e917..caa82d39fbab39ce7c90dcec401aa8d54a5b39da 100644
 --- a/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
 +++ b/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
-@@ -384,13 +384,9 @@ void FullscreenController::EnterFullscreenModeInternal(
+@@ -16,12 +16,16 @@
+ #include "build/build_config.h"
+ #include "chrome/browser/app_mode/app_mode_utils.h"
+ #include "chrome/browser/profiles/profile.h"
++#if 0
+ #include "chrome/browser/ui/blocked_content/popunder_preventer.h"
++#endif
+ #include "chrome/browser/ui/exclusive_access/exclusive_access_context.h"
+ #include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
+ #include "chrome/browser/ui/exclusive_access/fullscreen_within_tab_helper.h"
++#if 0
+ #include "chrome/browser/ui/status_bubble.h"
+ #include "chrome/browser/ui/tabs/tab_strip_model.h"
++#endif
+ #include "chrome/common/chrome_switches.h"
+ #include "content/public/browser/navigation_details.h"
+ #include "content/public/browser/navigation_entry.h"
+@@ -161,6 +165,7 @@ void FullscreenController::EnterFullscreenModeForTab(
+     return;
+   }
+ 
++#if 0
+   if (base::FeatureList::IsEnabled(
+           blink::features::kWindowPlacementFullscreenCompanionWindow)) {
+     if (!popunder_preventer_)
+@@ -168,6 +173,7 @@ void FullscreenController::EnterFullscreenModeForTab(
+     else
+       popunder_preventer_->WillActivateWebContents(web_contents);
+   }
++#endif
+ 
+   SetTabWithExclusiveAccess(web_contents);
+   requesting_origin_ =
+@@ -203,7 +209,9 @@ void FullscreenController::EnterFullscreenModeForTab(
+ }
+ 
+ void FullscreenController::ExitFullscreenModeForTab(WebContents* web_contents) {
++#if 0
+   popunder_preventer_.reset();
++#endif
+ 
+   if (MaybeToggleFullscreenWithinTab(web_contents, false)) {
+     // During tab capture of fullscreen-within-tab views, the browser window
+@@ -248,11 +256,13 @@ void FullscreenController::ExitFullscreenModeForTab(WebContents* web_contents) {
+ void FullscreenController::FullscreenTabOpeningPopup(
+     content::WebContents* opener,
+     content::WebContents* popup) {
++#if 0
+   DCHECK(base::FeatureList::IsEnabled(
+       blink::features::kWindowPlacementFullscreenCompanionWindow));
+   DCHECK_EQ(exclusive_access_tab(), opener);
+   DCHECK(popunder_preventer_);
+   popunder_preventer_->AddPotentialPopunder(popup);
++#endif
+ }
+ 
+ void FullscreenController::OnTabDeactivated(
+@@ -402,13 +412,9 @@ void FullscreenController::EnterFullscreenModeInternal(
    // Do not enter fullscreen mode if disallowed by pref. This prevents the user
    // from manually entering fullscreen mode and also disables kiosk mode on
    // desktop platforms.
@@ -33,7 +90,7 @@ index 8d6f8aedab475c1a553949bfcba3753ebed87778..e379e4995b0812be5970cf9741a00e4f
  #endif
  
    toggled_into_fullscreen_ = true;
-@@ -403,6 +399,7 @@ void FullscreenController::EnterFullscreenModeInternal(
+@@ -421,6 +427,7 @@ void FullscreenController::EnterFullscreenModeInternal(
        url = extension_caused_fullscreen_;
    }
  
@@ -41,7 +98,7 @@ index 8d6f8aedab475c1a553949bfcba3753ebed87778..e379e4995b0812be5970cf9741a00e4f
    if (display_id != display::kInvalidDisplayId) {
      // Check, but do not prompt, for permission to request a specific screen.
      // Sites generally need permission to get the display id in the first place.
-@@ -415,6 +412,7 @@ void FullscreenController::EnterFullscreenModeInternal(
+@@ -434,6 +441,7 @@ void FullscreenController::EnterFullscreenModeInternal(
        display_id = display::kInvalidDisplayId;
      }
    }
@@ -49,3 +106,20 @@ index 8d6f8aedab475c1a553949bfcba3753ebed87778..e379e4995b0812be5970cf9741a00e4f
  
    if (option == BROWSER)
      base::RecordAction(base::UserMetricsAction("ToggleFullscreen"));
+diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller.h b/chrome/browser/ui/exclusive_access/fullscreen_controller.h
+index 7bd40f52ef5f6b04a7ea114ec4d18c8a98ec6d42..fb04fed5cc1e2e255c9e67c180fababe1fbb3fe0 100644
+--- a/chrome/browser/ui/exclusive_access/fullscreen_controller.h
++++ b/chrome/browser/ui/exclusive_access/fullscreen_controller.h
+@@ -222,10 +222,12 @@ class FullscreenController : public ExclusiveAccessControllerBase {
+   // Used in testing to set the state to tab fullscreen.
+   bool is_tab_fullscreen_for_testing_ = false;
+ 
++#if 0
+   // Tracks related popups that lost activation or were shown without activation
+   // during content fullscreen sessions. This also activates the popups when
+   // fullscreen exits, to prevent sites from creating persisent popunders.
+   std::unique_ptr<PopunderPreventer> popunder_preventer_;
++#endif
+ 
+   base::ObserverList<FullscreenObserver> observer_list_;
+ 

+ 2 - 2
patches/chromium/fix_properly_honor_printing_page_ranges.patch

@@ -62,10 +62,10 @@ index 9e351c7e80a135adf0ebe011763f5164e51981bb..b9fcb4d2a8c7a22ebc7cd8434636454e
    PMPrintSettings print_settings =
        static_cast<PMPrintSettings>([print_info_.get() PMPrintSettings]);
 diff --git a/printing/printing_context_system_dialog_win.cc b/printing/printing_context_system_dialog_win.cc
-index ba604d33cc0601276320f3f81f20e98cb2811f74..1da667c66b75ab44727c5029c02d44379f924007 100644
+index b7ba6ba4446963b08bce9fe416379169bd880378..7c621ea7a60725d08ee9ade68b65fd5bc88b0c2d 100644
 --- a/printing/printing_context_system_dialog_win.cc
 +++ b/printing/printing_context_system_dialog_win.cc
-@@ -53,14 +53,28 @@ void PrintingContextSystemDialogWin::AskUserForSettings(
+@@ -75,14 +75,28 @@ void PrintingContextSystemDialogWin::AskUserForSettings(
    PRINTPAGERANGE ranges[32];
    dialog_options.nStartPage = START_PAGE_GENERAL;
    if (max_pages) {

+ 4 - 4
patches/chromium/frame_host_manager.patch

@@ -6,10 +6,10 @@ Subject: frame_host_manager.patch
 Allows embedder to intercept site instances created by chromium.
 
 diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc
-index 6ecce70efe2d63259f8de512de276a49da1ee9c0..3068a27d60c109156d91dee68715d00aaf5f972d 100644
+index 9208dc75b4e3d969fbb0bb13de64d2b129de9509..b5779d43456c5e356497f2cb671fcb9b3492b47f 100644
 --- a/content/browser/renderer_host/render_frame_host_manager.cc
 +++ b/content/browser/renderer_host/render_frame_host_manager.cc
-@@ -3167,6 +3167,9 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
+@@ -3170,6 +3170,9 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
      request->ResetStateForSiteInstanceChange();
    }
  
@@ -20,10 +20,10 @@ index 6ecce70efe2d63259f8de512de276a49da1ee9c0..3068a27d60c109156d91dee68715d00a
  }
  
 diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
-index 8573ea54135e363f83bd786db3483d1c539e4bb1..11036e52affafe46bab3146184b8d89696d4163c 100644
+index 1b7e71e12d01929b8bfacf8c7c8950922bdd3d59..ca5a03653611843a8eac90e1be86ca4aa40ecce2 100644
 --- a/content/public/browser/content_browser_client.h
 +++ b/content/public/browser/content_browser_client.h
-@@ -276,6 +276,11 @@ class CONTENT_EXPORT ContentBrowserClient {
+@@ -277,6 +277,11 @@ class CONTENT_EXPORT ContentBrowserClient {
  
    virtual ~ContentBrowserClient() = default;
  

+ 2 - 2
patches/chromium/gritsettings_resource_ids.patch

@@ -6,10 +6,10 @@ 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 22896db086972ff3865df9cbb4d904f1e00b7321..8e23293f8cd7f0a4203b3d5fdae24aa5e26fc2ec 100644
+index 862a5fa7d1f388c9e6cda18416fb5d9ae56cca4b..2da5d367dacd557bcca79412ed77fd74d37241f4 100644
 --- a/tools/gritsettings/resource_ids.spec
 +++ b/tools/gritsettings/resource_ids.spec
-@@ -955,6 +955,11 @@
+@@ -950,6 +950,11 @@
      "includes": [4960],
    },
  

+ 1 - 1
patches/chromium/hack_to_allow_gclient_sync_with_host_os_mac_on_linux_in_ci.patch

@@ -11,7 +11,7 @@ If removing this patch causes no sync failures, it's safe to delete :+1:
 Ref https://chromium-review.googlesource.com/c/chromium/src/+/2953903
 
 diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
-index 8cf820d7d1f5d9e85156a18e9ec573dbeb63d41a..a7d6ea676aaba90220761fa7ecc4569012806581 100755
+index 90f738057d3040b5421d51592097c7c30106a94f..3cb2f0880bb36f19fc9b55f2351f891088e8c304 100755
 --- a/tools/clang/scripts/update.py
 +++ b/tools/clang/scripts/update.py
 @@ -298,6 +298,8 @@ def GetDefaultHostOs():

+ 37 - 0
patches/chromium/introduce_ozoneplatform_electron_can_call_x11_property.patch

@@ -0,0 +1,37 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Marek Rusinowski <[email protected]>
+Date: Wed, 23 Mar 2022 21:09:37 +0100
+Subject: introduce OzonePlatform::electron_can_call_x11 property
+
+We expose this additonal property in the OzonePlatform to be able to easily
+determine whatever we can call X11 functions without crashing the application
+at rutime. It would be best if eventually all usages of this property were
+replaced with clean ozone native implementations.
+
+diff --git a/ui/ozone/platform/x11/ozone_platform_x11.cc b/ui/ozone/platform/x11/ozone_platform_x11.cc
+index 9008af973427d7dab8170449bc5767cebc9d2e9e..e312287e4aca61b51a69c8413088f56f9f704b5e 100644
+--- a/ui/ozone/platform/x11/ozone_platform_x11.cc
++++ b/ui/ozone/platform/x11/ozone_platform_x11.cc
+@@ -200,6 +200,7 @@ class OzonePlatformX11 : public OzonePlatform,
+       properties->supports_vulkan_swap_chain = true;
+       properties->uses_external_vulkan_image_factory = true;
+       properties->skia_can_fall_back_to_x11 = true;
++      properties->electron_can_call_x11 = true;
+       properties->platform_shows_drag_image = false;
+       properties->supports_global_application_menus = true;
+       properties->app_modal_dialogs_use_event_blocker = true;
+diff --git a/ui/ozone/public/ozone_platform.h b/ui/ozone/public/ozone_platform.h
+index 22ba32317a74df24249d1528dcaaa28ff18bd0f4..fa57f97520a0327be2c7f5179591ca61b801c8b0 100644
+--- a/ui/ozone/public/ozone_platform.h
++++ b/ui/ozone/public/ozone_platform.h
+@@ -132,6 +132,10 @@ class COMPONENT_EXPORT(OZONE) OzonePlatform {
+     // Linux only: determines if Skia can fall back to the X11 output device.
+     bool skia_can_fall_back_to_x11 = false;
+ 
++    // Linux only: determines is Electron can call selected X11 functions while
++    // it migrates to pure ozone abstractions.
++    bool electron_can_call_x11 = false;
++
+     // Wayland only: determines whether windows which are not top level ones
+     // should be given parents explicitly.
+     bool set_parent_for_non_top_level_windows = false;

+ 1 - 1
patches/chromium/load_v8_snapshot_in_browser_process.patch

@@ -9,7 +9,7 @@ but due to the nature of electron, we need to load the v8 snapshot
 in the browser process.
 
 diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc
-index 7074141f95253587ae3ca156118ac6b10dd60e26..0476d00de005060c991cd6fa9ccd323ef5d56ea3 100644
+index ce5f2904c283643558375a84453073f7ea8aba3e..a17bf60c79fdd2511a46796b80879ed7926c706d 100644
 --- a/content/app/content_main_runner_impl.cc
 +++ b/content/app/content_main_runner_impl.cc
 @@ -248,11 +248,8 @@ void LoadV8SnapshotFile(const base::CommandLine& command_line) {

+ 1 - 1
patches/chromium/notification_provenance.patch

@@ -131,7 +131,7 @@ index 951075749b24814606f494c5a89ee2adf527f512..7036323ff8ee38ae92790dfd2e216df6
        const GURL& document_url,
        mojo::PendingReceiver<blink::mojom::NotificationService> receiver);
 diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
-index cc5f7c8d616ec9a433da428f180483da60736a9d..fb25a7c19f20ca690963c5a15bd09224687b5f57 100644
+index a188b1282e7ceca3fe24cb2d82c644bf0c21bc6f..f0b6fa61bb24d5b5fc4cf9cb8fc2f635f515f3f6 100644
 --- a/content/browser/renderer_host/render_process_host_impl.cc
 +++ b/content/browser/renderer_host/render_process_host_impl.cc
 @@ -2083,7 +2083,7 @@ void RenderProcessHostImpl::CreateNotificationService(

+ 18 - 18
patches/chromium/picture-in-picture.patch

@@ -22,7 +22,7 @@ index 7bc8d118f87b91baf1c3bd1d34374996ab1d3638..2d2c1c86f311b07f0c2b09d5a4c082cc
  #include "ui/base/metadata/metadata_impl_macros.h"
  #include "ui/base/models/image_model.h"
 diff --git a/chrome/browser/ui/views/overlay/back_to_tab_label_button.cc b/chrome/browser/ui/views/overlay/back_to_tab_label_button.cc
-index 7d0e39968bf34cdc99549cb48f6bf0a11c182565..f21c1672abf34dc9d19cd39c5d09083a60ef6978 100644
+index d566dbf99ea1164c6a8407026a9839218a6ba1fb..239cd53d70c547c79214988a82efdc8c472d553c 100644
 --- a/chrome/browser/ui/views/overlay/back_to_tab_label_button.cc
 +++ b/chrome/browser/ui/views/overlay/back_to_tab_label_button.cc
 @@ -5,7 +5,7 @@
@@ -35,7 +35,7 @@ index 7d0e39968bf34cdc99549cb48f6bf0a11c182565..f21c1672abf34dc9d19cd39c5d09083a
  #include "ui/base/cursor/cursor.h"
  #include "ui/base/l10n/l10n_util.h"
 diff --git a/chrome/browser/ui/views/overlay/close_image_button.cc b/chrome/browser/ui/views/overlay/close_image_button.cc
-index d3400d7b02edc9cffba4cb53ec601b6e4cfea3b2..8e620ad6172a650ea96f80c0b44035932471d88b 100644
+index a3d9c0f03c8ade2553bad5721d4e15e6fd658074..b3b043cbf9144013bf7903121575b31b348ea87e 100644
 --- a/chrome/browser/ui/views/overlay/close_image_button.cc
 +++ b/chrome/browser/ui/views/overlay/close_image_button.cc
 @@ -6,7 +6,7 @@
@@ -150,10 +150,10 @@ index 3309906bcae27ba89d73ce4fba49843a10cd31f6..9f828f70606238186b35b5e1ca875113
    web_view->SetWebContents(pip_contents);
  
 diff --git a/chrome/browser/ui/views/overlay/document_overlay_window_views.h b/chrome/browser/ui/views/overlay/document_overlay_window_views.h
-index 86d385842501d28b5eb42f841822294eb597e6ed..43c19dfa6ec6b48f8694636cc184dd616e5d6aca 100644
+index b2b178ccadce82f8d4ec8e5a6dafe1c67bcecd74..603d82a461c4c443ac26c85a46fbd866a42237e6 100644
 --- a/chrome/browser/ui/views/overlay/document_overlay_window_views.h
 +++ b/chrome/browser/ui/views/overlay/document_overlay_window_views.h
-@@ -55,7 +55,6 @@ class DocumentOverlayWindowViews : public OverlayWindowViews,
+@@ -56,7 +56,6 @@ class DocumentOverlayWindowViews : public OverlayWindowViews,
    bool IsVisible() const override;
    void OnNativeWidgetMove() override;
    void OnNativeWidgetDestroyed() override;
@@ -162,13 +162,13 @@ index 86d385842501d28b5eb42f841822294eb597e6ed..43c19dfa6ec6b48f8694636cc184dd61
    // OverlayWindowViews
    bool ControlsHitTestContainsPoint(const gfx::Point& point) override;
 diff --git a/chrome/browser/ui/views/overlay/hang_up_button.cc b/chrome/browser/ui/views/overlay/hang_up_button.cc
-index 26f8f5ffa444d874b229b5e8debf087e4469dfd1..10149e812a43e3d5c92701e9b2ae8d68ed8395c7 100644
+index 75bfe0f7a4d759f677cad5c365fa7f98121d54de..cb251381f1c77ad01d4906132f3d68865aaace10 100644
 --- a/chrome/browser/ui/views/overlay/hang_up_button.cc
 +++ b/chrome/browser/ui/views/overlay/hang_up_button.cc
-@@ -5,7 +5,7 @@
- #include "chrome/browser/ui/views/overlay/hang_up_button.h"
+@@ -6,7 +6,7 @@
  
  #include "chrome/browser/ui/color/chrome_color_id.h"
+ #include "chrome/browser/ui/views/overlay/constants.h"
 -#include "chrome/grit/generated_resources.h"
 +#include "electron/grit/electron_resources.h"
  #include "components/vector_icons/vector_icons.h"
@@ -205,13 +205,13 @@ index 850b34e3b40f7ff1848c66158976db079e0853bd..105dbc3661eb2710b2f10ca6584e85c3
  #include "ui/aura/window.h"
  #include "ui/aura/window_tree_host.h"
 diff --git a/chrome/browser/ui/views/overlay/playback_image_button.cc b/chrome/browser/ui/views/overlay/playback_image_button.cc
-index bcd3b2e1038786b660a4b91fbc20d9d8b4afffb4..a953c9d0ee0b49d6cc096e3eb236296b57cbc6c0 100644
+index cb1621a9deefcec601d7537e2cc2fbd24e5f7f64..2d74ab12e1eaf77a6f9dde13e894172d6835e061 100644
 --- a/chrome/browser/ui/views/overlay/playback_image_button.cc
 +++ b/chrome/browser/ui/views/overlay/playback_image_button.cc
-@@ -6,7 +6,7 @@
- 
+@@ -7,7 +7,7 @@
  #include "chrome/app/vector_icons/vector_icons.h"
  #include "chrome/browser/ui/color/chrome_color_id.h"
+ #include "chrome/browser/ui/views/overlay/constants.h"
 -#include "chrome/grit/generated_resources.h"
 +#include "electron/grit/electron_resources.h"
  #include "components/vector_icons/vector_icons.h"
@@ -244,26 +244,26 @@ index 51c7db1bfbd3c03b9cb2786c8c7482b33e3aca0b..2890f7420d2fd258f84019963eab6c96
  #include "ui/base/metadata/metadata_impl_macros.h"
  #include "ui/gfx/color_palette.h"
 diff --git a/chrome/browser/ui/views/overlay/toggle_camera_button.cc b/chrome/browser/ui/views/overlay/toggle_camera_button.cc
-index 46ec4441ddb227325b319359f9d33a80aa856d85..57957d72310c0a232c78489fba5a07cdf475dc53 100644
+index 20b82ff4dcf7fef3315b2b47bb480446509c6541..244a50e57b6c12680405c92f0ecbdbdb8bcfcb4f 100644
 --- a/chrome/browser/ui/views/overlay/toggle_camera_button.cc
 +++ b/chrome/browser/ui/views/overlay/toggle_camera_button.cc
-@@ -5,7 +5,7 @@
- #include "chrome/browser/ui/views/overlay/toggle_camera_button.h"
+@@ -6,7 +6,7 @@
  
  #include "chrome/browser/ui/color/chrome_color_id.h"
+ #include "chrome/browser/ui/views/overlay/constants.h"
 -#include "chrome/grit/generated_resources.h"
 +#include "electron/grit/electron_resources.h"
  #include "components/vector_icons/vector_icons.h"
  #include "ui/base/l10n/l10n_util.h"
  #include "ui/base/metadata/metadata_impl_macros.h"
 diff --git a/chrome/browser/ui/views/overlay/toggle_microphone_button.cc b/chrome/browser/ui/views/overlay/toggle_microphone_button.cc
-index 59b9a5442185bfb9efd8ed571ec63d56e3bc3326..34d58bf54019e0b8001c29cb301861d045c60214 100644
+index 1a1edb6321490fdbf5cd347cb3d2cb9a6a5b1080..1e959cf1c8fe356ab4427e4bf4f8da1028f4575f 100644
 --- a/chrome/browser/ui/views/overlay/toggle_microphone_button.cc
 +++ b/chrome/browser/ui/views/overlay/toggle_microphone_button.cc
-@@ -5,7 +5,7 @@
- #include "chrome/browser/ui/views/overlay/toggle_microphone_button.h"
+@@ -6,7 +6,7 @@
  
  #include "chrome/browser/ui/color/chrome_color_id.h"
+ #include "chrome/browser/ui/views/overlay/constants.h"
 -#include "chrome/grit/generated_resources.h"
 +#include "electron/grit/electron_resources.h"
  #include "components/vector_icons/vector_icons.h"
@@ -283,7 +283,7 @@ index 5e136488b37887e9523ac04a9ff4ccdfaf96c104..24899f4c2b6fe66b96a6728bf747f1aa
  #include "ui/base/l10n/l10n_util.h"
  #include "ui/base/metadata/metadata_impl_macros.h"
 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 b2e281840f48592eb773c16042fb6b56a0fa132b..d5156bab0c81ca508733a8d3ba95f052ff6d83e6 100644
+index 6d2744b673ecb31464d4aa9b0d11177892c030f4..f9ea66415b85ce385be429ead5e04c8a96dc31c4 100644
 --- a/chrome/browser/ui/views/overlay/video_overlay_window_views.cc
 +++ b/chrome/browser/ui/views/overlay/video_overlay_window_views.cc
 @@ -15,9 +15,11 @@
@@ -319,7 +319,7 @@ index b2e281840f48592eb773c16042fb6b56a0fa132b..d5156bab0c81ca508733a8d3ba95f052
  #include "chrome/browser/shell_integration_win.h"
  #include "ui/aura/window.h"
  #include "ui/aura/window_tree_host.h"
-@@ -148,7 +150,7 @@ std::unique_ptr<VideoOverlayWindowViews> VideoOverlayWindowViews::Create(
+@@ -167,7 +169,7 @@ std::unique_ptr<VideoOverlayWindowViews> VideoOverlayWindowViews::Create(
    overlay_window->Init(std::move(params));
    overlay_window->OnRootViewReady();
  

+ 64 - 56
patches/chromium/printing.patch

@@ -69,7 +69,7 @@ index 650c78f16c812170aeda99d75300ff88f47347a0..c33ce445a23f97a744db3a4ac30ef471
      NEW_DOC,
  
 diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc
-index 27305997182f0a669291d2f36dd6b0b98c43f314..cbb83e1f5661852d84468ec9d342af1b2d05ae45 100644
+index b11b8f34cf7e252a8d22e167d6555f3aa432e5c4..a5950a9d4c823e3df145c365bb499c0163fe3e77 100644
 --- a/chrome/browser/printing/print_job_worker.cc
 +++ b/chrome/browser/printing/print_job_worker.cc
 @@ -20,7 +20,6 @@
@@ -88,7 +88,7 @@ index 27305997182f0a669291d2f36dd6b0b98c43f314..cbb83e1f5661852d84468ec9d342af1b
  #include "printing/backend/print_backend.h"
  #include "printing/buildflags/buildflags.h"
  #include "printing/mojom/print.mojom.h"
-@@ -234,16 +234,21 @@ void PrintJobWorker::UpdatePrintSettings(base::Value new_settings,
+@@ -229,16 +229,21 @@ void PrintJobWorker::UpdatePrintSettings(base::Value new_settings,
  #endif  // BUILDFLAG(IS_LINUX) && defined(USE_CUPS)
    }
  
@@ -114,10 +114,10 @@ index 27305997182f0a669291d2f36dd6b0b98c43f314..cbb83e1f5661852d84468ec9d342af1b
  
  #if BUILDFLAG(IS_CHROMEOS)
 diff --git a/chrome/browser/printing/print_job_worker_oop.cc b/chrome/browser/printing/print_job_worker_oop.cc
-index 52a13c0c47f7f3f18c4f552806add67291ce8726..765bde402fec094b51faea68e67d3782bbc06564 100644
+index 56232bf979e90a01bb580c0a1972ae0860d994e9..96e05b5cd4b556a6ddb41664b5ff999b899e5972 100644
 --- a/chrome/browser/printing/print_job_worker_oop.cc
 +++ b/chrome/browser/printing/print_job_worker_oop.cc
-@@ -226,7 +226,7 @@ void PrintJobWorkerOop::OnFailure() {
+@@ -305,7 +305,7 @@ void PrintJobWorkerOop::OnFailure() {
  }
  
  void PrintJobWorkerOop::ShowErrorDialog() {
@@ -127,7 +127,7 @@ index 52a13c0c47f7f3f18c4f552806add67291ce8726..765bde402fec094b51faea68e67d3782
  
  void PrintJobWorkerOop::UnregisterServiceManagerClient() {
 diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
-index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521e01702ac 100644
+index 2eb81c133b94fd237e4eaa60472c08515fd6d01e..abd7e5e5832919cbd06b3b337f54d79d284a4247 100644
 --- a/chrome/browser/printing/print_view_manager_base.cc
 +++ b/chrome/browser/printing/print_view_manager_base.cc
 @@ -30,10 +30,10 @@
@@ -151,7 +151,7 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
  #include "mojo/public/cpp/system/buffer.h"
  #include "printing/buildflags/buildflags.h"
  #include "printing/metafile_skia.h"
-@@ -86,6 +87,8 @@ using PrintSettingsCallback =
+@@ -88,6 +89,8 @@ using PrintSettingsCallback =
      base::OnceCallback<void(std::unique_ptr<PrinterQuery>)>;
  
  void ShowWarningMessageBox(const std::u16string& message) {
@@ -160,7 +160,7 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
    // Runs always on the UI thread.
    static bool is_dialog_shown = false;
    if (is_dialog_shown)
-@@ -94,6 +97,7 @@ void ShowWarningMessageBox(const std::u16string& message) {
+@@ -96,6 +99,7 @@ void ShowWarningMessageBox(const std::u16string& message) {
    base::AutoReset<bool> auto_reset(&is_dialog_shown, true);
  
    chrome::ShowWarningMessageBox(nullptr, std::u16string(), message);
@@ -168,7 +168,7 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
  }
  
  #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
-@@ -191,7 +195,9 @@ void UpdatePrintSettingsReplyOnIO(
+@@ -193,7 +197,9 @@ void UpdatePrintSettingsReplyOnIO(
    DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
    DCHECK(printer_query);
    mojom::PrintPagesParamsPtr params = CreateEmptyPrintPagesParamsPtr();
@@ -179,7 +179,7 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
      RenderParamsFromPrintSettings(printer_query->settings(),
                                    params->params.get());
      params->params->document_cookie = printer_query->cookie();
-@@ -244,6 +250,7 @@ void ScriptedPrintReplyOnIO(
+@@ -246,6 +252,7 @@ void ScriptedPrintReplyOnIO(
      mojom::PrintManagerHost::ScriptedPrintCallback callback) {
    DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
    mojom::PrintPagesParamsPtr params = CreateEmptyPrintPagesParamsPtr();
@@ -187,7 +187,7 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
    if (printer_query->last_status() == mojom::ResultCode::kSuccess &&
        printer_query->settings().dpi()) {
      RenderParamsFromPrintSettings(printer_query->settings(),
-@@ -253,8 +260,9 @@ void ScriptedPrintReplyOnIO(
+@@ -255,8 +262,9 @@ void ScriptedPrintReplyOnIO(
    }
    bool has_valid_cookie = params->params->document_cookie;
    bool has_dpi = !params->params->dpi.IsEmpty();
@@ -198,7 +198,7 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
  
    if (has_dpi && has_valid_cookie) {
      queue->QueuePrinterQuery(std::move(printer_query));
-@@ -292,12 +300,14 @@ PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents)
+@@ -295,12 +303,14 @@ PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents)
      : PrintManager(web_contents),
        queue_(g_browser_process->print_job_manager()->queue()) {
    DCHECK(queue_);
@@ -213,7 +213,7 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
  }
  
  PrintViewManagerBase::~PrintViewManagerBase() {
-@@ -305,7 +315,10 @@ PrintViewManagerBase::~PrintViewManagerBase() {
+@@ -308,7 +318,10 @@ PrintViewManagerBase::~PrintViewManagerBase() {
    DisconnectFromCurrentPrintJob();
  }
  
@@ -225,8 +225,8 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
    // Remember the ID for `rfh`, to enable checking that the `RenderFrameHost`
    // is still valid after a possible inner message loop runs in
    // `DisconnectFromCurrentPrintJob()`.
-@@ -328,7 +341,9 @@ bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh) {
-   // go in `ReleasePrintJob()`.
+@@ -334,7 +347,9 @@ bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh) {
+ #endif
  
    SetPrintingRFH(rfh);
 -  GetPrintRenderFrame(rfh)->PrintRequestedPages();
@@ -236,7 +236,7 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
  
    for (auto& observer : GetObservers())
      observer.OnPrintNow(rfh);
-@@ -471,7 +486,8 @@ void PrintViewManagerBase::GetDefaultPrintSettingsReply(
+@@ -487,7 +502,8 @@ void PrintViewManagerBase::GetDefaultPrintSettingsReply(
  void PrintViewManagerBase::ScriptedPrintReply(
      ScriptedPrintCallback callback,
      int process_id,
@@ -245,8 +245,8 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
 +    bool canceled) {
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  
-   if (!content::RenderProcessHost::FromID(process_id)) {
-@@ -479,16 +495,19 @@ void PrintViewManagerBase::ScriptedPrintReply(
+ #if BUILDFLAG(ENABLE_OOP_PRINTING)
+@@ -500,16 +516,19 @@ void PrintViewManagerBase::ScriptedPrintReply(
      return;
    }
  
@@ -270,22 +270,22 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
  }
  
  void PrintViewManagerBase::NavigationStopped() {
-@@ -602,12 +621,13 @@ void PrintViewManagerBase::DidPrintDocument(
+@@ -625,11 +644,14 @@ void PrintViewManagerBase::DidPrintDocument(
  void PrintViewManagerBase::GetDefaultPrintSettings(
      GetDefaultPrintSettingsCallback callback) {
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 +#if 0 // Printing is always enabled.
++
    if (!printing_enabled_.GetValue()) {
      GetDefaultPrintSettingsReply(std::move(callback),
                                   mojom::PrintParams::New());
      return;
    }
--
 +#endif
-   content::RenderFrameHost* render_frame_host = GetCurrentTargetFrame();
-   auto callback_wrapper =
-       base::BindOnce(&PrintViewManagerBase::GetDefaultPrintSettingsReply,
-@@ -624,18 +644,20 @@ void PrintViewManagerBase::UpdatePrintSettings(
+ #if BUILDFLAG(ENABLE_OOP_PRINTING)
+   if (printing::features::kEnableOopPrintDriversJobPrint.Get() &&
+       !service_manager_client_id_.has_value()) {
+@@ -656,18 +678,20 @@ void PrintViewManagerBase::UpdatePrintSettings(
      base::Value job_settings,
      UpdatePrintSettingsCallback callback) {
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
@@ -307,7 +307,7 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
    content::BrowserContext* context =
        web_contents() ? web_contents()->GetBrowserContext() : nullptr;
    PrefService* prefs =
-@@ -645,6 +667,7 @@ void PrintViewManagerBase::UpdatePrintSettings(
+@@ -677,6 +701,7 @@ void PrintViewManagerBase::UpdatePrintSettings(
      if (value > 0)
        job_settings.SetIntKey(kSettingRasterizePdfDpi, value);
    }
@@ -315,7 +315,7 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
  
    auto callback_wrapper =
        base::BindOnce(&PrintViewManagerBase::UpdatePrintSettingsReply,
-@@ -670,7 +693,7 @@ void PrintViewManagerBase::ScriptedPrint(mojom::ScriptedPrintParamsPtr params,
+@@ -702,14 +727,14 @@ void PrintViewManagerBase::ScriptedPrint(mojom::ScriptedPrintParamsPtr params,
      // didn't happen for some reason.
      bad_message::ReceivedBadMessage(
          render_process_host, bad_message::PVMB_SCRIPTED_PRINT_FENCED_FRAME);
@@ -323,8 +323,16 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
 +    std::move(callback).Run(CreateEmptyPrintPagesParamsPtr(), false);
      return;
    }
-   auto callback_wrapper = base::BindOnce(
-@@ -691,7 +714,6 @@ void PrintViewManagerBase::PrintingFailed(int32_t cookie) {
+ #if BUILDFLAG(ENABLE_OOP_PRINTING)
+   if (printing::features::kEnableOopPrintDriversJobPrint.Get() &&
+       !service_manager_client_id_.has_value()) {
+     // Renderer process has requested settings outside of the expected setup.
+-    std::move(callback).Run(CreateEmptyPrintPagesParamsPtr());
++    std::move(callback).Run(CreateEmptyPrintPagesParamsPtr(), false);
+     return;
+   }
+ #endif
+@@ -732,7 +757,6 @@ void PrintViewManagerBase::PrintingFailed(int32_t cookie) {
    PrintManager::PrintingFailed(cookie);
  
  #if !BUILDFLAG(IS_ANDROID)  // Android does not implement this function.
@@ -332,7 +340,7 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
  #endif
  
    ReleasePrinterQuery();
-@@ -706,6 +728,11 @@ void PrintViewManagerBase::RemoveObserver(Observer& observer) {
+@@ -747,6 +771,11 @@ void PrintViewManagerBase::RemoveObserver(Observer& observer) {
  }
  
  void PrintViewManagerBase::ShowInvalidPrinterSettingsError() {
@@ -344,7 +352,7 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(&ShowWarningMessageBox,
                                  l10n_util::GetStringUTF16(
-@@ -716,10 +743,12 @@ void PrintViewManagerBase::RenderFrameHostStateChanged(
+@@ -757,10 +786,12 @@ void PrintViewManagerBase::RenderFrameHostStateChanged(
      content::RenderFrameHost* render_frame_host,
      content::RenderFrameHost::LifecycleState /*old_state*/,
      content::RenderFrameHost::LifecycleState new_state) {
@@ -357,7 +365,7 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
  }
  
  void PrintViewManagerBase::DidStartLoading() {
-@@ -779,6 +808,11 @@ void PrintViewManagerBase::OnJobDone() {
+@@ -820,6 +851,11 @@ void PrintViewManagerBase::OnJobDone() {
    ReleasePrintJob();
  }
  
@@ -369,7 +377,7 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
  void PrintViewManagerBase::OnFailed() {
    TerminatePrintJob(true);
  }
-@@ -840,7 +874,10 @@ bool PrintViewManagerBase::CreateNewPrintJob(
+@@ -881,7 +917,10 @@ bool PrintViewManagerBase::CreateNewPrintJob(
  
    // Disconnect the current |print_job_|.
    auto weak_this = weak_ptr_factory_.GetWeakPtr();
@@ -381,9 +389,9 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
    if (!weak_this)
      return false;
  
-@@ -915,6 +952,13 @@ void PrintViewManagerBase::ReleasePrintJob() {
-   content::RenderFrameHost* rfh = printing_rfh_;
-   printing_rfh_ = nullptr;
+@@ -963,6 +1002,13 @@ void PrintViewManagerBase::ReleasePrintJob() {
+   UnregisterSystemPrintClient();
+ #endif
  
 +  if (!callback_.is_null()) {
 +    std::string cb_str = "";
@@ -395,7 +403,7 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
    if (!print_job_)
      return;
  
-@@ -964,7 +1008,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
+@@ -1012,7 +1058,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
  }
  
  bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
@@ -405,7 +413,7 @@ index 1f37c11047d47bb2d65975fa69f33d822206dd08..d13ee6a81cd7edc5be99f595515ca521
  
    if (!cookie) {
 diff --git a/chrome/browser/printing/print_view_manager_base.h b/chrome/browser/printing/print_view_manager_base.h
-index 2661776307f773ac8f2c62529ec86349b045ee8f..cb41b271adbb02517a5e1ad222d0320000437dfb 100644
+index 3a4cfa1e44d781a94030dec6992ffd6f6391020f..d14804d02cc61b6f75d47893f6dd61ddde6cd552 100644
 --- a/chrome/browser/printing/print_view_manager_base.h
 +++ b/chrome/browser/printing/print_view_manager_base.h
 @@ -37,6 +37,8 @@ namespace printing {
@@ -437,7 +445,7 @@ index 2661776307f773ac8f2c62529ec86349b045ee8f..cb41b271adbb02517a5e1ad222d03200
  
    // Adds and removes observers for `PrintViewManagerBase` events. The order in
    // which notifications are sent to observers is undefined. Observers must be
-@@ -193,7 +199,8 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
+@@ -207,7 +213,8 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
    // Runs `callback` with `params` to reply to ScriptedPrint().
    void ScriptedPrintReply(ScriptedPrintCallback callback,
                            int process_id,
@@ -447,7 +455,7 @@ index 2661776307f773ac8f2c62529ec86349b045ee8f..cb41b271adbb02517a5e1ad222d03200
  
    // Requests the RenderView to render all the missing pages for the print job.
    // No-op if no print job is pending. Returns true if at least one page has
-@@ -248,9 +255,15 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
+@@ -262,9 +269,15 @@ class PrintViewManagerBase : public PrintManager, public PrintJob::Observer {
    // The current RFH that is printing with a system printing dialog.
    raw_ptr<content::RenderFrameHost> printing_rfh_ = nullptr;
  
@@ -539,10 +547,10 @@ index 66810a2a5f0c77ba107c71d2abaef8692bda0fea..cd6103af4571f82f11652a3c7ecf0e53
  
  void PdfPrintManager::ShowInvalidPrinterSettingsError() {
 diff --git a/components/printing/common/print.mojom b/components/printing/common/print.mojom
-index 5afad24754e12554368a6619466ca025edc26180..e2e786692bd877d3b8bf7c31829496afa99ed539 100644
+index 6cd585d597315940be144506b9bb819137a7981e..8ea9c38a46460edd237f003ddd7362240a02887e 100644
 --- a/components/printing/common/print.mojom
 +++ b/components/printing/common/print.mojom
-@@ -274,7 +274,7 @@ interface PrintPreviewUI {
+@@ -275,7 +275,7 @@ interface PrintPreviewUI {
  interface PrintRenderFrame {
    // Tells the RenderFrame to switch the CSS to print media type, render every
    // requested page, and then switch back the CSS to display media type.
@@ -551,7 +559,7 @@ index 5afad24754e12554368a6619466ca025edc26180..e2e786692bd877d3b8bf7c31829496af
  
    // Tells the RenderFrame to switch the CSS to print media type, render every
    // requested page using the print preview document's frame/node, and then
-@@ -341,7 +341,7 @@ interface PrintManagerHost {
+@@ -342,7 +342,7 @@ interface PrintManagerHost {
    // Request the print settings from the user. This step is about showing
    // UI to the user to select the final print settings.
    [Sync]
@@ -561,7 +569,7 @@ index 5afad24754e12554368a6619466ca025edc26180..e2e786692bd877d3b8bf7c31829496af
    // Tells the browser that there are invalid printer settings.
    ShowInvalidPrinterSettingsError();
 diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
-index 066521576d021cbd3e68057f68199c23a8a30437..72777428d2456191875806bc3c57d0801b43a8ea 100644
+index 419a2daf45c123df7cd4e38614598278cb775cba..9b3fcc2e7cfbd70587845bbd056957255b74f0a2 100644
 --- a/components/printing/renderer/print_render_frame_helper.cc
 +++ b/components/printing/renderer/print_render_frame_helper.cc
 @@ -40,6 +40,7 @@
@@ -610,7 +618,7 @@ index 066521576d021cbd3e68057f68199c23a8a30437..72777428d2456191875806bc3c57d080
    if (!render_frame_gone_)
      print_preview_context_.DispatchAfterPrintEvent();
    // WARNING: |this| may be gone at this point. Do not do any more work here and
-@@ -1387,6 +1390,8 @@ void PrintRenderFrameHelper::PrintPreview(base::Value settings) {
+@@ -1389,6 +1392,8 @@ void PrintRenderFrameHelper::PrintPreview(base::Value settings) {
    if (ipc_nesting_level_ > kAllowedIpcDepthForPrint)
      return;
  
@@ -618,8 +626,8 @@ index 066521576d021cbd3e68057f68199c23a8a30437..72777428d2456191875806bc3c57d080
 +  print_preview_context_.InitWithFrame(frame);
    print_preview_context_.OnPrintPreview();
  
-   if (print_preview_context_.IsForArc()) {
-@@ -1924,7 +1929,8 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) {
+ #if BUILDFLAG(IS_CHROMEOS_ASH)
+@@ -1941,7 +1946,8 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) {
        return;
  
      Print(duplicate_node.GetDocument().GetFrame(), duplicate_node,
@@ -629,7 +637,7 @@ index 066521576d021cbd3e68057f68199c23a8a30437..72777428d2456191875806bc3c57d080
      // Check if |this| is still valid.
      if (!weak_this)
        return;
-@@ -1939,7 +1945,9 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) {
+@@ -1956,7 +1962,9 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) {
  
  void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
                                     const blink::WebNode& node,
@@ -640,7 +648,7 @@ index 066521576d021cbd3e68057f68199c23a8a30437..72777428d2456191875806bc3c57d080
    // If still not finished with earlier print request simply ignore.
    if (prep_frame_view_)
      return;
-@@ -1947,7 +1955,7 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
+@@ -1964,7 +1972,7 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
    FrameReference frame_ref(frame);
  
    uint32_t expected_page_count = 0;
@@ -649,7 +657,7 @@ index 066521576d021cbd3e68057f68199c23a8a30437..72777428d2456191875806bc3c57d080
      DidFinishPrinting(FAIL_PRINT_INIT);
      return;  // Failed to init print page settings.
    }
-@@ -1966,8 +1974,15 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
+@@ -1983,8 +1991,15 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
          print_pages_params_->params->print_scaling_option;
  
      auto self = weak_ptr_factory_.GetWeakPtr();
@@ -666,7 +674,7 @@ index 066521576d021cbd3e68057f68199c23a8a30437..72777428d2456191875806bc3c57d080
      // Check if |this| is still valid.
      if (!self)
        return;
-@@ -2215,36 +2230,51 @@ void PrintRenderFrameHelper::IPCProcessed() {
+@@ -2232,36 +2247,51 @@ void PrintRenderFrameHelper::IPCProcessed() {
    }
  }
  
@@ -724,13 +732,13 @@ index 066521576d021cbd3e68057f68199c23a8a30437..72777428d2456191875806bc3c57d080
 +    uint32_t* number_of_pages,
 +    const base::DictionaryValue& settings) {
    DCHECK(frame);
-   bool fit_to_paper_size = !IsPrintingNodeOrPdfFrame(frame, node);
+   bool fit_to_paper_size = !IsPrintingPdfFrame(frame, node);
 -  if (!InitPrintSettings(fit_to_paper_size)) {
 +  if (!InitPrintSettings(fit_to_paper_size, settings)) {
      notify_browser_of_print_failure_ = false;
      GetPrintManagerHost()->ShowInvalidPrinterSettingsError();
      return false;
-@@ -2389,7 +2419,7 @@ mojom::PrintPagesParamsPtr PrintRenderFrameHelper::GetPrintSettingsFromUser(
+@@ -2405,7 +2435,7 @@ mojom::PrintPagesParamsPtr PrintRenderFrameHelper::GetPrintSettingsFromUser(
        std::move(params),
        base::BindOnce(
            [](base::OnceClosure quit_closure, mojom::PrintPagesParamsPtr* output,
@@ -739,7 +747,7 @@ index 066521576d021cbd3e68057f68199c23a8a30437..72777428d2456191875806bc3c57d080
              *output = std::move(input);
              std::move(quit_closure).Run();
            },
-@@ -2634,18 +2664,7 @@ void PrintRenderFrameHelper::RequestPrintPreview(PrintPreviewRequestType type,
+@@ -2656,18 +2686,7 @@ void PrintRenderFrameHelper::RequestPrintPreview(PrintPreviewRequestType type,
  }
  
  bool PrintRenderFrameHelper::CheckForCancel() {
@@ -760,10 +768,10 @@ index 066521576d021cbd3e68057f68199c23a8a30437..72777428d2456191875806bc3c57d080
  
  bool PrintRenderFrameHelper::PreviewPageRendered(
 diff --git a/components/printing/renderer/print_render_frame_helper.h b/components/printing/renderer/print_render_frame_helper.h
-index 2b703118bf94a82262adc293368dcfcdb67807ff..a07f307ff48f3ce5409354a5ba8d54b43325da73 100644
+index 023594185e3aa9c79e8c5179c40ce867a5bb80e9..312cf5d4dbdb130dee3a07f970c9d92d6cd2cdbf 100644
 --- a/components/printing/renderer/print_render_frame_helper.h
 +++ b/components/printing/renderer/print_render_frame_helper.h
-@@ -254,7 +254,7 @@ class PrintRenderFrameHelper
+@@ -256,7 +256,7 @@ class PrintRenderFrameHelper
        mojo::PendingAssociatedReceiver<mojom::PrintRenderFrame> receiver);
  
    // printing::mojom::PrintRenderFrame:
@@ -772,7 +780,7 @@ index 2b703118bf94a82262adc293368dcfcdb67807ff..a07f307ff48f3ce5409354a5ba8d54b4
  #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
    void PrintForSystemDialog() override;
    void SetPrintPreviewUI(
-@@ -321,7 +321,9 @@ class PrintRenderFrameHelper
+@@ -323,7 +323,9 @@ class PrintRenderFrameHelper
    // WARNING: |this| may be gone after this method returns.
    void Print(blink::WebLocalFrame* frame,
               const blink::WebNode& node,
@@ -783,7 +791,7 @@ index 2b703118bf94a82262adc293368dcfcdb67807ff..a07f307ff48f3ce5409354a5ba8d54b4
  
    // Notification when printing is done - signal tear-down/free resources.
    void DidFinishPrinting(PrintingResult result);
-@@ -330,12 +332,14 @@ class PrintRenderFrameHelper
+@@ -332,12 +334,14 @@ class PrintRenderFrameHelper
  
    // Initialize print page settings with default settings.
    // Used only for native printing workflow.

+ 2 - 2
patches/chromium/refactor_expose_cursor_changes_to_the_webcontentsobserver.patch

@@ -43,10 +43,10 @@ index ed56e947fa137cbaddaa12503ae983d7acd4463f..e1d77416991bac0178935b1bd255947d
  
  void RenderWidgetHostImpl::ShowContextMenuAtPoint(
 diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
-index 92dcf2308842ce8922426b0cafdd5a3e83f4bd52..d69e028b34ab4407abcdea3ece93db39926c587e 100644
+index 3fa51ecee644055db44bd4dd54c27ec224ff46d6..cc6afdef869470136c2cec392911742a289f6339 100644
 --- a/content/browser/web_contents/web_contents_impl.cc
 +++ b/content/browser/web_contents/web_contents_impl.cc
-@@ -4494,6 +4494,11 @@ TextInputManager* WebContentsImpl::GetTextInputManager() {
+@@ -4500,6 +4500,11 @@ TextInputManager* WebContentsImpl::GetTextInputManager() {
    return text_input_manager_.get();
  }
  

+ 3 - 3
patches/chromium/resource_file_conflict.patch

@@ -52,10 +52,10 @@ Some alternatives to this patch:
 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 6a696e816a185f8492674fcaf1cbbf7e2faabf99..a6e0a53d4ebbd585114bc0cda2e2d1caaab4a015 100644
+index f1e0552dedf377238e9cd9d24a5ebea77ed83717..1f86073736f849e797e029678bc212ce96ba0bd9 100644
 --- a/chrome/BUILD.gn
 +++ b/chrome/BUILD.gn
-@@ -1545,7 +1545,7 @@ if (is_chrome_branded && !is_android) {
+@@ -1547,7 +1547,7 @@ if (is_chrome_branded && !is_android) {
    }
  }
  
@@ -64,7 +64,7 @@ index 6a696e816a185f8492674fcaf1cbbf7e2faabf99..a6e0a53d4ebbd585114bc0cda2e2d1ca
    chrome_paks("packed_resources") {
      if (is_mac) {
        output_dir = "$root_gen_dir/repack"
-@@ -1574,6 +1574,12 @@ if (!is_android) {
+@@ -1576,6 +1576,12 @@ if (!is_android) {
    }
  }
  

+ 1 - 1
patches/chromium/support_mixed_sandbox_with_zygote.patch

@@ -22,7 +22,7 @@ However, the patch would need to be reviewed by the security team, as it
 does touch a security-sensitive class.
 
 diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
-index fb25a7c19f20ca690963c5a15bd09224687b5f57..d8939c1936830b101d6bb4079cd99e6015b481c4 100644
+index f0b6fa61bb24d5b5fc4cf9cb8fc2f635f515f3f6..ca056c66af681548ba01bd07db7dadc5ce2a5280 100644
 --- a/content/browser/renderer_host/render_process_host_impl.cc
 +++ b/content/browser/renderer_host/render_process_host_impl.cc
 @@ -1786,9 +1786,15 @@ bool RenderProcessHostImpl::Init() {

+ 15 - 5
patches/chromium/ui_gtk_public_header.patch

@@ -3,22 +3,32 @@ From: deepak1556 <[email protected]>
 Date: Fri, 10 Apr 2020 17:47:18 -0700
 Subject: ui_gtk_public_header.patch
 
-Allow electron to depend on //ui/gtk/gtk_util.h
+Allow electron to depend on gtk_util.h and gtk_ui.h from //ui/gtk/
 
 diff --git a/ui/gtk/BUILD.gn b/ui/gtk/BUILD.gn
-index 4093df78da0bbb1d8df743942f364cf728ad3414..2f31d99b207ffc3531b5334b5a01239cc1fefb35 100644
+index 4093df78da0bbb1d8df743942f364cf728ad3414..2f7c404307bfebb0e2890148cf9b0d6d9c68094f 100644
 --- a/ui/gtk/BUILD.gn
 +++ b/ui/gtk/BUILD.gn
-@@ -69,7 +69,7 @@ generate_stubs("gtk_stubs") {
+@@ -69,7 +69,11 @@ generate_stubs("gtk_stubs") {
  }
  
  component("gtk") {
 -  public = [ "gtk_ui_factory.h" ]
-+  public = [ "gtk_ui_factory.h", "gtk_util.h" ]
++  public = [
++    "gtk_ui.h",
++    "gtk_ui_factory.h",
++    "gtk_util.h",
++  ]
  
    sources = [
      "gtk_color_mixers.cc",
-@@ -85,7 +85,6 @@ component("gtk") {
+@@ -79,13 +83,11 @@ component("gtk") {
+     "gtk_key_bindings_handler.cc",
+     "gtk_key_bindings_handler.h",
+     "gtk_ui.cc",
+-    "gtk_ui.h",
+     "gtk_ui_factory.cc",
+     "gtk_ui_platform.h",
      "gtk_ui_platform_stub.cc",
      "gtk_ui_platform_stub.h",
      "gtk_util.cc",

+ 3 - 3
patches/chromium/web_contents.patch

@@ -9,10 +9,10 @@ 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 a82b571fdabe90771bc8f8ed4ae40df3085592c7..1942d3446225411bdce80628e219641b3089d4a3 100644
+index 2033877b86eddbc9baac6a603587e631021f6819..7f4679943fa1d7b2585552a811098d97cada3070 100644
 --- a/content/browser/web_contents/web_contents_impl.cc
 +++ b/content/browser/web_contents/web_contents_impl.cc
-@@ -3045,6 +3045,13 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
+@@ -3051,6 +3051,13 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
        site_instance.get(), params.renderer_initiated_creation,
        params.main_frame_name, GetOriginalOpener(), primary_main_frame_policy);
  
@@ -26,7 +26,7 @@ index a82b571fdabe90771bc8f8ed4ae40df3085592c7..1942d3446225411bdce80628e219641b
    WebContentsViewDelegate* delegate =
        GetContentClient()->browser()->GetWebContentsViewDelegate(this);
  
-@@ -3055,6 +3062,7 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
+@@ -3061,6 +3068,7 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
      view_.reset(CreateWebContentsView(this, delegate,
                                        &render_view_host_delegate_view_));
    }

+ 2 - 2
patches/chromium/webview_cross_drag.patch

@@ -24,10 +24,10 @@ index 4095ee0ef25226180acb35d320630f971305528e..a0aff5ad93e7644211a2c15553b3d098
  
  ////////////////////////////////////////////////////////////////////////////////
 diff --git a/content/browser/web_contents/web_drag_dest_mac.mm b/content/browser/web_contents/web_drag_dest_mac.mm
-index 6455404fdccab1fffceef4b8d291c137d3a448c4..483b0b5b689da03f0d7e43576fa73275197f5a95 100644
+index dab3703cc4469802bae9e4d45c3e7d0f0857f577..ecd8af37c681ae5c97060af00bbeb8ebddb72b26 100644
 --- a/content/browser/web_contents/web_drag_dest_mac.mm
 +++ b/content/browser/web_contents/web_drag_dest_mac.mm
-@@ -385,9 +385,7 @@ - (void)setDragStartTrackersForProcess:(int)processID {
+@@ -388,9 +388,7 @@ - (void)setDragStartTrackersForProcess:(int)processID {
  }
  
  - (bool)isValidDragTarget:(content::RenderWidgetHostImpl*)targetRWH {

+ 2 - 2
patches/chromium/webview_fullscreen.patch

@@ -14,10 +14,10 @@ Note that we also need to manually update embedder's
 `api::WebContents::IsFullscreenForTabOrPending` value.
 
 diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
-index a969bbaaecb4b589808413d40299b68f3bc1fd3e..6e5d3ae228b98295bd95bad3cc58215a13c20106 100644
+index 5ad53ce87d8757b18e5ecedbd7ec9aec54bea165..37f181f16cd2520de1cbec678e02061b165fed62 100644
 --- a/content/browser/renderer_host/render_frame_host_impl.cc
 +++ b/content/browser/renderer_host/render_frame_host_impl.cc
-@@ -6267,6 +6267,15 @@ void RenderFrameHostImpl::EnterFullscreen(
+@@ -6293,6 +6293,15 @@ void RenderFrameHostImpl::EnterFullscreen(
      notified_instances.insert(parent_site_instance);
    }
  

+ 4 - 4
patches/chromium/worker_context_will_destroy.patch

@@ -55,10 +55,10 @@ index 8cbfe0a939e97de8dd8d4b5e4d741fb46e94fd45..2bc2ef61890a4c189613ae8a3f61c746
        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 ced2c8e433d5b807bd4f1aa44c6af53e93261c23..53b1ebb708e2332e38090d1adba88dbe850bf02d 100644
+index b68c90f1f1dd23b8b938936a092b01ffa41f0f28..60aa2e562901d9ff7b915c105acaf49851c959ba 100644
 --- a/third_party/blink/public/platform/platform.h
 +++ b/third_party/blink/public/platform/platform.h
-@@ -716,6 +716,7 @@ class BLINK_PLATFORM_EXPORT Platform {
+@@ -714,6 +714,7 @@ class BLINK_PLATFORM_EXPORT Platform {
    virtual void DidStartWorkerThread() {}
    virtual void WillStopWorkerThread() {}
    virtual void WorkerContextCreated(const v8::Local<v8::Context>& worker) {}
@@ -67,10 +67,10 @@ index ced2c8e433d5b807bd4f1aa44c6af53e93261c23..53b1ebb708e2332e38090d1adba88dbe
        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 2406a8b438de5f01f5354e08bcfc8810238b1bea..e7a60f6cae0fabeac6a5adec633ad5f45d43ef33 100644
+index 68c38d2045c7c23650bd56717081bb001a4e690e..e0e08d4bdf9521ed5c1940d31665d1b675119f0d 100644
 --- a/third_party/blink/renderer/core/workers/worker_thread.cc
 +++ b/third_party/blink/renderer/core/workers/worker_thread.cc
-@@ -731,6 +731,12 @@ void WorkerThread::PrepareForShutdownOnWorkerThread() {
+@@ -732,6 +732,12 @@ void WorkerThread::PrepareForShutdownOnWorkerThread() {
      nested_runner_->QuitNow();
    }
  

+ 2 - 2
patches/chromium/worker_feat_add_hook_to_notify_script_ready.patch

@@ -65,10 +65,10 @@ index 2bc2ef61890a4c189613ae8a3f61c746ffc5d310..36661d62ec1e6f7966b0789326fcbefa
    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 53b1ebb708e2332e38090d1adba88dbe850bf02d..8e86b79cf98c5e2429d0ec54b27eb950c6ce6303 100644
+index 60aa2e562901d9ff7b915c105acaf49851c959ba..bec02889875ef8f6e422d99c8a161898b36610c5 100644
 --- a/third_party/blink/public/platform/platform.h
 +++ b/third_party/blink/public/platform/platform.h
-@@ -716,6 +716,8 @@ class BLINK_PLATFORM_EXPORT Platform {
+@@ -714,6 +714,8 @@ class BLINK_PLATFORM_EXPORT Platform {
    virtual void DidStartWorkerThread() {}
    virtual void WillStopWorkerThread() {}
    virtual void WorkerContextCreated(const v8::Local<v8::Context>& worker) {}

+ 1 - 1
patches/node/.patches

@@ -1,5 +1,4 @@
 refactor_alter_child_process_fork_to_use_execute_script_with.patch
-feat_add_uv_loop_watcher_queue_code.patch
 feat_initialize_asar_support.patch
 expose_get_builtin_module_function.patch
 build_add_gn_build_files.patch
@@ -42,3 +41,4 @@ unix_remove_uv_cloexec_ioctl_3515.patch
 process_simplify_uv_write_int_calls_3519.patch
 macos_don_t_use_thread-unsafe_strtok_3524.patch
 process_fix_hang_after_note_exit_3521.patch
+feat_add_uv_loop_interrupt_on_io_change_option_to_uv_loop_configure.patch

+ 11 - 2
patches/node/build_add_gn_build_files.patch

@@ -7,10 +7,10 @@ This adds GN build files for Node, so we don't have to build with GYP.
 
 diff --git a/BUILD.gn b/BUILD.gn
 new file mode 100644
-index 0000000000000000000000000000000000000000..bd5788caa61305fd9af8f9d7f8f1937a224fda83
+index 0000000000000000000000000000000000000000..4afca42d22ee702af50da92aa08c1de897891424
 --- /dev/null
 +++ b/BUILD.gn
-@@ -0,0 +1,394 @@
+@@ -0,0 +1,403 @@
 +import("//electron/build/asar.gni")
 +import("//v8/gni/v8.gni")
 +
@@ -192,6 +192,15 @@ index 0000000000000000000000000000000000000000..bd5788caa61305fd9af8f9d7f8f1937a
 +  }
 +}
 +
++executable("overlapped-checker") {
++  sources = []
++  if (is_win) {
++    sources += [ "test/overlapped-checker/main_win.c" ]
++  } else {
++    sources += [ "test/overlapped-checker/main_unix.c" ]
++  }
++}
++
 +component("node_lib") {
 +  deps = [
 +    ":node_js2c",

+ 503 - 0
patches/node/feat_add_uv_loop_interrupt_on_io_change_option_to_uv_loop_configure.patch

@@ -0,0 +1,503 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Cheng Zhao <[email protected]>
+Date: Mon, 31 Jan 2022 20:56:58 +0900
+Subject: feat: add UV_LOOP_INTERRUPT_ON_IO_CHANGE option to uv_loop_configure
+
+https://github.com/libuv/libuv/pull/3308
+
+diff --git a/deps/uv/docs/src/loop.rst b/deps/uv/docs/src/loop.rst
+index 0f5ddfb3ca21b7e5b38d0a4ce4b9e77387597199..ba815202fb157aa82859ec0518523cf6f2ec6ba1 100644
+--- a/deps/uv/docs/src/loop.rst
++++ b/deps/uv/docs/src/loop.rst
+@@ -73,7 +73,15 @@ API
+ 
+       This option is necessary to use :c:func:`uv_metrics_idle_time`.
+ 
++    - UV_LOOP_INTERRUPT_ON_IO_CHANGE: Interrupt the loop whenever a new IO
++      event has been added or changed.
++
++      This option is usually when implementing event loop integration, to make
++      the polling of backend fd interrupt to recognize the changes of IO events.
++
+     .. versionchanged:: 1.39.0 added the UV_METRICS_IDLE_TIME option.
++    .. versionchanged:: 1.43.0 added the UV_LOOP_INTERRUPT_ON_IO_CHANGE option.
++
+ 
+ .. c:function:: int uv_loop_close(uv_loop_t* loop)
+ 
+diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
+index 606083c87de5790d7e66fc34aeaae9a58acb8ef4..824b0b77cf5f0a46dcb3855c44ac73faaba2055f 100644
+--- a/deps/uv/include/uv.h
++++ b/deps/uv/include/uv.h
+@@ -252,7 +252,8 @@ typedef struct uv_statfs_s uv_statfs_t;
+ 
+ typedef enum {
+   UV_LOOP_BLOCK_SIGNAL = 0,
+-  UV_METRICS_IDLE_TIME
++  UV_METRICS_IDLE_TIME,
++  UV_LOOP_INTERRUPT_ON_IO_CHANGE
+ } uv_loop_option;
+ 
+ typedef enum {
+diff --git a/deps/uv/src/unix/async.c b/deps/uv/src/unix/async.c
+index e1805c323795e5b0c465d80100eebeb7bf838caa..dd4358c0cdaa97ba8fadf4d9755993803beddd18 100644
+--- a/deps/uv/src/unix/async.c
++++ b/deps/uv/src/unix/async.c
+@@ -38,7 +38,6 @@
+ #include <sys/eventfd.h>
+ #endif
+ 
+-static void uv__async_send(uv_loop_t* loop);
+ static int uv__async_start(uv_loop_t* loop);
+ 
+ 
+@@ -70,7 +69,7 @@ int uv_async_send(uv_async_t* handle) {
+     return 0;
+ 
+   /* Wake up the other thread's event loop. */
+-  uv__async_send(handle->loop);
++  uv__loop_interrupt(handle->loop);
+ 
+   /* Tell the other thread we're done. */
+   if (cmpxchgi(&handle->pending, 1, 2) != 1)
+@@ -165,40 +164,6 @@ static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
+ }
+ 
+ 
+-static void uv__async_send(uv_loop_t* loop) {
+-  const void* buf;
+-  ssize_t len;
+-  int fd;
+-  int r;
+-
+-  buf = "";
+-  len = 1;
+-  fd = loop->async_wfd;
+-
+-#if defined(__linux__)
+-  if (fd == -1) {
+-    static const uint64_t val = 1;
+-    buf = &val;
+-    len = sizeof(val);
+-    fd = loop->async_io_watcher.fd;  /* eventfd */
+-  }
+-#endif
+-
+-  do
+-    r = write(fd, buf, len);
+-  while (r == -1 && errno == EINTR);
+-
+-  if (r == len)
+-    return;
+-
+-  if (r == -1)
+-    if (errno == EAGAIN || errno == EWOULDBLOCK)
+-      return;
+-
+-  abort();
+-}
+-
+-
+ static int uv__async_start(uv_loop_t* loop) {
+   int pipefd[2];
+   int err;
+diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
+index 7cd3a2a954ff7d70e6ba7a6f7538648841bc54b2..f89b7158218be60ac10e61484a2d5e5e28a3182f 100644
+--- a/deps/uv/src/unix/core.c
++++ b/deps/uv/src/unix/core.c
+@@ -887,6 +887,9 @@ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
+     loop->watchers[w->fd] = w;
+     loop->nfds++;
+   }
++
++  if (uv__get_internal_fields(loop)->flags & UV_LOOP_INTERRUPT_ON_IO_CHANGE)
++    uv__loop_interrupt(loop);
+ }
+ 
+ 
+@@ -918,6 +921,9 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
+   }
+   else if (QUEUE_EMPTY(&w->watcher_queue))
+     QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
++
++  if (uv__get_internal_fields(loop)->flags & UV_LOOP_INTERRUPT_ON_IO_CHANGE)
++    uv__loop_interrupt(loop);
+ }
+ 
+ 
+@@ -934,6 +940,9 @@ void uv__io_close(uv_loop_t* loop, uv__io_t* w) {
+ void uv__io_feed(uv_loop_t* loop, uv__io_t* w) {
+   if (QUEUE_EMPTY(&w->pending_queue))
+     QUEUE_INSERT_TAIL(&loop->pending_queue, &w->pending_queue);
++
++  if (uv__get_internal_fields(loop)->flags & UV_LOOP_INTERRUPT_ON_IO_CHANGE)
++    uv__loop_interrupt(loop);
+ }
+ 
+ 
+diff --git a/deps/uv/src/unix/loop.c b/deps/uv/src/unix/loop.c
+index a88e71c339351f2ebcdd6c3f933fc3b1122910ed..353143e5ebecae598425dc036f4458bb7c43bb0b 100644
+--- a/deps/uv/src/unix/loop.c
++++ b/deps/uv/src/unix/loop.c
+@@ -217,6 +217,11 @@ int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) {
+     return 0;
+   }
+ 
++  if (option == UV_LOOP_INTERRUPT_ON_IO_CHANGE) {
++    lfields->flags |= UV_LOOP_INTERRUPT_ON_IO_CHANGE;
++    return 0;
++  }
++
+   if (option != UV_LOOP_BLOCK_SIGNAL)
+     return UV_ENOSYS;
+ 
+@@ -226,3 +231,37 @@ int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) {
+   loop->flags |= UV_LOOP_BLOCK_SIGPROF;
+   return 0;
+ }
++
++
++void uv__loop_interrupt(uv_loop_t* loop) {
++  const void* buf;
++  ssize_t len;
++  int fd;
++  int r;
++
++  buf = "";
++  len = 1;
++  fd = loop->async_wfd;
++
++#if defined(__linux__)
++  if (fd == -1) {
++    static const uint64_t val = 1;
++    buf = &val;
++    len = sizeof(val);
++    fd = loop->async_io_watcher.fd;  /* eventfd */
++  }
++#endif
++
++  do
++    r = write(fd, buf, len);
++  while (r == -1 && errno == EINTR);
++
++  if (r == len)
++    return;
++
++  if (r == -1)
++    if (errno == EAGAIN || errno == EWOULDBLOCK)
++      return;
++
++  abort();
++}
+diff --git a/deps/uv/src/uv-common.h b/deps/uv/src/uv-common.h
+index 6001b0cf68d0b0268b578218b664a737f43c9521..5d2212571f4bcb648ab332f0c5650d0fdb37c03a 100644
+--- a/deps/uv/src/uv-common.h
++++ b/deps/uv/src/uv-common.h
+@@ -140,6 +140,8 @@ int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap);
+ 
+ void uv__loop_close(uv_loop_t* loop);
+ 
++void uv__loop_interrupt(uv_loop_t* loop);
++
+ int uv__read_start(uv_stream_t* stream,
+                    uv_alloc_cb alloc_cb,
+                    uv_read_cb read_cb);
+@@ -268,6 +270,10 @@ void uv__threadpool_cleanup(void);
+     if (((h)->flags & UV_HANDLE_ACTIVE) != 0) break;                          \
+     (h)->flags |= UV_HANDLE_ACTIVE;                                           \
+     if (((h)->flags & UV_HANDLE_REF) != 0) uv__active_handle_add(h);          \
++    int loop_flags = uv__get_internal_fields((h)->loop)->flags;               \
++    if (loop_flags & UV_LOOP_INTERRUPT_ON_IO_CHANGE) {                        \
++      uv__loop_interrupt((h)->loop);                                          \
++    }                                                                         \
+   }                                                                           \
+   while (0)
+ 
+diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c
+index e53a0f8e28637a58ceec7852d1a79874fc1a9548..dd4065c1cc68763bfe258492e3119669311394dc 100644
+--- a/deps/uv/src/win/core.c
++++ b/deps/uv/src/win/core.c
+@@ -381,10 +381,20 @@ int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) {
+     return 0;
+   }
+ 
++  if (option == UV_LOOP_INTERRUPT_ON_IO_CHANGE) {
++    lfields->flags |= UV_LOOP_INTERRUPT_ON_IO_CHANGE;
++    return 0;
++  }
++
+   return UV_ENOSYS;
+ }
+ 
+ 
++void uv__loop_interrupt(uv_loop_t* loop) {
++  PostQueuedCompletionStatus(loop->iocp, 0, 0, NULL);
++}
++
++
+ int uv_backend_fd(const uv_loop_t* loop) {
+   return -1;
+ }
+diff --git a/deps/uv/test/test-embed.c b/deps/uv/test/test-embed.c
+index c6ddceb149d9c1d68b0dd17b6dac0d4c3c3e9dbc..f6572c5dc2b6ef39bd11889ad1f7873007a6437d 100644
+--- a/deps/uv/test/test-embed.c
++++ b/deps/uv/test/test-embed.c
+@@ -25,115 +25,179 @@
+ #include <stdlib.h>
+ #include <errno.h>
+ 
+-#ifndef HAVE_KQUEUE
+-# if defined(__APPLE__) ||                                                    \
+-     defined(__DragonFly__) ||                                                \
+-     defined(__FreeBSD__) ||                                                  \
+-     defined(__FreeBSD_kernel__) ||                                           \
+-     defined(__OpenBSD__) ||                                                  \
+-     defined(__NetBSD__)
+-#  define HAVE_KQUEUE 1
+-# endif
+-#endif
+-
+ #ifndef HAVE_EPOLL
+ # if defined(__linux__)
+ #  define HAVE_EPOLL 1
+ # endif
+ #endif
+ 
+-#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
++#if defined(HAVE_EPOLL)
++# include <sys/epoll.h>
++#endif
+ 
+-#if defined(HAVE_KQUEUE)
++#if !defined(_WIN32)
+ # include <sys/types.h>
+-# include <sys/event.h>
+ # include <sys/time.h>
+ #endif
+ 
+-#if defined(HAVE_EPOLL)
+-# include <sys/epoll.h>
+-#endif
+-
++static uv_loop_t main_loop;
++static uv_loop_t external_loop;
+ static uv_thread_t embed_thread;
+ static uv_sem_t embed_sem;
+-static uv_timer_t embed_timer;
+ static uv_async_t embed_async;
++static uv_async_t main_async;
+ static volatile int embed_closed;
+ 
+-static int embed_timer_called;
++static uv_timer_t main_timer;
++static int main_timer_called;
+ 
+ 
+-static void embed_thread_runner(void* arg) {
++#if defined(_WIN32)
++static void embed_thread_poll_win(HANDLE iocp, int timeout) {
++  DWORD bytes;
++  ULONG_PTR key;
++  OVERLAPPED* overlapped;
++
++  GetQueuedCompletionStatus(iocp,
++                            &bytes,
++                            &key,
++                            &overlapped,
++                            timeout >= 0 ? timeout : INFINITE);
++
++  /* Give the event back so the loop can deal with it. */
++  if (overlapped != NULL)
++    PostQueuedCompletionStatus(iocp,
++                               bytes,
++                               key,
++                               overlapped);
++}
++#else
++static void embed_thread_poll_unix(int fd, int timeout) {
+   int r;
+-  int fd;
++  do {
++#if defined(HAVE_EPOLL)
++    struct epoll_event ev;
++    r = epoll_wait(fd, &ev, 1, timeout);
++#else
++    struct timeval tv;
++    if (timeout >= 0) {
++      tv.tv_sec = timeout / 1000;
++      tv.tv_usec = (timeout % 1000) * 1000;
++    }
++    fd_set readset;
++    FD_ZERO(&readset);
++    FD_SET(fd, &readset);
++    r = select(fd + 1, &readset, NULL, NULL, timeout >= 0 ? &tv : NULL);
++#endif
++  } while (r == -1 && errno == EINTR);
++}
++#endif /* !_WIN32 */
++
++
++static void embed_thread_runner(void* arg) {
+   int timeout;
+ 
+-  while (!embed_closed) {
+-    fd = uv_backend_fd(uv_default_loop());
+-    timeout = uv_backend_timeout(uv_default_loop());
+-
+-    do {
+-#if defined(HAVE_KQUEUE)
+-      struct timespec ts;
+-      ts.tv_sec = timeout / 1000;
+-      ts.tv_nsec = (timeout % 1000) * 1000000;
+-      r = kevent(fd, NULL, 0, NULL, 0, &ts);
+-#elif defined(HAVE_EPOLL)
+-      {
+-        struct epoll_event ev;
+-        r = epoll_wait(fd, &ev, 1, timeout);
+-      }
++  do {
++    timeout = uv_backend_timeout(&main_loop);
++
++#if defined(_WIN32)
++    embed_thread_poll_win(main_loop.iocp, timeout);
++#else
++    embed_thread_poll_unix(uv_backend_fd(&main_loop), timeout);
+ #endif
+-    } while (r == -1 && errno == EINTR);
++
+     uv_async_send(&embed_async);
++
+     uv_sem_wait(&embed_sem);
+-  }
++  } while (!embed_closed);
+ }
+ 
+ 
+ static void embed_cb(uv_async_t* async) {
+-  uv_run(uv_default_loop(), UV_RUN_ONCE);
++  /* Run tasks in main loop */
++  uv_run(&main_loop, UV_RUN_NOWAIT);
+ 
++  /* Tell embed thread to continue polling */
+   uv_sem_post(&embed_sem);
+ }
+ 
+ 
+-static void embed_timer_cb(uv_timer_t* timer) {
+-  embed_timer_called++;
++static void main_timer_cb(uv_timer_t* timer) {
++  main_timer_called++;
+   embed_closed = 1;
+ 
+   uv_close((uv_handle_t*) &embed_async, NULL);
++  uv_close((uv_handle_t*) &main_async, NULL);
+ }
+-#endif
+ 
+ 
+-TEST_IMPL(embed) {
+-#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
+-  uv_loop_t external;
+-
+-  ASSERT(0 == uv_loop_init(&external));
++static void init_loops(void) {
++  ASSERT_EQ(0, uv_loop_init(&main_loop));
++  ASSERT_EQ(0, uv_loop_init(&external_loop));
+ 
+-  embed_timer_called = 0;
++  main_timer_called = 0;
+   embed_closed = 0;
+ 
+-  uv_async_init(&external, &embed_async, embed_cb);
++  uv_async_init(&external_loop, &embed_async, embed_cb);
+ 
+-  /* Start timer in default loop */
+-  uv_timer_init(uv_default_loop(), &embed_timer);
+-  uv_timer_start(&embed_timer, embed_timer_cb, 250, 0);
++  /* Create a dummy async for main loop otherwise backend timeout will
++     always be 0 */
++  uv_async_init(&main_loop, &main_async, embed_cb);
+ 
+-  /* Start worker that will interrupt external loop */
++  /* Start worker that will poll main loop and interrupt external loop */
+   uv_sem_init(&embed_sem, 0);
+   uv_thread_create(&embed_thread, embed_thread_runner, NULL);
++}
+ 
+-  /* But run external loop */
+-  uv_run(&external, UV_RUN_DEFAULT);
++
++static void run_loop(void) {
++  /* Run external loop */
++  uv_run(&external_loop, UV_RUN_DEFAULT);
+ 
+   uv_thread_join(&embed_thread);
+-  uv_loop_close(&external);
++  uv_sem_destroy(&embed_sem);
++  uv_loop_close(&external_loop);
++  uv_loop_close(&main_loop);
++}
+ 
+-  ASSERT(embed_timer_called == 1);
+-#endif
++
++TEST_IMPL(embed) {
++  init_loops();
++
++  /* Start timer in main loop */
++  uv_timer_init(&main_loop, &main_timer);
++  uv_timer_start(&main_timer, main_timer_cb, 250, 0);
++
++  run_loop();
++  ASSERT_EQ(main_timer_called, 1);
++
++  return 0;
++}
++
++
++static uv_timer_t external_timer;
++
++
++static void external_timer_cb(uv_timer_t* timer) {
++  /* Start timer in main loop */
++  uv_timer_init(&main_loop, &main_timer);
++  uv_timer_start(&main_timer, main_timer_cb, 250, 0);
++}
++
++
++TEST_IMPL(embed_with_external_timer) {
++  init_loops();
++
++  /* Interrupt embed polling when a handle is started */
++  ASSERT_EQ(0, uv_loop_configure(&main_loop, UV_LOOP_INTERRUPT_ON_IO_CHANGE));
++
++  /* Start timer in external loop, whose callback will not interrupt the
++     polling in embed thread */
++  uv_timer_init(&external_loop, &external_timer);
++  uv_timer_start(&external_timer, external_timer_cb, 100, 0);
++
++  run_loop();
++  ASSERT_EQ(main_timer_called, 1);
+ 
+   return 0;
+ }
+diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
+index a43edf1a4a9b0932ec73b8edaca0f676ecf3ccfa..199402e31406cf8ba360d54769461bb5285011ee 100644
+--- a/deps/uv/test/test-list.h
++++ b/deps/uv/test/test-list.h
+@@ -263,6 +263,7 @@ TEST_DECLARE   (process_priority)
+ TEST_DECLARE   (has_ref)
+ TEST_DECLARE   (active)
+ TEST_DECLARE   (embed)
++TEST_DECLARE   (embed_with_external_timer)
+ TEST_DECLARE   (async)
+ TEST_DECLARE   (async_null_cb)
+ TEST_DECLARE   (eintr_handling)
+@@ -860,6 +861,7 @@ TASK_LIST_START
+   TEST_ENTRY  (active)
+ 
+   TEST_ENTRY  (embed)
++  TEST_ENTRY  (embed_with_external_timer)
+ 
+   TEST_ENTRY  (async)
+   TEST_ENTRY  (async_null_cb)

+ 0 - 59
patches/node/feat_add_uv_loop_watcher_queue_code.patch

@@ -1,59 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Shelley Vohr <[email protected]>
-Date: Mon, 30 Jul 2018 10:34:54 -0700
-Subject: feat: add uv_loop watcher_queue code
-
-Electron's Node Integration works by listening to Node's backend file descriptor in a separate thread; when an event is ready the backend file descriptor will trigger a new event for it, and the main thread will then iterate the libuv loop. For certain operations (ex. adding a timeout task) the backend file descriptor isn't informed, & as a result the main thread doesn't know it needs to iterate the libuv loop so the timeout task will never execute until something else trigger a new event. This commit should be removed when https://github.com/libuv/libuv/pull/1921 is merged
-
-diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
-index 606083c87de5790d7e66fc34aeaae9a58acb8ef4..ca9568c58b1ccd554318f5deb27d2b4e80f08a28 100644
---- a/deps/uv/include/uv.h
-+++ b/deps/uv/include/uv.h
-@@ -1805,6 +1805,8 @@ union uv_any_req {
- struct uv_loop_s {
-   /* User data - use this for whatever. */
-   void* data;
-+  /* Callback when loop's watcher queue updates. */
-+  void (*on_watcher_queue_updated)(uv_loop_t*);
-   /* Loop reference counting. */
-   unsigned int active_handles;
-   void* handle_queue[2];
-diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
-index 71e9c525c4a77b8b5322e8516c58329100a8d951..a6425294086ff2f1435fdd6866380d3aaaf68200 100644
---- a/deps/uv/src/unix/core.c
-+++ b/deps/uv/src/unix/core.c
-@@ -906,8 +906,11 @@ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
-     return;
- #endif
- 
--  if (QUEUE_EMPTY(&w->watcher_queue))
-+  if (QUEUE_EMPTY(&w->watcher_queue)) {
-     QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
-+    if (loop->on_watcher_queue_updated)
-+      loop->on_watcher_queue_updated(loop);
-+  }
- 
-   if (loop->watchers[w->fd] == NULL) {
-     loop->watchers[w->fd] = w;
-@@ -942,8 +945,11 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
-       loop->nfds--;
-     }
-   }
--  else if (QUEUE_EMPTY(&w->watcher_queue))
-+  else if (QUEUE_EMPTY(&w->watcher_queue)) {
-     QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
-+    if (loop->on_watcher_queue_updated)
-+      loop->on_watcher_queue_updated(loop);
-+  }
- }
- 
- 
-@@ -960,6 +966,8 @@ void uv__io_close(uv_loop_t* loop, uv__io_t* w) {
- void uv__io_feed(uv_loop_t* loop, uv__io_t* w) {
-   if (QUEUE_EMPTY(&w->pending_queue))
-     QUEUE_INSERT_TAIL(&loop->pending_queue, &w->pending_queue);
-+  if (loop->on_watcher_queue_updated)
-+    loop->on_watcher_queue_updated(loop);
- }
- 
- 

+ 1 - 1
patches/node/unix_remove_uv_cloexec_ioctl_3515.patch

@@ -8,7 +8,7 @@ Now that uv__cloexec_fcntl() is simplified
 maintaining duplicate code paths for the same thing.
 
 diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
-index 6cd519ad5b3e7af8f5c71b18a59b88458a233f15..8c30802ad15316a8ec20ecedfb5123174d74276b 100644
+index a87b96cfc1dfdc88fa712a4fa991320ff28f2dcd..7cd3a2a954ff7d70e6ba7a6f7538648841bc54b2 100644
 --- a/deps/uv/src/unix/core.c
 +++ b/deps/uv/src/unix/core.c
 @@ -597,20 +597,6 @@ int uv__nonblock_ioctl(int fd, int set) {

+ 1 - 1
patches/node/unix_simplify_uv_cloexec_fcntl_3492.patch

@@ -7,7 +7,7 @@ FD_CLOEXEC is the only defined flag for fcntl(F_SETFD) so don't bother
 getting the status of that flag first with fcntl(F_GETFD), just set it.
 
 diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
-index a6425294086ff2f1435fdd6866380d3aaaf68200..6cd519ad5b3e7af8f5c71b18a59b88458a233f15 100644
+index 71e9c525c4a77b8b5322e8516c58329100a8d951..a87b96cfc1dfdc88fa712a4fa991320ff28f2dcd 100644
 --- a/deps/uv/src/unix/core.c
 +++ b/deps/uv/src/unix/core.c
 @@ -649,21 +649,9 @@ int uv__cloexec_fcntl(int fd, int set) {

+ 2 - 0
patches/squirrel.mac/.patches

@@ -1,3 +1,5 @@
 build_add_gn_config.patch
 fix_ensure_that_self_is_retained_until_the_racsignal_is_complete.patch
 fix_use_kseccschecknestedcode_kseccsstrictvalidate_in_the_sec.patch
+feat_add_new_squirrel_mac_bundle_installation_method_behind_flag.patch
+refactor_use_posix_spawn_instead_of_nstask_so_we_can_disclaim_the.patch

+ 128 - 0
patches/squirrel.mac/feat_add_new_squirrel_mac_bundle_installation_method_behind_flag.patch

@@ -0,0 +1,128 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Samuel Attard <[email protected]>
+Date: Mon, 28 Mar 2022 02:43:18 -0700
+Subject: feat: add new Squirrel.Mac bundle installation method behind flag
+
+The 'SquirrelMacEnableDirectContentsWrite' user default in your apps defaults suite
+can be used to control this new installation method.  It is designed to remove the
+requirement that the updating process have write access to its parent directory.
+
+With this feature enabled the updating process only needs write access to it's own
+.app bundle folder, not the owning /Applications folder.  This should allow more
+non-admin users to update applications when appropriately granted group based permissions.
+
+E.g. 775 and chown :staff
+
+diff --git a/Squirrel/SQRLInstaller.m b/Squirrel/SQRLInstaller.m
+index 7dd98ddee4ae0f4e01fd7aaa3486083bff7d0da1..c1f328fa8c3689218ef260347cb8f9d30b789efe 100644
+--- a/Squirrel/SQRLInstaller.m
++++ b/Squirrel/SQRLInstaller.m
+@@ -249,6 +249,7 @@ - (RACSignal *)acquireTargetBundleURLForRequest:(SQRLShipItRequest *)request {
+ 		] reduce:^(NSURL *directoryURL, SQRLCodeSignature *codeSignature) {
+ 			NSURL *targetBundleURL = request.targetBundleURL;
+ 			NSURL *newBundleURL = [directoryURL URLByAppendingPathComponent:targetBundleURL.lastPathComponent];
++			[NSFileManager.defaultManager createDirectoryAtURL:newBundleURL withIntermediateDirectories:FALSE attributes:nil error:nil];
+ 
+ 			return [[SQRLInstallerOwnedBundle alloc] initWithOriginalURL:request.targetBundleURL temporaryURL:newBundleURL codeSignature:codeSignature];
+ 		}]
+@@ -481,10 +482,50 @@ - (RACSignal *)installItemToURL:(NSURL *)targetURL fromURL:(NSURL *)sourceURL {
+ 	NSParameterAssert(targetURL != nil);
+ 	NSParameterAssert(sourceURL != nil);
+ 
++	NSLog(@"Moving bundle from %@ to %@", sourceURL, targetURL);
++
++	// If both the sourceURL and the targetURL exist we can try to skip a permissions check
++	// by moving Thing.app/Contents directly.  This allows us to update applications without
++	// permission to write files into the parent directory of Thing.app
++	//
++	// There is no known case where these directories don't exist but in order to handle
++	// edge cases / race conditions we'll handle it anyway.
++	//
++	// This exists check is non-atomic with the rename call below but that's OK
++	BOOL canRenameContentsDirectly = FALSE;
++	// For now while this is tested at scale this new option is behind a user default, this
++	// can be set by applications wishing to test this feature at runtime.  If it causes issues
++	// it can be opted out by individual users by setting this key to false explicitly.
++	// Once this has bene tested at scale it will become the default for all Squirrel.Mac
++	// users.
++	NSUserDefaults *defaults = [[NSUserDefaults alloc] init];
++	[defaults addSuiteNamed:_applicationIdentifier];
++	// In cases where this code is being executed under the ShipIt executable it's running
++	// under an application identifier equal to {parent_identifier}.ShipIt
++	// In this case we need to use the true parent identifier too as that is 99% of the time
++	// where the key will be set.
++	if ([_applicationIdentifier hasSuffix:@".ShipIt"]) {
++		[defaults addSuiteNamed:[_applicationIdentifier substringToIndex:[_applicationIdentifier length] - 7]];
++	}
++
++	if ([defaults boolForKey:@"SquirrelMacEnableDirectContentsWrite"]) {
++		canRenameContentsDirectly = [NSFileManager.defaultManager fileExistsAtPath:targetURL.path] && [NSFileManager.defaultManager fileExistsAtPath:sourceURL.path];
++
++		if (canRenameContentsDirectly) {
++			NSLog(@"Moving bundles via 'Contents' folder rename");
++		} else {
++			NSLog(@"Moving bundles directly as one of source / target does not exist.  This is unexpected.");
++		}
++	} else {
++		NSLog(@"Moving bundles directly as SquirrelMacEnableDirectContentsWrite is disabled for app: %@", _applicationIdentifier);
++	}
++	NSURL *targetContentsURL = canRenameContentsDirectly ? [targetURL URLByAppendingPathComponent:@"Contents"] : targetURL;
++	NSURL *sourceContentsURL = canRenameContentsDirectly ? [sourceURL URLByAppendingPathComponent:@"Contents"] : sourceURL;
++
+ 	return [[[[RACSignal
+ 		defer:^{
+ 			// rename() is atomic, NSFileManager sucks.
+-			if (rename(sourceURL.path.fileSystemRepresentation, targetURL.path.fileSystemRepresentation) == 0) {
++			if (rename(sourceContentsURL.path.fileSystemRepresentation, targetContentsURL.path.fileSystemRepresentation) == 0) {
+ 				return [RACSignal empty];
+ 			} else {
+ 				int code = errno;
+@@ -497,24 +538,24 @@ - (RACSignal *)installItemToURL:(NSURL *)targetURL fromURL:(NSURL *)sourceURL {
+ 			}
+ 		}]
+ 		doCompleted:^{
+-			NSLog(@"Moved bundle from %@ to %@", sourceURL, targetURL);
++			NSLog(@"Moved bundle contents from %@ to %@", sourceContentsURL, targetContentsURL);
+ 		}]
+ 		catch:^(NSError *error) {
+ 			if (![error.domain isEqual:NSPOSIXErrorDomain] || error.code != EXDEV) return [RACSignal error:error];
+ 
+ 			// If the locations lie on two different volumes, remove the
+ 			// destination by hand, then perform a move.
+-			[NSFileManager.defaultManager removeItemAtURL:targetURL error:NULL];
++			[NSFileManager.defaultManager removeItemAtURL:targetContentsURL error:NULL];
+ 
+-			if ([NSFileManager.defaultManager moveItemAtURL:sourceURL toURL:targetURL error:&error]) {
+-				NSLog(@"Moved bundle across volumes from %@ to %@", sourceURL, targetURL);
++			if ([NSFileManager.defaultManager moveItemAtURL:sourceContentsURL toURL:targetContentsURL error:&error]) {
++				NSLog(@"Moved bundle contents across volumes from %@ to %@", sourceContentsURL, targetContentsURL);
+ 				return [RACSignal empty];
+ 			} else {
+-				NSString *description = [NSString stringWithFormat:NSLocalizedString(@"Couldn't move bundle %@ across volumes to %@", nil), sourceURL, targetURL];
++				NSString *description = [NSString stringWithFormat:NSLocalizedString(@"Couldn't move bundle contents %@ across volumes to %@", nil), sourceContentsURL, targetContentsURL];
+ 				return [RACSignal error:[self errorByAddingDescription:description code:SQRLInstallerErrorMovingAcrossVolumes toError:error]];
+ 			}
+ 		}]
+-		setNameWithFormat:@"%@ -installItemAtURL: %@ fromURL: %@", self, targetURL, sourceURL];
++		setNameWithFormat:@"%@ -installItemAtURL: %@ fromURL: %@", self, targetContentsURL, sourceContentsURL];
+ }
+ 
+ #pragma mark Quarantine Bit Removal
+diff --git a/Squirrel/SQRLUpdater.m b/Squirrel/SQRLUpdater.m
+index c81c820d61da3c7d1cfd2c516147c954a5773a0c..4c703159a2bb0239b7d4e1793a985b5ec2edcfa9 100644
+--- a/Squirrel/SQRLUpdater.m
++++ b/Squirrel/SQRLUpdater.m
+@@ -329,7 +329,12 @@ - (id)initWithUpdateRequest:(NSURLRequest *)updateRequest requestForDownload:(SQ
+ 
+ 			BOOL targetWritable = [self canWriteToURL:targetURL];
+ 			BOOL parentWritable = [self canWriteToURL:targetURL.URLByDeletingLastPathComponent];
+-			return [SQRLShipItLauncher launchPrivileged:!targetWritable || !parentWritable];
++			BOOL launchPrivileged = !targetWritable || !parentWritable;
++			if ([[NSUserDefaults standardUserDefaults] boolForKey:@"SquirrelMacEnableDirectContentsWrite"]) {
++				// If SquirrelMacEnableDirectContentsWrite is enabled we don't care if the parent directory is writeable or not
++				BOOL launchPrivileged = !targetWritable;
++			}
++			return [SQRLShipItLauncher launchPrivileged:launchPrivileged];
+ 		}]
+ 		replayLazily]
+ 		setNameWithFormat:@"shipItLauncher"];

+ 101 - 0
patches/squirrel.mac/refactor_use_posix_spawn_instead_of_nstask_so_we_can_disclaim_the.patch

@@ -0,0 +1,101 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Samuel Attard <[email protected]>
+Date: Mon, 28 Mar 2022 02:36:39 -0700
+Subject: refactor: use posix_spawn instead of NSTask so we can disclaim the
+ spawned ShipIt executable
+
+This ensures that if the ShipIt executable is hotswapped it doesn't inherit TCC permissions
+
+diff --git a/Squirrel/ShipIt-main.m b/Squirrel/ShipIt-main.m
+index db246534e176f9c3ea2dd8b1c8659378fdc2435d..2c515ffdd67052a08ee8155c0e46b57e9721a0e5 100644
+--- a/Squirrel/ShipIt-main.m
++++ b/Squirrel/ShipIt-main.m
+@@ -13,6 +13,9 @@
+ #import <ReactiveObjC/RACSignal+Operations.h>
+ #import <ReactiveObjC/RACScheduler.h>
+ 
++#include <spawn.h>
++#include <sys/wait.h>
++
+ #import "NSError+SQRLVerbosityExtensions.h"
+ #import "RACSignal+SQRLTransactionExtensions.h"
+ #import "SQRLInstaller.h"
+@@ -20,6 +23,20 @@
+ #import "SQRLTerminationListener.h"
+ #import "SQRLShipItRequest.h"
+ 
++extern char **environ;
++
++int responsibility_spawnattrs_setdisclaim(posix_spawnattr_t attrs, int disclaim)
++__attribute__((availability(macos,introduced=10.14),weak_import));
++
++#define CHECK_ERR(expr) \
++	{ \
++		int err = (expr); \
++    if (err) { \
++        fprintf(stderr, "%s: %s", #expr, strerror(err)); \
++        exit(err); \
++    } \
++	}
++
+ // The maximum number of times ShipIt should run the same installation state, in
+ // an attempt to update.
+ //
+@@ -136,11 +153,37 @@ static void installRequest(RACSignal *readRequestSignal, NSString *applicationId
+ 							NSString *exe = NSProcessInfo.processInfo.arguments[0];
+ 							NSLog(@"Launching new ShipIt at %@ with instructions to launch %@", exe, bundleURL);
+ 
+-							NSTask *task = [[NSTask alloc] init];
+-							[task setLaunchPath: exe];
+-							[task setArguments: @[launchSignal, bundleURL.path]];
+-							[task launch];
+-							[task waitUntilExit];
++							posix_spawnattr_t attr;
++							CHECK_ERR(posix_spawnattr_init(&attr));
++
++							if (@available(macOS 10.14, *)) {
++									// Disclaim TCC responsibilities
++									if (responsibility_spawnattrs_setdisclaim)
++											CHECK_ERR(responsibility_spawnattrs_setdisclaim(&attr, 1));
++							}
++
++							pid_t pid = 0;
++
++							const char* launchPath = [exe fileSystemRepresentation];
++							const char* signal = [launchSignal fileSystemRepresentation];
++							const char* path = [bundleURL.path fileSystemRepresentation];
++							const char* args[] = { launchPath, signal, path, 0 };
++							int status = posix_spawn(&pid, [exe UTF8String], NULL, &attr, (char *const*)args, environ);
++							if (status == 0) {
++								NSLog(@"New ShipIt pid: %i", pid);
++								do {
++									if (waitpid(pid, &status, 0) != -1) {
++										NSLog(@"ShipIt status %d", WEXITSTATUS(status));
++									} else {
++										perror("waitpid");
++										exit(1);
++									}
++								} while (!WIFEXITED(status) && !WIFSIGNALED(status));
++							} else {
++								NSLog(@"posix_spawn: %s", strerror(status));
++							}
++
++							posix_spawnattr_destroy(&attr);
+ 
+ 							NSLog(@"New ShipIt exited");
+ 						} else {
+@@ -172,7 +215,13 @@ int main(int argc, const char * argv[]) {
+ 		});
+ 
+ 		if (argc < 3) {
+-			NSLog(@"Missing launchd job label or state path for ShipIt");
++			NSLog(@"Missing launchd job label or state path for ShipIt (%d)", argc);
++			if (argc >= 1) {
++				NSLog(@"Arg 1: {%s}", argv[0]);
++			}
++			if (argc >= 2) {
++				NSLog(@"Arg 2: {%s}", argv[1]);
++			}
+ 			return EXIT_FAILURE;
+ 		}
+ 

+ 3 - 3
patches/v8/build_gn.patch

@@ -9,7 +9,7 @@ necessary for native modules to load.
 Also, some fixes relating to mksnapshot on ARM.
 
 diff --git a/BUILD.gn b/BUILD.gn
-index 8a09944249fb0c9ee77c49ed018d6e145265df6b..0fdbf62eae3e5bc2d3b16a2084a59ba9c394446f 100644
+index e4ea82d914cf99a9368c94da2cc35bd3214d8c23..c4de87b38433bed1a14ce5c3a482023de909ec47 100644
 --- a/BUILD.gn
 +++ b/BUILD.gn
 @@ -605,7 +605,7 @@ config("internal_config") {
@@ -21,7 +21,7 @@ index 8a09944249fb0c9ee77c49ed018d6e145265df6b..0fdbf62eae3e5bc2d3b16a2084a59ba9
      defines += [ "BUILDING_V8_SHARED" ]
    }
  
-@@ -5818,7 +5818,7 @@ if (current_toolchain == v8_generator_toolchain) {
+@@ -5821,7 +5821,7 @@ if (current_toolchain == v8_generator_toolchain) {
        "src/interpreter/bytecodes.h",
      ]
  
@@ -30,7 +30,7 @@ index 8a09944249fb0c9ee77c49ed018d6e145265df6b..0fdbf62eae3e5bc2d3b16a2084a59ba9
  
      deps = [
        ":v8_libbase",
-@@ -5856,6 +5856,8 @@ if (current_toolchain == v8_snapshot_toolchain) {
+@@ -5859,6 +5859,8 @@ if (current_toolchain == v8_snapshot_toolchain) {
  
      configs = [ ":internal_config" ]
  

+ 1 - 1
patches/v8/do_not_export_private_v8_symbols_on_windows.patch

@@ -12,7 +12,7 @@ This patch can be safely removed if, when it is removed, `node.lib` does not
 contain any standard C++ library exports (e.g. `std::ostringstream`).
 
 diff --git a/BUILD.gn b/BUILD.gn
-index 2262d19f0f9ced2c9e69862252d94ecb885c839f..2e5dcdd037f29cf51b2ff5d325a43036c8713f33 100644
+index d465e67c094b01ee128b9cecfb5ee999f4a1d8d1..f30fec3bc5c1901f96ff168da422aad1fa7ecd08 100644
 --- a/BUILD.gn
 +++ b/BUILD.gn
 @@ -605,6 +605,10 @@ config("internal_config") {

+ 2 - 2
patches/v8/export_symbols_needed_for_windows_build.patch

@@ -6,10 +6,10 @@ Subject: Export symbols needed for Windows build
 These symbols are required to build v8 with BUILD_V8_SHARED on Windows.
 
 diff --git a/src/objects/objects.h b/src/objects/objects.h
-index 1e3950ab2292ce6a3e6a4e469d8327da28f2d899..5e9b17acc59590147d8b3e2d74f62050e6b5a7ec 100644
+index 316f870e31f33c990793fdfe7ecb69bb120bb024..5db324b2bf0169657fc6e9dc3b15fa3ccaeac9c4 100644
 --- a/src/objects/objects.h
 +++ b/src/objects/objects.h
-@@ -911,7 +911,7 @@ enum AccessorComponent { ACCESSOR_GETTER, ACCESSOR_SETTER };
+@@ -927,7 +927,7 @@ enum AccessorComponent { ACCESSOR_GETTER, ACCESSOR_SETTER };
  // Utility superclass for stack-allocated objects that must be updated
  // on gc.  It provides two ways for the gc to update instances, either
  // iterating or updating after gc.

+ 2 - 2
patches/v8/expose_mksnapshot.patch

@@ -6,10 +6,10 @@ Subject: expose_mksnapshot.patch
 Needed in order to target mksnapshot for mksnapshot zip.
 
 diff --git a/BUILD.gn b/BUILD.gn
-index 0fdbf62eae3e5bc2d3b16a2084a59ba9c394446f..2262d19f0f9ced2c9e69862252d94ecb885c839f 100644
+index c4de87b38433bed1a14ce5c3a482023de909ec47..d465e67c094b01ee128b9cecfb5ee999f4a1d8d1 100644
 --- a/BUILD.gn
 +++ b/BUILD.gn
-@@ -5830,7 +5830,6 @@ if (current_toolchain == v8_generator_toolchain) {
+@@ -5833,7 +5833,6 @@ if (current_toolchain == v8_generator_toolchain) {
  
  if (current_toolchain == v8_snapshot_toolchain) {
    v8_executable("mksnapshot") {

+ 48 - 0
script/lib/azput.js

@@ -0,0 +1,48 @@
+/* eslint-disable camelcase */
+const { BlobServiceClient } = require('@azure/storage-blob');
+const fs = require('fs');
+const path = require('path');
+
+const blobServiceClient = BlobServiceClient.fromConnectionString(process.env.ELECTRON_ARTIFACTS_BLOB_STORAGE);
+
+const args = require('minimist')(process.argv.slice(2));
+
+let { prefix = '/', key_prefix = '', _: files } = args;
+if (prefix && !prefix.endsWith(path.sep)) prefix = path.resolve(prefix) + path.sep;
+
+function filenameToKey (file) {
+  file = path.resolve(file);
+  if (file.startsWith(prefix)) file = file.substr(prefix.length - 1);
+  return key_prefix + (path.sep === '\\' ? file.replace(/\\/g, '/') : file);
+}
+
+let anErrorOccurred = false;
+function next (done) {
+  const file = files.shift();
+  if (!file) return done();
+  let key = filenameToKey(file);
+  // TODO: When we drop s3put, migrate the key to not include atom-shell in the callsites
+  key = key.replace('atom-shell/dist/', 'headers/dist/');
+  key = key.replace('atom-shell/symbols/', 'symbols/');
+  key = key.replace('atom-shell/tmp/', 'checksums-scratchpad/');
+  key = key.replace('electron-artifacts/', 'release-builds/');
+
+  const [containerName, ...keyPath] = key.split('/');
+  const blobKey = keyPath.join('/');
+  console.log(`Uploading '${file}' to container '${containerName}' with key '${blobKey}'...`);
+
+  const containerClient = blobServiceClient.getContainerClient(containerName);
+  const blockBlobClient = containerClient.getBlockBlobClient(blobKey);
+  blockBlobClient.uploadFile(file)
+    .then((uploadBlobResponse) => {
+      console.log(`Upload block blob ${blobKey} successfully: https://artifacts.electronjs.org/${key}`, uploadBlobResponse.requestId);
+    })
+    .catch((err) => {
+      console.error(err);
+      anErrorOccurred = true;
+    })
+    .then(() => next(done));
+}
+next(() => {
+  process.exit(anErrorOccurred ? 1 : 0);
+});

+ 19 - 2
script/lib/util.py

@@ -15,7 +15,7 @@ except ImportError:
   from urllib2 import urlopen
 import zipfile
 
-from lib.config import is_verbose_mode
+from lib.config import is_verbose_mode, s3_config
 
 ELECTRON_DIR = os.path.abspath(
   os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
@@ -155,7 +155,14 @@ def get_electron_version():
   with open(version_file) as f:
     return 'v' + f.read().strip()
 
-def s3put(bucket, access_key, secret_key, prefix, key_prefix, files):
+def store_artifact(prefix, key_prefix, files):
+  # Legacy S3 Bucket
+  s3put(prefix, key_prefix, files)
+  # New AZ Storage
+  azput(prefix, key_prefix, files)
+
+def s3put(prefix, key_prefix, files):
+  bucket, access_key, secret_key = s3_config()
   env = os.environ.copy()
   env['AWS_ACCESS_KEY_ID'] = access_key
   env['AWS_SECRET_ACCESS_KEY'] = secret_key
@@ -169,6 +176,16 @@ def s3put(bucket, access_key, secret_key, prefix, key_prefix, files):
   ] + files, env)
   print(output)
 
+def azput(prefix, key_prefix, files):
+  env = os.environ.copy()
+  output = execute([
+    'node',
+    os.path.join(os.path.dirname(__file__), 'azput.js'),
+    '--prefix', prefix,
+    '--key_prefix', key_prefix,
+  ] + files, env)
+  print(output)
+
 def get_out_dir():
   out_dir = 'Debug'
   override = os.environ.get('ELECTRON_OUT_DIR')

+ 0 - 4
script/node-disabled-tests.json

@@ -3,11 +3,7 @@
   "async-hooks/test-crypto-pbkdf2",
   "async-hooks/test-crypto-randomBytes",
   "parallel/test-bootstrap-modules",
-  "parallel/test-buffer-backing-arraybuffer",
-  "parallel/test-buffer-constructor-node-modules-paths",
-  "parallel/test-buffer-constructor-outside-node-modules",
   "parallel/test-child-process-fork-exec-path",
-  "parallel/test-child-process-stdio-overlapped",
   "parallel/test-cli-node-print-help",
   "parallel/test-cluster-bind-privileged-port",
   "parallel/test-cluster-shared-handle-bind-privileged-port",

+ 47 - 45
script/release/release.js

@@ -17,8 +17,8 @@ const pkgVersion = `v${pkg.version}`;
 const path = require('path');
 const temp = require('temp').track();
 const { URL } = require('url');
+const { BlobServiceClient } = require('@azure/storage-blob');
 const { Octokit } = require('@octokit/rest');
-const AWS = require('aws-sdk');
 
 require('colors');
 const pass = '✓'.green;
@@ -80,6 +80,8 @@ async function validateReleaseAssets (release, validatingRelease) {
     }
     const s3RemoteFiles = s3RemoteFilesForVersion(release.tag_name);
     await verifyShasumsForRemoteFiles(s3RemoteFiles, true);
+    const azRemoteFiles = azRemoteFilesForVersion(release.tag_name);
+    await verifyShasumsForRemoteFiles(s3RemoteFiles, true);
   }
 }
 
@@ -181,26 +183,36 @@ function assetsForVersion (version, validatingRelease) {
   return patterns;
 }
 
+const cloudStoreFilePaths = (version) => [
+  `iojs-${version}-headers.tar.gz`,
+  `iojs-${version}.tar.gz`,
+  `node-${version}.tar.gz`,
+  'node.lib',
+  'x64/node.lib',
+  'win-x64/iojs.lib',
+  'win-x86/iojs.lib',
+  'win-arm64/iojs.lib',
+  'win-x64/node.lib',
+  'win-x86/node.lib',
+  'win-arm64/node.lib',
+  'arm64/node.lib',
+  'SHASUMS.txt',
+  'SHASUMS256.txt'
+];
+
 function s3RemoteFilesForVersion (version) {
   const bucket = 'https://gh-contractor-zcbenz.s3.amazonaws.com/';
   const versionPrefix = `${bucket}atom-shell/dist/${version}/`;
-  const filePaths = [
-    `iojs-${version}-headers.tar.gz`,
-    `iojs-${version}.tar.gz`,
-    `node-${version}.tar.gz`,
-    'node.lib',
-    'x64/node.lib',
-    'win-x64/iojs.lib',
-    'win-x86/iojs.lib',
-    'win-arm64/iojs.lib',
-    'win-x64/node.lib',
-    'win-x86/node.lib',
-    'win-arm64/node.lib',
-    'arm64/node.lib',
-    'SHASUMS.txt',
-    'SHASUMS256.txt'
-  ];
-  return filePaths.map((filePath) => ({
+  return cloudStoreFilePaths(version).map((filePath) => ({
+    file: filePath,
+    url: `${versionPrefix}${filePath}`
+  }));
+}
+
+function azRemoteFilesForVersion (version) {
+  const azCDN = 'https://artifacts.electronjs.org/headers/';
+  const versionPrefix = `${azCDN}dist/${version}/`;
+  return cloudStoreFilePaths(version).map((filePath) => ({
     file: filePath,
     url: `${versionPrefix}${filePath}`
   }));
@@ -221,49 +233,39 @@ function runScript (scriptName, scriptArgs, cwd) {
 }
 
 function uploadNodeShasums () {
-  console.log('Uploading Node SHASUMS file to S3.');
+  console.log('Uploading Node SHASUMS file to artifacts.electronjs.org.');
   const scriptPath = path.join(ELECTRON_DIR, 'script', 'release', 'uploaders', 'upload-node-checksums.py');
   runScript(scriptPath, ['-v', pkgVersion]);
-  console.log(`${pass} Done uploading Node SHASUMS file to S3.`);
+  console.log(`${pass} Done uploading Node SHASUMS file to artifacts.electronjs.org.`);
 }
 
 function uploadIndexJson () {
-  console.log('Uploading index.json to S3.');
+  console.log('Uploading index.json to artifacts.electronjs.org.');
   const scriptPath = path.join(ELECTRON_DIR, 'script', 'release', 'uploaders', 'upload-index-json.py');
   runScript(scriptPath, [pkgVersion]);
-  console.log(`${pass} Done uploading index.json to S3.`);
+  console.log(`${pass} Done uploading index.json to artifacts.electronjs.org.`);
 }
 
 async function mergeShasums (pkgVersion) {
-  // Download individual checksum files for Electron zip files from S3,
+  // Download individual checksum files for Electron zip files from artifact storage,
   // concatenate them, and upload to GitHub.
 
-  const bucket = process.env.ELECTRON_S3_BUCKET;
-  const accessKeyId = process.env.ELECTRON_S3_ACCESS_KEY;
-  const secretAccessKey = process.env.ELECTRON_S3_SECRET_KEY;
-  if (!bucket || !accessKeyId || !secretAccessKey) {
-    throw new Error('Please set the $ELECTRON_S3_BUCKET, $ELECTRON_S3_ACCESS_KEY, and $ELECTRON_S3_SECRET_KEY environment variables');
+  const connectionString = process.env.ELECTRON_ARTIFACTS_BLOB_STORAGE;
+  if (!connectionString) {
+    throw new Error('Please set the $ELECTRON_ARTIFACTS_BLOB_STORAGE environment variable');
   }
 
-  const s3 = new AWS.S3({
-    apiVersion: '2006-03-01',
-    accessKeyId,
-    secretAccessKey,
-    region: 'us-west-2'
+  const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
+  const containerClient = blobServiceClient.getContainerClient('checksums-scratchpad');
+  const blobsIter = containerClient.listBlobsFlat({
+    prefix: `${pkgVersion}/`
   });
-  const objects = await s3.listObjectsV2({
-    Bucket: bucket,
-    Prefix: `atom-shell/tmp/${pkgVersion}/`,
-    Delimiter: '/'
-  }).promise();
   const shasums = [];
-  for (const obj of objects.Contents) {
-    if (obj.Key.endsWith('.sha256sum')) {
-      const data = await s3.getObject({
-        Bucket: bucket,
-        Key: obj.Key
-      }).promise();
-      shasums.push(data.Body.toString('ascii').trim());
+  for await (const blob of blobsIter) {
+    if (blob.name.endsWith('.sha256sum')) {
+      const blobClient = containerClient.getBlockBlobClient(blob.name);
+      const response = await blobClient.downloadToBuffer();
+      shasums.push(response.toString('ascii').trim());
     }
   }
   return shasums.join('\n');

+ 3 - 5
script/release/uploaders/upload-index-json.py

@@ -9,8 +9,8 @@ import urllib2
 sys.path.append(
   os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/../.."))
 
-from lib.config import s3_config
-from lib.util import s3put, scoped_cwd, safe_mkdir, get_out_dir, ELECTRON_DIR
+from lib.util import store_artifact, scoped_cwd, safe_mkdir, get_out_dir, \
+  ELECTRON_DIR
 
 OUT_DIR     = get_out_dir()
 
@@ -59,9 +59,7 @@ def main():
     with open(index_json, "w") as f:
       f.write(new_content)
 
-    bucket, access_key, secret_key = s3_config()
-    s3put(bucket, access_key, secret_key, OUT_DIR, 'atom-shell/dist',
-          [index_json])
+    store_artifact(OUT_DIR, 'atom-shell/dist', [index_json])
 
 
 if __name__ == '__main__':

+ 3 - 5
script/release/uploaders/upload-node-checksums.py

@@ -10,8 +10,7 @@ import tempfile
 sys.path.append(
   os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/../.."))
 
-from lib.config import s3_config
-from lib.util import download, rm_rf, s3put, safe_mkdir
+from lib.util import download, rm_rf, store_artifact, safe_mkdir
 
 DIST_URL = 'https://electronjs.org/headers/'
 
@@ -30,9 +29,8 @@ def main():
   ]
 
   if args.target_dir is None:
-    bucket, access_key, secret_key = s3_config()
-    s3put(bucket, access_key, secret_key, directory,
-          'atom-shell/dist/{0}'.format(args.version), checksums)
+    store_artifact(directory, 'atom-shell/dist/{0}'.format(args.version),
+                   checksums)
   else:
     copy_files(checksums, args.target_dir)
 

+ 14 - 16
script/release/uploaders/upload-node-headers.py

@@ -9,8 +9,9 @@ import sys
 sys.path.append(
   os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/../.."))
 
-from lib.config import PLATFORM, get_target_arch, s3_config
-from lib.util import safe_mkdir, scoped_cwd, s3put, get_out_dir, get_dist_dir
+from lib.config import PLATFORM, get_target_arch
+from lib.util import safe_mkdir, scoped_cwd, store_artifact, get_out_dir, \
+  get_dist_dir
 
 DIST_DIR    = get_dist_dir()
 OUT_DIR     = get_out_dir()
@@ -26,9 +27,8 @@ HEADER_TAR_NAMES = [
 def main():
   args = parse_args()
 
-  # Upload node's headers to S3.
-  bucket, access_key, secret_key = s3_config()
-  upload_node(bucket, access_key, secret_key, args.version)
+  # Upload node's headers to artifact storage.
+  upload_node(args.version)
 
 
 def parse_args():
@@ -38,17 +38,17 @@ def parse_args():
   return parser.parse_args()
 
 
-def upload_node(bucket, access_key, secret_key, version):
+def upload_node(version):
   with scoped_cwd(GEN_DIR):
     generated_tar = os.path.join(GEN_DIR, 'node_headers.tar.gz')
     for header_tar in HEADER_TAR_NAMES:
       versioned_header_tar = header_tar.format(version)
       shutil.copy2(generated_tar, os.path.join(GEN_DIR, versioned_header_tar))
 
-    s3put(bucket, access_key, secret_key, GEN_DIR,
-          'atom-shell/dist/{0}'.format(version), glob.glob('node-*.tar.gz'))
-    s3put(bucket, access_key, secret_key, GEN_DIR,
-          'atom-shell/dist/{0}'.format(version), glob.glob('iojs-*.tar.gz'))
+    store_artifact(GEN_DIR, 'atom-shell/dist/{0}'.format(version),
+                   glob.glob('node-*.tar.gz'))
+    store_artifact(GEN_DIR, 'atom-shell/dist/{0}'.format(version),
+                   glob.glob('iojs-*.tar.gz'))
 
   if PLATFORM == 'win32':
     if get_target_arch() == 'ia32':
@@ -73,16 +73,14 @@ def upload_node(bucket, access_key, secret_key, version):
     shutil.copy2(electron_lib, v4_node_lib)
 
     # Upload the node.lib.
-    s3put(bucket, access_key, secret_key, DIST_DIR,
-          'atom-shell/dist/{0}'.format(version), [node_lib])
+    store_artifact(DIST_DIR, 'atom-shell/dist/{0}'.format(version), [node_lib])
 
     # Upload the iojs.lib.
-    s3put(bucket, access_key, secret_key, DIST_DIR,
-          'atom-shell/dist/{0}'.format(version), [iojs_lib])
+    store_artifact(DIST_DIR, 'atom-shell/dist/{0}'.format(version), [iojs_lib])
 
     # Upload the v4 node.lib.
-    s3put(bucket, access_key, secret_key, DIST_DIR,
-          'atom-shell/dist/{0}'.format(version), [v4_node_lib])
+    store_artifact(DIST_DIR, 'atom-shell/dist/{0}'.format(version),
+                   [v4_node_lib])
 
 
 if __name__ == '__main__':

+ 5 - 6
script/release/uploaders/upload-symbols.py

@@ -14,8 +14,8 @@ def is_fs_case_sensitive():
 sys.path.append(
   os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/../.."))
 
-from lib.config import PLATFORM, s3_config
-from lib.util import get_electron_branding, execute, s3put, \
+from lib.config import PLATFORM
+from lib.util import get_electron_branding, execute, store_artifact, \
                      get_out_dir, ELECTRON_DIR
 
 RELEASE_DIR = get_out_dir()
@@ -76,16 +76,15 @@ def main():
   for f in files:
     assert os.path.exists(f)
 
-  bucket, access_key, secret_key = s3_config()
-  upload_symbols(bucket, access_key, secret_key, files)
+  upload_symbols(files)
 
 
 def run_symstore(pdb, dest, product):
   execute(['symstore', 'add', '/r', '/f', pdb, '/s', dest, '/t', product])
 
 
-def upload_symbols(bucket, access_key, secret_key, files):
-  s3put(bucket, access_key, secret_key, SYMBOLS_DIR, 'atom-shell/symbols',
+def upload_symbols(files):
+  store_artifact(SYMBOLS_DIR, 'atom-shell/symbols',
         files)
 
 

+ 4 - 10
script/release/uploaders/upload.py

@@ -16,10 +16,10 @@ sys.path.append(
   os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/../.."))
 
 from zipfile import ZipFile
-from lib.config import PLATFORM, get_target_arch,s3_config, \
+from lib.config import PLATFORM, get_target_arch, \
                        get_zip_name, enable_verbose_mode, get_platform_key
 from lib.util import get_electron_branding, execute, get_electron_version, \
-                     s3put, get_electron_exec, get_out_dir, \
+                     store_artifact, get_electron_exec, get_out_dir, \
                      SRC_DIR, ELECTRON_DIR, TS_NODE
 
 
@@ -342,14 +342,10 @@ def upload_electron(release, file_path, args):
 
   # if upload_to_s3 is set, skip github upload.
   if args.upload_to_s3:
-    bucket, access_key, secret_key = s3_config()
     key_prefix = 'electron-artifacts/{0}_{1}'.format(args.version,
                                                      args.upload_timestamp)
-    s3put(bucket, access_key, secret_key, os.path.dirname(file_path),
-          key_prefix, [file_path])
+    store_artifact(os.path.dirname(file_path), key_prefix, [file_path])
     upload_sha256_checksum(args.version, file_path, key_prefix)
-    s3url = 'https://gh-contractor-zcbenz.s3.amazonaws.com'
-    print('{0} uploaded to {1}/{2}/{0}'.format(filename, s3url, key_prefix))
     return
 
   # Upload the file.
@@ -369,7 +365,6 @@ def upload_io_to_github(release, filename, filepath, version):
 
 
 def upload_sha256_checksum(version, file_path, key_prefix=None):
-  bucket, access_key, secret_key = s3_config()
   checksum_path = '{}.sha256sum'.format(file_path)
   if key_prefix is None:
     key_prefix = 'atom-shell/tmp/{0}'.format(version)
@@ -380,8 +375,7 @@ def upload_sha256_checksum(version, file_path, key_prefix=None):
   filename = os.path.basename(file_path)
   with open(checksum_path, 'w') as checksum:
     checksum.write('{} *{}'.format(sha256.hexdigest(), filename))
-  s3put(bucket, access_key, secret_key, os.path.dirname(checksum_path),
-        key_prefix, [checksum_path])
+  store_artifact(os.path.dirname(checksum_path), key_prefix, [checksum_path])
 
 
 def get_release(version):

+ 6 - 6
shell/app/electron_content_client.cc

@@ -35,7 +35,8 @@
 #endif  // defined(WIDEVINE_CDM_AVAILABLE)
 
 #if BUILDFLAG(ENABLE_PDF_VIEWER)
-#include "components/pdf/renderer/internal_plugin_renderer_helpers.h"
+#include "chrome/common/pdf_util.h"
+#include "components/pdf/common/internal_plugin_helpers.h"
 #include "pdf/pdf.h"  // nogncheck
 #include "shell/common/electron_constants.h"
 #endif  // BUILDFLAG(ENABLE_PDF_VIEWER)
@@ -111,11 +112,11 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
   content::PepperPluginInfo pdf_info;
   pdf_info.is_internal = true;
   pdf_info.is_out_of_process = true;
-  pdf_info.name = "Chromium PDF Viewer";
+  pdf_info.name = kPDFInternalPluginName;
   pdf_info.description = "Portable Document Format";
   // This isn't a real file path; it's just used as a unique identifier.
   pdf_info.path = base::FilePath(kPdfPluginPath);
-  content::WebPluginMimeType pdf_mime_type(kPdfPluginMimeType, "pdf",
+  content::WebPluginMimeType pdf_mime_type(pdf::kInternalPluginMimeType, "pdf",
                                            "Portable Document Format");
   pdf_info.mime_types.push_back(pdf_mime_type);
   plugins->push_back(pdf_info);
@@ -126,12 +127,11 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
   // here.
   content::WebPluginInfo info;
   info.type = content::WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN;
-  info.name = u"Chromium PDF Viewer";
+  info.name = base::ASCIIToUTF16(kPDFExtensionPluginName);
   // This isn't a real file path; it's just used as a unique identifier.
   info.path = base::FilePath::FromUTF8Unsafe(extension_misc::kPdfExtensionId);
   info.background_color = content::WebPluginInfo::kDefaultBackgroundColor;
-  info.mime_types.emplace_back("application/pdf", "pdf",
-                               "Portable Document Format");
+  info.mime_types.emplace_back(kPDFMimeType, "pdf", "Portable Document Format");
   content::PluginService::GetInstance()->RefreshPlugins();
   content::PluginService::GetInstance()->RegisterInternalPlugin(info, true);
 #endif  // BUILDFLAG(ENABLE_PDF_VIEWER)

+ 3 - 0
shell/browser/api/electron_api_app.cc

@@ -1148,6 +1148,8 @@ bool App::RequestSingleInstanceLock(gin::Arguments* args) {
 
   base::FilePath user_dir;
   base::PathService::Get(chrome::DIR_USER_DATA, &user_dir);
+  // The user_dir may not have been created yet.
+  base::CreateDirectoryAndGetError(user_dir, nullptr);
 
   auto cb = base::BindRepeating(&App::OnSecondInstance, base::Unretained(this));
   auto wrapped_cb = base::BindRepeating(NotificationCallbackWrapper, cb);
@@ -1769,6 +1771,7 @@ gin::ObjectTemplateBuilder App::GetObjectTemplateBuilder(v8::Isolate* isolate) {
                  base::BindRepeating(&Browser::IsEmojiPanelSupported, browser))
 #if BUILDFLAG(IS_MAC)
       .SetMethod("hide", base::BindRepeating(&Browser::Hide, browser))
+      .SetMethod("isHidden", base::BindRepeating(&Browser::IsHidden, browser))
       .SetMethod("show", base::BindRepeating(&Browser::Show, browser))
       .SetMethod("setUserActivity",
                  base::BindRepeating(&Browser::SetUserActivity, browser))

+ 18 - 1
shell/browser/api/electron_api_browser_view.cc

@@ -6,10 +6,13 @@
 
 #include <vector>
 
+#include "content/browser/renderer_host/render_widget_host_view_base.h"  // nogncheck
+#include "content/public/browser/render_widget_host_view.h"
 #include "shell/browser/api/electron_api_web_contents.h"
 #include "shell/browser/browser.h"
 #include "shell/browser/native_browser_view.h"
 #include "shell/browser/ui/drag_util.h"
+#include "shell/browser/web_contents_preferences.h"
 #include "shell/common/color_util.h"
 #include "shell/common/gin_converters/gfx_converter.h"
 #include "shell/common/gin_helper/dictionary.h"
@@ -154,11 +157,25 @@ gfx::Rect BrowserView::GetBounds() {
 }
 
 void BrowserView::SetBackgroundColor(const std::string& color_name) {
-  view_->SetBackgroundColor(ParseCSSColor(color_name));
+  SkColor color = ParseCSSColor(color_name);
+  view_->SetBackgroundColor(color);
 
   if (web_contents()) {
     auto* wc = web_contents()->web_contents();
     wc->SetPageBaseBackgroundColor(ParseCSSColor(color_name));
+
+    auto* const rwhv = wc->GetRenderWidgetHostView();
+    if (rwhv) {
+      rwhv->SetBackgroundColor(color);
+      static_cast<content::RenderWidgetHostViewBase*>(rwhv)
+          ->SetContentBackgroundColor(color);
+    }
+
+    // Ensure new color is stored in webPreferences, otherwise
+    // the color will be reset on the next load via HandleNewRenderFrame.
+    auto* web_preferences = WebContentsPreferences::From(wc);
+    if (web_preferences)
+      web_preferences->SetBackgroundColor(color);
   }
 }
 

+ 6 - 4
shell/browser/api/electron_api_web_contents.cc

@@ -1489,11 +1489,13 @@ void WebContents::HandleNewRenderFrame(
   // Set the background color of RenderWidgetHostView.
   auto* web_preferences = WebContentsPreferences::From(web_contents());
   if (web_preferences) {
+    absl::optional<SkColor> maybe_color = web_preferences->GetBackgroundColor();
+    web_contents()->SetPageBaseBackgroundColor(maybe_color);
+
     bool guest = IsGuest() || type_ == Type::kBrowserView;
-    absl::optional<SkColor> color =
-        guest ? SK_ColorTRANSPARENT : web_preferences->GetBackgroundColor();
-    web_contents()->SetPageBaseBackgroundColor(color);
-    SetBackgroundColor(rwhv, color.value_or(SK_ColorWHITE));
+    SkColor color =
+        maybe_color.value_or(guest ? SK_ColorTRANSPARENT : SK_ColorWHITE);
+    SetBackgroundColor(rwhv, color);
   }
 
   if (!background_throttling_)

+ 2 - 2
shell/browser/api/electron_api_web_request.cc

@@ -164,8 +164,8 @@ void ToDictionary(gin_helper::Dictionary* details,
                  HttpResponseHeadersToV8(info->response_headers.get()));
   }
 
-  auto* render_frame_host =
-      content::RenderFrameHost::FromID(info->render_process_id, info->frame_id);
+  auto* render_frame_host = content::RenderFrameHost::FromID(
+      info->render_process_id, info->frame_routing_id);
   if (render_frame_host) {
     details->SetGetter("frame", render_frame_host);
     auto* web_contents =

+ 1 - 0
shell/browser/browser.h

@@ -158,6 +158,7 @@ class Browser : public WindowListObserver {
 
   // Hide the application.
   void Hide();
+  bool IsHidden();
 
   // Show the application.
   void Show();

+ 4 - 0
shell/browser/browser_mac.mm

@@ -117,6 +117,10 @@ void Browser::Hide() {
   [[AtomApplication sharedApplication] hide:nil];
 }
 
+bool Browser::IsHidden() {
+  return [[AtomApplication sharedApplication] isHidden];
+}
+
 void Browser::Show() {
   [[AtomApplication sharedApplication] unhide:nil];
 }

+ 1 - 0
shell/browser/electron_api_ipc_handler_impl.h

@@ -11,6 +11,7 @@
 #include "base/memory/weak_ptr.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "electron/shell/common/api/api.mojom.h"
+#include "mojo/public/cpp/bindings/associated_receiver.h"
 #include "shell/browser/api/electron_api_web_contents.h"
 
 namespace content {

+ 8 - 9
shell/browser/electron_browser_client.cc

@@ -27,16 +27,11 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/post_task.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/pdf/chrome_pdf_stream_delegate.h"
-#include "chrome/browser/plugins/pdf_iframe_navigation_throttle.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version.h"
 #include "components/net_log/chrome_net_log.h"
 #include "components/network_hints/common/network_hints.mojom.h"
-#include "components/pdf/browser/pdf_navigation_throttle.h"
-#include "components/pdf/browser/pdf_url_loader_request_interceptor.h"
-#include "components/pdf/common/internal_plugin_helpers.h"
 #include "content/browser/keyboard_lock/keyboard_lock_service_impl.h"  // nogncheck
 #include "content/browser/site_instance_impl.h"  // nogncheck
 #include "content/public/browser/browser_main_runner.h"
@@ -52,6 +47,7 @@
 #include "content/public/browser/site_instance.h"
 #include "content/public/browser/tts_controller.h"
 #include "content/public/browser/tts_platform.h"
+#include "content/public/browser/url_loader_request_interceptor.h"
 #include "content/public/common/content_descriptors.h"
 #include "content/public/common/content_paths.h"
 #include "content/public/common/content_switches.h"
@@ -212,7 +208,12 @@
 #endif
 
 #if BUILDFLAG(ENABLE_PDF_VIEWER)
+#include "chrome/browser/pdf/chrome_pdf_stream_delegate.h"
+#include "chrome/browser/plugins/pdf_iframe_navigation_throttle.h"  // nogncheck
+#include "components/pdf/browser/pdf_navigation_throttle.h"
+#include "components/pdf/browser/pdf_url_loader_request_interceptor.h"
 #include "components/pdf/browser/pdf_web_contents_helper.h"  // nogncheck
+#include "components/pdf/common/internal_plugin_helpers.h"
 #endif
 
 using content::BrowserThread;
@@ -1478,10 +1479,8 @@ bool ElectronBrowserClient::WillCreateURLLoaderFactory(
   new ProxyingURLLoaderFactory(
       web_request.get(), protocol_registry->intercept_handlers(),
       render_process_id,
-      frame_host ? frame_host->GetRoutingID() : MSG_ROUTING_NONE,
-      frame_host ? frame_host->GetRenderViewHost()->GetRoutingID()
-                 : MSG_ROUTING_NONE,
-      &next_id_, std::move(navigation_ui_data), std::move(navigation_id),
+      frame_host ? frame_host->GetRoutingID() : MSG_ROUTING_NONE, &next_id_,
+      std::move(navigation_ui_data), std::move(navigation_id),
       std::move(proxied_receiver), std::move(target_factory_remote),
       std::move(header_client_receiver), type);
 

+ 2 - 2
shell/browser/electron_browser_main_parts.cc

@@ -402,8 +402,8 @@ void ElectronBrowserMainParts::ToolkitInitialized() {
 int ElectronBrowserMainParts::PreMainMessageLoopRun() {
   // Run user's main script before most things get initialized, so we can have
   // a chance to setup everything.
-  node_bindings_->PrepareMessageLoop();
-  node_bindings_->RunMessageLoop();
+  node_bindings_->PrepareEmbedThread();
+  node_bindings_->StartPolling();
 
   // url::Add*Scheme are not threadsafe, this helps prevent data races.
   url::LockSchemeRegistries();

+ 0 - 6
shell/browser/electron_browser_main_parts.h

@@ -36,12 +36,6 @@ class Screen;
 }
 #endif
 
-#if defined(USE_X11)
-namespace ui {
-class GtkUiPlatform;
-}
-#endif
-
 namespace device {
 class GeolocationManager;
 }

+ 1 - 0
shell/browser/electron_web_contents_utility_handler_impl.h

@@ -11,6 +11,7 @@
 #include "base/memory/weak_ptr.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "electron/shell/common/api/api.mojom.h"
+#include "mojo/public/cpp/bindings/associated_receiver.h"
 #include "shell/browser/api/electron_api_web_contents.h"
 
 namespace content {

+ 7 - 0
shell/browser/media/media_stream_devices_controller.cc

@@ -152,6 +152,13 @@ void MediaStreamDevicesController::Accept() {
         NOTREACHED();
         break;
       }
+      case blink::MEDIA_GET_OPEN_DEVICE: {
+        // Transferred tracks, that use blink::MEDIA_GET_OPEN_DEVICE type, do
+        // not need to get permissions for MediaStreamDevice as those are
+        // controlled by the original context.
+        NOTREACHED();
+        break;
+      }
     }
   }
 

+ 1 - 1
shell/browser/native_window.cc

@@ -26,7 +26,7 @@
 #include "ui/display/win/screen_win.h"
 #endif
 
-#if defined(USE_OZONE) || defined(USE_X11)
+#if defined(USE_OZONE)
 #include "ui/base/ui_base_features.h"
 #include "ui/ozone/public/ozone_platform.h"
 #endif

+ 2 - 0
shell/browser/native_window_mac.h

@@ -267,6 +267,8 @@ class NativeWindowMac : public NativeWindow,
   // Maximizable window state; necessary for persistence through redraws.
   bool maximizable_ = true;
 
+  bool user_set_bounds_maximized_ = false;
+
   // Simple (pre-Lion) Fullscreen Settings
   bool always_simple_fullscreen_ = false;
   bool is_simple_fullscreen_ = false;

+ 26 - 2
shell/browser/native_window_mac.mm

@@ -328,6 +328,8 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
       [](NativeWindowMac* window) {
         if (window->window_)
           window->window_ = nil;
+        if (window->buttons_proxy_)
+          window->buttons_proxy_.reset();
       },
       this));
 
@@ -600,17 +602,38 @@ void NativeWindowMac::SetEnabled(bool enable) {
 }
 
 void NativeWindowMac::Maximize() {
-  if (IsMaximized())
+  const bool is_visible = [window_ isVisible];
+
+  if (IsMaximized()) {
+    if (!is_visible)
+      ShowInactive();
     return;
+  }
 
   // Take note of the current window size
   if (IsNormal())
     original_frame_ = [window_ frame];
   [window_ zoom:nil];
+
+  if (!is_visible) {
+    ShowInactive();
+    NotifyWindowMaximize();
+  }
 }
 
 void NativeWindowMac::Unmaximize() {
-  if (!IsMaximized())
+  // Bail if the last user set bounds were the same size as the window
+  // screen (e.g. the user set the window to maximized via setBounds)
+  //
+  // Per docs during zoom:
+  // > If there’s no saved user state because there has been no previous
+  // > zoom,the size and location of the window don’t change.
+  //
+  // However, in classic Apple fashion, this is not the case in practice,
+  // and the frame inexplicably becomes very tiny. We should prevent
+  // zoom from being called if the window is being unmaximized and its
+  // unmaximized window bounds are themselves functionally maximized.
+  if (!IsMaximized() || user_set_bounds_maximized_)
     return;
 
   [window_ zoom:nil];
@@ -712,6 +735,7 @@ void NativeWindowMac::SetBounds(const gfx::Rect& bounds, bool animate) {
   cocoa_bounds.origin.y = NSHeight([screen frame]) - size.height() - bounds.y();
 
   [window_ setFrame:cocoa_bounds display:YES animate:animate];
+  user_set_bounds_maximized_ = IsMaximized() ? true : false;
 }
 
 gfx::Rect NativeWindowMac::GetBounds() {

+ 140 - 115
shell/browser/native_window_views.cc

@@ -19,7 +19,6 @@
 #include "content/public/browser/desktop_media_id.h"
 #include "shell/browser/api/electron_api_web_contents.h"
 #include "shell/browser/native_browser_view_views.h"
-#include "shell/browser/native_window_features.h"
 #include "shell/browser/ui/drag_util.h"
 #include "shell/browser/ui/inspectable_web_contents.h"
 #include "shell/browser/ui/inspectable_web_contents_view.h"
@@ -55,20 +54,16 @@
 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
 #include "ui/views/window/native_frame_view.h"
 
-#if defined(USE_X11)
+#if defined(USE_OZONE)
 #include "shell/browser/ui/views/global_menu_bar_x11.h"
 #include "shell/browser/ui/x/event_disabler.h"
-#include "shell/browser/ui/x/window_state_watcher.h"
 #include "shell/browser/ui/x/x_window_utils.h"
 #include "ui/base/x/x11_util.h"
 #include "ui/gfx/x/shape.h"
 #include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/gfx/x/xproto.h"
 #include "ui/gfx/x/xproto_util.h"
-#endif
-
-#if defined(USE_OZONE) || defined(USE_X11)
-#include "ui/base/ui_base_features.h"
+#include "ui/ozone/public/ozone_platform.h"
 #endif
 
 #elif BUILDFLAG(IS_WIN)
@@ -130,6 +125,26 @@ gfx::Rect DIPToScreenRect(HWND hwnd, const gfx::Rect& pixel_bounds) {
 
 #endif
 
+#if defined(USE_OZONE)
+
+bool CreateGlobalMenuBar() {
+  return ui::OzonePlatform::GetInstance()
+      ->GetPlatformProperties()
+      .supports_global_application_menus;
+}
+
+#endif
+
+#if defined(USE_OZONE_PLATFORM_X11)
+
+bool IsX11() {
+  return ui::OzonePlatform::GetInstance()
+      ->GetPlatformProperties()
+      .electron_can_call_x11;
+}
+
+#endif
+
 class NativeWindowClientView : public views::ClientView {
  public:
   NativeWindowClientView(views::Widget* widget,
@@ -257,12 +272,10 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
   params.wm_class_name = base::ToLowerASCII(name);
   params.wm_class_class = name;
 
-  if (base::FeatureList::IsEnabled(features::kWaylandWindowDecorations)) {
-    auto* native_widget = new views::DesktopNativeWidgetAura(widget());
-    params.native_widget = native_widget;
-    params.desktop_window_tree_host =
-        new ElectronDesktopWindowTreeHostLinux(this, native_widget);
-  }
+  auto* native_widget = new views::DesktopNativeWidgetAura(widget());
+  params.native_widget = native_widget;
+  params.desktop_window_tree_host =
+      new ElectronDesktopWindowTreeHostLinux(this, native_widget);
 #endif
 
   widget()->Init(std::move(params));
@@ -274,55 +287,52 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
   std::string window_type;
   options.Get(options::kType, &window_type);
 
-#if defined(USE_X11)
-  // Start monitoring window states.
-  window_state_watcher_ = std::make_unique<WindowStateWatcher>(this);
-
+#if BUILDFLAG(IS_LINUX)
   // Set _GTK_THEME_VARIANT to dark if we have "dark-theme" option set.
   bool use_dark_theme = false;
   if (options.Get(options::kDarkTheme, &use_dark_theme) && use_dark_theme) {
     SetGTKDarkThemeEnabled(use_dark_theme);
   }
-#endif
 
-#if BUILDFLAG(IS_LINUX)
   if (parent)
     SetParentWindow(parent);
 #endif
 
-#if defined(USE_X11)
-  // TODO(ckerr): remove in Electron v20.0.0
-  // Before the window is mapped the SetWMSpecState can not work, so we have
-  // to manually set the _NET_WM_STATE.
-  std::vector<x11::Atom> state_atom_list;
-  bool skip_taskbar = false;
-  if (options.Get(options::kSkipTaskbar, &skip_taskbar) && skip_taskbar) {
-    state_atom_list.push_back(x11::GetAtom("_NET_WM_STATE_SKIP_TASKBAR"));
-  }
+#if defined(USE_OZONE_PLATFORM_X11)
+  if (IsX11()) {
+    // TODO(ckerr): remove in Electron v20.0.0
+    // Before the window is mapped the SetWMSpecState can not work, so we have
+    // to manually set the _NET_WM_STATE.
+    std::vector<x11::Atom> state_atom_list;
+    bool skip_taskbar = false;
+    if (options.Get(options::kSkipTaskbar, &skip_taskbar) && skip_taskbar) {
+      state_atom_list.push_back(x11::GetAtom("_NET_WM_STATE_SKIP_TASKBAR"));
+    }
 
-  // Before the window is mapped, there is no SHOW_FULLSCREEN_STATE.
-  if (fullscreen) {
-    state_atom_list.push_back(x11::GetAtom("_NET_WM_STATE_FULLSCREEN"));
-  }
+    // Before the window is mapped, there is no SHOW_FULLSCREEN_STATE.
+    if (fullscreen) {
+      state_atom_list.push_back(x11::GetAtom("_NET_WM_STATE_FULLSCREEN"));
+    }
 
-  if (parent) {
-    // Force using dialog type for child window.
-    window_type = "dialog";
+    if (parent) {
+      // Force using dialog type for child window.
+      window_type = "dialog";
 
-    // Modal window needs the _NET_WM_STATE_MODAL hint.
-    if (is_modal())
-      state_atom_list.push_back(x11::GetAtom("_NET_WM_STATE_MODAL"));
-  }
+      // Modal window needs the _NET_WM_STATE_MODAL hint.
+      if (is_modal())
+        state_atom_list.push_back(x11::GetAtom("_NET_WM_STATE_MODAL"));
+    }
 
-  if (!state_atom_list.empty())
-    SetArrayProperty(static_cast<x11::Window>(GetAcceleratedWidget()),
-                     x11::GetAtom("_NET_WM_STATE"), x11::Atom::ATOM,
-                     state_atom_list);
+    if (!state_atom_list.empty())
+      SetArrayProperty(static_cast<x11::Window>(GetAcceleratedWidget()),
+                       x11::GetAtom("_NET_WM_STATE"), x11::Atom::ATOM,
+                       state_atom_list);
 
-  // Set the _NET_WM_WINDOW_TYPE.
-  if (!window_type.empty())
-    SetWindowType(static_cast<x11::Window>(GetAcceleratedWidget()),
-                  window_type);
+    // Set the _NET_WM_WINDOW_TYPE.
+    if (!window_type.empty())
+      SetWindowType(static_cast<x11::Window>(GetAcceleratedWidget()),
+                    window_type);
+  }
 #endif
 
 #if BUILDFLAG(IS_WIN)
@@ -419,11 +429,13 @@ NativeWindowViews::~NativeWindowViews() {
 }
 
 void NativeWindowViews::SetGTKDarkThemeEnabled(bool use_dark_theme) {
-#if defined(USE_X11)
-  const std::string color = use_dark_theme ? "dark" : "light";
-  x11::SetStringProperty(static_cast<x11::Window>(GetAcceleratedWidget()),
-                         x11::GetAtom("_GTK_THEME_VARIANT"),
-                         x11::GetAtom("UTF8_STRING"), color);
+#if defined(USE_OZONE_PLATFORM_X11)
+  if (IsX11()) {
+    const std::string color = use_dark_theme ? "dark" : "light";
+    x11::SetStringProperty(static_cast<x11::Window>(GetAcceleratedWidget()),
+                           x11::GetAtom("_GTK_THEME_VARIANT"),
+                           x11::GetAtom("UTF8_STRING"), color);
+  }
 #endif
 }
 
@@ -478,7 +490,7 @@ void NativeWindowViews::Show() {
 
   NotifyWindowShow();
 
-#if defined(USE_X11)
+#if defined(USE_OZONE)
   if (global_menu_bar_)
     global_menu_bar_->OnWindowMapped();
 #endif
@@ -489,7 +501,7 @@ void NativeWindowViews::ShowInactive() {
 
   NotifyWindowShow();
 
-#if defined(USE_X11)
+#if defined(USE_OZONE)
   if (global_menu_bar_)
     global_menu_bar_->OnWindowMapped();
 #endif
@@ -503,7 +515,7 @@ void NativeWindowViews::Hide() {
 
   NotifyWindowHide();
 
-#if defined(USE_X11)
+#if defined(USE_OZONE)
   if (global_menu_bar_)
     global_menu_bar_->OnWindowUnmapped();
 #endif
@@ -525,8 +537,9 @@ bool NativeWindowViews::IsEnabled() {
 #if BUILDFLAG(IS_WIN)
   return ::IsWindowEnabled(GetAcceleratedWidget());
 #elif BUILDFLAG(IS_LINUX)
-#if defined(USE_X11)
-  return !event_disabler_.get();
+#if defined(USE_OZONE_PLATFORM_X11)
+  if (IsX11())
+    return !event_disabler_.get();
 #endif
   NOTIMPLEMENTED();
   return true;
@@ -565,16 +578,18 @@ void NativeWindowViews::SetEnabledInternal(bool enable) {
 
 #if BUILDFLAG(IS_WIN)
   ::EnableWindow(GetAcceleratedWidget(), enable);
-#elif defined(USE_X11)
-  views::DesktopWindowTreeHostPlatform* tree_host =
-      views::DesktopWindowTreeHostLinux::GetHostForWidget(
-          GetAcceleratedWidget());
-  if (enable) {
-    tree_host->RemoveEventRewriter(event_disabler_.get());
-    event_disabler_.reset();
-  } else {
-    event_disabler_ = std::make_unique<EventDisabler>();
-    tree_host->AddEventRewriter(event_disabler_.get());
+#elif defined(USE_OZONE_PLATFORM_X11)
+  if (IsX11()) {
+    views::DesktopWindowTreeHostPlatform* tree_host =
+        views::DesktopWindowTreeHostLinux::GetHostForWidget(
+            GetAcceleratedWidget());
+    if (enable) {
+      tree_host->RemoveEventRewriter(event_disabler_.get());
+      event_disabler_.reset();
+    } else {
+      event_disabler_ = std::make_unique<EventDisabler>();
+      tree_host->AddEventRewriter(event_disabler_.get());
+    }
   }
 #endif
 }
@@ -798,12 +813,14 @@ bool NativeWindowViews::MoveAbove(const std::string& sourceId) {
   ::SetWindowPos(GetAcceleratedWidget(), GetWindow(otherWindow, GW_HWNDPREV), 0,
                  0, 0, 0,
                  SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
-#elif defined(USE_X11)
-  if (!IsWindowValid(static_cast<x11::Window>(id.id)))
-    return false;
+#elif defined(USE_OZONE_PLATFORM_X11)
+  if (IsX11()) {
+    if (!IsWindowValid(static_cast<x11::Window>(id.id)))
+      return false;
 
-  electron::MoveWindowAbove(static_cast<x11::Window>(GetAcceleratedWidget()),
-                            static_cast<x11::Window>(id.id));
+    electron::MoveWindowAbove(static_cast<x11::Window>(GetAcceleratedWidget()),
+                              static_cast<x11::Window>(id.id));
+  }
 #endif
 
   return true;
@@ -818,9 +835,10 @@ void NativeWindowViews::MoveTop() {
   ::SetWindowPos(GetAcceleratedWidget(), HWND_TOP, pos.x(), pos.y(),
                  size.width(), size.height(),
                  SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
-#elif defined(USE_X11)
-  electron::MoveWindowToForeground(
-      static_cast<x11::Window>(GetAcceleratedWidget()));
+#elif defined(USE_OZONE_PLATFORM_X11)
+  if (IsX11())
+    electron::MoveWindowToForeground(
+        static_cast<x11::Window>(GetAcceleratedWidget()));
 #endif
 }
 
@@ -1002,9 +1020,10 @@ void NativeWindowViews::SetSkipTaskbar(bool skip) {
     taskbar->AddTab(GetAcceleratedWidget());
     taskbar_host_.RestoreThumbarButtons(GetAcceleratedWidget());
   }
-#elif defined(USE_X11)
-  SetWMSpecState(static_cast<x11::Window>(GetAcceleratedWidget()), skip,
-                 x11::GetAtom("_NET_WM_STATE_SKIP_TASKBAR"));
+#elif defined(USE_OZONE_PLATFORM_X11)
+  if (IsX11())
+    SetWMSpecState(static_cast<x11::Window>(GetAcceleratedWidget()), skip,
+                   x11::GetAtom("_NET_WM_STATE_SKIP_TASKBAR"));
 #endif
 }
 
@@ -1104,24 +1123,28 @@ void NativeWindowViews::SetIgnoreMouseEvents(bool ignore, bool forward) {
   } else {
     SetForwardMouseMessages(forward);
   }
-#elif defined(USE_X11)
-  auto* connection = x11::Connection::Get();
-  if (ignore) {
-    x11::Rectangle r{0, 0, 1, 1};
-    connection->shape().Rectangles({
-        .operation = x11::Shape::So::Set,
-        .destination_kind = x11::Shape::Sk::Input,
-        .ordering = x11::ClipOrdering::YXBanded,
-        .destination_window = static_cast<x11::Window>(GetAcceleratedWidget()),
-        .rectangles = {r},
-    });
-  } else {
-    connection->shape().Mask({
-        .operation = x11::Shape::So::Set,
-        .destination_kind = x11::Shape::Sk::Input,
-        .destination_window = static_cast<x11::Window>(GetAcceleratedWidget()),
-        .source_bitmap = x11::Pixmap::None,
-    });
+#elif defined(USE_OZONE_PLATFORM_X11)
+  if (IsX11()) {
+    auto* connection = x11::Connection::Get();
+    if (ignore) {
+      x11::Rectangle r{0, 0, 1, 1};
+      connection->shape().Rectangles({
+          .operation = x11::Shape::So::Set,
+          .destination_kind = x11::Shape::Sk::Input,
+          .ordering = x11::ClipOrdering::YXBanded,
+          .destination_window =
+              static_cast<x11::Window>(GetAcceleratedWidget()),
+          .rectangles = {r},
+      });
+    } else {
+      connection->shape().Mask({
+          .operation = x11::Shape::So::Set,
+          .destination_kind = x11::Shape::Sk::Input,
+          .destination_window =
+              static_cast<x11::Window>(GetAcceleratedWidget()),
+          .source_bitmap = x11::Pixmap::None,
+      });
+    }
   }
 #endif
 }
@@ -1168,7 +1191,7 @@ bool NativeWindowViews::IsFocusable() {
 }
 
 void NativeWindowViews::SetMenu(ElectronMenuModel* menu_model) {
-#if defined(USE_X11)
+#if defined(USE_OZONE)
   // Remove global menu bar.
   if (global_menu_bar_ && menu_model == nullptr) {
     global_menu_bar_.reset();
@@ -1177,7 +1200,7 @@ void NativeWindowViews::SetMenu(ElectronMenuModel* menu_model) {
   }
 
   // Use global application menu bar when possible.
-  if (ShouldUseGlobalMenuBar()) {
+  if (CreateGlobalMenuBar() && ShouldUseGlobalMenuBar()) {
     if (!global_menu_bar_)
       global_menu_bar_ = std::make_unique<GlobalMenuBarX11>(this);
     if (global_menu_bar_->IsServerStarted()) {
@@ -1264,12 +1287,13 @@ void NativeWindowViews::SetTopBrowserView(NativeBrowserView* view) {
 void NativeWindowViews::SetParentWindow(NativeWindow* parent) {
   NativeWindow::SetParentWindow(parent);
 
-#if defined(USE_X11)
-  x11::SetProperty(
-      static_cast<x11::Window>(GetAcceleratedWidget()),
-      x11::Atom::WM_TRANSIENT_FOR, x11::Atom::WINDOW,
-      parent ? static_cast<x11::Window>(parent->GetAcceleratedWidget())
-             : ui::GetX11RootWindow());
+#if defined(USE_OZONE_PLATFORM_X11)
+  if (IsX11())
+    x11::SetProperty(
+        static_cast<x11::Window>(GetAcceleratedWidget()),
+        x11::Atom::WM_TRANSIENT_FOR, x11::Atom::WINDOW,
+        parent ? static_cast<x11::Window>(parent->GetAcceleratedWidget())
+               : ui::GetX11RootWindow());
 #elif BUILDFLAG(IS_WIN)
   // To set parentship between windows into Windows is better to play with the
   //  owner instead of the parent, as Windows natively seems to do if a parent
@@ -1347,18 +1371,19 @@ void NativeWindowViews::SetVisibleOnAllWorkspaces(
 }
 
 bool NativeWindowViews::IsVisibleOnAllWorkspaces() {
-#if defined(USE_X11)
-  // Use the presence/absence of _NET_WM_STATE_STICKY in _NET_WM_STATE to
-  // determine whether the current window is visible on all workspaces.
-  x11::Atom sticky_atom = x11::GetAtom("_NET_WM_STATE_STICKY");
-  std::vector<x11::Atom> wm_states;
-  GetArrayProperty(static_cast<x11::Window>(GetAcceleratedWidget()),
-                   x11::GetAtom("_NET_WM_STATE"), &wm_states);
-  return std::find(wm_states.begin(), wm_states.end(), sticky_atom) !=
-         wm_states.end();
-#else
-  return false;
+#if defined(USE_OZONE_PLATFORM_X11)
+  if (IsX11()) {
+    // Use the presence/absence of _NET_WM_STATE_STICKY in _NET_WM_STATE to
+    // determine whether the current window is visible on all workspaces.
+    x11::Atom sticky_atom = x11::GetAtom("_NET_WM_STATE_STICKY");
+    std::vector<x11::Atom> wm_states;
+    GetArrayProperty(static_cast<x11::Window>(GetAcceleratedWidget()),
+                     x11::GetAtom("_NET_WM_STATE"), &wm_states);
+    return std::find(wm_states.begin(), wm_states.end(), sticky_atom) !=
+           wm_states.end();
+  }
 #endif
+  return false;
 }
 
 content::DesktopMediaID NativeWindowViews::GetDesktopMediaID() const {

+ 11 - 4
shell/browser/native_window_views.h

@@ -16,6 +16,13 @@
 #include "third_party/skia/include/core/SkRegion.h"
 #include "ui/views/widget/widget_observer.h"
 
+#if defined(USE_OZONE)
+#include "ui/ozone/buildflags.h"
+#if BUILDFLAG(OZONE_PLATFORM_X11)
+#define USE_OZONE_PLATFORM_X11
+#endif
+#endif
+
 #if BUILDFLAG(IS_WIN)
 #include "base/win/scoped_gdi_object.h"
 #include "shell/browser/ui/win/taskbar_host.h"
@@ -32,7 +39,7 @@ class GlobalMenuBarX11;
 class RootView;
 class WindowStateWatcher;
 
-#if defined(USE_X11)
+#if defined(USE_OZONE_PLATFORM_X11)
 class EventDisabler;
 #endif
 
@@ -259,12 +266,12 @@ class NativeWindowViews : public NativeWindow,
   // events from resizing the window.
   extensions::SizeConstraints old_size_constraints_;
 
-#if defined(USE_X11)
+#if defined(USE_OZONE)
   std::unique_ptr<GlobalMenuBarX11> global_menu_bar_;
 
-  // Handles window state events.
-  std::unique_ptr<WindowStateWatcher> window_state_watcher_;
+#endif
 
+#if defined(USE_OZONE_PLATFORM_X11)
   // To disable the mouse events.
   std::unique_ptr<EventDisabler> event_disabler_;
 #endif

+ 3 - 8
shell/browser/net/proxying_url_loader_factory.cc

@@ -38,7 +38,6 @@ ProxyingURLLoaderFactory::InProgressRequest::FollowRedirectParams::
 ProxyingURLLoaderFactory::InProgressRequest::InProgressRequest(
     ProxyingURLLoaderFactory* factory,
     uint64_t web_request_id,
-    int32_t view_routing_id,
     int32_t frame_routing_id,
     int32_t network_service_request_id,
     uint32_t options,
@@ -51,7 +50,6 @@ ProxyingURLLoaderFactory::InProgressRequest::InProgressRequest(
       original_initiator_(request.request_initiator),
       request_id_(web_request_id),
       network_service_request_id_(network_service_request_id),
-      view_routing_id_(view_routing_id),
       frame_routing_id_(frame_routing_id),
       options_(options),
       traffic_annotation_(traffic_annotation),
@@ -120,7 +118,7 @@ void ProxyingURLLoaderFactory::InProgressRequest::UpdateRequestInfo() {
       request_id_, factory_->render_process_id_, frame_routing_id_,
       factory_->navigation_ui_data_ ? factory_->navigation_ui_data_->DeepCopy()
                                     : nullptr,
-      view_routing_id_, request_for_info, false,
+      request_for_info, false,
       !(options_ & network::mojom::kURLLoadOptionSynchronous),
       factory_->IsForServiceWorkerScript(), factory_->navigation_id_,
       ukm::kInvalidSourceIdObj));
@@ -757,7 +755,6 @@ ProxyingURLLoaderFactory::ProxyingURLLoaderFactory(
     const HandlersMap& intercepted_handlers,
     int render_process_id,
     int frame_routing_id,
-    int view_routing_id,
     uint64_t* request_id_generator,
     std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data,
     absl::optional<int64_t> navigation_id,
@@ -770,7 +767,6 @@ ProxyingURLLoaderFactory::ProxyingURLLoaderFactory(
       intercepted_handlers_(intercepted_handlers),
       render_process_id_(render_process_id),
       frame_routing_id_(frame_routing_id),
-      view_routing_id_(view_routing_id),
       request_id_generator_(request_id_generator),
       navigation_ui_data_(std::move(navigation_ui_data)),
       navigation_id_(std::move(navigation_id)),
@@ -866,9 +862,8 @@ void ProxyingURLLoaderFactory::CreateLoaderAndStart(
   auto result = requests_.emplace(
       web_request_id,
       std::make_unique<InProgressRequest>(
-          this, web_request_id, view_routing_id_, frame_routing_id_, request_id,
-          options, request, traffic_annotation, std::move(loader),
-          std::move(client)));
+          this, web_request_id, frame_routing_id_, request_id, options, request,
+          traffic_annotation, std::move(loader), std::move(client)));
   result.first->second->Restart();
 }
 

+ 0 - 4
shell/browser/net/proxying_url_loader_factory.h

@@ -54,7 +54,6 @@ class ProxyingURLLoaderFactory
     InProgressRequest(
         ProxyingURLLoaderFactory* factory,
         uint64_t web_request_id,
-        int32_t view_routing_id,
         int32_t frame_routing_id,
         int32_t network_service_request_id,
         uint32_t options,
@@ -136,7 +135,6 @@ class ProxyingURLLoaderFactory
     const absl::optional<url::Origin> original_initiator_;
     const uint64_t request_id_ = 0;
     const int32_t network_service_request_id_ = 0;
-    const int32_t view_routing_id_ = MSG_ROUTING_NONE;
     const int32_t frame_routing_id_ = MSG_ROUTING_NONE;
     const uint32_t options_ = 0;
     const net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
@@ -195,7 +193,6 @@ class ProxyingURLLoaderFactory
       const HandlersMap& intercepted_handlers,
       int render_process_id,
       int frame_routing_id,
-      int view_routing_id,
       uint64_t* request_id_generator,
       std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data,
       absl::optional<int64_t> navigation_id,
@@ -260,7 +257,6 @@ class ProxyingURLLoaderFactory
 
   const int render_process_id_;
   const int frame_routing_id_;
-  const int view_routing_id_;
   uint64_t* request_id_generator_;  // managed by ElectronBrowserClient
   std::unique_ptr<extensions::ExtensionNavigationUIData> navigation_ui_data_;
   absl::optional<int64_t> navigation_id_;

+ 0 - 1
shell/browser/net/proxying_websocket.cc

@@ -40,7 +40,6 @@ ProxyingWebSocket::ProxyingWebSocket(
           process_id,
           render_frame_id,
           nullptr,
-          MSG_ROUTING_NONE,
           request,
           /*is_download=*/false,
           /*is_async=*/true,

+ 0 - 4
shell/browser/net/system_network_context_manager.cc

@@ -288,10 +288,6 @@ void SystemNetworkContextManager::OnNetworkServiceCreated(
       base::FeatureList::IsEnabled(features::kAsyncDns),
       default_secure_dns_mode, doh_config, additional_dns_query_types_enabled);
 
-  // Initializes first party sets component
-  // CL: https://chromium-review.googlesource.com/c/chromium/src/+/3449280
-  content::GetNetworkService()->SetFirstPartySets(base::File());
-
   std::string app_name = electron::Browser::Get()->GetName();
 #if BUILDFLAG(IS_MAC)
   KeychainPassword::GetServiceName() = app_name + " Safe Storage";

+ 4 - 4
shell/browser/resources/win/electron.rc

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

Some files were not shown because too many files changed in this diff