mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
170 Commits
v5.0.0-bet
...
v5.0.9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97df834c1c | ||
|
|
d98735cff7 | ||
|
|
9e0eb96141 | ||
|
|
753501442f | ||
|
|
303559e2f1 | ||
|
|
5a8bdb2380 | ||
|
|
21aaf670ce | ||
|
|
fa2b3a3767 | ||
|
|
fc94fb4480 | ||
|
|
f5d936d52c | ||
|
|
b4f5c4ba4a | ||
|
|
3af498e17c | ||
|
|
670291b0ab | ||
|
|
7b6a14b667 | ||
|
|
4fa89a1fbc | ||
|
|
6b0eaa4832 | ||
|
|
bc30aeac7c | ||
|
|
c5573d2b6c | ||
|
|
7e80f3fb19 | ||
|
|
e64d407bfd | ||
|
|
7771886073 | ||
|
|
9b1147c7c9 | ||
|
|
69ff736ace | ||
|
|
04c7453074 | ||
|
|
46c0859c49 | ||
|
|
31e43f54d0 | ||
|
|
d545757191 | ||
|
|
ddc85869de | ||
|
|
65faec8659 | ||
|
|
9b72734f7c | ||
|
|
29a6dd079c | ||
|
|
dd58f2a6ac | ||
|
|
8e68e6eb75 | ||
|
|
0a3ec23967 | ||
|
|
6f85e4de57 | ||
|
|
b8f3325a04 | ||
|
|
3e6cd062a7 | ||
|
|
a2f68c1e57 | ||
|
|
bff8573646 | ||
|
|
32ad5be74e | ||
|
|
3d60f82d03 | ||
|
|
3aa16f5632 | ||
|
|
d0f7f9f894 | ||
|
|
7865fa37fa | ||
|
|
714fa6f3c0 | ||
|
|
61d9d7c657 | ||
|
|
558bb52847 | ||
|
|
c979c90f46 | ||
|
|
a9ada36097 | ||
|
|
0c4b2e99ec | ||
|
|
f35b166844 | ||
|
|
ff54817a92 | ||
|
|
25e5432863 | ||
|
|
4b9ae99f34 | ||
|
|
e2e7a82ebc | ||
|
|
385e548073 | ||
|
|
938b3440ef | ||
|
|
eb821a3c7f | ||
|
|
4318ad8f3a | ||
|
|
b3c44d1fe6 | ||
|
|
401f6641c8 | ||
|
|
18e31da478 | ||
|
|
ae5d556845 | ||
|
|
ebc937cfd5 | ||
|
|
f09f926cba | ||
|
|
4964a09677 | ||
|
|
a7c4d21427 | ||
|
|
07cd1e6b4d | ||
|
|
7a135c736b | ||
|
|
183c687f49 | ||
|
|
b04eaabf4e | ||
|
|
aae58ffcae | ||
|
|
226dd755f8 | ||
|
|
2e6814c4b0 | ||
|
|
d4319badce | ||
|
|
b034bf9ae6 | ||
|
|
c0e688ff35 | ||
|
|
bf9b001989 | ||
|
|
0e0c3da49a | ||
|
|
63d994808c | ||
|
|
e0d566a7e7 | ||
|
|
eaa22b4aa8 | ||
|
|
99c3ff60bb | ||
|
|
38cca77346 | ||
|
|
a0872b2314 | ||
|
|
8517c499e9 | ||
|
|
3f23f8b2a3 | ||
|
|
45ab468ce1 | ||
|
|
be458b547a | ||
|
|
050bbfb211 | ||
|
|
0a4d90d41f | ||
|
|
0e56578e11 | ||
|
|
7a2777cc00 | ||
|
|
fc6b98766c | ||
|
|
7d06861a6d | ||
|
|
851a84d301 | ||
|
|
91bc35fbfc | ||
|
|
76414e58d4 | ||
|
|
d6ad3e6a17 | ||
|
|
49d6f5cc14 | ||
|
|
610f61603d | ||
|
|
6b371a5ef9 | ||
|
|
7ee06c354e | ||
|
|
a60ad6aeed | ||
|
|
693d840202 | ||
|
|
7a759ea0b6 | ||
|
|
83a4b7371b | ||
|
|
82bb6d4ccf | ||
|
|
2de54a3dbc | ||
|
|
7eac676fa7 | ||
|
|
54199d21c3 | ||
|
|
2483dcc09c | ||
|
|
1154f3c585 | ||
|
|
232d9fe808 | ||
|
|
5693b7f3a1 | ||
|
|
d4e631f1b9 | ||
|
|
2252ac060e | ||
|
|
bb28195b74 | ||
|
|
2f426a031a | ||
|
|
761b14316f | ||
|
|
f3a05c30ae | ||
|
|
7514372e79 | ||
|
|
151a338956 | ||
|
|
d57293503d | ||
|
|
c4009760c7 | ||
|
|
3408997289 | ||
|
|
9ca2b31b7c | ||
|
|
5aa0a1a77a | ||
|
|
3825bf0b6d | ||
|
|
d15bcfb1ed | ||
|
|
ccb051caf7 | ||
|
|
3284aabd48 | ||
|
|
6d575f80fa | ||
|
|
b91dcfb314 | ||
|
|
321e66d0cc | ||
|
|
81eedb6efa | ||
|
|
b08dc0f7e6 | ||
|
|
11c1c255bf | ||
|
|
c89bab9730 | ||
|
|
5ffe634824 | ||
|
|
3ad9fb1473 | ||
|
|
b0298cca2e | ||
|
|
ed8ab7e9ad | ||
|
|
c75726f9ef | ||
|
|
ff7e22c675 | ||
|
|
946c11145c | ||
|
|
ffd2224bbe | ||
|
|
c326de860d | ||
|
|
145aa919ca | ||
|
|
2cc55fee5e | ||
|
|
119e8bec93 | ||
|
|
82f91b7efa | ||
|
|
900feef89f | ||
|
|
c58d39e71b | ||
|
|
48f190690e | ||
|
|
faa308c88c | ||
|
|
9619688706 | ||
|
|
a724aced43 | ||
|
|
9a9f7af971 | ||
|
|
0184ccd019 | ||
|
|
cdd8021509 | ||
|
|
1e31bfe287 | ||
|
|
7304af93ed | ||
|
|
69f6a44e81 | ||
|
|
354b32a9fc | ||
|
|
d5bb0e968f | ||
|
|
9e12e8c63f | ||
|
|
ebcd094222 | ||
|
|
5dd735f5b3 | ||
|
|
46841d7373 |
@@ -35,6 +35,7 @@ env-debug-build: &env-debug-build
|
||||
|
||||
env-testing-build: &env-testing-build
|
||||
GN_CONFIG: //electron/build/args/testing.gn
|
||||
CHECK_DIST_MANIFEST: '1'
|
||||
|
||||
env-release-build: &env-release-build
|
||||
GN_CONFIG: //electron/build/args/release.gn
|
||||
@@ -254,6 +255,28 @@ step-electron-dist-build: &step-electron-dist-build
|
||||
command: |
|
||||
cd src
|
||||
ninja -C out/Default electron:electron_dist_zip
|
||||
if [ "$CHECK_DIST_MANIFEST" == "1" ]; then
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
target_os=mac
|
||||
target_cpu=x64
|
||||
if [ x"$MAS_BUILD" == x"true" ]; then
|
||||
target_os=mac_mas
|
||||
fi
|
||||
elif [ "`uname`" == "Linux" ]; then
|
||||
target_os=linux
|
||||
if [ x"$TARGET_ARCH" == x ]; then
|
||||
target_cpu=x64
|
||||
elif [ "$TARGET_ARCH" == "ia32" ]; then
|
||||
target_cpu=x86
|
||||
else
|
||||
target_cpu="$TARGET_ARCH"
|
||||
fi
|
||||
else
|
||||
echo "Unknown system: `uname`"
|
||||
exit 1
|
||||
fi
|
||||
electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.$target_os.$target_cpu.manifest
|
||||
fi
|
||||
|
||||
step-electron-dist-store: &step-electron-dist-store
|
||||
store_artifacts:
|
||||
@@ -402,25 +425,13 @@ step-mksnapshot-store: &step-mksnapshot-store
|
||||
path: src/out/Default/mksnapshot.zip
|
||||
destination: mksnapshot.zip
|
||||
|
||||
step-maybe-build-dump-syms: &step-maybe-build-dump-syms
|
||||
run:
|
||||
name: Build dump_syms binary
|
||||
command: |
|
||||
if [ "$GENERATE_SYMBOLS" == "true" ]; then
|
||||
cd src
|
||||
# Build needed dump_syms executable
|
||||
ninja -C out/Default third_party/breakpad:dump_syms
|
||||
fi
|
||||
|
||||
step-maybe-generate-breakpad-symbols: &step-maybe-generate-breakpad-symbols
|
||||
run:
|
||||
name: Generate breakpad symbols
|
||||
command: |
|
||||
if [ "$GENERATE_SYMBOLS" == "true" ]; then
|
||||
cd src
|
||||
export BUILD_PATH="$PWD/out/Default"
|
||||
export DEST_PATH="$BUILD_PATH/breakpad_symbols"
|
||||
electron/script/dump-symbols.py -b $BUILD_PATH -d $DEST_PATH -v
|
||||
ninja -C out/Default electron:electron_symbols
|
||||
fi
|
||||
|
||||
step-maybe-zip-symbols: &step-maybe-zip-symbols
|
||||
@@ -492,6 +503,39 @@ step-maybe-generate-typescript-defs: &step-maybe-generate-typescript-defs
|
||||
fi
|
||||
|
||||
# Lists of steps.
|
||||
steps-lint: &steps-lint
|
||||
steps:
|
||||
- *step-checkout-electron
|
||||
- run:
|
||||
name: Setup third_party Depot Tools
|
||||
command: |
|
||||
# "depot_tools" has to be checkout into "//third_party/depot_tools" so pylint.py can a "pylintrc" file.
|
||||
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git src/third_party/depot_tools
|
||||
echo 'export PATH="$PATH:'"$PWD"'/src/third_party/depot_tools"' >> $BASH_ENV
|
||||
- run:
|
||||
name: Download GN Binary
|
||||
command: |
|
||||
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
|
||||
buildtools_revision="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep buildtools_revision -A1 | tr -d '\n' | cut -d\' -f4)"
|
||||
|
||||
git clone https://chromium.googlesource.com/chromium/buildtools "buildtools"
|
||||
(cd "buildtools" && git checkout "$buildtools_revision")
|
||||
echo 'export CHROMIUM_BUILDTOOLS_PATH="'"$PWD"'/buildtools"' >> $BASH_ENV
|
||||
|
||||
download_from_google_storage --bucket chromium-gn -s "buildtools/linux64/gn.sha1"
|
||||
- run:
|
||||
name: Run Lint
|
||||
command: |
|
||||
# gn.py tries to find a gclient root folder starting from the current dir.
|
||||
# When it fails and returns "None" path, the whole script fails. Let's "fix" it.
|
||||
touch .gclient
|
||||
# Another option would be to checkout "buildtools" inside the Electron checkout,
|
||||
# but then we would lint its contents (at least gn format), and it doesn't pass it.
|
||||
|
||||
cd src/electron
|
||||
npm install
|
||||
npm run lint
|
||||
|
||||
steps-checkout: &steps-checkout
|
||||
steps:
|
||||
- *step-checkout-electron
|
||||
@@ -596,7 +640,6 @@ steps-electron-build-for-tests: &steps-electron-build-for-tests
|
||||
# Save all data needed for a further tests run.
|
||||
- *step-persist-data-for-tests
|
||||
|
||||
- *step-maybe-build-dump-syms
|
||||
- *step-maybe-generate-breakpad-symbols
|
||||
- *step-maybe-zip-symbols
|
||||
|
||||
@@ -621,7 +664,6 @@ steps-electron-build-for-publish: &steps-electron-build-for-publish
|
||||
- *step-maybe-electron-dist-strip
|
||||
- *step-electron-dist-build
|
||||
- *step-electron-dist-store
|
||||
- *step-maybe-build-dump-syms
|
||||
- *step-maybe-generate-breakpad-symbols
|
||||
- *step-maybe-zip-symbols
|
||||
|
||||
@@ -779,6 +821,13 @@ chromium-upgrade-branches: &chromium-upgrade-branches
|
||||
# List of all jobs.
|
||||
version: 2
|
||||
jobs:
|
||||
# Layer 0: Lint. Standalone.
|
||||
lint:
|
||||
<<: *machine-linux-medium
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *steps-lint
|
||||
|
||||
# Layer 1: Checkout.
|
||||
linux-checkout:
|
||||
<<: *machine-linux-2xlarge
|
||||
@@ -1302,6 +1351,10 @@ jobs:
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
lint:
|
||||
jobs:
|
||||
- lint
|
||||
|
||||
build-linux:
|
||||
jobs:
|
||||
- linux-checkout
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# These env vars are only necessary for creating Electron releases.
|
||||
# See docs/development/releasing.md
|
||||
|
||||
APPVEYOR_TOKEN=
|
||||
APPVEYOR_CLOUD_TOKEN=
|
||||
CIRCLE_TOKEN=
|
||||
ELECTRON_GITHUB_TOKEN=
|
||||
VSTS_TOKEN=
|
||||
33
.github/CODEOWNERS
vendored
33
.github/CODEOWNERS
vendored
@@ -3,19 +3,24 @@
|
||||
# https://help.github.com/articles/about-codeowners
|
||||
# https://git-scm.com/docs/gitignore
|
||||
|
||||
# Everything that falls through the cracks:
|
||||
* @electron/reviewers
|
||||
# Most stuff in here is owned by the Community & Safety WG...
|
||||
/.github/* @electron/wg-community
|
||||
|
||||
# filename patterns
|
||||
*browser_view* @electron/browserview
|
||||
*notification* @electron/notifications
|
||||
*pdf* @electron/printing
|
||||
*printing* @electron/printing
|
||||
*updater* @electron/updater
|
||||
# ...except the Admin WG maintains this file.
|
||||
/.github/CODEOWNERS @electron/wg-admin
|
||||
|
||||
# directories
|
||||
/.github/ @electron/electrocats
|
||||
/default_app/ @electron/docs
|
||||
/docs/ @electron/docs
|
||||
/docs-translations/ @electron/i18n
|
||||
/npm/ @electron/electrocats
|
||||
# Upgrades WG
|
||||
/patches/ @electron/wg-upgrades
|
||||
|
||||
# Releases WG
|
||||
/npm/ @electron/wg-releases
|
||||
/script/release-notes @electron/wg-releases
|
||||
/script/prepare-release.js @electron/wg-releases
|
||||
/script/bump-version.js @electron/wg-releases
|
||||
/script/ci-release-build.js @electron/wg-releases
|
||||
/script/release.js @electron/wg-releases
|
||||
/script/upload-to-github.js @electron/wg-releases
|
||||
/script/release-artifact-cleanup.js @electron/wg-releases
|
||||
/script/get-last-major-for-master.js @electron/wg-releases
|
||||
/script/find-release.js @electron/wg-releases
|
||||
/script/download-circleci-artifacts.js @electron/wg-releases
|
||||
@@ -1,31 +0,0 @@
|
||||
pool:
|
||||
vmImage: 'Ubuntu 16.04'
|
||||
|
||||
steps:
|
||||
- bash: |
|
||||
# "depot_tools" has to be checkout into "//third_party/depot_tools" so pylint.py can a "pylintrc" file.
|
||||
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git "${AGENT_BUILDDIRECTORY}/third_party/depot_tools"
|
||||
echo "##vso[task.setvariable variable=PATH]$PATH:${AGENT_BUILDDIRECTORY}/third_party/depot_tools"
|
||||
displayName: Setup Depot Tools
|
||||
|
||||
- bash: |
|
||||
chromium_revision="$(grep -A1 chromium_version DEPS | tr -d '\n' | cut -d\' -f4)"
|
||||
buildtools_revision="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep buildtools_revision -A1 | tr -d '\n' | cut -d\' -f4)"
|
||||
|
||||
git clone https://chromium.googlesource.com/chromium/buildtools "${AGENT_TEMPDIRECTORY}/buildtools"
|
||||
(cd "${AGENT_TEMPDIRECTORY}/buildtools" && git checkout "$buildtools_revision")
|
||||
echo "##vso[task.setvariable variable=CHROMIUM_BUILDTOOLS_PATH]$AGENT_TEMPDIRECTORY/buildtools"
|
||||
|
||||
download_from_google_storage --bucket chromium-gn -s "${AGENT_TEMPDIRECTORY}/buildtools/linux64/gn.sha1"
|
||||
displayName: Download gn binary
|
||||
|
||||
- bash: |
|
||||
# gn.py tries to find a gclient root folder starting from the current dir.
|
||||
# When it fails and returns "None" path, the whole script fails. Let's "fix" it.
|
||||
touch .gclient
|
||||
# Another option would be to checkout "buildtools" inside the Electron checkout,
|
||||
# but then we would lint its contents (at least gn format), and it doesn't pass it.
|
||||
|
||||
npm install
|
||||
npm run lint
|
||||
displayName: Run Lint
|
||||
160
BUILD.gn
160
BUILD.gn
@@ -9,6 +9,8 @@ import("//tools/grit/repack.gni")
|
||||
import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
|
||||
import("//v8/snapshot_toolchain.gni")
|
||||
import("build/asar.gni")
|
||||
import("build/extract_symbols.gni")
|
||||
import("build/js_wrap.gni")
|
||||
import("build/npm.gni")
|
||||
import("buildflags/buildflags.gni")
|
||||
import("electron_paks.gni")
|
||||
@@ -52,7 +54,7 @@ config("branding") {
|
||||
]
|
||||
}
|
||||
|
||||
npm_action("atom_browserify_sandbox") {
|
||||
npm_action("atom_browserify_sandbox_unwrapped") {
|
||||
script = "browserify"
|
||||
|
||||
inputs = [
|
||||
@@ -64,7 +66,7 @@ npm_action("atom_browserify_sandbox") {
|
||||
]
|
||||
|
||||
outputs = [
|
||||
"$target_gen_dir/js2c/preload_bundle.js",
|
||||
"$target_gen_dir/js2c/preload_bundle_unwrapped.js",
|
||||
]
|
||||
|
||||
args = [
|
||||
@@ -73,12 +75,14 @@ npm_action("atom_browserify_sandbox") {
|
||||
"./lib/sandboxed_renderer/api/exports/electron.js:electron",
|
||||
"-t",
|
||||
"aliasify",
|
||||
"--standalone",
|
||||
"sandboxed_preload",
|
||||
"-o",
|
||||
rebase_path(outputs[0]),
|
||||
]
|
||||
}
|
||||
|
||||
npm_action("atom_browserify_isolated") {
|
||||
npm_action("atom_browserify_isolated_unwrapped") {
|
||||
script = "browserify"
|
||||
|
||||
inputs = [
|
||||
@@ -86,18 +90,48 @@ npm_action("atom_browserify_isolated") {
|
||||
]
|
||||
|
||||
outputs = [
|
||||
"$target_gen_dir/js2c/isolated_bundle.js",
|
||||
"$target_gen_dir/js2c/isolated_bundle_unwrapped.js",
|
||||
]
|
||||
|
||||
args = [
|
||||
"lib/isolated_renderer/init.js",
|
||||
"-t",
|
||||
"aliasify",
|
||||
"--standalone",
|
||||
"isolated_preload",
|
||||
"-o",
|
||||
rebase_path(outputs[0]),
|
||||
]
|
||||
}
|
||||
|
||||
js_wrap("atom_browserify_isolated") {
|
||||
deps = [
|
||||
":atom_browserify_isolated_unwrapped",
|
||||
]
|
||||
|
||||
inputs = [
|
||||
"$target_gen_dir/js2c/isolated_bundle_unwrapped.js",
|
||||
]
|
||||
|
||||
outputs = [
|
||||
"$target_gen_dir/js2c/isolated_bundle.js",
|
||||
]
|
||||
}
|
||||
|
||||
js_wrap("atom_browserify_sandbox") {
|
||||
deps = [
|
||||
":atom_browserify_sandbox_unwrapped",
|
||||
]
|
||||
|
||||
inputs = [
|
||||
"$target_gen_dir/js2c/preload_bundle_unwrapped.js",
|
||||
]
|
||||
|
||||
outputs = [
|
||||
"$target_gen_dir/js2c/preload_bundle.js",
|
||||
]
|
||||
}
|
||||
|
||||
copy("atom_js2c_copy") {
|
||||
sources = [
|
||||
"lib/common/asar.js",
|
||||
@@ -324,8 +358,6 @@ static_library("electron_lib") {
|
||||
"*_views.cc",
|
||||
"*_views.h",
|
||||
"*\bviews/*",
|
||||
"*/autofill_popup.cc",
|
||||
"*/autofill_popup.h",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -350,6 +382,10 @@ static_library("electron_lib") {
|
||||
"//third_party/crashpad/crashpad/client",
|
||||
"//ui/accelerated_widget_mac",
|
||||
]
|
||||
sources += [
|
||||
"atom/browser/ui/views/autofill_popup_view.cc",
|
||||
"atom/browser/ui/views/autofill_popup_view.h",
|
||||
]
|
||||
include_dirs += [
|
||||
# NOTE(nornagon): other chromium files use the full path to include
|
||||
# crashpad; this is just here for compatibility between GN and GYP, so that
|
||||
@@ -422,11 +458,13 @@ static_library("electron_lib") {
|
||||
|
||||
if (enable_osr) {
|
||||
sources += [
|
||||
"atom/browser/osr/osr_output_device.cc",
|
||||
"atom/browser/osr/osr_output_device.h",
|
||||
"atom/browser/osr/osr_host_display_client.cc",
|
||||
"atom/browser/osr/osr_host_display_client.h",
|
||||
"atom/browser/osr/osr_host_display_client_mac.mm",
|
||||
"atom/browser/osr/osr_render_widget_host_view.cc",
|
||||
"atom/browser/osr/osr_render_widget_host_view.h",
|
||||
"atom/browser/osr/osr_render_widget_host_view_mac.mm",
|
||||
"atom/browser/osr/osr_video_consumer.cc",
|
||||
"atom/browser/osr/osr_video_consumer.h",
|
||||
"atom/browser/osr/osr_view_proxy.cc",
|
||||
"atom/browser/osr/osr_view_proxy.h",
|
||||
"atom/browser/osr/osr_web_contents_view.cc",
|
||||
@@ -499,6 +537,7 @@ if (is_mac) {
|
||||
electron_helper_name = "$electron_product_name Helper"
|
||||
electron_login_helper_name = "$electron_product_name Login Helper"
|
||||
electron_framework_version = "A"
|
||||
electron_version = read_file("ELECTRON_VERSION", "trim string")
|
||||
|
||||
mac_xib_bundle_data("electron_xibs") {
|
||||
sources = [
|
||||
@@ -581,7 +620,6 @@ if (is_mac) {
|
||||
}
|
||||
info_plist = "atom/common/resources/mac/Info.plist"
|
||||
|
||||
electron_version = read_file("ELECTRON_VERSION", "trim string")
|
||||
extra_substitutions = [
|
||||
"ATOM_BUNDLE_ID=$electron_mac_bundle_id.framework",
|
||||
"ELECTRON_VERSION=$electron_version",
|
||||
@@ -600,6 +638,11 @@ if (is_mac) {
|
||||
"ServiceManagement.framework",
|
||||
"StoreKit.framework",
|
||||
]
|
||||
|
||||
if (enable_osr) {
|
||||
libs += [ "IOSurface.framework" ]
|
||||
}
|
||||
|
||||
ldflags = [
|
||||
"-F",
|
||||
rebase_path("external_binaries", root_build_dir),
|
||||
@@ -747,6 +790,56 @@ if (is_mac) {
|
||||
"@executable_path/../Frameworks",
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_dsyms) {
|
||||
extract_symbols("electron_framework_syms") {
|
||||
binary = "$root_out_dir/$electron_framework_name.framework/Versions/$electron_framework_version/$electron_framework_name"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/$electron_framework_name.dSYM/Contents/Resources/DWARF/$electron_framework_name"
|
||||
deps = [
|
||||
":electron_framework",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("electron_helper_syms") {
|
||||
binary = "$root_out_dir/$electron_helper_name.app/Contents/MacOS/$electron_helper_name"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/$electron_helper_name.dSYM/Contents/Resources/DWARF/$electron_helper_name"
|
||||
deps = [
|
||||
":electron_helper_app",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("electron_app_syms") {
|
||||
binary = "$root_out_dir/$electron_product_name.app/Contents/MacOS/$electron_product_name"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/$electron_product_name.dSYM/Contents/Resources/DWARF/$electron_product_name"
|
||||
deps = [
|
||||
":electron_app",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("crashpad_handler_syms") {
|
||||
binary = "$root_out_dir/crashpad_handler"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/crashpad_handler.dSYM/Contents/Resources/DWARF/crashpad_handler"
|
||||
deps = [
|
||||
"//third_party/crashpad/crashpad/handler:crashpad_handler",
|
||||
]
|
||||
}
|
||||
|
||||
group("electron_symbols") {
|
||||
deps = [
|
||||
":crashpad_handler_syms",
|
||||
":electron_app_syms",
|
||||
":electron_framework_syms",
|
||||
":electron_helper_syms",
|
||||
]
|
||||
}
|
||||
} else {
|
||||
group("electron_symbols") {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
windows_manifest("electron_app_manifest") {
|
||||
sources = [
|
||||
@@ -844,6 +937,53 @@ if (is_mac) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_official_build) {
|
||||
if (is_linux) {
|
||||
_target_executable_suffix = ""
|
||||
_target_shared_library_suffix = ".so"
|
||||
} else if (is_win) {
|
||||
_target_executable_suffix = ".exe"
|
||||
_target_shared_library_suffix = ".dll"
|
||||
}
|
||||
|
||||
extract_symbols("electron_app_symbols") {
|
||||
binary = "$root_out_dir/$electron_project_name$_target_executable_suffix"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
deps = [
|
||||
":electron_app",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("swiftshader_egl_symbols") {
|
||||
binary = "$root_out_dir/swiftshader/libEGL$_target_shared_library_suffix"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
deps = [
|
||||
"//third_party/swiftshader/src/OpenGL/libEGL:swiftshader_libEGL",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("swiftshader_gles_symbols") {
|
||||
binary =
|
||||
"$root_out_dir/swiftshader/libGLESv2$_target_shared_library_suffix"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
deps = [
|
||||
"//third_party/swiftshader/src/OpenGL/libGLESv2:swiftshader_libGLESv2",
|
||||
]
|
||||
}
|
||||
|
||||
group("electron_symbols") {
|
||||
deps = [
|
||||
":electron_app_symbols",
|
||||
]
|
||||
if (target_cpu == "x86" || target_cpu == "x64") {
|
||||
deps += [
|
||||
":swiftshader_egl_symbols",
|
||||
":swiftshader_gles_symbols",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template("dist_zip") {
|
||||
|
||||
7
DEPS
7
DEPS
@@ -10,9 +10,9 @@ gclient_gn_args = [
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'73.0.3683.94',
|
||||
'73.0.3683.121',
|
||||
'node_version':
|
||||
'f807d72614d4b8973d71548328be213532b46b1b',
|
||||
'666c67e078bddc32f25409f4a929c1e9b5f47373',
|
||||
|
||||
'boto_version': 'f7574aa6cc2c819430c1f05e9a1a1a666ef8169b',
|
||||
'pyyaml_version': '3.12',
|
||||
@@ -21,6 +21,7 @@ vars = {
|
||||
'boto_git': 'https://github.com/boto',
|
||||
'chromium_git': 'https://chromium.googlesource.com',
|
||||
'electron_git': 'https://github.com/electron',
|
||||
'nodejs_git': 'https://github.com/nodejs',
|
||||
'requests_git': 'https://github.com/kennethreitz',
|
||||
'yaml_git': 'https://github.com/yaml',
|
||||
|
||||
@@ -64,7 +65,7 @@ deps = {
|
||||
'condition': 'checkout_chromium',
|
||||
},
|
||||
'src/third_party/electron_node': {
|
||||
'url': (Var("electron_git")) + '/node.git@' + (Var("node_version")),
|
||||
'url': (Var("nodejs_git")) + '/node.git@' + (Var("node_version")),
|
||||
'condition': 'checkout_node',
|
||||
},
|
||||
'src/electron/vendor/pyyaml': {
|
||||
|
||||
@@ -16,7 +16,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
locales \
|
||||
lsb-release \
|
||||
nano \
|
||||
python-dbusmock \
|
||||
python-dbus \
|
||||
python-pip \
|
||||
python-setuptools \
|
||||
sudo \
|
||||
@@ -33,6 +33,9 @@ RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
|
||||
# crcmod is required by gsutil, which is used for filling the gclient git cache
|
||||
RUN pip install -U crcmod
|
||||
|
||||
# dbusmock is needed for Electron tests
|
||||
RUN pip install python-dbusmock
|
||||
|
||||
RUN mkdir /tmp/workspace
|
||||
RUN chown builduser:builduser /tmp/workspace
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
5.0.0-beta.7
|
||||
5.0.9
|
||||
@@ -68,14 +68,16 @@ build_script:
|
||||
- appveyor PushArtifact out/ffmpeg/ffmpeg.zip
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
ninja -C out/Default third_party/breakpad:dump_syms
|
||||
# Needed for msdia140.dll on 64-bit windows
|
||||
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
|
||||
ninja -C out/Default electron:electron_symbols
|
||||
}
|
||||
- if "%GN_CONFIG%"=="release" ( python electron\script\dump-symbols.py -d %cd%\out\Default\breakpad_symbols -v)
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
python electron\script\zip-symbols.py
|
||||
appveyor PushArtifact out/Default/symbols.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:
|
||||
- ps: >-
|
||||
if ((-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
|
||||
|
||||
@@ -58,6 +58,11 @@ bool IsBrowserProcess(base::CommandLine* cmd) {
|
||||
return process_type.empty();
|
||||
}
|
||||
|
||||
bool IsSandboxEnabled(base::CommandLine* command_line) {
|
||||
return command_line->HasSwitch(switches::kEnableSandbox) ||
|
||||
!command_line->HasSwitch(service_manager::switches::kNoSandbox);
|
||||
}
|
||||
|
||||
// Returns true if this subprocess type needs the ResourceBundle initialized
|
||||
// and resources loaded.
|
||||
bool SubprocessNeedsResourceBundle(const std::string& process_type) {
|
||||
@@ -183,6 +188,14 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
base::win::DisableHandleVerifier();
|
||||
#endif
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
// Check for --no-sandbox parameter when running as root.
|
||||
if (getuid() == 0 && IsSandboxEnabled(command_line))
|
||||
LOG(FATAL) << "Running as root without --"
|
||||
<< service_manager::switches::kNoSandbox
|
||||
<< " is not supported. See https://crbug.com/638180.";
|
||||
#endif
|
||||
|
||||
content_client_ = std::make_unique<AtomContentClient>();
|
||||
SetContentClient(content_client_.get());
|
||||
|
||||
@@ -259,10 +272,9 @@ content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
|
||||
|
||||
content::ContentRendererClient*
|
||||
AtomMainDelegate::CreateContentRendererClient() {
|
||||
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kEnableSandbox) ||
|
||||
!base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
service_manager::switches::kNoSandbox)) {
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
if (IsSandboxEnabled(command_line)) {
|
||||
renderer_client_.reset(new AtomSandboxedRendererClient);
|
||||
} else {
|
||||
renderer_client_.reset(new AtomRendererClient);
|
||||
|
||||
@@ -96,6 +96,7 @@ int NodeMain(int argc, char* argv[]) {
|
||||
}
|
||||
} while (more == true);
|
||||
|
||||
node_debugger.Stop();
|
||||
exit_code = node::EmitExit(env);
|
||||
node::RunAtExit(env);
|
||||
gin_env.platform()->DrainTasks(env->isolate());
|
||||
|
||||
@@ -1413,4 +1413,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_app, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_app, Initialize)
|
||||
|
||||
@@ -154,4 +154,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_auto_updater, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_auto_updater, Initialize)
|
||||
|
||||
@@ -172,4 +172,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_browser_view, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_browser_view, Initialize)
|
||||
|
||||
@@ -68,7 +68,7 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
|
||||
}
|
||||
|
||||
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||
api_web_contents_ = web_contents.get();
|
||||
api_web_contents_ = web_contents->GetWeakPtr();
|
||||
api_web_contents_->AddObserver(this);
|
||||
Observe(api_web_contents_->web_contents());
|
||||
|
||||
@@ -86,8 +86,7 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
|
||||
InitWith(isolate, wrapper);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
if (!window()->has_frame())
|
||||
OverrideNSWindowContentView(web_contents->managed_web_contents());
|
||||
OverrideNSWindowContentView(web_contents->managed_web_contents());
|
||||
#endif
|
||||
|
||||
// Init window after everything has been setup.
|
||||
@@ -95,7 +94,9 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
|
||||
}
|
||||
|
||||
BrowserWindow::~BrowserWindow() {
|
||||
api_web_contents_->RemoveObserver(this);
|
||||
// FIXME This is a hack rather than a proper fix preventing shutdown crashes.
|
||||
if (api_web_contents_)
|
||||
api_web_contents_->RemoveObserver(this);
|
||||
// Note that the OnWindowClosed will not be called after the destructor runs,
|
||||
// since the window object is managed by the TopLevelWindow class.
|
||||
if (web_contents())
|
||||
@@ -481,4 +482,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_window, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_window, Initialize)
|
||||
|
||||
@@ -116,7 +116,7 @@ class BrowserWindow : public TopLevelWindow,
|
||||
#endif
|
||||
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
api::WebContents* api_web_contents_;
|
||||
base::WeakPtr<api::WebContents> api_web_contents_;
|
||||
|
||||
base::WeakPtrFactory<BrowserWindow> weak_factory_;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "content/public/browser/tracing_controller.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
@@ -59,6 +60,11 @@ scoped_refptr<TracingController::TraceDataEndpoint> GetTraceDataEndpoint(
|
||||
const base::FilePath& path,
|
||||
const CompletionCallback& callback) {
|
||||
base::FilePath result_file_path = path;
|
||||
|
||||
// base::CreateTemporaryFile prevents blocking so we need to allow it
|
||||
// for now since offloading this to a different sequence would require
|
||||
// changing the api shape
|
||||
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
||||
if (result_file_path.empty() && !base::CreateTemporaryFile(&result_file_path))
|
||||
LOG(ERROR) << "Creating temporary file failed";
|
||||
|
||||
@@ -134,4 +140,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_content_tracing, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_content_tracing, Initialize)
|
||||
|
||||
@@ -226,13 +226,13 @@ void FlushCookieStoreOnIOThread(
|
||||
void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
std::unique_ptr<base::DictionaryValue> details,
|
||||
util::Promise promise) {
|
||||
std::string url, name, value, domain, path;
|
||||
std::string url_string, name, value, domain, path;
|
||||
bool secure = false;
|
||||
bool http_only = false;
|
||||
double creation_date;
|
||||
double expiration_date;
|
||||
double last_access_date;
|
||||
details->GetString("url", &url);
|
||||
details->GetString("url", &url_string);
|
||||
details->GetString("name", &name);
|
||||
details->GetString("value", &value);
|
||||
details->GetString("domain", &domain);
|
||||
@@ -261,24 +261,27 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
: base::Time::FromDoubleT(last_access_date);
|
||||
}
|
||||
|
||||
auto completion_callback = base::BindOnce(OnSetCookie, std::move(promise));
|
||||
GURL url(url_string);
|
||||
if (!url.is_valid()) {
|
||||
std::move(completion_callback).Run(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (name.empty()) {
|
||||
std::move(completion_callback).Run(false);
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<net::CanonicalCookie> canonical_cookie(
|
||||
net::CanonicalCookie::CreateSanitizedCookie(
|
||||
GURL(url), name, value, domain, path, creation_time, expiration_time,
|
||||
url, name, value, domain, path, creation_time, expiration_time,
|
||||
last_access_time, secure, http_only,
|
||||
net::CookieSameSite::DEFAULT_MODE, net::COOKIE_PRIORITY_DEFAULT));
|
||||
auto completion_callback = base::BindOnce(OnSetCookie, std::move(promise));
|
||||
if (!canonical_cookie || !canonical_cookie->IsCanonical()) {
|
||||
std::move(completion_callback).Run(false);
|
||||
return;
|
||||
}
|
||||
if (url.empty()) {
|
||||
std::move(completion_callback).Run(false);
|
||||
return;
|
||||
}
|
||||
if (name.empty()) {
|
||||
std::move(completion_callback).Run(false);
|
||||
return;
|
||||
}
|
||||
GetCookieStore(getter)->SetCanonicalCookieAsync(
|
||||
std::move(canonical_cookie), secure, http_only,
|
||||
std::move(completion_callback));
|
||||
|
||||
@@ -205,4 +205,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_debugger, Initialize);
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_debugger, Initialize);
|
||||
|
||||
@@ -88,10 +88,6 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
||||
capture_screen_ = capture_screen;
|
||||
|
||||
{
|
||||
// Remove this once
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=795340 is fixed.
|
||||
base::ScopedAllowBaseSyncPrimitivesForTesting
|
||||
scoped_allow_base_sync_primitives;
|
||||
// Initialize the source list.
|
||||
// Apply the new thumbnail size and restart capture.
|
||||
if (capture_window) {
|
||||
@@ -230,4 +226,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_desktop_capturer, Initialize);
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_desktop_capturer, Initialize);
|
||||
|
||||
@@ -96,4 +96,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_dialog, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_dialog, Initialize)
|
||||
|
||||
@@ -251,4 +251,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_download_item, Initialize);
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_download_item, Initialize);
|
||||
|
||||
@@ -23,4 +23,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_event, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_event, Initialize)
|
||||
|
||||
@@ -166,4 +166,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_global_shortcut, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_global_shortcut, Initialize)
|
||||
|
||||
@@ -62,7 +62,7 @@ struct Converter<in_app_purchase::Product> {
|
||||
dict.Set("formattedPrice", val.formattedPrice);
|
||||
|
||||
// Downloadable Content Information
|
||||
dict.Set("isDownloadable", val.downloadable);
|
||||
dict.Set("isDownloadable", val.isDownloadable);
|
||||
|
||||
return dict.GetHandle();
|
||||
}
|
||||
@@ -140,4 +140,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_in_app_purchase, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_in_app_purchase, Initialize)
|
||||
|
||||
@@ -245,4 +245,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_menu, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_menu, Initialize)
|
||||
|
||||
@@ -61,4 +61,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_net, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_net, Initialize)
|
||||
|
||||
@@ -272,4 +272,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_common_notification, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_common_notification, Initialize)
|
||||
|
||||
@@ -148,4 +148,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_power_monitor, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_power_monitor, Initialize)
|
||||
|
||||
@@ -151,4 +151,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_power_save_blocker, Initialize);
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_power_save_blocker, Initialize);
|
||||
|
||||
@@ -317,4 +317,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_protocol, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_protocol, Initialize)
|
||||
|
||||
@@ -87,5 +87,5 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_render_process_preferences,
|
||||
Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_render_process_preferences,
|
||||
Initialize)
|
||||
|
||||
@@ -52,6 +52,19 @@ std::vector<std::string> MetricsToArray(uint32_t metrics) {
|
||||
return array;
|
||||
}
|
||||
|
||||
void DelayEmit(Screen* screen,
|
||||
const base::StringPiece& name,
|
||||
const display::Display& display) {
|
||||
screen->Emit(name, display);
|
||||
}
|
||||
|
||||
void DelayEmitWithMetrics(Screen* screen,
|
||||
const base::StringPiece& name,
|
||||
const display::Display& display,
|
||||
const std::vector<std::string>& metrics) {
|
||||
screen->Emit(name, display, metrics);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Screen::Screen(v8::Isolate* isolate, display::Screen* screen)
|
||||
@@ -101,16 +114,23 @@ static gfx::Rect DIPToScreenRect(atom::NativeWindow* window,
|
||||
#endif
|
||||
|
||||
void Screen::OnDisplayAdded(const display::Display& new_display) {
|
||||
Emit("display-added", new_display);
|
||||
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
|
||||
FROM_HERE, base::Bind(&DelayEmit, base::Unretained(this), "display-added",
|
||||
new_display));
|
||||
}
|
||||
|
||||
void Screen::OnDisplayRemoved(const display::Display& old_display) {
|
||||
Emit("display-removed", old_display);
|
||||
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
|
||||
FROM_HERE, base::Bind(&DelayEmit, base::Unretained(this),
|
||||
"display-removed", old_display));
|
||||
}
|
||||
|
||||
void Screen::OnDisplayMetricsChanged(const display::Display& display,
|
||||
uint32_t changed_metrics) {
|
||||
Emit("display-metrics-changed", display, MetricsToArray(changed_metrics));
|
||||
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
|
||||
FROM_HERE, base::Bind(&DelayEmitWithMetrics, base::Unretained(this),
|
||||
"display-metrics-changed", display,
|
||||
MetricsToArray(changed_metrics)));
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -171,4 +191,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_common_screen, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_common_screen, Initialize)
|
||||
|
||||
@@ -420,6 +420,17 @@ void Session::ResolveProxy(
|
||||
browser_context_->GetResolveProxyHelper()->ResolveProxy(url, callback);
|
||||
}
|
||||
|
||||
void Session::GetCacheSize(const net::CompletionCallback& callback) {
|
||||
content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
|
||||
->GetNetworkContext()
|
||||
->ComputeHttpCacheSize(
|
||||
base::Time(), base::Time::Max(),
|
||||
base::BindOnce(
|
||||
[](const net::CompletionCallback& cb, bool is_upper_bound,
|
||||
int64_t size_or_error) { cb.Run(size_or_error); },
|
||||
callback));
|
||||
}
|
||||
|
||||
template <Session::CacheAction action>
|
||||
void Session::DoCacheAction(const net::CompletionCallback& callback) {
|
||||
base::PostTaskWithTraits(
|
||||
@@ -748,7 +759,7 @@ void Session::BuildPrototype(v8::Isolate* isolate,
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
.SetMethod("resolveProxy", &Session::ResolveProxy)
|
||||
.SetMethod("getCacheSize", &Session::DoCacheAction<CacheAction::STATS>)
|
||||
.SetMethod("getCacheSize", &Session::GetCacheSize)
|
||||
.SetMethod("clearCache", &Session::DoCacheAction<CacheAction::CLEAR>)
|
||||
.SetMethod("clearStorageData", &Session::ClearStorageData)
|
||||
.SetMethod("flushStorageData", &Session::FlushStorageData)
|
||||
@@ -819,4 +830,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_session, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_session, Initialize)
|
||||
|
||||
@@ -66,6 +66,7 @@ class Session : public mate::TrackableObject<Session>,
|
||||
const ResolveProxyHelper::ResolveProxyCallback& callback);
|
||||
template <CacheAction action>
|
||||
void DoCacheAction(const net::CompletionCallback& callback);
|
||||
void GetCacheSize(const net::CompletionCallback& callback);
|
||||
void ClearStorageData(mate::Arguments* args);
|
||||
void FlushStorageData();
|
||||
void SetProxy(const mate::Dictionary& options, const base::Closure& callback);
|
||||
|
||||
@@ -128,4 +128,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_system_preferences, Initialize);
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_system_preferences, Initialize);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "atom/browser/mac/atom_application.h"
|
||||
#include "atom/browser/mac/dict_util.h"
|
||||
#include "atom/browser/ui/cocoa/NSColor+Hex.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "base/mac/sdk_forward_declarations.h"
|
||||
@@ -19,6 +20,7 @@
|
||||
#include "base/values.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/base/mac/url_conversions.h"
|
||||
#include "ui/native_theme/native_theme.h"
|
||||
|
||||
namespace mate {
|
||||
template <>
|
||||
@@ -56,11 +58,11 @@ struct Converter<NSAppearance*> {
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
if (val.name == NSAppearanceNameAqua) {
|
||||
if ([val.name isEqualToString:NSAppearanceNameAqua]) {
|
||||
return mate::ConvertToV8(isolate, "light");
|
||||
}
|
||||
if (@available(macOS 10.14, *)) {
|
||||
if (val.name == NSAppearanceNameDarkAqua) {
|
||||
if ([val.name isEqualToString:NSAppearanceNameDarkAqua]) {
|
||||
return mate::ConvertToV8(isolate, "dark");
|
||||
}
|
||||
}
|
||||
@@ -106,21 +108,6 @@ std::string ConvertAuthorizationStatus(AVAuthorizationStatusMac status) {
|
||||
}
|
||||
}
|
||||
|
||||
// Convert color to RGBA value like "aabbccdd"
|
||||
std::string ToRGBA(NSColor* color) {
|
||||
return base::StringPrintf(
|
||||
"%02X%02X%02X%02X", (int)(color.redComponent * 0xFF),
|
||||
(int)(color.greenComponent * 0xFF), (int)(color.blueComponent * 0xFF),
|
||||
(int)(color.alphaComponent * 0xFF));
|
||||
}
|
||||
|
||||
// Convert color to RGB hex value like "#ABCDEF"
|
||||
std::string ToRGBHex(NSColor* color) {
|
||||
return base::StringPrintf("#%02X%02X%02X", (int)(color.redComponent * 0xFF),
|
||||
(int)(color.greenComponent * 0xFF),
|
||||
(int)(color.blueComponent * 0xFF));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void SystemPreferences::PostNotification(const std::string& name,
|
||||
@@ -400,7 +387,7 @@ std::string SystemPreferences::GetAccentColor() {
|
||||
if (@available(macOS 10.14, *))
|
||||
sysColor = [NSColor controlAccentColor];
|
||||
|
||||
return ToRGBA(sysColor);
|
||||
return base::SysNSStringToUTF8([sysColor RGBAValue]);
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetSystemColor(const std::string& color,
|
||||
@@ -429,7 +416,7 @@ std::string SystemPreferences::GetSystemColor(const std::string& color,
|
||||
return "";
|
||||
}
|
||||
|
||||
return ToRGBHex(sysColor);
|
||||
return base::SysNSStringToUTF8([sysColor hexadecimalValue]);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -519,7 +506,7 @@ std::string SystemPreferences::GetColor(const std::string& color,
|
||||
return "";
|
||||
}
|
||||
|
||||
return ToRGBHex(sysColor);
|
||||
return base::SysNSStringToUTF8([sysColor hexadecimalValue]);
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetMediaAccessStatus(
|
||||
@@ -571,6 +558,9 @@ void SystemPreferences::RemoveUserDefault(const std::string& name) {
|
||||
}
|
||||
|
||||
bool SystemPreferences::IsDarkMode() {
|
||||
if (@available(macOS 10.15, *)) {
|
||||
return ui::NativeTheme::GetInstanceForNativeUi()->SystemDarkModeEnabled();
|
||||
}
|
||||
NSString* mode = [[NSUserDefaults standardUserDefaults]
|
||||
stringForKey:@"AppleInterfaceStyle"];
|
||||
return [mode isEqualToString:@"Dark"];
|
||||
|
||||
@@ -1199,4 +1199,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_top_level_window, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_top_level_window, Initialize)
|
||||
|
||||
@@ -59,11 +59,7 @@ Tray::Tray(v8::Isolate* isolate,
|
||||
InitWith(isolate, wrapper);
|
||||
}
|
||||
|
||||
Tray::~Tray() {
|
||||
// Destroy the native tray in next tick.
|
||||
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
|
||||
tray_icon_.release());
|
||||
}
|
||||
Tray::~Tray() = default;
|
||||
|
||||
// static
|
||||
mate::WrappableBase* Tray::New(mate::Handle<NativeImage> image,
|
||||
@@ -192,7 +188,7 @@ void Tray::DisplayBalloon(mate::Arguments* args,
|
||||
|
||||
#if defined(OS_WIN)
|
||||
tray_icon_->DisplayBalloon(
|
||||
icon.IsEmpty() ? NULL : icon->GetHICON(GetSystemMetrics(SM_CXSMICON)),
|
||||
icon.IsEmpty() ? NULL : icon->GetHICON(GetSystemMetrics(SM_CXICON)),
|
||||
title, content);
|
||||
#else
|
||||
tray_icon_->DisplayBalloon(icon.IsEmpty() ? gfx::Image() : icon->image(),
|
||||
@@ -261,4 +257,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_tray, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_tray, Initialize)
|
||||
|
||||
@@ -86,4 +86,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_view, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_view, Initialize)
|
||||
|
||||
@@ -87,7 +87,6 @@
|
||||
#include "ui/events/base_event_utils.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_OSR)
|
||||
#include "atom/browser/osr/osr_output_device.h"
|
||||
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
||||
#include "atom/browser/osr/osr_web_contents_view.h"
|
||||
#endif
|
||||
@@ -288,7 +287,9 @@ struct WebContents::FrameDispatchHelper {
|
||||
|
||||
WebContents::WebContents(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents)
|
||||
: content::WebContentsObserver(web_contents), type_(REMOTE) {
|
||||
: content::WebContentsObserver(web_contents),
|
||||
type_(REMOTE),
|
||||
weak_factory_(this) {
|
||||
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent(),
|
||||
false);
|
||||
Init(isolate);
|
||||
@@ -299,7 +300,9 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
WebContents::WebContents(v8::Isolate* isolate,
|
||||
std::unique_ptr<content::WebContents> web_contents,
|
||||
Type type)
|
||||
: content::WebContentsObserver(web_contents.get()), type_(type) {
|
||||
: content::WebContentsObserver(web_contents.get()),
|
||||
type_(type),
|
||||
weak_factory_(this) {
|
||||
DCHECK(type != REMOTE) << "Can't take ownership of a remote WebContents";
|
||||
auto session = Session::CreateFrom(isolate, GetBrowserContext());
|
||||
session_.Reset(isolate, session.ToV8());
|
||||
@@ -307,8 +310,8 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
mate::Dictionary::CreateEmpty(isolate));
|
||||
}
|
||||
|
||||
WebContents::WebContents(v8::Isolate* isolate,
|
||||
const mate::Dictionary& options) {
|
||||
WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
|
||||
: weak_factory_(this) {
|
||||
// Read options.
|
||||
options.Get("backgroundThrottling", &background_throttling_);
|
||||
|
||||
@@ -598,7 +601,7 @@ void WebContents::SetContentsBounds(content::WebContents* source,
|
||||
|
||||
void WebContents::CloseContents(content::WebContents* source) {
|
||||
Emit("close");
|
||||
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
HideAutofillPopup();
|
||||
#endif
|
||||
if (managed_web_contents())
|
||||
@@ -838,6 +841,10 @@ void WebContents::DidChangeThemeColor(SkColor theme_color) {
|
||||
}
|
||||
}
|
||||
|
||||
void WebContents::DidAcquireFullscreen(content::RenderFrameHost* rfh) {
|
||||
set_fullscreen_frame(rfh);
|
||||
}
|
||||
|
||||
void WebContents::DocumentLoadedInFrame(
|
||||
content::RenderFrameHost* render_frame_host) {
|
||||
if (!render_frame_host->GetParent())
|
||||
@@ -1026,7 +1033,7 @@ void WebContents::DevToolsClosed() {
|
||||
Emit("devtools-closed");
|
||||
}
|
||||
|
||||
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
void WebContents::ShowAutofillPopup(content::RenderFrameHost* frame_host,
|
||||
const gfx::RectF& bounds,
|
||||
const std::vector<base::string16>& values,
|
||||
@@ -1073,7 +1080,7 @@ bool WebContents::OnMessageReceived(const IPC::Message& message,
|
||||
FrameDispatchHelper::OnSetTemporaryZoomLevel)
|
||||
IPC_MESSAGE_FORWARD_DELAY_REPLY(AtomFrameHostMsg_GetZoomLevel, &helper,
|
||||
FrameDispatchHelper::OnGetZoomLevel)
|
||||
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_ShowPopup, ShowAutofillPopup)
|
||||
IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_HidePopup, HideAutofillPopup)
|
||||
#endif
|
||||
@@ -1214,6 +1221,9 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
|
||||
params.transition_type = ui::PAGE_TRANSITION_TYPED;
|
||||
params.should_clear_history_list = true;
|
||||
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
|
||||
// Discord non-committed entries to ensure that we don't re-use a pending
|
||||
// entry
|
||||
web_contents()->GetController().DiscardNonCommittedEntries();
|
||||
web_contents()->GetController().LoadURLWithParams(params);
|
||||
|
||||
// Set the background color of RenderWidgetHostView.
|
||||
@@ -1670,13 +1680,24 @@ bool WebContents::SendIPCMessageWithSender(bool internal,
|
||||
const std::string& channel,
|
||||
const base::ListValue& args,
|
||||
int32_t sender_id) {
|
||||
auto* frame_host = web_contents()->GetMainFrame();
|
||||
if (frame_host) {
|
||||
return frame_host->Send(new AtomFrameMsg_Message(frame_host->GetRoutingID(),
|
||||
internal, send_to_all,
|
||||
channel, args, sender_id));
|
||||
std::vector<content::RenderFrameHost*> target_hosts;
|
||||
if (!send_to_all) {
|
||||
auto* frame_host = web_contents()->GetMainFrame();
|
||||
if (frame_host) {
|
||||
target_hosts.push_back(frame_host);
|
||||
}
|
||||
} else {
|
||||
target_hosts = web_contents()->GetAllFrames();
|
||||
}
|
||||
return false;
|
||||
|
||||
bool handled = false;
|
||||
for (auto* frame_host : target_hosts) {
|
||||
handled = frame_host->Send(
|
||||
new AtomFrameMsg_Message(frame_host->GetRoutingID(), internal,
|
||||
false, channel, args, sender_id)) ||
|
||||
handled;
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
bool WebContents::SendIPCMessageToFrame(bool internal,
|
||||
@@ -1735,6 +1756,19 @@ void WebContents::SendInputEvent(v8::Isolate* isolate,
|
||||
mouse_wheel_event);
|
||||
#endif
|
||||
} else {
|
||||
// Chromium expects phase info in wheel events (and applies a
|
||||
// DCHECK to verify it). See: https://crbug.com/756524.
|
||||
mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
|
||||
mouse_wheel_event.dispatch_type = blink::WebInputEvent::kBlocking;
|
||||
rwh->ForwardWheelEvent(mouse_wheel_event);
|
||||
|
||||
// Send a synthetic wheel event with phaseEnded to finish scrolling.
|
||||
mouse_wheel_event.has_synthetic_phase = true;
|
||||
mouse_wheel_event.delta_x = 0;
|
||||
mouse_wheel_event.delta_y = 0;
|
||||
mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
|
||||
mouse_wheel_event.dispatch_type =
|
||||
blink::WebInputEvent::kEventNonBlocking;
|
||||
rwh->ForwardWheelEvent(mouse_wheel_event);
|
||||
}
|
||||
return;
|
||||
@@ -1756,7 +1790,7 @@ void WebContents::BeginFrameSubscription(mate::Arguments* args) {
|
||||
}
|
||||
|
||||
frame_subscriber_.reset(
|
||||
new FrameSubscriber(isolate(), web_contents(), callback, only_dirty));
|
||||
new FrameSubscriber(web_contents(), callback, only_dirty));
|
||||
}
|
||||
|
||||
void WebContents::EndFrameSubscription() {
|
||||
@@ -2296,4 +2330,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_web_contents, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_web_contents, Initialize)
|
||||
|
||||
@@ -111,6 +111,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
base::WeakPtr<WebContents> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
|
||||
|
||||
// Destroy the managed content::WebContents instance.
|
||||
//
|
||||
// Note: The |async| should only be |true| when users are expecting to use the
|
||||
@@ -448,6 +450,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
const MediaPlayerId& id,
|
||||
content::WebContentsObserver::MediaStoppedReason reason) override;
|
||||
void DidChangeThemeColor(SkColor theme_color) override;
|
||||
void DidAcquireFullscreen(content::RenderFrameHost* rfh) override;
|
||||
|
||||
// InspectableWebContentsDelegate:
|
||||
void DevToolsReloadPage() override;
|
||||
@@ -544,6 +547,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
// -1 means no speculative RVH has been committed yet.
|
||||
int currently_committed_process_id_ = -1;
|
||||
|
||||
base::WeakPtrFactory<WebContents> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContents);
|
||||
};
|
||||
|
||||
|
||||
@@ -131,4 +131,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_web_contents_view, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_web_contents_view, Initialize)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "atom/browser/api/atom_api_web_request.h"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
@@ -20,23 +21,6 @@
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<URLPattern> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
URLPattern* out) {
|
||||
std::string pattern;
|
||||
if (!ConvertFromV8(isolate, val, &pattern))
|
||||
return false;
|
||||
*out = URLPattern(URLPattern::SCHEME_ALL);
|
||||
return out->Parse(pattern) == URLPattern::ParseResult::kSuccess;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -84,7 +68,25 @@ void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) {
|
||||
// { urls }.
|
||||
URLPatterns patterns;
|
||||
mate::Dictionary dict;
|
||||
args->GetNext(&dict) && dict.Get("urls", &patterns);
|
||||
std::set<std::string> filter_patterns;
|
||||
|
||||
if (args->GetNext(&dict) && !dict.Get("urls", &filter_patterns)) {
|
||||
args->ThrowError(
|
||||
"onBeforeRequest parameter 'filter' must have property 'urls'.");
|
||||
return;
|
||||
}
|
||||
|
||||
URLPattern pattern(URLPattern::SCHEME_ALL);
|
||||
for (const std::string& filter_pattern : filter_patterns) {
|
||||
const URLPattern::ParseResult result = pattern.Parse(filter_pattern);
|
||||
if (result == URLPattern::ParseResult::kSuccess) {
|
||||
patterns.insert(pattern);
|
||||
} else {
|
||||
const char* error_type = URLPattern::GetParseResultString(result);
|
||||
args->ThrowError("Invalid url pattern " + filter_pattern + ": " +
|
||||
error_type);
|
||||
}
|
||||
}
|
||||
|
||||
// Function or null.
|
||||
v8::Local<v8::Value> value;
|
||||
|
||||
@@ -55,4 +55,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_web_view_manager, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_web_view_manager, Initialize)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/render_widget_host.h"
|
||||
#include "content/public/browser/render_widget_host_view.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
#include "ui/gfx/skbitmap_operations.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
@@ -20,12 +21,10 @@ namespace api {
|
||||
|
||||
constexpr static int kMaxFrameRate = 30;
|
||||
|
||||
FrameSubscriber::FrameSubscriber(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents,
|
||||
FrameSubscriber::FrameSubscriber(content::WebContents* web_contents,
|
||||
const FrameCaptureCallback& callback,
|
||||
bool only_dirty)
|
||||
: content::WebContentsObserver(web_contents),
|
||||
isolate_(isolate),
|
||||
callback_(callback),
|
||||
only_dirty_(only_dirty),
|
||||
weak_ptr_factory_(this) {
|
||||
@@ -149,26 +148,23 @@ void FrameSubscriber::Done(const gfx::Rect& damage, const SkBitmap& frame) {
|
||||
if (frame.drawsNothing())
|
||||
return;
|
||||
|
||||
v8::Locker locker(isolate_);
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
|
||||
const_cast<SkBitmap&>(frame).setAlphaType(kPremul_SkAlphaType);
|
||||
const SkBitmap& bitmap = only_dirty_ ? SkBitmapOperations::CreateTiledBitmap(
|
||||
frame, damage.x(), damage.y(),
|
||||
damage.width(), damage.height())
|
||||
: frame;
|
||||
|
||||
size_t rgb_row_size = bitmap.width() * bitmap.bytesPerPixel();
|
||||
auto* source = static_cast<const char*>(bitmap.getPixels());
|
||||
// Copying SkBitmap does not copy the internal pixels, we have to manually
|
||||
// allocate and write pixels otherwise crash may happen when the original
|
||||
// frame is modified.
|
||||
SkBitmap copy;
|
||||
copy.allocPixels(SkImageInfo::Make(bitmap.width(), bitmap.height(),
|
||||
kRGBA_8888_SkColorType,
|
||||
kPremul_SkAlphaType));
|
||||
SkPixmap pixmap;
|
||||
bool success = bitmap.peekPixels(&pixmap) && copy.writePixels(pixmap, 0, 0);
|
||||
CHECK(success);
|
||||
|
||||
v8::MaybeLocal<v8::Object> buffer =
|
||||
node::Buffer::Copy(isolate_, source, rgb_row_size * bitmap.height());
|
||||
auto local_buffer = buffer.ToLocalChecked();
|
||||
|
||||
v8::Local<v8::Value> damage_rect =
|
||||
mate::Converter<gfx::Rect>::ToV8(isolate_, damage);
|
||||
|
||||
callback_.Run(local_buffer, damage_rect);
|
||||
callback_.Run(gfx::Image::CreateFrom1xBitmap(copy), damage);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace gfx {
|
||||
class Image;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -24,10 +28,9 @@ class FrameSubscriber : public content::WebContentsObserver,
|
||||
public viz::mojom::FrameSinkVideoConsumer {
|
||||
public:
|
||||
using FrameCaptureCallback =
|
||||
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>;
|
||||
base::Callback<void(const gfx::Image&, const gfx::Rect&)>;
|
||||
|
||||
FrameSubscriber(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents,
|
||||
FrameSubscriber(content::WebContents* web_contents,
|
||||
const FrameCaptureCallback& callback,
|
||||
bool only_dirty);
|
||||
~FrameSubscriber() override;
|
||||
@@ -52,7 +55,6 @@ class FrameSubscriber : public content::WebContentsObserver,
|
||||
|
||||
void Done(const gfx::Rect& damage, const SkBitmap& frame);
|
||||
|
||||
v8::Isolate* isolate_;
|
||||
FrameCaptureCallback callback_;
|
||||
bool only_dirty_;
|
||||
|
||||
|
||||
@@ -84,4 +84,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_box_layout, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_box_layout, Initialize)
|
||||
|
||||
@@ -57,4 +57,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_button, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_button, Initialize)
|
||||
|
||||
@@ -77,4 +77,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_label_button, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_label_button, Initialize)
|
||||
|
||||
@@ -60,4 +60,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_layout_manager, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_layout_manager, Initialize)
|
||||
|
||||
@@ -54,4 +54,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_md_text_button, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_md_text_button, Initialize)
|
||||
|
||||
@@ -57,4 +57,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_resize_area, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_resize_area, Initialize)
|
||||
|
||||
@@ -64,4 +64,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_text_field, Initialize)
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_text_field, Initialize)
|
||||
|
||||
@@ -611,11 +611,6 @@ bool AtomBrowserClient::CanCreateWindow(
|
||||
|
||||
int opener_render_process_id = opener->GetProcess()->GetID();
|
||||
|
||||
if (IsRendererSandboxed(opener_render_process_id)) {
|
||||
*no_javascript_access = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (RendererUsesNativeWindowOpen(opener_render_process_id)) {
|
||||
if (RendererDisablesPopups(opener_render_process_id)) {
|
||||
// <webview> without allowpopups attribute should return
|
||||
|
||||
@@ -481,6 +481,7 @@ void AtomBrowserMainParts::PostMainMessageLoopRun() {
|
||||
ui::SetX11ErrorHandlers(X11EmptyErrorHandler, X11EmptyIOErrorHandler);
|
||||
#endif
|
||||
|
||||
node_debugger_->Stop();
|
||||
js_env_->OnMessageLoopDestroying();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
|
||||
@@ -54,8 +54,26 @@ void AtomBrowserMainParts::InitializeMainNib() {
|
||||
auto application = [principalClass sharedApplication];
|
||||
|
||||
NSString* mainNibName = [infoDictionary objectForKey:@"NSMainNibFile"];
|
||||
auto mainNib = [[NSNib alloc] initWithNibNamed:mainNibName
|
||||
bundle:base::mac::FrameworkBundle()];
|
||||
|
||||
NSNib* mainNib;
|
||||
|
||||
@try {
|
||||
mainNib = [[NSNib alloc] initWithNibNamed:mainNibName
|
||||
bundle:base::mac::FrameworkBundle()];
|
||||
// Handle failure of initWithNibNamed on SMB shares
|
||||
// TODO(codebytere): Remove when
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=932935 is fixed
|
||||
} @catch (NSException* exception) {
|
||||
NSString* nibPath =
|
||||
[NSString stringWithFormat:@"Resources/%@.nib", mainNibName];
|
||||
nibPath = [base::mac::FrameworkBundle().bundlePath
|
||||
stringByAppendingPathComponent:nibPath];
|
||||
|
||||
NSData* data = [NSData dataWithContentsOfFile:nibPath];
|
||||
mainNib = [[NSNib alloc] initWithNibData:data
|
||||
bundle:base::mac::FrameworkBundle()];
|
||||
}
|
||||
|
||||
[mainNib instantiateWithOwner:application topLevelObjects:nil];
|
||||
[mainNib release];
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
|
||||
settings.parent_window = window;
|
||||
if (settings.title.size() == 0)
|
||||
settings.title = item->GetURL().spec();
|
||||
if (!settings.default_path.empty())
|
||||
if (settings.default_path.empty())
|
||||
settings.default_path = default_path;
|
||||
|
||||
auto* web_preferences = WebContentsPreferences::From(web_contents);
|
||||
|
||||
@@ -61,9 +61,16 @@ void AtomJavaScriptDialogManager::RunJavaScriptDialog(
|
||||
return;
|
||||
}
|
||||
|
||||
// No default button
|
||||
int default_id = -1;
|
||||
int cancel_id = 0;
|
||||
|
||||
std::vector<std::string> buttons = {"OK"};
|
||||
if (dialog_type == JavaScriptDialogType::JAVASCRIPT_DIALOG_TYPE_CONFIRM) {
|
||||
buttons.push_back("Cancel");
|
||||
// First button is default, second button is cancel
|
||||
default_id = 0;
|
||||
cancel_id = 1;
|
||||
}
|
||||
|
||||
origin_counts_[origin]++;
|
||||
@@ -85,8 +92,8 @@ void AtomJavaScriptDialogManager::RunJavaScriptDialog(
|
||||
}
|
||||
|
||||
atom::ShowMessageBox(
|
||||
window, atom::MessageBoxType::MESSAGE_BOX_TYPE_NONE, buttons, -1, 0,
|
||||
atom::MessageBoxOptions::MESSAGE_BOX_NONE, "",
|
||||
window, atom::MessageBoxType::MESSAGE_BOX_TYPE_NONE, buttons, default_id,
|
||||
cancel_id, atom::MessageBoxOptions::MESSAGE_BOX_NONE, "",
|
||||
base::UTF16ToUTF8(message_text), "", checkbox, false, gfx::ImageSkia(),
|
||||
base::Bind(&AtomJavaScriptDialogManager::OnMessageBoxCallback,
|
||||
base::Unretained(this), base::Passed(std::move(callback)),
|
||||
|
||||
@@ -183,12 +183,14 @@ int AtomPermissionManager::RequestPermissionsWithDetails(
|
||||
const auto callback =
|
||||
base::Bind(&AtomPermissionManager::OnPermissionResponse,
|
||||
base::Unretained(this), request_id, i);
|
||||
if (details == nullptr) {
|
||||
request_handler_.Run(web_contents, permission, callback,
|
||||
base::DictionaryValue());
|
||||
} else {
|
||||
request_handler_.Run(web_contents, permission, callback, *details);
|
||||
}
|
||||
auto mutable_details =
|
||||
details == nullptr ? base::DictionaryValue() : details->Clone();
|
||||
mutable_details.SetKey(
|
||||
"requestingUrl",
|
||||
base::Value(render_frame_host->GetLastCommittedURL().spec()));
|
||||
mutable_details.SetKey(
|
||||
"isMainFrame", base::Value(render_frame_host->GetParent() == nullptr));
|
||||
request_handler_.Run(web_contents, permission, callback, mutable_details);
|
||||
}
|
||||
|
||||
return request_id;
|
||||
@@ -241,8 +243,15 @@ bool AtomPermissionManager::CheckPermissionWithDetails(
|
||||
}
|
||||
auto* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(render_frame_host);
|
||||
auto mutable_details =
|
||||
details == nullptr ? base::DictionaryValue() : details->Clone();
|
||||
mutable_details.SetKey(
|
||||
"requestingUrl",
|
||||
base::Value(render_frame_host->GetLastCommittedURL().spec()));
|
||||
mutable_details.SetKey(
|
||||
"isMainFrame", base::Value(render_frame_host->GetParent() == nullptr));
|
||||
return check_handler_.Run(web_contents, permission, requesting_origin,
|
||||
*details);
|
||||
mutable_details);
|
||||
}
|
||||
|
||||
blink::mojom::PermissionStatus
|
||||
|
||||
@@ -31,11 +31,11 @@ class AtomPermissionManager : public content::PermissionControllerDelegate {
|
||||
using RequestHandler = base::Callback<void(content::WebContents*,
|
||||
content::PermissionType,
|
||||
const StatusCallback&,
|
||||
const base::DictionaryValue&)>;
|
||||
const base::Value&)>;
|
||||
using CheckHandler = base::Callback<bool(content::WebContents*,
|
||||
content::PermissionType,
|
||||
const GURL& requesting_origin,
|
||||
const base::DictionaryValue&)>;
|
||||
const base::Value&)>;
|
||||
|
||||
// Handler to dispatch permission requests in JS.
|
||||
void SetPermissionRequestHandler(const RequestHandler& handler);
|
||||
|
||||
@@ -145,7 +145,8 @@ bool Browser::IsUnityRunning() {
|
||||
void Browser::ShowAboutPanel() {
|
||||
std::string app_name, version, copyright, icon_path, website;
|
||||
|
||||
GtkAboutDialog* dialog = GTK_ABOUT_DIALOG(gtk_about_dialog_new());
|
||||
GtkWidget* dialogWidget = gtk_about_dialog_new();
|
||||
GtkAboutDialog* dialog = GTK_ABOUT_DIALOG(dialogWidget);
|
||||
|
||||
if (about_panel_options_.GetString("applicationName", &app_name))
|
||||
gtk_about_dialog_set_program_name(dialog, app_name.c_str());
|
||||
@@ -157,7 +158,12 @@ void Browser::ShowAboutPanel() {
|
||||
gtk_about_dialog_set_website(dialog, website.c_str());
|
||||
if (about_panel_options_.GetString("iconPath", &icon_path)) {
|
||||
GError* error = nullptr;
|
||||
GdkPixbuf* icon = gdk_pixbuf_new_from_file(icon_path.c_str(), &error);
|
||||
constexpr int width = 64; // width of about panel icon in pixels
|
||||
constexpr int height = 64; // height of about panel icon in pixels
|
||||
|
||||
// set preserve_aspect_ratio to true
|
||||
GdkPixbuf* icon = gdk_pixbuf_new_from_file_at_size(icon_path.c_str(), width,
|
||||
height, &error);
|
||||
if (error != nullptr) {
|
||||
g_warning("%s", error->message);
|
||||
g_clear_error(&error);
|
||||
@@ -168,7 +174,7 @@ void Browser::ShowAboutPanel() {
|
||||
}
|
||||
|
||||
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
g_clear_object(&dialog);
|
||||
gtk_widget_destroy(dialogWidget);
|
||||
}
|
||||
|
||||
void Browser::SetAboutPanelOptions(const base::DictionaryValue& options) {
|
||||
|
||||
@@ -95,9 +95,6 @@ void Browser::Focus() {
|
||||
}
|
||||
|
||||
void Browser::AddRecentDocument(const base::FilePath& path) {
|
||||
if (base::win::GetVersion() < base::win::VERSION_WIN7)
|
||||
return;
|
||||
|
||||
CComPtr<IShellItem> item;
|
||||
HRESULT hr = SHCreateItemFromParsingName(path.value().c_str(), NULL,
|
||||
IID_PPV_ARGS(&item));
|
||||
@@ -110,13 +107,7 @@ void Browser::AddRecentDocument(const base::FilePath& path) {
|
||||
}
|
||||
|
||||
void Browser::ClearRecentDocuments() {
|
||||
CComPtr<IApplicationDestinations> destinations;
|
||||
if (FAILED(destinations.CoCreateInstance(CLSID_ApplicationDestinations, NULL,
|
||||
CLSCTX_INPROC_SERVER)))
|
||||
return;
|
||||
if (FAILED(destinations->SetAppID(GetAppUserModelID())))
|
||||
return;
|
||||
destinations->RemoveAllDestinations();
|
||||
SHAddToRecentDocs(SHARD_APPIDINFO, nullptr);
|
||||
}
|
||||
|
||||
void Browser::SetAppUserModelID(const base::string16& name) {
|
||||
|
||||
@@ -208,7 +208,7 @@ void CommonWebContentsDelegate::SetOwnerWindow(
|
||||
NativeWindow* owner_window) {
|
||||
if (owner_window) {
|
||||
owner_window_ = owner_window->GetWeakPtr();
|
||||
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
autofill_popup_.reset(new AutofillPopup());
|
||||
#endif
|
||||
NativeWindowRelay::CreateForWebContents(web_contents,
|
||||
@@ -322,9 +322,12 @@ void CommonWebContentsDelegate::EnterFullscreenModeForTab(
|
||||
const blink::WebFullscreenOptions& options) {
|
||||
if (!owner_window_)
|
||||
return;
|
||||
if (IsFullscreenForTabOrPending(source)) {
|
||||
DCHECK_EQ(fullscreen_frame_, source->GetFocusedFrame());
|
||||
return;
|
||||
}
|
||||
SetHtmlApiFullscreen(true);
|
||||
owner_window_->NotifyWindowEnterHtmlFullScreen();
|
||||
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::ExitFullscreenModeForTab(
|
||||
@@ -333,7 +336,6 @@ void CommonWebContentsDelegate::ExitFullscreenModeForTab(
|
||||
return;
|
||||
SetHtmlApiFullscreen(false);
|
||||
owner_window_->NotifyWindowLeaveHtmlFullScreen();
|
||||
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
|
||||
}
|
||||
|
||||
bool CommonWebContentsDelegate::IsFullscreenForTabOrPending(
|
||||
@@ -621,4 +623,24 @@ void CommonWebContentsDelegate::SetHtmlApiFullscreen(bool enter_fullscreen) {
|
||||
native_fullscreen_ = false;
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::ShowAutofillPopup(
|
||||
content::RenderFrameHost* frame_host,
|
||||
content::RenderFrameHost* embedder_frame_host,
|
||||
bool offscreen,
|
||||
const gfx::RectF& bounds,
|
||||
const std::vector<base::string16>& values,
|
||||
const std::vector<base::string16>& labels) {
|
||||
if (!owner_window())
|
||||
return;
|
||||
|
||||
autofill_popup_->CreateView(frame_host, embedder_frame_host, offscreen,
|
||||
owner_window()->content_view(), bounds);
|
||||
autofill_popup_->SetItems(values, labels);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::HideAutofillPopup() {
|
||||
if (autofill_popup_)
|
||||
autofill_popup_->Hide();
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "content/public/browser/web_contents_delegate.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
|
||||
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
#include "atom/browser/ui/autofill_popup.h"
|
||||
#endif
|
||||
|
||||
@@ -68,6 +68,10 @@ class CommonWebContentsDelegate : public content::WebContentsDelegate,
|
||||
|
||||
bool is_html_fullscreen() const { return html_fullscreen_; }
|
||||
|
||||
void set_fullscreen_frame(content::RenderFrameHost* rfh) {
|
||||
fullscreen_frame_ = rfh;
|
||||
}
|
||||
|
||||
protected:
|
||||
#if BUILDFLAG(ENABLE_OSR)
|
||||
virtual OffScreenWebContentsView* GetOffScreenWebContentsView() const;
|
||||
@@ -105,7 +109,7 @@ class CommonWebContentsDelegate : public content::WebContentsDelegate,
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
|
||||
// Autofill related events.
|
||||
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
void ShowAutofillPopup(content::RenderFrameHost* frame_host,
|
||||
content::RenderFrameHost* embedder_frame_host,
|
||||
bool offscreen,
|
||||
@@ -175,7 +179,7 @@ class CommonWebContentsDelegate : public content::WebContentsDelegate,
|
||||
bool native_fullscreen_ = false;
|
||||
|
||||
// UI related helper classes.
|
||||
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
std::unique_ptr<AutofillPopup> autofill_popup_;
|
||||
#endif
|
||||
std::unique_ptr<WebDialogHelper> web_dialog_helper_;
|
||||
@@ -203,6 +207,9 @@ class CommonWebContentsDelegate : public content::WebContentsDelegate,
|
||||
|
||||
scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
|
||||
|
||||
// Stores the frame thats currently in fullscreen, nullptr if there is none.
|
||||
content::RenderFrameHost* fullscreen_frame_ = nullptr;
|
||||
|
||||
base::WeakPtrFactory<CommonWebContentsDelegate> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CommonWebContentsDelegate);
|
||||
|
||||
@@ -41,27 +41,6 @@ bool CommonWebContentsDelegate::HandleKeyboardEvent(
|
||||
return false;
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::ShowAutofillPopup(
|
||||
content::RenderFrameHost* frame_host,
|
||||
content::RenderFrameHost* embedder_frame_host,
|
||||
bool offscreen,
|
||||
const gfx::RectF& bounds,
|
||||
const std::vector<base::string16>& values,
|
||||
const std::vector<base::string16>& labels) {
|
||||
if (!owner_window())
|
||||
return;
|
||||
|
||||
auto* window = static_cast<NativeWindowViews*>(owner_window());
|
||||
autofill_popup_->CreateView(frame_host, embedder_frame_host, offscreen,
|
||||
window->content_view(), bounds);
|
||||
autofill_popup_->SetItems(values, labels);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::HideAutofillPopup() {
|
||||
if (autofill_popup_)
|
||||
autofill_popup_->Hide();
|
||||
}
|
||||
|
||||
gfx::ImageSkia CommonWebContentsDelegate::GetDevToolsWindowIcon() {
|
||||
if (!owner_window())
|
||||
return gfx::ImageSkia();
|
||||
|
||||
@@ -74,6 +74,7 @@ void JavascriptEnvironment::OnMessageLoopCreated() {
|
||||
void JavascriptEnvironment::OnMessageLoopDestroying() {
|
||||
DCHECK(microtasks_runner_);
|
||||
base::MessageLoopCurrent::Get()->RemoveTaskObserver(microtasks_runner_.get());
|
||||
platform_->DrainTasks(isolate_);
|
||||
platform_->UnregisterIsolate(isolate_);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ struct Product {
|
||||
std::string formattedPrice;
|
||||
|
||||
// Downloadable Content Information
|
||||
bool downloadable = false;
|
||||
bool isDownloadable = false;
|
||||
|
||||
Product(const Product&);
|
||||
Product();
|
||||
|
||||
@@ -141,15 +141,13 @@
|
||||
|
||||
if (product.priceLocale != nil) {
|
||||
productStruct.formattedPrice =
|
||||
[[self formatPrice:product.price withLocal:product.priceLocale]
|
||||
UTF8String];
|
||||
[[self formatPrice:product.price
|
||||
withLocal:product.priceLocale] UTF8String];
|
||||
}
|
||||
}
|
||||
|
||||
// Downloadable Content Information
|
||||
if (product.downloadable == true) {
|
||||
productStruct.downloadable = true;
|
||||
}
|
||||
productStruct.isDownloadable = [product downloadable];
|
||||
|
||||
return productStruct;
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ class NativeWindowMac : public NativeWindow {
|
||||
|
||||
private:
|
||||
// Add custom layers to the content view.
|
||||
void AddContentViewLayers();
|
||||
void AddContentViewLayers(bool minimizable, bool closable);
|
||||
|
||||
void InternalSetParentWindow(NativeWindow* parent, bool attach);
|
||||
void SetForwardMouseMessages(bool forward);
|
||||
|
||||
@@ -73,9 +73,11 @@
|
||||
NSButton* close_button =
|
||||
[NSWindow standardWindowButton:NSWindowCloseButton
|
||||
forStyleMask:NSWindowStyleMaskTitled];
|
||||
[close_button setTag:1];
|
||||
NSButton* miniaturize_button =
|
||||
[NSWindow standardWindowButton:NSWindowMiniaturizeButton
|
||||
forStyleMask:NSWindowStyleMaskTitled];
|
||||
[miniaturize_button setTag:2];
|
||||
|
||||
CGFloat x = 0;
|
||||
const CGFloat space_between = 20;
|
||||
@@ -233,7 +235,10 @@ namespace atom {
|
||||
namespace {
|
||||
|
||||
bool IsFramelessWindow(NSView* view) {
|
||||
NativeWindow* window = [static_cast<AtomNSWindow*>([view window]) shell];
|
||||
NSWindow* nswindow = [view window];
|
||||
if (![nswindow respondsToSelector:@selector(shell)])
|
||||
return false;
|
||||
NativeWindow* window = [static_cast<AtomNSWindow*>(nswindow) shell];
|
||||
return window && !window->has_frame();
|
||||
}
|
||||
|
||||
@@ -456,7 +461,7 @@ NativeWindowMac::NativeWindowMac(const mate::Dictionary& options,
|
||||
|
||||
// Default content view.
|
||||
SetContentView(new views::View());
|
||||
AddContentViewLayers();
|
||||
AddContentViewLayers(minimizable, closable);
|
||||
|
||||
original_frame_ = [window_ frame];
|
||||
original_level_ = [window_ level];
|
||||
@@ -820,6 +825,7 @@ void NativeWindowMac::SetAlwaysOnTop(bool top,
|
||||
int relativeLevel,
|
||||
std::string* error) {
|
||||
int windowLevel = NSNormalWindowLevel;
|
||||
bool level_changed = top != widget()->IsAlwaysOnTop();
|
||||
CGWindowLevel maxWindowLevel = CGWindowLevelForKey(kCGMaximumWindowLevelKey);
|
||||
CGWindowLevel minWindowLevel = CGWindowLevelForKey(kCGMinimumWindowLevelKey);
|
||||
|
||||
@@ -846,12 +852,22 @@ void NativeWindowMac::SetAlwaysOnTop(bool top,
|
||||
|
||||
NSInteger newLevel = windowLevel + relativeLevel;
|
||||
if (newLevel >= minWindowLevel && newLevel <= maxWindowLevel) {
|
||||
was_maximizable_ = IsMaximizable();
|
||||
[window_ setLevel:newLevel];
|
||||
// Set level will make the zoom button revert to default, probably
|
||||
// a bug of Cocoa or macOS.
|
||||
[[window_ standardWindowButton:NSWindowZoomButton]
|
||||
setEnabled:was_maximizable_];
|
||||
} else {
|
||||
*error = std::string([
|
||||
[NSString stringWithFormat:@"relativeLevel must be between %d and %d",
|
||||
minWindowLevel, maxWindowLevel] UTF8String]);
|
||||
*error = std::string([[NSString
|
||||
stringWithFormat:@"relativeLevel must be between %d and %d",
|
||||
minWindowLevel, maxWindowLevel] UTF8String]);
|
||||
}
|
||||
|
||||
// This must be notified at the very end or IsAlwaysOnTop
|
||||
// will not yet have been updated to reflect the new status
|
||||
if (level_changed)
|
||||
NativeWindow::NotifyWindowAlwaysOnTopChanged();
|
||||
}
|
||||
|
||||
bool NativeWindowMac::IsAlwaysOnTop() {
|
||||
@@ -1089,7 +1105,7 @@ void NativeWindowMac::RemoveBrowserView(NativeBrowserView* view) {
|
||||
}
|
||||
|
||||
[view->GetInspectableWebContentsView()->GetNativeView().GetNativeNSView()
|
||||
removeFromSuperview];
|
||||
removeFromSuperview];
|
||||
remove_browser_view(view);
|
||||
|
||||
[CATransaction commit];
|
||||
@@ -1371,7 +1387,7 @@ views::View* NativeWindowMac::GetContentsView() {
|
||||
return root_view_.get();
|
||||
}
|
||||
|
||||
void NativeWindowMac::AddContentViewLayers() {
|
||||
void NativeWindowMac::AddContentViewLayers(bool minimizable, bool closable) {
|
||||
// Make sure the bottom corner is rounded for non-modal windows:
|
||||
// http://crbug.com/396264.
|
||||
if (!is_modal()) {
|
||||
@@ -1411,6 +1427,12 @@ void NativeWindowMac::AddContentViewLayers() {
|
||||
[[CustomWindowButtonView alloc] initWithFrame:NSZeroRect]);
|
||||
// NSWindowStyleMaskFullSizeContentView does not work with zoom button
|
||||
SetFullScreenable(false);
|
||||
|
||||
if (!minimizable)
|
||||
[[buttons_view_ viewWithTag:2] removeFromSuperview];
|
||||
if (!closable)
|
||||
[[buttons_view_ viewWithTag:1] removeFromSuperview];
|
||||
|
||||
[[window_ contentView] addSubview:buttons_view_];
|
||||
} else {
|
||||
if (title_bar_style_ != NORMAL)
|
||||
@@ -1467,7 +1489,7 @@ void NativeWindowMac::OverrideNSWindowContentView() {
|
||||
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||
[container_view_ setFrame:[[[window_ contentView] superview] bounds]];
|
||||
[window_ setContentView:container_view_];
|
||||
AddContentViewLayers();
|
||||
AddContentViewLayers(IsMinimizable(), IsClosable());
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetStyleMask(bool on, NSUInteger flag) {
|
||||
|
||||
@@ -358,6 +358,9 @@ void NativeWindowViews::Show() {
|
||||
|
||||
widget()->native_widget_private()->Show(GetRestoredState(), gfx::Rect());
|
||||
|
||||
// explicitly focus the window
|
||||
widget()->Activate();
|
||||
|
||||
NotifyWindowShow();
|
||||
|
||||
#if defined(USE_X11)
|
||||
@@ -734,10 +737,14 @@ void NativeWindowViews::SetAlwaysOnTop(bool top,
|
||||
const std::string& level,
|
||||
int relativeLevel,
|
||||
std::string* error) {
|
||||
if (top != widget()->IsAlwaysOnTop())
|
||||
NativeWindow::NotifyWindowAlwaysOnTopChanged();
|
||||
bool level_changed = top != widget()->IsAlwaysOnTop();
|
||||
|
||||
widget()->SetAlwaysOnTop(top);
|
||||
|
||||
// This must be notified at the very end or IsAlwaysOnTop
|
||||
// will not yet have been updated to reflect the new status
|
||||
if (level_changed)
|
||||
NativeWindow::NotifyWindowAlwaysOnTopChanged();
|
||||
}
|
||||
|
||||
bool NativeWindowViews::IsAlwaysOnTop() {
|
||||
|
||||
@@ -51,6 +51,8 @@ network::mojom::HttpAuthDynamicParamsPtr CreateHttpAuthDynamicParams() {
|
||||
command_line->GetSwitchValueASCII(atom::switches::kAuthServerWhitelist);
|
||||
auth_dynamic_params->delegate_whitelist = command_line->GetSwitchValueASCII(
|
||||
atom::switches::kAuthNegotiateDelegateWhitelist);
|
||||
auth_dynamic_params->enable_negotiate_port =
|
||||
command_line->HasSwitch(atom::switches::kEnableAuthNegotiatePort);
|
||||
|
||||
return auth_dynamic_params;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,21 @@ void BeforeStartInUI(base::WeakPtr<URLRequestAsyncAsarJob> job,
|
||||
error = net::ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// sanitize custom headers
|
||||
if (request_options && request_options->is_dict()) {
|
||||
const base::Value* headersDict = request_options->FindKeyOfType(
|
||||
"headers", base::Value::Type::DICTIONARY);
|
||||
if (headersDict) {
|
||||
for (const auto& iter : headersDict->DictItems()) {
|
||||
if (!iter.second.is_string()) {
|
||||
args->ThrowError("Value of '" + iter.first +
|
||||
"' header has to be a string");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::IO},
|
||||
base::BindOnce(&URLRequestAsyncAsarJob::StartAsync, job,
|
||||
|
||||
@@ -38,13 +38,13 @@ void NodeDebugger::Start() {
|
||||
}
|
||||
|
||||
node::DebugOptions options;
|
||||
node::options_parser::DebugOptionsParser options_parser;
|
||||
std::vector<std::string> exec_args;
|
||||
std::vector<std::string> v8_args;
|
||||
std::vector<std::string> errors;
|
||||
|
||||
node::options_parser::DebugOptionsParser::instance.Parse(
|
||||
&args, &exec_args, &v8_args, &options,
|
||||
node::options_parser::kDisallowedInEnvironment, &errors);
|
||||
options_parser.Parse(&args, &exec_args, &v8_args, &options,
|
||||
node::options_parser::kDisallowedInEnvironment, &errors);
|
||||
|
||||
if (!errors.empty()) {
|
||||
// TODO(jeremy): what's the appropriate behaviour here?
|
||||
@@ -52,13 +52,6 @@ void NodeDebugger::Start() {
|
||||
<< base::JoinString(errors, " ");
|
||||
}
|
||||
|
||||
// Set process._debugWaitConnect if --inspect-brk was specified to stop
|
||||
// the debugger on the first line
|
||||
if (options.wait_for_connect()) {
|
||||
mate::Dictionary process(env_->isolate(), env_->process_object());
|
||||
process.Set("_breakFirstLine", true);
|
||||
}
|
||||
|
||||
const char* path = "";
|
||||
if (inspector->Start(path, options,
|
||||
std::make_shared<node::HostPort>(options.host_port),
|
||||
@@ -66,4 +59,10 @@ void NodeDebugger::Start() {
|
||||
DCHECK(env_->inspector_agent()->IsListening());
|
||||
}
|
||||
|
||||
void NodeDebugger::Stop() {
|
||||
auto* inspector = env_->inspector_agent();
|
||||
if (inspector && inspector->IsListening())
|
||||
inspector->Stop();
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -20,6 +20,7 @@ class NodeDebugger {
|
||||
~NodeDebugger();
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
node::Environment* env_;
|
||||
|
||||
@@ -109,6 +109,8 @@ void CocoaNotification::Dismiss() {
|
||||
NotificationDismissed();
|
||||
|
||||
this->LogAction("dismissed");
|
||||
|
||||
notification_.reset(nil);
|
||||
}
|
||||
|
||||
void CocoaNotification::NotificationDisplayed() {
|
||||
|
||||
@@ -269,10 +269,16 @@ LRESULT DesktopNotificationController::Toast::WndProc(HWND hwnd,
|
||||
case WM_MOUSEACTIVATE:
|
||||
return MA_NOACTIVATE;
|
||||
|
||||
case WM_TIMER:
|
||||
case WM_TIMER: {
|
||||
if (wparam == TimerID_AutoDismiss) {
|
||||
Get(hwnd)->AutoDismiss();
|
||||
auto* inst = Get(hwnd);
|
||||
|
||||
Notification notification(inst->data_);
|
||||
inst->data_->controller->OnNotificationDismissed(notification);
|
||||
|
||||
inst->AutoDismiss();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_LBUTTONDOWN: {
|
||||
|
||||
@@ -47,8 +47,12 @@ void Win32Notification::Show(const NotificationOptions& options) {
|
||||
|
||||
if (existing) {
|
||||
existing->tag_.clear();
|
||||
|
||||
this->notification_ref_ = std::move(existing->notification_ref_);
|
||||
this->notification_ref_.Set(options.title, options.msg, image);
|
||||
// Need to remove the entry in the notifications set that
|
||||
// NotificationPresenter is holding
|
||||
existing->Destroy();
|
||||
} else {
|
||||
this->notification_ref_ =
|
||||
presenter->AddNotification(options.title, options.msg, image);
|
||||
|
||||
121
atom/browser/osr/osr_host_display_client.cc
Normal file
121
atom/browser/osr/osr_host_display_client.cc
Normal file
@@ -0,0 +1,121 @@
|
||||
// Copyright (c) 2019 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/osr/osr_host_display_client.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "components/viz/common/resources/resource_format.h"
|
||||
#include "components/viz/common/resources/resource_sizes.h"
|
||||
#include "mojo/public/cpp/system/platform_handle.h"
|
||||
#include "skia/ext/platform_canvas.h"
|
||||
#include "third_party/skia/include/core/SkColor.h"
|
||||
#include "third_party/skia/include/core/SkRect.h"
|
||||
#include "third_party/skia/src/core/SkDevice.h"
|
||||
#include "ui/gfx/skia_util.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "skia/ext/skia_utils_win.h"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
LayeredWindowUpdater::LayeredWindowUpdater(
|
||||
viz::mojom::LayeredWindowUpdaterRequest request,
|
||||
OnPaintCallback callback)
|
||||
: callback_(callback), binding_(this, std::move(request)) {}
|
||||
|
||||
LayeredWindowUpdater::~LayeredWindowUpdater() = default;
|
||||
|
||||
void LayeredWindowUpdater::SetActive(bool active) {
|
||||
active_ = active;
|
||||
}
|
||||
|
||||
void LayeredWindowUpdater::OnAllocatedSharedMemory(
|
||||
const gfx::Size& pixel_size,
|
||||
mojo::ScopedSharedBufferHandle scoped_buffer_handle) {
|
||||
canvas_.reset();
|
||||
|
||||
// Make sure |pixel_size| is sane.
|
||||
size_t expected_bytes;
|
||||
bool size_result = viz::ResourceSizes::MaybeSizeInBytes(
|
||||
pixel_size, viz::ResourceFormat::RGBA_8888, &expected_bytes);
|
||||
if (!size_result)
|
||||
return;
|
||||
|
||||
#if defined(WIN32)
|
||||
base::SharedMemoryHandle shm_handle;
|
||||
size_t required_bytes;
|
||||
MojoResult unwrap_result = mojo::UnwrapSharedMemoryHandle(
|
||||
std::move(scoped_buffer_handle), &shm_handle, &required_bytes, nullptr);
|
||||
if (unwrap_result != MOJO_RESULT_OK)
|
||||
return;
|
||||
|
||||
base::SharedMemory shm(shm_handle, false);
|
||||
if (!shm.Map(required_bytes)) {
|
||||
DLOG(ERROR) << "Failed to map " << required_bytes << " bytes";
|
||||
return;
|
||||
}
|
||||
|
||||
canvas_ = skia::CreatePlatformCanvasWithSharedSection(
|
||||
pixel_size.width(), pixel_size.height(), false, shm.handle().GetHandle(),
|
||||
skia::CRASH_ON_FAILURE);
|
||||
#else
|
||||
auto shm =
|
||||
mojo::UnwrapWritableSharedMemoryRegion(std::move(scoped_buffer_handle));
|
||||
if (!shm.IsValid()) {
|
||||
DLOG(ERROR) << "Failed to unwrap shared memory region";
|
||||
return;
|
||||
}
|
||||
|
||||
shm_mapping_ = shm.Map();
|
||||
if (!shm_mapping_.IsValid()) {
|
||||
DLOG(ERROR) << "Failed to map shared memory region";
|
||||
return;
|
||||
}
|
||||
|
||||
canvas_ = skia::CreatePlatformCanvasWithPixels(
|
||||
pixel_size.width(), pixel_size.height(), false,
|
||||
static_cast<uint8_t*>(shm_mapping_.memory()), skia::CRASH_ON_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void LayeredWindowUpdater::Draw(const gfx::Rect& damage_rect,
|
||||
DrawCallback draw_callback) {
|
||||
SkPixmap pixmap;
|
||||
SkBitmap bitmap;
|
||||
|
||||
if (active_ && canvas_->peekPixels(&pixmap)) {
|
||||
bitmap.installPixels(pixmap);
|
||||
callback_.Run(damage_rect, bitmap);
|
||||
}
|
||||
|
||||
std::move(draw_callback).Run();
|
||||
}
|
||||
|
||||
OffScreenHostDisplayClient::OffScreenHostDisplayClient(
|
||||
gfx::AcceleratedWidget widget,
|
||||
OnPaintCallback callback)
|
||||
: viz::HostDisplayClient(widget), callback_(callback) {}
|
||||
OffScreenHostDisplayClient::~OffScreenHostDisplayClient() {}
|
||||
|
||||
void OffScreenHostDisplayClient::SetActive(bool active) {
|
||||
active_ = active;
|
||||
if (layered_window_updater_) {
|
||||
layered_window_updater_->SetActive(active_);
|
||||
}
|
||||
}
|
||||
|
||||
void OffScreenHostDisplayClient::IsOffscreen(IsOffscreenCallback callback) {
|
||||
std::move(callback).Run(true);
|
||||
}
|
||||
|
||||
void OffScreenHostDisplayClient::CreateLayeredWindowUpdater(
|
||||
viz::mojom::LayeredWindowUpdaterRequest request) {
|
||||
layered_window_updater_ =
|
||||
std::make_unique<LayeredWindowUpdater>(std::move(request), callback_);
|
||||
layered_window_updater_->SetActive(active_);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
77
atom/browser/osr/osr_host_display_client.h
Normal file
77
atom/browser/osr/osr_host_display_client.h
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright (c) 2019 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_OSR_OSR_HOST_DISPLAY_CLIENT_H_
|
||||
#define ATOM_BROWSER_OSR_OSR_HOST_DISPLAY_CLIENT_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/memory/shared_memory.h"
|
||||
#include "components/viz/host/host_display_client.h"
|
||||
#include "services/viz/privileged/interfaces/compositing/layered_window_updater.mojom.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "third_party/skia/include/core/SkCanvas.h"
|
||||
#include "ui/gfx/native_widget_types.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
typedef base::Callback<void(const gfx::Rect&, const SkBitmap&)> OnPaintCallback;
|
||||
|
||||
class LayeredWindowUpdater : public viz::mojom::LayeredWindowUpdater {
|
||||
public:
|
||||
explicit LayeredWindowUpdater(viz::mojom::LayeredWindowUpdaterRequest request,
|
||||
OnPaintCallback callback);
|
||||
~LayeredWindowUpdater() override;
|
||||
|
||||
void SetActive(bool active);
|
||||
|
||||
// viz::mojom::LayeredWindowUpdater implementation.
|
||||
void OnAllocatedSharedMemory(
|
||||
const gfx::Size& pixel_size,
|
||||
mojo::ScopedSharedBufferHandle scoped_buffer_handle) override;
|
||||
void Draw(const gfx::Rect& damage_rect, DrawCallback draw_callback) override;
|
||||
|
||||
private:
|
||||
OnPaintCallback callback_;
|
||||
mojo::Binding<viz::mojom::LayeredWindowUpdater> binding_;
|
||||
std::unique_ptr<SkCanvas> canvas_;
|
||||
bool active_ = false;
|
||||
|
||||
#if !defined(WIN32)
|
||||
base::WritableSharedMemoryMapping shm_mapping_;
|
||||
#endif
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(LayeredWindowUpdater);
|
||||
};
|
||||
|
||||
class OffScreenHostDisplayClient : public viz::HostDisplayClient {
|
||||
public:
|
||||
explicit OffScreenHostDisplayClient(gfx::AcceleratedWidget widget,
|
||||
OnPaintCallback callback);
|
||||
~OffScreenHostDisplayClient() override;
|
||||
|
||||
void SetActive(bool active);
|
||||
|
||||
private:
|
||||
void IsOffscreen(IsOffscreenCallback callback) override;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void OnDisplayReceivedCALayerParams(
|
||||
const gfx::CALayerParams& ca_layer_params) override;
|
||||
#endif
|
||||
|
||||
void CreateLayeredWindowUpdater(
|
||||
viz::mojom::LayeredWindowUpdaterRequest request) override;
|
||||
|
||||
std::unique_ptr<LayeredWindowUpdater> layered_window_updater_;
|
||||
OnPaintCallback callback_;
|
||||
bool active_ = false;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(OffScreenHostDisplayClient);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_OSR_OSR_HOST_DISPLAY_CLIENT_H_
|
||||
35
atom/browser/osr/osr_host_display_client_mac.mm
Normal file
35
atom/browser/osr/osr_host_display_client_mac.mm
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2019 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/osr/osr_host_display_client.h"
|
||||
|
||||
#include <IOSurface/IOSurface.h>
|
||||
|
||||
namespace atom {
|
||||
|
||||
void OffScreenHostDisplayClient::OnDisplayReceivedCALayerParams(
|
||||
const gfx::CALayerParams& ca_layer_params) {
|
||||
if (!ca_layer_params.is_empty) {
|
||||
base::ScopedCFTypeRef<IOSurfaceRef> io_surface(
|
||||
IOSurfaceLookupFromMachPort(ca_layer_params.io_surface_mach_port));
|
||||
|
||||
gfx::Size pixel_size_ = ca_layer_params.pixel_size;
|
||||
void* pixels = static_cast<void*>(IOSurfaceGetBaseAddress(io_surface));
|
||||
size_t stride = IOSurfaceGetBytesPerRow(io_surface);
|
||||
|
||||
struct IOSurfacePinner {
|
||||
base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
|
||||
};
|
||||
|
||||
SkBitmap bitmap;
|
||||
bitmap.installPixels(
|
||||
SkImageInfo::MakeN32(pixel_size_.width(), pixel_size_.height(),
|
||||
kPremul_SkAlphaType),
|
||||
pixels, stride);
|
||||
bitmap.setImmutable();
|
||||
callback_.Run(ca_layer_params.damage, bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
@@ -1,101 +0,0 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/osr/osr_output_device.h"
|
||||
|
||||
#include "third_party/skia/include/core/SkColor.h"
|
||||
#include "third_party/skia/include/core/SkRect.h"
|
||||
#include "third_party/skia/src/core/SkDevice.h"
|
||||
#include "ui/gfx/skia_util.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
OffScreenOutputDevice::OffScreenOutputDevice(bool transparent,
|
||||
const OnPaintCallback& callback)
|
||||
: transparent_(transparent), callback_(callback) {
|
||||
DCHECK(!callback_.is_null());
|
||||
}
|
||||
|
||||
OffScreenOutputDevice::~OffScreenOutputDevice() {}
|
||||
|
||||
void OffScreenOutputDevice::Resize(const gfx::Size& pixel_size,
|
||||
float scale_factor) {
|
||||
if (viewport_pixel_size_ == pixel_size)
|
||||
return;
|
||||
viewport_pixel_size_ = pixel_size;
|
||||
|
||||
canvas_.reset();
|
||||
bitmap_.reset(new SkBitmap);
|
||||
bitmap_->allocN32Pixels(viewport_pixel_size_.width(),
|
||||
viewport_pixel_size_.height(), !transparent_);
|
||||
if (bitmap_->drawsNothing()) {
|
||||
NOTREACHED();
|
||||
bitmap_.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (transparent_) {
|
||||
bitmap_->eraseColor(SK_ColorTRANSPARENT);
|
||||
} else {
|
||||
bitmap_->eraseColor(SK_ColorWHITE);
|
||||
}
|
||||
|
||||
canvas_.reset(new SkCanvas(*bitmap_));
|
||||
}
|
||||
|
||||
SkCanvas* OffScreenOutputDevice::BeginPaint(const gfx::Rect& damage_rect) {
|
||||
DCHECK(canvas_.get());
|
||||
DCHECK(bitmap_.get());
|
||||
|
||||
damage_rect_ = damage_rect;
|
||||
SkIRect damage =
|
||||
SkIRect::MakeXYWH(damage_rect_.x(), damage_rect_.y(),
|
||||
damage_rect_.width(), damage_rect_.height());
|
||||
|
||||
if (transparent_) {
|
||||
bitmap_->erase(SK_ColorTRANSPARENT, damage);
|
||||
} else {
|
||||
bitmap_->erase(SK_ColorWHITE, damage);
|
||||
}
|
||||
|
||||
return canvas_.get();
|
||||
}
|
||||
|
||||
void OffScreenOutputDevice::EndPaint() {
|
||||
DCHECK(canvas_.get());
|
||||
DCHECK(bitmap_.get());
|
||||
|
||||
if (!bitmap_.get())
|
||||
return;
|
||||
|
||||
viz::SoftwareOutputDevice::EndPaint();
|
||||
|
||||
if (active_)
|
||||
OnPaint(damage_rect_);
|
||||
}
|
||||
|
||||
void OffScreenOutputDevice::SetActive(bool active, bool paint) {
|
||||
if (active == active_)
|
||||
return;
|
||||
active_ = active;
|
||||
|
||||
if (!active_ && !pending_damage_rect_.IsEmpty() && paint)
|
||||
OnPaint(gfx::Rect(viewport_pixel_size_));
|
||||
}
|
||||
|
||||
void OffScreenOutputDevice::OnPaint(const gfx::Rect& damage_rect) {
|
||||
gfx::Rect rect = damage_rect;
|
||||
if (!pending_damage_rect_.IsEmpty()) {
|
||||
rect.Union(pending_damage_rect_);
|
||||
pending_damage_rect_.SetRect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
rect.Intersect(gfx::Rect(viewport_pixel_size_));
|
||||
if (rect.IsEmpty())
|
||||
return;
|
||||
|
||||
callback_.Run(rect, *bitmap_);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
@@ -1,47 +0,0 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_OSR_OSR_OUTPUT_DEVICE_H_
|
||||
#define ATOM_BROWSER_OSR_OSR_OUTPUT_DEVICE_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "components/viz/service/display/software_output_device.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "third_party/skia/include/core/SkCanvas.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
typedef base::Callback<void(const gfx::Rect&, const SkBitmap&)> OnPaintCallback;
|
||||
|
||||
class OffScreenOutputDevice : public viz::SoftwareOutputDevice {
|
||||
public:
|
||||
OffScreenOutputDevice(bool transparent, const OnPaintCallback& callback);
|
||||
~OffScreenOutputDevice() override;
|
||||
|
||||
// viz::SoftwareOutputDevice:
|
||||
void Resize(const gfx::Size& pixel_size, float scale_factor) override;
|
||||
SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override;
|
||||
void EndPaint() override;
|
||||
|
||||
void SetActive(bool active, bool paint);
|
||||
void OnPaint(const gfx::Rect& damage_rect);
|
||||
|
||||
private:
|
||||
const bool transparent_;
|
||||
OnPaintCallback callback_;
|
||||
|
||||
bool active_ = false;
|
||||
|
||||
std::unique_ptr<SkCanvas> canvas_;
|
||||
std::unique_ptr<SkBitmap> bitmap_;
|
||||
gfx::Rect pending_damage_rect_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(OffScreenOutputDevice);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_OSR_OSR_OUTPUT_DEVICE_H_
|
||||
@@ -20,14 +20,15 @@
|
||||
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
|
||||
#include "components/viz/common/gl_helper.h"
|
||||
#include "components/viz/common/quads/render_pass.h"
|
||||
#include "content/browser/renderer_host/cursor_manager.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_delegate.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_owner_delegate.h"
|
||||
#include "content/browser/renderer_host/cursor_manager.h" // nogncheck
|
||||
#include "content/browser/renderer_host/input/synthetic_gesture_target.h" // nogncheck
|
||||
#include "content/browser/renderer_host/render_widget_host_delegate.h" // nogncheck
|
||||
#include "content/browser/renderer_host/render_widget_host_owner_delegate.h" // nogncheck
|
||||
#include "content/common/view_messages.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/context_factory.h"
|
||||
#include "content/public/browser/gpu_data_manager.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "media/base/video_frame.h"
|
||||
#include "third_party/blink/public/platform/web_input_event.h"
|
||||
@@ -50,7 +51,6 @@ namespace atom {
|
||||
namespace {
|
||||
|
||||
const float kDefaultScaleFactor = 1.0;
|
||||
const int kFrameRetryLimit = 2;
|
||||
|
||||
ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
|
||||
ui::EventType type = ui::EventType::ET_UNKNOWN;
|
||||
@@ -120,105 +120,6 @@ ui::MouseWheelEvent UiMouseWheelEventFromWebMouseEvent(
|
||||
|
||||
} // namespace
|
||||
|
||||
class AtomCopyFrameGenerator {
|
||||
public:
|
||||
AtomCopyFrameGenerator(OffScreenRenderWidgetHostView* view,
|
||||
int frame_rate_threshold_us)
|
||||
: view_(view),
|
||||
frame_duration_(
|
||||
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us)),
|
||||
weak_ptr_factory_(this) {
|
||||
last_time_ = base::Time::Now();
|
||||
}
|
||||
|
||||
void GenerateCopyFrame(const gfx::Rect& damage_rect) {
|
||||
if (!view_->render_widget_host() || !view_->IsPainting())
|
||||
return;
|
||||
|
||||
auto request = std::make_unique<viz::CopyOutputRequest>(
|
||||
viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
|
||||
base::BindOnce(
|
||||
&AtomCopyFrameGenerator::CopyFromCompositingSurfaceHasResult,
|
||||
weak_ptr_factory_.GetWeakPtr(), damage_rect));
|
||||
|
||||
request->set_area(gfx::Rect(view_->GetCompositorViewportPixelSize()));
|
||||
view_->GetRootLayer()->RequestCopyOfOutput(std::move(request));
|
||||
}
|
||||
|
||||
void set_frame_rate_threshold_us(int frame_rate_threshold_us) {
|
||||
frame_duration_ =
|
||||
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us);
|
||||
}
|
||||
|
||||
private:
|
||||
void CopyFromCompositingSurfaceHasResult(
|
||||
const gfx::Rect& damage_rect,
|
||||
std::unique_ptr<viz::CopyOutputResult> result) {
|
||||
if (result->IsEmpty() || result->size().IsEmpty() ||
|
||||
!view_->render_widget_host()) {
|
||||
OnCopyFrameCaptureFailure(damage_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK(!result->IsEmpty());
|
||||
auto source = std::make_unique<SkBitmap>(result->AsSkBitmap());
|
||||
DCHECK(source->readyToDraw());
|
||||
if (source) {
|
||||
base::AutoLock autolock(lock_);
|
||||
std::shared_ptr<SkBitmap> bitmap(source.release());
|
||||
|
||||
base::TimeTicks now = base::TimeTicks::Now();
|
||||
base::TimeDelta next_frame_in = next_frame_time_ - now;
|
||||
if (next_frame_in > frame_duration_ / 4) {
|
||||
next_frame_time_ += frame_duration_;
|
||||
base::PostDelayedTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(&AtomCopyFrameGenerator::OnCopyFrameCaptureSuccess,
|
||||
weak_ptr_factory_.GetWeakPtr(), damage_rect, bitmap),
|
||||
next_frame_in);
|
||||
} else {
|
||||
next_frame_time_ = now + frame_duration_;
|
||||
OnCopyFrameCaptureSuccess(damage_rect, bitmap);
|
||||
}
|
||||
|
||||
frame_retry_count_ = 0;
|
||||
} else {
|
||||
OnCopyFrameCaptureFailure(damage_rect);
|
||||
}
|
||||
}
|
||||
|
||||
void OnCopyFrameCaptureFailure(const gfx::Rect& damage_rect) {
|
||||
const bool force_frame = (++frame_retry_count_ <= kFrameRetryLimit);
|
||||
if (force_frame) {
|
||||
// Retry with the same |damage_rect|.
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(&AtomCopyFrameGenerator::GenerateCopyFrame,
|
||||
weak_ptr_factory_.GetWeakPtr(), damage_rect));
|
||||
}
|
||||
}
|
||||
|
||||
void OnCopyFrameCaptureSuccess(const gfx::Rect& damage_rect,
|
||||
const std::shared_ptr<SkBitmap>& bitmap) {
|
||||
base::AutoLock lock(onPaintLock_);
|
||||
view_->OnPaint(damage_rect, *bitmap);
|
||||
}
|
||||
|
||||
base::Lock lock_;
|
||||
base::Lock onPaintLock_;
|
||||
OffScreenRenderWidgetHostView* view_;
|
||||
|
||||
base::Time last_time_;
|
||||
|
||||
int frame_retry_count_ = 0;
|
||||
base::TimeTicks next_frame_time_ = base::TimeTicks::Now();
|
||||
base::TimeDelta frame_duration_;
|
||||
|
||||
base::WeakPtrFactory<AtomCopyFrameGenerator> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomCopyFrameGenerator);
|
||||
};
|
||||
|
||||
class AtomBeginFrameTimer : public viz::DelayBasedTimeSourceClient {
|
||||
public:
|
||||
AtomBeginFrameTimer(int frame_rate_threshold_us,
|
||||
@@ -253,7 +154,6 @@ class AtomBeginFrameTimer : public viz::DelayBasedTimeSourceClient {
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBeginFrameTimer);
|
||||
};
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
class AtomDelegatedFrameHostClient : public content::DelegatedFrameHostClient {
|
||||
public:
|
||||
explicit AtomDelegatedFrameHostClient(OffScreenRenderWidgetHostView* view)
|
||||
@@ -297,7 +197,6 @@ class AtomDelegatedFrameHostClient : public content::DelegatedFrameHostClient {
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomDelegatedFrameHostClient);
|
||||
};
|
||||
#endif // !defined(OS_MACOSX)
|
||||
|
||||
OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
bool transparent,
|
||||
@@ -315,19 +214,23 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
frame_rate_(frame_rate),
|
||||
size_(initial_size),
|
||||
painting_(painting),
|
||||
is_showing_(!render_widget_host_->is_hidden()),
|
||||
is_showing_(false),
|
||||
cursor_manager_(new content::CursorManager(this)),
|
||||
mouse_wheel_phase_handler_(this),
|
||||
backing_(new SkBitmap),
|
||||
weak_ptr_factory_(this) {
|
||||
DCHECK(render_widget_host_);
|
||||
bool is_guest_view_hack = parent_host_view_ != nullptr;
|
||||
|
||||
current_device_scale_factor_ = kDefaultScaleFactor;
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
local_surface_id_allocator_.GenerateId();
|
||||
local_surface_id_allocation_ =
|
||||
local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
|
||||
delegated_frame_host_allocator_.GenerateId();
|
||||
delegated_frame_host_allocation_ =
|
||||
delegated_frame_host_allocator_.GetCurrentLocalSurfaceIdAllocation();
|
||||
compositor_allocator_.GenerateId();
|
||||
compositor_allocation_ =
|
||||
compositor_allocator_.GetCurrentLocalSurfaceIdAllocation();
|
||||
|
||||
delegated_frame_host_client_.reset(new AtomDelegatedFrameHostClient(this));
|
||||
delegated_frame_host_ = std::make_unique<content::DelegatedFrameHost>(
|
||||
AllocateFrameSinkId(is_guest_view_hack),
|
||||
@@ -335,59 +238,49 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
true /* should_register_frame_sink_id */);
|
||||
|
||||
root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
last_frame_root_background_color_ = SK_ColorTRANSPARENT;
|
||||
CreatePlatformWidget(is_guest_view_hack);
|
||||
#endif
|
||||
|
||||
bool opaque = SkColorGetA(background_color_) == SK_AlphaOPAQUE;
|
||||
GetRootLayer()->SetFillsBoundsOpaquely(opaque);
|
||||
GetRootLayer()->SetColor(background_color_);
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
// On macOS the ui::Compositor is created/owned by the platform view.
|
||||
content::ImageTransportFactory* factory =
|
||||
content::ImageTransportFactory::GetInstance();
|
||||
|
||||
ui::ContextFactoryPrivate* context_factory_private =
|
||||
factory->GetContextFactoryPrivate();
|
||||
compositor_.reset(new ui::Compositor(
|
||||
context_factory_private->AllocateFrameSinkId(),
|
||||
content::GetContextFactory(), context_factory_private,
|
||||
base::ThreadTaskRunnerHandle::Get(), false /* enable_pixel_canvas */));
|
||||
compositor_.reset(
|
||||
new ui::Compositor(context_factory_private->AllocateFrameSinkId(),
|
||||
content::GetContextFactory(), context_factory_private,
|
||||
base::ThreadTaskRunnerHandle::Get(),
|
||||
false /* enable_pixel_canvas */, this));
|
||||
compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
|
||||
compositor_->SetRootLayer(root_layer_.get());
|
||||
#endif
|
||||
|
||||
GetCompositor()->SetDelegate(this);
|
||||
|
||||
ResizeRootLayer(false);
|
||||
render_widget_host_->SetView(this);
|
||||
InstallTransparency();
|
||||
|
||||
if (content::GpuDataManager::GetInstance()->HardwareAccelerationEnabled()) {
|
||||
video_consumer_.reset(new OffScreenVideoConsumer(
|
||||
this, base::Bind(&OffScreenRenderWidgetHostView::OnPaint,
|
||||
weak_ptr_factory_.GetWeakPtr())));
|
||||
video_consumer_->SetActive(IsPainting());
|
||||
video_consumer_->SetFrameRate(GetFrameRate());
|
||||
}
|
||||
}
|
||||
|
||||
OffScreenRenderWidgetHostView::~OffScreenRenderWidgetHostView() {
|
||||
#if defined(OS_MACOSX)
|
||||
if (is_showing_)
|
||||
browser_compositor_->SetRenderWidgetHostIsHidden(true);
|
||||
#else
|
||||
// Marking the DelegatedFrameHost as removed from the window hierarchy is
|
||||
// necessary to remove all connections to its old ui::Compositor.
|
||||
if (is_showing_)
|
||||
delegated_frame_host_->WasHidden();
|
||||
delegated_frame_host_->DetachFromCompositor();
|
||||
#endif
|
||||
|
||||
if (copy_frame_generator_.get())
|
||||
copy_frame_generator_.reset(NULL);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
DestroyPlatformWidget();
|
||||
#else
|
||||
delegated_frame_host_.reset(NULL);
|
||||
compositor_.reset(NULL);
|
||||
root_layer_.reset(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
content::BrowserAccessibilityManager*
|
||||
@@ -422,8 +315,17 @@ void OffScreenRenderWidgetHostView::SendBeginFrame(
|
||||
DCHECK(begin_frame_args.IsValid());
|
||||
begin_frame_number_++;
|
||||
|
||||
if (renderer_compositor_frame_sink_)
|
||||
renderer_compositor_frame_sink_->OnBeginFrame(begin_frame_args, {});
|
||||
compositor_->context_factory_private()->IssueExternalBeginFrame(
|
||||
compositor_.get(), begin_frame_args);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnDisplayDidFinishFrame(
|
||||
const viz::BeginFrameAck& ack) {}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnNeedsExternalBeginFrames(
|
||||
bool needs_begin_frames) {
|
||||
SetupFrameRate(true);
|
||||
begin_frame_timer_->SetActive(needs_begin_frames);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) {
|
||||
@@ -437,7 +339,7 @@ void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) {
|
||||
parent_host_view_->Hide();
|
||||
|
||||
ResizeRootLayer(false);
|
||||
Show();
|
||||
SetPainting(parent_host_view_->IsPainting());
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetSize(const gfx::Size& size) {
|
||||
@@ -478,14 +380,10 @@ void OffScreenRenderWidgetHostView::Show() {
|
||||
|
||||
is_showing_ = true;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
browser_compositor_->SetRenderWidgetHostIsHidden(false);
|
||||
#else
|
||||
delegated_frame_host_->AttachToCompositor(compositor_.get());
|
||||
delegated_frame_host_->WasShown(
|
||||
GetLocalSurfaceIdAllocation().local_surface_id(),
|
||||
GetRootLayer()->bounds().size(), false);
|
||||
#endif
|
||||
|
||||
if (render_widget_host_)
|
||||
render_widget_host_->WasShown(false);
|
||||
@@ -498,12 +396,8 @@ void OffScreenRenderWidgetHostView::Hide() {
|
||||
if (render_widget_host_)
|
||||
render_widget_host_->WasHidden();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
browser_compositor_->SetRenderWidgetHostIsHidden(true);
|
||||
#else
|
||||
GetDelegatedFrameHost()->WasHidden();
|
||||
GetDelegatedFrameHost()->DetachFromCompositor();
|
||||
#endif
|
||||
|
||||
is_showing_ = false;
|
||||
}
|
||||
@@ -576,67 +470,17 @@ void OffScreenRenderWidgetHostView::DidCreateNewRendererCompositorFrameSink(
|
||||
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink) {
|
||||
renderer_compositor_frame_sink_ = renderer_compositor_frame_sink;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
browser_compositor_->DidCreateNewRendererCompositorFrameSink(
|
||||
renderer_compositor_frame_sink_);
|
||||
#else
|
||||
if (GetDelegatedFrameHost()) {
|
||||
GetDelegatedFrameHost()->DidCreateNewRendererCompositorFrameSink(
|
||||
renderer_compositor_frame_sink_);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SubmitCompositorFrame(
|
||||
const viz::LocalSurfaceId& local_surface_id,
|
||||
viz::CompositorFrame frame,
|
||||
base::Optional<viz::HitTestRegionList> hit_test_region_list) {
|
||||
#if defined(OS_MACOSX)
|
||||
last_frame_root_background_color_ = frame.metadata.root_background_color;
|
||||
#endif
|
||||
|
||||
if (frame.metadata.root_scroll_offset != last_scroll_offset_) {
|
||||
last_scroll_offset_ = frame.metadata.root_scroll_offset;
|
||||
}
|
||||
|
||||
if (!frame.render_pass_list.empty()) {
|
||||
if (software_output_device_) {
|
||||
if (!begin_frame_timer_.get() || IsPopupWidget()) {
|
||||
software_output_device_->SetActive(painting_, false);
|
||||
}
|
||||
|
||||
// The compositor will draw directly to the SoftwareOutputDevice which
|
||||
// then calls OnPaint.
|
||||
// We would normally call BrowserCompositorMac::SubmitCompositorFrame on
|
||||
// macOS, however it contains compositor resize logic that we don't want.
|
||||
// Consequently we instead call the SubmitCompositorFrame method directly.
|
||||
GetDelegatedFrameHost()->SubmitCompositorFrame(
|
||||
local_surface_id, std::move(frame), std::move(hit_test_region_list));
|
||||
} else {
|
||||
if (!copy_frame_generator_.get()) {
|
||||
copy_frame_generator_.reset(
|
||||
new AtomCopyFrameGenerator(this, frame_rate_threshold_us_));
|
||||
}
|
||||
|
||||
// Determine the damage rectangle for the current frame. This is the same
|
||||
// calculation that SwapDelegatedFrame uses.
|
||||
viz::RenderPass* root_pass = frame.render_pass_list.back().get();
|
||||
gfx::Size frame_size = root_pass->output_rect.size();
|
||||
gfx::Rect damage_rect =
|
||||
gfx::ToEnclosingRect(gfx::RectF(root_pass->damage_rect));
|
||||
damage_rect.Intersect(gfx::Rect(frame_size));
|
||||
|
||||
// We would normally call BrowserCompositorMac::SubmitCompositorFrame on
|
||||
// macOS, however it contains compositor resize logic that we don't want.
|
||||
// Consequently we instead call the SubmitCompositorFrame method directly.
|
||||
GetDelegatedFrameHost()->SubmitCompositorFrame(
|
||||
local_surface_id, std::move(frame), std::move(hit_test_region_list));
|
||||
|
||||
// Request a copy of the last compositor frame which will eventually call
|
||||
// OnPaint asynchronously.
|
||||
copy_frame_generator_->GenerateCopyFrame(damage_rect);
|
||||
}
|
||||
}
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::ClearCompositorFrame() {
|
||||
@@ -651,13 +495,13 @@ void OffScreenRenderWidgetHostView::InitAsPopup(
|
||||
content::RenderWidgetHostView* parent_host_view,
|
||||
const gfx::Rect& pos) {
|
||||
DCHECK_EQ(parent_host_view_, parent_host_view);
|
||||
DCHECK_EQ(widget_type_, content::WidgetType::kPopup);
|
||||
|
||||
if (parent_host_view_->popup_host_view_) {
|
||||
parent_host_view_->popup_host_view_->CancelWidget();
|
||||
}
|
||||
|
||||
parent_host_view_->set_popup_host_view(this);
|
||||
parent_host_view_->popup_bitmap_.reset(new SkBitmap);
|
||||
parent_callback_ =
|
||||
base::Bind(&OffScreenRenderWidgetHostView::OnPopupPaint,
|
||||
parent_host_view_->weak_ptr_factory_.GetWeakPtr());
|
||||
@@ -665,6 +509,10 @@ void OffScreenRenderWidgetHostView::InitAsPopup(
|
||||
popup_position_ = pos;
|
||||
|
||||
ResizeRootLayer(false);
|
||||
SetPainting(parent_host_view_->IsPainting());
|
||||
if (video_consumer_) {
|
||||
video_consumer_->SizeChanged();
|
||||
}
|
||||
Show();
|
||||
}
|
||||
|
||||
@@ -698,7 +546,6 @@ void OffScreenRenderWidgetHostView::Destroy() {
|
||||
} else {
|
||||
if (popup_host_view_)
|
||||
popup_host_view_->CancelWidget();
|
||||
popup_bitmap_.reset();
|
||||
if (child_host_view_)
|
||||
child_host_view_->CancelWidget();
|
||||
if (!guest_host_views_.empty()) {
|
||||
@@ -748,6 +595,7 @@ void OffScreenRenderWidgetHostView::InitAsGuest(
|
||||
content::RenderWidgetHostView* parent_host_view,
|
||||
content::RenderWidgetHostViewGuest* guest_view) {
|
||||
parent_host_view_->AddGuestHostView(this);
|
||||
SetPainting(parent_host_view_->IsPainting());
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::TransformPointToRootSurface(
|
||||
@@ -763,6 +611,12 @@ viz::SurfaceId OffScreenRenderWidgetHostView::GetCurrentSurfaceId() const {
|
||||
: viz::SurfaceId();
|
||||
}
|
||||
|
||||
std::unique_ptr<content::SyntheticGestureTarget>
|
||||
OffScreenRenderWidgetHostView::CreateSyntheticGestureTarget() {
|
||||
NOTIMPLEMENTED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::ImeCompositionRangeChanged(
|
||||
const gfx::Range&,
|
||||
const std::vector<gfx::Rect>&) {}
|
||||
@@ -800,12 +654,8 @@ const viz::FrameSinkId& OffScreenRenderWidgetHostView::GetFrameSinkId() const {
|
||||
|
||||
void OffScreenRenderWidgetHostView::DidNavigate() {
|
||||
ResizeRootLayer(true);
|
||||
#if defined(OS_MACOSX)
|
||||
browser_compositor_->DidNavigate();
|
||||
#else
|
||||
if (delegated_frame_host_)
|
||||
delegated_frame_host_->DidNavigate();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool OffScreenRenderWidgetHostView::TransformPointToLocalCoordSpaceLegacy(
|
||||
@@ -847,7 +697,6 @@ void OffScreenRenderWidgetHostView::CancelWidget() {
|
||||
if (parent_host_view_) {
|
||||
if (parent_host_view_->popup_host_view_ == this) {
|
||||
parent_host_view_->set_popup_host_view(NULL);
|
||||
parent_host_view_->popup_bitmap_.reset();
|
||||
} else if (parent_host_view_->child_host_view_ == this) {
|
||||
parent_host_view_->set_child_host_view(NULL);
|
||||
parent_host_view_->Show();
|
||||
@@ -890,29 +739,21 @@ void OffScreenRenderWidgetHostView::ProxyViewDestroyed(
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
std::unique_ptr<viz::SoftwareOutputDevice>
|
||||
OffScreenRenderWidgetHostView::CreateSoftwareOutputDevice(
|
||||
std::unique_ptr<viz::HostDisplayClient>
|
||||
OffScreenRenderWidgetHostView::CreateHostDisplayClient(
|
||||
ui::Compositor* compositor) {
|
||||
DCHECK_EQ(GetCompositor(), compositor);
|
||||
DCHECK(!copy_frame_generator_);
|
||||
DCHECK(!software_output_device_);
|
||||
|
||||
ResizeRootLayer(false);
|
||||
|
||||
software_output_device_ = new OffScreenOutputDevice(
|
||||
transparent_, base::Bind(&OffScreenRenderWidgetHostView::OnPaint,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
return base::WrapUnique(software_output_device_);
|
||||
host_display_client_ = new OffScreenHostDisplayClient(
|
||||
gfx::kNullAcceleratedWidget,
|
||||
base::Bind(&OffScreenRenderWidgetHostView::OnPaint,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
host_display_client_->SetActive(IsPainting());
|
||||
return base::WrapUnique(host_display_client_);
|
||||
}
|
||||
|
||||
bool OffScreenRenderWidgetHostView::InstallTransparency() {
|
||||
if (transparent_) {
|
||||
SetBackgroundColor(SkColor());
|
||||
#if defined(OS_MACOSX)
|
||||
browser_compositor_->SetBackgroundColor(SK_ColorTRANSPARENT);
|
||||
#else
|
||||
compositor_->SetBackgroundColor(SK_ColorTRANSPARENT);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -921,76 +762,99 @@ bool OffScreenRenderWidgetHostView::InstallTransparency() {
|
||||
void OffScreenRenderWidgetHostView::SetNeedsBeginFrames(
|
||||
bool needs_begin_frames) {
|
||||
SetupFrameRate(true);
|
||||
|
||||
begin_frame_timer_->SetActive(needs_begin_frames);
|
||||
|
||||
if (software_output_device_) {
|
||||
software_output_device_->SetActive(painting_, false);
|
||||
}
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetWantsAnimateOnlyBeginFrames() {
|
||||
if (GetDelegatedFrameHost()) {
|
||||
GetDelegatedFrameHost()->SetWantsAnimateOnlyBeginFrames();
|
||||
}
|
||||
void OffScreenRenderWidgetHostView::SetWantsAnimateOnlyBeginFrames() {}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void OffScreenRenderWidgetHostView::SetActive(bool active) {}
|
||||
|
||||
void OffScreenRenderWidgetHostView::ShowDefinitionForSelection() {}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SpeakSelection() {}
|
||||
|
||||
bool OffScreenRenderWidgetHostView::UpdateNSViewAndDisplay() {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnPaint(const gfx::Rect& damage_rect,
|
||||
const SkBitmap& bitmap) {
|
||||
backing_.reset(new SkBitmap());
|
||||
backing_->allocN32Pixels(bitmap.width(), bitmap.height(), !transparent_);
|
||||
bitmap.readPixels(backing_->pixmap());
|
||||
|
||||
if (IsPopupWidget() && parent_callback_) {
|
||||
parent_callback_.Run(this->popup_position_);
|
||||
} else {
|
||||
CompositeFrame(damage_rect);
|
||||
}
|
||||
}
|
||||
|
||||
gfx::Size OffScreenRenderWidgetHostView::SizeInPixels() {
|
||||
if (IsPopupWidget()) {
|
||||
return gfx::ConvertSizeToPixel(current_device_scale_factor_,
|
||||
popup_position_.size());
|
||||
} else {
|
||||
return gfx::ConvertSizeToPixel(current_device_scale_factor_,
|
||||
GetViewBounds().size());
|
||||
}
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::CompositeFrame(
|
||||
const gfx::Rect& damage_rect) {
|
||||
HoldResize();
|
||||
|
||||
if (parent_callback_) {
|
||||
parent_callback_.Run(damage_rect, bitmap);
|
||||
gfx::Size size_in_pixels = SizeInPixels();
|
||||
|
||||
SkBitmap frame;
|
||||
|
||||
// Optimize for the case when there is no popup
|
||||
if (proxy_views_.size() == 0 && !popup_host_view_) {
|
||||
frame = GetBacking();
|
||||
} else {
|
||||
gfx::Rect damage(damage_rect);
|
||||
frame.allocN32Pixels(size_in_pixels.width(), size_in_pixels.height(),
|
||||
false);
|
||||
if (!GetBacking().drawsNothing()) {
|
||||
SkCanvas canvas(frame);
|
||||
canvas.writePixels(GetBacking(), 0, 0);
|
||||
|
||||
gfx::Size size_in_pixels = gfx::ConvertSizeToPixel(
|
||||
current_device_scale_factor_, GetViewBounds().size());
|
||||
if (popup_host_view_ && !popup_host_view_->GetBacking().drawsNothing()) {
|
||||
gfx::Rect rect = popup_host_view_->popup_position_;
|
||||
gfx::Point origin_in_pixels = gfx::ConvertPointToPixel(
|
||||
current_device_scale_factor_, rect.origin());
|
||||
canvas.writePixels(popup_host_view_->GetBacking(), origin_in_pixels.x(),
|
||||
origin_in_pixels.y());
|
||||
}
|
||||
|
||||
SkBitmap backing;
|
||||
backing.allocN32Pixels(size_in_pixels.width(), size_in_pixels.height(),
|
||||
false);
|
||||
SkCanvas canvas(backing);
|
||||
|
||||
canvas.writePixels(bitmap, 0, 0);
|
||||
|
||||
if (popup_host_view_ && popup_bitmap_.get()) {
|
||||
gfx::Rect rect = popup_host_view_->popup_position_;
|
||||
gfx::Point origin_in_pixels =
|
||||
gfx::ConvertPointToPixel(current_device_scale_factor_, rect.origin());
|
||||
damage.Union(rect);
|
||||
canvas.writePixels(*popup_bitmap_.get(), origin_in_pixels.x(),
|
||||
origin_in_pixels.y());
|
||||
for (auto* proxy_view : proxy_views_) {
|
||||
gfx::Rect rect = proxy_view->GetBounds();
|
||||
gfx::Point origin_in_pixels = gfx::ConvertPointToPixel(
|
||||
current_device_scale_factor_, rect.origin());
|
||||
canvas.writePixels(*proxy_view->GetBitmap(), origin_in_pixels.x(),
|
||||
origin_in_pixels.y());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto* proxy_view : proxy_views_) {
|
||||
gfx::Rect rect = proxy_view->GetBounds();
|
||||
gfx::Point origin_in_pixels =
|
||||
gfx::ConvertPointToPixel(current_device_scale_factor_, rect.origin());
|
||||
damage.Union(rect);
|
||||
canvas.writePixels(*proxy_view->GetBitmap(), origin_in_pixels.x(),
|
||||
origin_in_pixels.y());
|
||||
}
|
||||
|
||||
damage.Intersect(GetViewBounds());
|
||||
paint_callback_running_ = true;
|
||||
callback_.Run(damage, backing);
|
||||
paint_callback_running_ = false;
|
||||
}
|
||||
|
||||
paint_callback_running_ = true;
|
||||
callback_.Run(gfx::IntersectRects(gfx::Rect(size_in_pixels), damage_rect),
|
||||
frame);
|
||||
paint_callback_running_ = false;
|
||||
|
||||
ReleaseResize();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnPopupPaint(const gfx::Rect& damage_rect,
|
||||
const SkBitmap& bitmap) {
|
||||
if (popup_host_view_ && popup_bitmap_.get())
|
||||
popup_bitmap_.reset(new SkBitmap(bitmap));
|
||||
InvalidateBounds(popup_host_view_->popup_position_);
|
||||
void OffScreenRenderWidgetHostView::OnPopupPaint(const gfx::Rect& damage_rect) {
|
||||
InvalidateBounds(
|
||||
gfx::ConvertRectToPixel(current_device_scale_factor_, damage_rect));
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnProxyViewPaint(
|
||||
const gfx::Rect& damage_rect) {
|
||||
InvalidateBounds(damage_rect);
|
||||
InvalidateBounds(
|
||||
gfx::ConvertRectToPixel(current_device_scale_factor_, damage_rect));
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::HoldResize() {
|
||||
@@ -1020,7 +884,7 @@ void OffScreenRenderWidgetHostView::SynchronizeVisualProperties() {
|
||||
return;
|
||||
}
|
||||
|
||||
ResizeRootLayer(false);
|
||||
ResizeRootLayer(true);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SendMouseEvent(
|
||||
@@ -1147,8 +1011,17 @@ void OffScreenRenderWidgetHostView::SendMouseWheelEvent(
|
||||
void OffScreenRenderWidgetHostView::SetPainting(bool painting) {
|
||||
painting_ = painting;
|
||||
|
||||
if (software_output_device_) {
|
||||
software_output_device_->SetActive(painting_, !paint_callback_running_);
|
||||
if (popup_host_view_) {
|
||||
popup_host_view_->SetPainting(painting);
|
||||
}
|
||||
|
||||
for (auto* guest_host_view : guest_host_views_)
|
||||
guest_host_view->SetPainting(painting);
|
||||
|
||||
if (video_consumer_) {
|
||||
video_consumer_->SetActive(IsPainting());
|
||||
} else if (host_display_client_) {
|
||||
host_display_client_->SetActive(IsPainting());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1173,6 +1046,10 @@ void OffScreenRenderWidgetHostView::SetFrameRate(int frame_rate) {
|
||||
|
||||
SetupFrameRate(true);
|
||||
|
||||
if (video_consumer_) {
|
||||
video_consumer_->SetFrameRate(GetFrameRate());
|
||||
}
|
||||
|
||||
for (auto* guest_host_view : guest_host_views_)
|
||||
guest_host_view->SetFrameRate(frame_rate);
|
||||
}
|
||||
@@ -1181,7 +1058,6 @@ int OffScreenRenderWidgetHostView::GetFrameRate() const {
|
||||
return frame_rate_;
|
||||
}
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
ui::Compositor* OffScreenRenderWidgetHostView::GetCompositor() const {
|
||||
return compositor_.get();
|
||||
}
|
||||
@@ -1190,18 +1066,15 @@ ui::Layer* OffScreenRenderWidgetHostView::GetRootLayer() const {
|
||||
return root_layer_.get();
|
||||
}
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
const viz::LocalSurfaceIdAllocation&
|
||||
OffScreenRenderWidgetHostView::GetLocalSurfaceIdAllocation() const {
|
||||
return local_surface_id_allocation_;
|
||||
return delegated_frame_host_allocation_;
|
||||
}
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
content::DelegatedFrameHost*
|
||||
OffScreenRenderWidgetHostView::GetDelegatedFrameHost() const {
|
||||
return delegated_frame_host_.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
|
||||
if (!force && frame_rate_threshold_us_ != 0)
|
||||
@@ -1209,11 +1082,6 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
|
||||
|
||||
frame_rate_threshold_us_ = 1000000 / frame_rate_;
|
||||
|
||||
if (copy_frame_generator_.get()) {
|
||||
copy_frame_generator_->set_frame_rate_threshold_us(
|
||||
frame_rate_threshold_us_);
|
||||
}
|
||||
|
||||
if (begin_frame_timer_.get()) {
|
||||
begin_frame_timer_->SetFrameRateThresholdUs(frame_rate_threshold_us_);
|
||||
} else {
|
||||
@@ -1225,15 +1093,11 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::Invalidate() {
|
||||
InvalidateBounds(GetViewBounds());
|
||||
InvalidateBounds(gfx::Rect(GetRequestedRendererSize()));
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::InvalidateBounds(const gfx::Rect& bounds) {
|
||||
if (software_output_device_) {
|
||||
software_output_device_->OnPaint(bounds);
|
||||
} else if (copy_frame_generator_) {
|
||||
copy_frame_generator_->GenerateCopyFrame(bounds);
|
||||
}
|
||||
CompositeFrame(bounds);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
|
||||
@@ -1259,23 +1123,24 @@ void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
|
||||
|
||||
GetRootLayer()->SetBounds(gfx::Rect(size));
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool resized = UpdateNSViewAndDisplay();
|
||||
#else
|
||||
const gfx::Size& size_in_pixels =
|
||||
gfx::ConvertSizeToPixel(current_device_scale_factor_, size);
|
||||
|
||||
local_surface_id_allocator_.GenerateId();
|
||||
local_surface_id_allocation_ =
|
||||
local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
|
||||
compositor_allocator_.GenerateId();
|
||||
compositor_allocation_ =
|
||||
compositor_allocator_.GetCurrentLocalSurfaceIdAllocation();
|
||||
|
||||
GetCompositor()->SetScaleAndSize(current_device_scale_factor_, size_in_pixels,
|
||||
local_surface_id_allocation_);
|
||||
compositor_allocation_);
|
||||
|
||||
delegated_frame_host_allocator_.GenerateId();
|
||||
delegated_frame_host_allocation_ =
|
||||
delegated_frame_host_allocator_.GetCurrentLocalSurfaceIdAllocation();
|
||||
|
||||
bool resized = true;
|
||||
GetDelegatedFrameHost()->EmbedSurface(
|
||||
local_surface_id_allocation_.local_surface_id(), size,
|
||||
delegated_frame_host_allocation_.local_surface_id(), size,
|
||||
cc::DeadlinePolicy::UseDefaultDeadline());
|
||||
#endif
|
||||
|
||||
// Note that |render_widget_host_| will retrieve resize parameters from the
|
||||
// DelegatedFrameHost, so it must have SynchronizeVisualProperties called
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "atom/browser/osr/osr_output_device.h"
|
||||
#include "atom/browser/osr/osr_host_display_client.h"
|
||||
#include "atom/browser/osr/osr_video_consumer.h"
|
||||
#include "atom/browser/osr/osr_view_proxy.h"
|
||||
#include "base/process/kill.h"
|
||||
#include "base/threading/thread.h"
|
||||
@@ -23,12 +24,12 @@
|
||||
#include "components/viz/common/frame_sinks/begin_frame_source.h"
|
||||
#include "components/viz/common/quads/compositor_frame.h"
|
||||
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
|
||||
#include "content/browser/frame_host/render_widget_host_view_guest.h"
|
||||
#include "content/browser/renderer_host/delegated_frame_host.h"
|
||||
#include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_view_base.h"
|
||||
#include "content/browser/web_contents/web_contents_view.h"
|
||||
#include "content/browser/frame_host/render_widget_host_view_guest.h" // nogncheck
|
||||
#include "content/browser/renderer_host/delegated_frame_host.h" // nogncheck
|
||||
#include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h" // nogncheck
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h" // nogncheck
|
||||
#include "content/browser/renderer_host/render_widget_host_view_base.h" // nogncheck
|
||||
#include "content/browser/web_contents/web_contents_view.h" // nogncheck
|
||||
#include "third_party/blink/public/platform/web_vector.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/base/ime/text_input_client.h"
|
||||
@@ -37,24 +38,13 @@
|
||||
#include "ui/compositor/layer_owner.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
|
||||
#include "components/viz/host/host_display_client.h"
|
||||
#include "ui/compositor/external_begin_frame_client.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "ui/gfx/win/window_impl.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "content/browser/renderer_host/browser_compositor_view_mac.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#ifdef __OBJC__
|
||||
@class CALayer;
|
||||
@class NSWindow;
|
||||
#else
|
||||
class CALayer;
|
||||
class NSWindow;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace content {
|
||||
class CursorManager;
|
||||
} // namespace content
|
||||
@@ -64,13 +54,13 @@ namespace atom {
|
||||
class AtomCopyFrameGenerator;
|
||||
class AtomBeginFrameTimer;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
class MacHelper;
|
||||
#else
|
||||
class AtomDelegatedFrameHostClient;
|
||||
#endif
|
||||
|
||||
typedef base::Callback<void(const gfx::Rect&, const SkBitmap&)> OnPaintCallback;
|
||||
typedef base::Callback<void(const gfx::Rect&)> OnPopupPaintCallback;
|
||||
|
||||
class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
public ui::ExternalBeginFrameClient,
|
||||
public ui::CompositorDelegate,
|
||||
public OffscreenViewProxyObserver {
|
||||
public:
|
||||
@@ -87,6 +77,9 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
content::BrowserAccessibilityDelegate*,
|
||||
bool) override;
|
||||
|
||||
void OnDisplayDidFinishFrame(const viz::BeginFrameAck& ack) override;
|
||||
void OnNeedsExternalBeginFrames(bool needs_begin_frames) override;
|
||||
|
||||
// content::RenderWidgetHostView:
|
||||
void InitAsChild(gfx::NativeView) override;
|
||||
void SetSize(const gfx::Size&) override;
|
||||
@@ -152,15 +145,12 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
void TransformPointToRootSurface(gfx::PointF* point) override;
|
||||
gfx::Rect GetBoundsInRootWindow(void) override;
|
||||
viz::SurfaceId GetCurrentSurfaceId() const override;
|
||||
std::unique_ptr<content::SyntheticGestureTarget>
|
||||
CreateSyntheticGestureTarget() override;
|
||||
void ImeCompositionRangeChanged(const gfx::Range&,
|
||||
const std::vector<gfx::Rect>&) override;
|
||||
gfx::Size GetCompositorViewportPixelSize() const override;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
viz::ScopedSurfaceIdAllocator DidUpdateVisualProperties(
|
||||
const cc::RenderFrameMetadata& metadata) override;
|
||||
#endif
|
||||
|
||||
content::RenderWidgetHostViewBase* CreateViewForWidget(
|
||||
content::RenderWidgetHost*,
|
||||
content::RenderWidgetHost*,
|
||||
@@ -183,7 +173,7 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
viz::EventSource source = viz::EventSource::ANY) override;
|
||||
|
||||
// ui::CompositorDelegate:
|
||||
std::unique_ptr<viz::SoftwareOutputDevice> CreateSoftwareOutputDevice(
|
||||
std::unique_ptr<viz::HostDisplayClient> CreateHostDisplayClient(
|
||||
ui::Compositor* compositor) override;
|
||||
|
||||
bool InstallTransparency();
|
||||
@@ -191,14 +181,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
void OnBeginFrameTimerTick();
|
||||
void SendBeginFrame(base::TimeTicks frame_time, base::TimeDelta vsync_period);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void CreatePlatformWidget(bool is_guest_view_hack);
|
||||
void DestroyPlatformWidget();
|
||||
SkColor last_frame_root_background_color() const {
|
||||
return last_frame_root_background_color_;
|
||||
}
|
||||
#endif
|
||||
|
||||
void CancelWidget();
|
||||
void AddGuestHostView(OffScreenRenderWidgetHostView* guest_host);
|
||||
void RemoveGuestHostView(OffScreenRenderWidgetHostView* guest_host);
|
||||
@@ -207,13 +189,19 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
void ProxyViewDestroyed(OffscreenViewProxy* proxy) override;
|
||||
|
||||
void OnPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap);
|
||||
void OnPopupPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap);
|
||||
void OnPopupPaint(const gfx::Rect& damage_rect);
|
||||
void OnProxyViewPaint(const gfx::Rect& damage_rect) override;
|
||||
|
||||
gfx::Size SizeInPixels();
|
||||
|
||||
void CompositeFrame(const gfx::Rect& damage_rect);
|
||||
|
||||
bool IsPopupWidget() const {
|
||||
return widget_type_ == content::WidgetType::kPopup;
|
||||
}
|
||||
|
||||
const SkBitmap& GetBacking() { return *backing_.get(); }
|
||||
|
||||
void HoldResize();
|
||||
void ReleaseResize();
|
||||
void SynchronizeVisualProperties();
|
||||
@@ -230,12 +218,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
ui::Compositor* GetCompositor() const;
|
||||
ui::Layer* GetRootLayer() const;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
content::BrowserCompositorMac* browser_compositor() const {
|
||||
return browser_compositor_.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
content::DelegatedFrameHost* GetDelegatedFrameHost() const;
|
||||
|
||||
void Invalidate();
|
||||
@@ -256,12 +238,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
}
|
||||
|
||||
private:
|
||||
#if defined(OS_MACOSX)
|
||||
display::Display GetDisplay();
|
||||
void OnDidUpdateVisualPropertiesComplete(
|
||||
const cc::RenderFrameMetadata& metadata);
|
||||
#endif
|
||||
|
||||
void SetupFrameRate(bool force);
|
||||
void ResizeRootLayer(bool force);
|
||||
|
||||
@@ -276,16 +252,13 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
|
||||
OffScreenRenderWidgetHostView* parent_host_view_ = nullptr;
|
||||
OffScreenRenderWidgetHostView* popup_host_view_ = nullptr;
|
||||
std::unique_ptr<SkBitmap> popup_bitmap_;
|
||||
OffScreenRenderWidgetHostView* child_host_view_ = nullptr;
|
||||
std::set<OffScreenRenderWidgetHostView*> guest_host_views_;
|
||||
std::set<OffscreenViewProxy*> proxy_views_;
|
||||
|
||||
OffScreenOutputDevice* software_output_device_ = nullptr;
|
||||
|
||||
const bool transparent_;
|
||||
OnPaintCallback callback_;
|
||||
OnPaintCallback parent_callback_;
|
||||
OnPopupPaintCallback parent_callback_;
|
||||
|
||||
int frame_rate_ = 0;
|
||||
int frame_rate_threshold_us_ = 0;
|
||||
@@ -305,8 +278,11 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
|
||||
bool paint_callback_running_ = false;
|
||||
|
||||
viz::LocalSurfaceIdAllocation local_surface_id_allocation_;
|
||||
viz::ParentLocalSurfaceIdAllocator local_surface_id_allocator_;
|
||||
viz::LocalSurfaceIdAllocation delegated_frame_host_allocation_;
|
||||
viz::ParentLocalSurfaceIdAllocator delegated_frame_host_allocator_;
|
||||
|
||||
viz::LocalSurfaceIdAllocation compositor_allocation_;
|
||||
viz::ParentLocalSurfaceIdAllocator compositor_allocator_;
|
||||
|
||||
std::unique_ptr<ui::Layer> root_layer_;
|
||||
std::unique_ptr<ui::Compositor> compositor_;
|
||||
@@ -314,27 +290,15 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
|
||||
std::unique_ptr<content::CursorManager> cursor_manager_;
|
||||
|
||||
std::unique_ptr<AtomCopyFrameGenerator> copy_frame_generator_;
|
||||
std::unique_ptr<AtomBeginFrameTimer> begin_frame_timer_;
|
||||
OffScreenHostDisplayClient* host_display_client_;
|
||||
std::unique_ptr<OffScreenVideoConsumer> video_consumer_;
|
||||
|
||||
// Provides |source_id| for BeginFrameArgs that we create.
|
||||
viz::StubBeginFrameSource begin_frame_source_;
|
||||
uint64_t begin_frame_number_ = viz::BeginFrameArgs::kStartingFrameNumber;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
std::unique_ptr<content::BrowserCompositorMac> browser_compositor_;
|
||||
|
||||
SkColor last_frame_root_background_color_;
|
||||
|
||||
// Can not be managed by smart pointer because its header can not be included
|
||||
// in the file that has the destructor.
|
||||
MacHelper* mac_helper_;
|
||||
|
||||
// Selected text on the renderer.
|
||||
std::string selected_text_;
|
||||
#else
|
||||
std::unique_ptr<AtomDelegatedFrameHostClient> delegated_frame_host_client_;
|
||||
#endif
|
||||
|
||||
content::MouseWheelPhaseHandler mouse_wheel_phase_handler_;
|
||||
|
||||
@@ -348,6 +312,8 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
|
||||
SkColor background_color_ = SkColor();
|
||||
|
||||
std::unique_ptr<SkBitmap> backing_;
|
||||
|
||||
base::WeakPtrFactory<OffScreenRenderWidgetHostView> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(OffScreenRenderWidgetHostView);
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/common/view_messages.h"
|
||||
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
|
||||
#include "ui/display/screen.h"
|
||||
|
||||
#include "components/viz/common/features.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class MacHelper : public content::BrowserCompositorMacClient,
|
||||
public ui::AcceleratedWidgetMacNSView {
|
||||
public:
|
||||
explicit MacHelper(OffScreenRenderWidgetHostView* view) : view_(view) {
|
||||
[view_->GetNativeView().GetNativeNSView() setWantsLayer:YES];
|
||||
}
|
||||
|
||||
virtual ~MacHelper() {}
|
||||
|
||||
// content::BrowserCompositorMacClient:
|
||||
SkColor BrowserCompositorMacGetGutterColor() const override {
|
||||
// When making an element on the page fullscreen the element's background
|
||||
// may not match the page's, so use black as the gutter color to avoid
|
||||
// flashes of brighter colors during the transition.
|
||||
if (view_->render_widget_host()->delegate() &&
|
||||
view_->render_widget_host()->delegate()->IsFullscreenForCurrentTab()) {
|
||||
return SK_ColorBLACK;
|
||||
}
|
||||
return view_->last_frame_root_background_color();
|
||||
}
|
||||
|
||||
void BrowserCompositorMacOnBeginFrame(base::TimeTicks frame_time) override {}
|
||||
|
||||
void OnFrameTokenChanged(uint32_t frame_token) override {
|
||||
view_->render_widget_host()->DidProcessFrame(frame_token);
|
||||
}
|
||||
|
||||
void AcceleratedWidgetCALayerParamsUpdated() override {}
|
||||
|
||||
void DestroyCompositorForShutdown() override {}
|
||||
|
||||
bool OnBrowserCompositorSurfaceIdChanged() override {
|
||||
return view_->render_widget_host()->SynchronizeVisualProperties();
|
||||
}
|
||||
|
||||
std::vector<viz::SurfaceId> CollectSurfaceIdsForEviction() override {
|
||||
return view_->render_widget_host()->CollectSurfaceIdsForEviction();
|
||||
}
|
||||
|
||||
private:
|
||||
OffScreenRenderWidgetHostView* view_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MacHelper);
|
||||
};
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetActive(bool active) {}
|
||||
|
||||
void OffScreenRenderWidgetHostView::ShowDefinitionForSelection() {}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SpeakSelection() {}
|
||||
|
||||
bool OffScreenRenderWidgetHostView::UpdateNSViewAndDisplay() {
|
||||
return browser_compositor_->UpdateSurfaceFromNSView(
|
||||
GetRootLayer()->bounds().size(), GetDisplay());
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::CreatePlatformWidget(
|
||||
bool is_guest_view_hack) {
|
||||
mac_helper_ = new MacHelper(this);
|
||||
browser_compositor_.reset(new content::BrowserCompositorMac(
|
||||
mac_helper_, mac_helper_, render_widget_host_->is_hidden(), GetDisplay(),
|
||||
AllocateFrameSinkId(is_guest_view_hack)));
|
||||
|
||||
if (!base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) {
|
||||
SetNeedsBeginFrames(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::DestroyPlatformWidget() {
|
||||
browser_compositor_.reset();
|
||||
delete mac_helper_;
|
||||
}
|
||||
|
||||
viz::ScopedSurfaceIdAllocator
|
||||
OffScreenRenderWidgetHostView::DidUpdateVisualProperties(
|
||||
const cc::RenderFrameMetadata& metadata) {
|
||||
base::OnceCallback<void()> allocation_task = base::BindOnce(
|
||||
base::IgnoreResult(
|
||||
&OffScreenRenderWidgetHostView::OnDidUpdateVisualPropertiesComplete),
|
||||
weak_ptr_factory_.GetWeakPtr(), metadata);
|
||||
return browser_compositor_->GetScopedRendererSurfaceIdAllocator(
|
||||
std::move(allocation_task));
|
||||
}
|
||||
|
||||
display::Display OffScreenRenderWidgetHostView::GetDisplay() {
|
||||
content::ScreenInfo screen_info;
|
||||
GetScreenInfo(&screen_info);
|
||||
|
||||
// Start with a reasonable display representation.
|
||||
display::Display display =
|
||||
display::Screen::GetScreen()->GetDisplayNearestView(nullptr);
|
||||
|
||||
// Populate attributes based on |screen_info|.
|
||||
display.set_bounds(screen_info.rect);
|
||||
display.set_work_area(screen_info.available_rect);
|
||||
display.set_device_scale_factor(screen_info.device_scale_factor);
|
||||
display.set_color_space(screen_info.color_space);
|
||||
display.set_color_depth(screen_info.depth);
|
||||
display.set_depth_per_component(screen_info.depth_per_component);
|
||||
display.set_is_monochrome(screen_info.is_monochrome);
|
||||
display.SetRotationAsDegree(screen_info.orientation_angle);
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnDidUpdateVisualPropertiesComplete(
|
||||
const cc::RenderFrameMetadata& metadata) {
|
||||
DCHECK_EQ(current_device_scale_factor_, metadata.device_scale_factor);
|
||||
browser_compositor_->UpdateSurfaceFromChild(
|
||||
metadata.device_scale_factor, metadata.viewport_size_in_pixels,
|
||||
metadata.local_surface_id_allocation.value_or(
|
||||
viz::LocalSurfaceIdAllocation()));
|
||||
}
|
||||
|
||||
const viz::LocalSurfaceIdAllocation&
|
||||
OffScreenRenderWidgetHostView::GetLocalSurfaceIdAllocation() const {
|
||||
return browser_compositor_->GetRendererLocalSurfaceIdAllocation();
|
||||
}
|
||||
|
||||
ui::Compositor* OffScreenRenderWidgetHostView::GetCompositor() const {
|
||||
return browser_compositor_->GetCompositor();
|
||||
}
|
||||
|
||||
ui::Layer* OffScreenRenderWidgetHostView::GetRootLayer() const {
|
||||
return browser_compositor_->GetRootLayer();
|
||||
}
|
||||
|
||||
content::DelegatedFrameHost*
|
||||
OffScreenRenderWidgetHostView::GetDelegatedFrameHost() const {
|
||||
return browser_compositor_->GetDelegatedFrameHost();
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
132
atom/browser/osr/osr_video_consumer.cc
Normal file
132
atom/browser/osr/osr_video_consumer.cc
Normal file
@@ -0,0 +1,132 @@
|
||||
// Copyright (c) 2019 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/osr/osr_video_consumer.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
||||
#include "media/base/video_frame_metadata.h"
|
||||
#include "media/capture/mojom/video_capture_types.mojom.h"
|
||||
#include "ui/gfx/skbitmap_operations.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
OffScreenVideoConsumer::OffScreenVideoConsumer(
|
||||
OffScreenRenderWidgetHostView* view,
|
||||
OnPaintCallback callback)
|
||||
: callback_(callback),
|
||||
view_(view),
|
||||
video_capturer_(view->CreateVideoCapturer()),
|
||||
weak_ptr_factory_(this) {
|
||||
video_capturer_->SetResolutionConstraints(view_->SizeInPixels(),
|
||||
view_->SizeInPixels(), true);
|
||||
video_capturer_->SetAutoThrottlingEnabled(false);
|
||||
video_capturer_->SetMinSizeChangePeriod(base::TimeDelta());
|
||||
video_capturer_->SetFormat(media::PIXEL_FORMAT_ARGB,
|
||||
gfx::ColorSpace::CreateREC709());
|
||||
SetFrameRate(view_->GetFrameRate());
|
||||
}
|
||||
|
||||
OffScreenVideoConsumer::~OffScreenVideoConsumer() = default;
|
||||
|
||||
void OffScreenVideoConsumer::SetActive(bool active) {
|
||||
if (active) {
|
||||
video_capturer_->Start(this);
|
||||
} else {
|
||||
video_capturer_->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void OffScreenVideoConsumer::SetFrameRate(int frame_rate) {
|
||||
video_capturer_->SetMinCapturePeriod(base::TimeDelta::FromSeconds(1) /
|
||||
frame_rate);
|
||||
}
|
||||
|
||||
void OffScreenVideoConsumer::SizeChanged() {
|
||||
video_capturer_->SetResolutionConstraints(view_->SizeInPixels(),
|
||||
view_->SizeInPixels(), true);
|
||||
video_capturer_->RequestRefreshFrame();
|
||||
}
|
||||
|
||||
void OffScreenVideoConsumer::OnFrameCaptured(
|
||||
base::ReadOnlySharedMemoryRegion data,
|
||||
::media::mojom::VideoFrameInfoPtr info,
|
||||
const gfx::Rect& update_rect,
|
||||
const gfx::Rect& content_rect,
|
||||
viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr callbacks) {
|
||||
if (!CheckContentRect(content_rect)) {
|
||||
gfx::Size view_size = view_->SizeInPixels();
|
||||
video_capturer_->SetResolutionConstraints(view_size, view_size, true);
|
||||
video_capturer_->RequestRefreshFrame();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.IsValid()) {
|
||||
callbacks->Done();
|
||||
return;
|
||||
}
|
||||
base::ReadOnlySharedMemoryMapping mapping = data.Map();
|
||||
if (!mapping.IsValid()) {
|
||||
DLOG(ERROR) << "Shared memory mapping failed.";
|
||||
return;
|
||||
}
|
||||
if (mapping.size() <
|
||||
media::VideoFrame::AllocationSize(info->pixel_format, info->coded_size)) {
|
||||
DLOG(ERROR) << "Shared memory size was less than expected.";
|
||||
return;
|
||||
}
|
||||
|
||||
// The SkBitmap's pixels will be marked as immutable, but the installPixels()
|
||||
// API requires a non-const pointer. So, cast away the const.
|
||||
void* const pixels = const_cast<void*>(mapping.memory());
|
||||
|
||||
// Call installPixels() with a |releaseProc| that: 1) notifies the capturer
|
||||
// that this consumer has finished with the frame, and 2) releases the shared
|
||||
// memory mapping.
|
||||
struct FramePinner {
|
||||
// Keeps the shared memory that backs |frame_| mapped.
|
||||
base::ReadOnlySharedMemoryMapping mapping;
|
||||
// Prevents FrameSinkVideoCapturer from recycling the shared memory that
|
||||
// backs |frame_|.
|
||||
viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr releaser;
|
||||
};
|
||||
|
||||
SkBitmap bitmap;
|
||||
bitmap.installPixels(
|
||||
SkImageInfo::MakeN32(content_rect.width(), content_rect.height(),
|
||||
kPremul_SkAlphaType),
|
||||
pixels,
|
||||
media::VideoFrame::RowBytes(media::VideoFrame::kARGBPlane,
|
||||
info->pixel_format, info->coded_size.width()),
|
||||
[](void* addr, void* context) {
|
||||
delete static_cast<FramePinner*>(context);
|
||||
},
|
||||
new FramePinner{std::move(mapping), std::move(callbacks)});
|
||||
bitmap.setImmutable();
|
||||
|
||||
media::VideoFrameMetadata metadata;
|
||||
metadata.MergeInternalValuesFrom(info->metadata);
|
||||
|
||||
callback_.Run(update_rect, bitmap);
|
||||
}
|
||||
|
||||
void OffScreenVideoConsumer::OnStopped() {}
|
||||
|
||||
bool OffScreenVideoConsumer::CheckContentRect(const gfx::Rect& content_rect) {
|
||||
gfx::Size view_size = view_->SizeInPixels();
|
||||
gfx::Size content_size = content_rect.size();
|
||||
|
||||
if (std::abs(view_size.width() - content_size.width()) > 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (std::abs(view_size.height() - content_size.height()) > 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
54
atom/browser/osr/osr_video_consumer.h
Normal file
54
atom/browser/osr/osr_video_consumer.h
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright (c) 2019 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_OSR_OSR_VIDEO_CONSUMER_H_
|
||||
#define ATOM_BROWSER_OSR_OSR_VIDEO_CONSUMER_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "components/viz/host/client_frame_sink_video_capturer.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class OffScreenRenderWidgetHostView;
|
||||
|
||||
typedef base::Callback<void(const gfx::Rect&, const SkBitmap&)> OnPaintCallback;
|
||||
|
||||
class OffScreenVideoConsumer : public viz::mojom::FrameSinkVideoConsumer {
|
||||
public:
|
||||
OffScreenVideoConsumer(OffScreenRenderWidgetHostView* view,
|
||||
OnPaintCallback callback);
|
||||
~OffScreenVideoConsumer() override;
|
||||
|
||||
void SetActive(bool active);
|
||||
void SetFrameRate(int frame_rate);
|
||||
void SizeChanged();
|
||||
|
||||
private:
|
||||
// viz::mojom::FrameSinkVideoConsumer implementation.
|
||||
void OnFrameCaptured(
|
||||
base::ReadOnlySharedMemoryRegion data,
|
||||
::media::mojom::VideoFrameInfoPtr info,
|
||||
const gfx::Rect& update_rect,
|
||||
const gfx::Rect& content_rect,
|
||||
viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr callbacks) override;
|
||||
void OnStopped() override;
|
||||
|
||||
bool CheckContentRect(const gfx::Rect& content_rect);
|
||||
|
||||
OnPaintCallback callback_;
|
||||
|
||||
OffScreenRenderWidgetHostView* view_;
|
||||
std::unique_ptr<viz::ClientFrameSinkVideoCapturer> video_capturer_;
|
||||
|
||||
base::WeakPtrFactory<OffScreenVideoConsumer> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(OffScreenVideoConsumer);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_OSR_OSR_VIDEO_CONSUMER_H_
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "atom/browser/osr/osr_web_contents_view.h"
|
||||
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "content/browser/web_contents/web_contents_impl.h"
|
||||
#include "content/browser/web_contents/web_contents_impl.h" // nogncheck
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "third_party/blink/public/platform/web_screen_info.h"
|
||||
#include "ui/display/screen.h"
|
||||
@@ -140,7 +140,7 @@ OffScreenWebContentsView::CreateViewForChildWidget(
|
||||
->GetRenderWidgetHostView()
|
||||
: web_contents_impl->GetRenderWidgetHostView());
|
||||
|
||||
return new OffScreenRenderWidgetHostView(transparent_, true,
|
||||
return new OffScreenRenderWidgetHostView(transparent_, painting_,
|
||||
view->GetFrameRate(), callback_,
|
||||
render_widget_host, view, GetSize());
|
||||
}
|
||||
@@ -189,10 +189,9 @@ void OffScreenWebContentsView::UpdateDragCursor(
|
||||
|
||||
void OffScreenWebContentsView::SetPainting(bool painting) {
|
||||
auto* view = GetView();
|
||||
painting_ = painting;
|
||||
if (view != nullptr) {
|
||||
view->SetPainting(painting);
|
||||
} else {
|
||||
painting_ = painting;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,10 +206,9 @@ bool OffScreenWebContentsView::IsPainting() const {
|
||||
|
||||
void OffScreenWebContentsView::SetFrameRate(int frame_rate) {
|
||||
auto* view = GetView();
|
||||
frame_rate_ = frame_rate;
|
||||
if (view != nullptr) {
|
||||
view->SetFrameRate(frame_rate);
|
||||
} else {
|
||||
frame_rate_ = frame_rate;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include "atom/browser/native_window_observer.h"
|
||||
|
||||
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
||||
#include "content/browser/renderer_host/render_view_host_delegate_view.h"
|
||||
#include "content/browser/web_contents/web_contents_view.h"
|
||||
#include "content/browser/renderer_host/render_view_host_delegate_view.h" // nogncheck
|
||||
#include "content/browser/web_contents/web_contents_view.h" // nogncheck
|
||||
#include "content/public/browser/web_contents.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>electron.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>5.0.0-beta.7</string>
|
||||
<string>5.0.9</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>5.0.0-beta.7</string>
|
||||
<string>5.0.9</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 5,0,0,7
|
||||
PRODUCTVERSION 5,0,0,7
|
||||
FILEVERSION 5,0,9,0
|
||||
PRODUCTVERSION 5,0,9,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -68,12 +68,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "5.0.0"
|
||||
VALUE "FileVersion", "5.0.9"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "5.0.0"
|
||||
VALUE "ProductVersion", "5.0.9"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "atom/browser/ui/autofill_popup.h"
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "base/i18n/rtl.h"
|
||||
#include "chrome/browser/ui/autofill/popup_view_common.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/screen.h"
|
||||
@@ -25,85 +27,18 @@
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
class PopupViewCommon : public autofill::PopupViewCommon {
|
||||
public:
|
||||
explicit PopupViewCommon(const gfx::Rect& window_bounds)
|
||||
: window_bounds_(window_bounds) {}
|
||||
|
||||
std::pair<int, int> CalculatePopupXAndWidth(
|
||||
const display::Display& left_display,
|
||||
const display::Display& right_display,
|
||||
int popup_required_width,
|
||||
const gfx::Rect& element_bounds,
|
||||
bool is_rtl) {
|
||||
int leftmost_display_x = left_display.bounds().x();
|
||||
int rightmost_display_x =
|
||||
right_display.GetSizeInPixel().width() + right_display.bounds().x();
|
||||
|
||||
// Calculate the start coordinates for the popup if it is growing right or
|
||||
// the end position if it is growing to the left, capped to screen space.
|
||||
int right_growth_start = std::max(
|
||||
leftmost_display_x, std::min(rightmost_display_x, element_bounds.x()));
|
||||
int left_growth_end =
|
||||
std::max(leftmost_display_x,
|
||||
std::min(rightmost_display_x, element_bounds.right()));
|
||||
|
||||
int right_available = rightmost_display_x - right_growth_start;
|
||||
int left_available = left_growth_end - leftmost_display_x;
|
||||
|
||||
int popup_width =
|
||||
std::min(popup_required_width, std::max(right_available, left_available));
|
||||
|
||||
std::pair<int, int> grow_right(right_growth_start, popup_width);
|
||||
std::pair<int, int> grow_left(left_growth_end - popup_width, popup_width);
|
||||
|
||||
// Prefer to grow towards the end (right for LTR, left for RTL). But if there
|
||||
// is not enough space available in the desired direction and more space in
|
||||
// the other direction, reverse it.
|
||||
if (is_rtl) {
|
||||
return left_available >= popup_width || left_available >= right_available
|
||||
? grow_left
|
||||
: grow_right;
|
||||
gfx::Rect GetWindowBounds(gfx::NativeView container_view) override {
|
||||
return window_bounds_;
|
||||
}
|
||||
return right_available >= popup_width || right_available >= left_available
|
||||
? grow_right
|
||||
: grow_left;
|
||||
}
|
||||
|
||||
std::pair<int, int> CalculatePopupYAndHeight(
|
||||
const display::Display& top_display,
|
||||
const display::Display& bottom_display,
|
||||
int popup_required_height,
|
||||
const gfx::Rect& element_bounds) {
|
||||
int topmost_display_y = top_display.bounds().y();
|
||||
int bottommost_display_y =
|
||||
bottom_display.GetSizeInPixel().height() + bottom_display.bounds().y();
|
||||
|
||||
// Calculate the start coordinates for the popup if it is growing down or
|
||||
// the end position if it is growing up, capped to screen space.
|
||||
int top_growth_end = std::max(
|
||||
topmost_display_y, std::min(bottommost_display_y, element_bounds.y()));
|
||||
int bottom_growth_start =
|
||||
std::max(topmost_display_y,
|
||||
std::min(bottommost_display_y, element_bounds.bottom()));
|
||||
|
||||
int top_available = bottom_growth_start - topmost_display_y;
|
||||
int bottom_available = bottommost_display_y - top_growth_end;
|
||||
|
||||
// TODO(csharp): Restrict the popup height to what is available.
|
||||
if (bottom_available >= popup_required_height ||
|
||||
bottom_available >= top_available) {
|
||||
// The popup can appear below the field.
|
||||
return std::make_pair(bottom_growth_start, popup_required_height);
|
||||
} else {
|
||||
// The popup must appear above the field.
|
||||
return std::make_pair(top_growth_end - popup_required_height,
|
||||
popup_required_height);
|
||||
}
|
||||
}
|
||||
|
||||
display::Display GetDisplayNearestPoint(const gfx::Point& point) {
|
||||
return display::Screen::GetScreen()->GetDisplayNearestPoint(point);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
private:
|
||||
gfx::Rect window_bounds_;
|
||||
};
|
||||
|
||||
AutofillPopup::AutofillPopup() {
|
||||
bold_font_list_ = gfx::FontList().DeriveWithWeight(gfx::Font::Weight::BOLD);
|
||||
@@ -134,7 +69,6 @@ void AutofillPopup::CreateView(content::RenderFrameHost* frame_host,
|
||||
parent_->AddObserver(this);
|
||||
|
||||
view_ = new AutofillPopupView(this, parent->GetWidget());
|
||||
view_->Show();
|
||||
|
||||
#if BUILDFLAG(ENABLE_OSR)
|
||||
if (offscreen) {
|
||||
@@ -148,6 +82,9 @@ void AutofillPopup::CreateView(content::RenderFrameHost* frame_host,
|
||||
osr_rwhv->AddViewProxy(view_->view_proxy_.get());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Do this after OSR setup, we check for view_proxy_ when showing
|
||||
view_->Show();
|
||||
}
|
||||
|
||||
void AutofillPopup::Hide() {
|
||||
@@ -181,34 +118,14 @@ void AutofillPopup::UpdatePopupBounds() {
|
||||
DCHECK(parent_);
|
||||
gfx::Point origin(element_bounds_.origin());
|
||||
views::View::ConvertPointToScreen(parent_, &origin);
|
||||
|
||||
gfx::Rect bounds(origin, element_bounds_.size());
|
||||
gfx::Rect window_bounds = parent_->GetBoundsInScreen();
|
||||
|
||||
int desired_width = GetDesiredPopupWidth();
|
||||
int desired_height = GetDesiredPopupHeight();
|
||||
bool is_rtl = false;
|
||||
|
||||
gfx::Point top_left_corner_of_popup =
|
||||
origin + gfx::Vector2d(bounds.width() - desired_width, -desired_height);
|
||||
|
||||
// This is the bottom right point of the popup if the popup is below the
|
||||
// element and grows to the right (since the is the lowest and furthest right
|
||||
// the popup could go).
|
||||
gfx::Point bottom_right_corner_of_popup =
|
||||
origin + gfx::Vector2d(desired_width, bounds.height() + desired_height);
|
||||
|
||||
display::Display top_left_display =
|
||||
GetDisplayNearestPoint(top_left_corner_of_popup);
|
||||
display::Display bottom_right_display =
|
||||
GetDisplayNearestPoint(bottom_right_corner_of_popup);
|
||||
|
||||
std::pair<int, int> popup_x_and_width = CalculatePopupXAndWidth(
|
||||
top_left_display, bottom_right_display, desired_width, bounds, is_rtl);
|
||||
std::pair<int, int> popup_y_and_height = CalculatePopupYAndHeight(
|
||||
top_left_display, bottom_right_display, desired_height, bounds);
|
||||
|
||||
popup_bounds_ =
|
||||
gfx::Rect(popup_x_and_width.first, popup_y_and_height.first,
|
||||
popup_x_and_width.second, popup_y_and_height.second);
|
||||
PopupViewCommon popup_view_common(window_bounds);
|
||||
popup_bounds_ = popup_view_common.CalculatePopupBounds(
|
||||
GetDesiredPopupWidth(), GetDesiredPopupHeight(), bounds,
|
||||
gfx::NativeView(), base::i18n::IsRTL());
|
||||
}
|
||||
|
||||
gfx::Rect AutofillPopup::popup_bounds_in_view() {
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface NSColor (Hex)
|
||||
- (NSString*)hexadecimalValue;
|
||||
- (NSString*)RGBAValue;
|
||||
+ (NSColor*)colorWithHexColorString:(NSString*)hex;
|
||||
@end
|
||||
|
||||
|
||||
@@ -8,17 +8,65 @@
|
||||
|
||||
@implementation NSColor (Hex)
|
||||
|
||||
- (NSString*)RGBAValue {
|
||||
double redFloatValue, greenFloatValue, blueFloatValue, alphaFloatValue;
|
||||
|
||||
NSColor* convertedColor =
|
||||
[self colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
|
||||
|
||||
if (convertedColor) {
|
||||
[convertedColor getRed:&redFloatValue
|
||||
green:&greenFloatValue
|
||||
blue:&blueFloatValue
|
||||
alpha:&alphaFloatValue];
|
||||
|
||||
int redIntValue = redFloatValue * 255.99999f;
|
||||
int greenIntValue = greenFloatValue * 255.99999f;
|
||||
int blueIntValue = blueFloatValue * 255.99999f;
|
||||
int alphaIntValue = alphaFloatValue * 255.99999f;
|
||||
|
||||
return
|
||||
[NSString stringWithFormat:@"%02x%02x%02x%02x", redIntValue,
|
||||
greenIntValue, blueIntValue, alphaIntValue];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString*)hexadecimalValue {
|
||||
double redFloatValue, greenFloatValue, blueFloatValue;
|
||||
|
||||
NSColor* convertedColor =
|
||||
[self colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
|
||||
|
||||
if (convertedColor) {
|
||||
[convertedColor getRed:&redFloatValue
|
||||
green:&greenFloatValue
|
||||
blue:&blueFloatValue
|
||||
alpha:NULL];
|
||||
|
||||
int redIntValue = redFloatValue * 255.99999f;
|
||||
int greenIntValue = greenFloatValue * 255.99999f;
|
||||
int blueIntValue = blueFloatValue * 255.99999f;
|
||||
|
||||
return [NSString stringWithFormat:@"#%02x%02x%02x", redIntValue,
|
||||
greenIntValue, blueIntValue];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (NSColor*)colorWithHexColorString:(NSString*)inColorString {
|
||||
unsigned colorCode = 0;
|
||||
unsigned char redByte, greenByte, blueByte;
|
||||
|
||||
if (inColorString) {
|
||||
NSScanner* scanner = [NSScanner scannerWithString:inColorString];
|
||||
(void)[scanner scanHexInt:&colorCode]; // ignore error
|
||||
}
|
||||
redByte = (unsigned char)(colorCode >> 16);
|
||||
greenByte = (unsigned char)(colorCode >> 8);
|
||||
blueByte = (unsigned char)(colorCode); // masks off high bits
|
||||
|
||||
unsigned char redByte = (unsigned char)(colorCode >> 16);
|
||||
unsigned char greenByte = (unsigned char)(colorCode >> 8);
|
||||
unsigned char blueByte = (unsigned char)(colorCode); // masks off high bits
|
||||
|
||||
return [NSColor colorWithCalibratedRed:(CGFloat)redByte / 0xff
|
||||
green:(CGFloat)greenByte / 0xff
|
||||
|
||||
@@ -353,8 +353,11 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
|
||||
NSButton* button = (NSButton*)item.view;
|
||||
|
||||
std::string backgroundColor;
|
||||
if (settings.Get("backgroundColor", &backgroundColor)) {
|
||||
if (settings.Get("backgroundColor", &backgroundColor) &&
|
||||
!backgroundColor.empty()) {
|
||||
button.bezelColor = [self colorFromHexColorString:backgroundColor];
|
||||
} else {
|
||||
button.bezelColor = nil;
|
||||
}
|
||||
|
||||
std::string label;
|
||||
|
||||
@@ -16,7 +16,19 @@ ViewsDelegateMac::~ViewsDelegateMac() {}
|
||||
void ViewsDelegateMac::OnBeforeWidgetInit(
|
||||
views::Widget::InitParams* params,
|
||||
views::internal::NativeWidgetDelegate* delegate) {
|
||||
DCHECK(params->native_widget);
|
||||
// If we already have a native_widget, we don't have to try to come
|
||||
// up with one.
|
||||
if (params->native_widget)
|
||||
return;
|
||||
|
||||
if (!native_widget_factory().is_null()) {
|
||||
params->native_widget = native_widget_factory().Run(*params, delegate);
|
||||
if (params->native_widget)
|
||||
return;
|
||||
}
|
||||
|
||||
// Setting null here causes Widget to create the default NativeWidget implementation.
|
||||
params->native_widget = nullptr;
|
||||
}
|
||||
|
||||
ui::ContextFactory* ViewsDelegateMac::GetContextFactory() {
|
||||
|
||||
@@ -8,9 +8,11 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/atom_paths.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
@@ -67,7 +69,7 @@ std::unique_ptr<content::DevToolsSocketFactory> CreateSocketFactory() {
|
||||
int temp_port;
|
||||
std::string port_str =
|
||||
command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort);
|
||||
if (base::StringToInt(port_str, &temp_port) && temp_port > 0 &&
|
||||
if (base::StringToInt(port_str, &temp_port) && temp_port >= 0 &&
|
||||
temp_port < 65535) {
|
||||
port = temp_port;
|
||||
} else {
|
||||
@@ -84,8 +86,10 @@ std::unique_ptr<content::DevToolsSocketFactory> CreateSocketFactory() {
|
||||
|
||||
// static
|
||||
void DevToolsManagerDelegate::StartHttpHandler() {
|
||||
base::FilePath user_dir;
|
||||
base::PathService::Get(DIR_USER_DATA, &user_dir);
|
||||
content::DevToolsAgentHost::StartRemoteDebuggingServer(
|
||||
CreateSocketFactory(), base::FilePath(), base::FilePath());
|
||||
CreateSocketFactory(), user_dir, base::FilePath());
|
||||
}
|
||||
|
||||
DevToolsManagerDelegate::DevToolsManagerDelegate() {}
|
||||
|
||||
@@ -29,6 +29,7 @@ class TrayIconCocoa : public TrayIcon, public AtomMenuModel::Observer {
|
||||
void SetHighlightMode(TrayIcon::HighlightMode mode) override;
|
||||
void SetIgnoreDoubleClickEvents(bool ignore) override;
|
||||
bool GetIgnoreDoubleClickEvents() override;
|
||||
void PopUpOnUI(AtomMenuModel* menu_model);
|
||||
void PopUpContextMenu(const gfx::Point& pos,
|
||||
AtomMenuModel* menu_model) override;
|
||||
void SetContextMenu(AtomMenuModel* menu_model) override;
|
||||
@@ -48,6 +49,8 @@ class TrayIconCocoa : public TrayIcon, public AtomMenuModel::Observer {
|
||||
// Used for unregistering observer.
|
||||
AtomMenuModel* menu_model_ = nullptr; // weak ref.
|
||||
|
||||
base::WeakPtrFactory<TrayIconCocoa> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TrayIconCocoa);
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user