mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
349 Commits
v6.0.0-bet
...
6-1-x
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb408dbb5b | ||
|
|
70dd6c1bdf | ||
|
|
45089c847b | ||
|
|
fc417894f3 | ||
|
|
32af89963e | ||
|
|
1bf5703e73 | ||
|
|
c821657a7b | ||
|
|
f4324fbd6a | ||
|
|
f2297c81dd | ||
|
|
12ea5a028d | ||
|
|
f452b9f9ac | ||
|
|
ae8956064d | ||
|
|
ee20443741 | ||
|
|
c4b90afab8 | ||
|
|
d0a326c1d6 | ||
|
|
dac2137420 | ||
|
|
b355d722dc | ||
|
|
890bd47caf | ||
|
|
4c09496cf0 | ||
|
|
8af46e4ed7 | ||
|
|
cbc0112991 | ||
|
|
0f67fac1ad | ||
|
|
18877923b3 | ||
|
|
61137132ba | ||
|
|
16af7fdc20 | ||
|
|
9ca060df7f | ||
|
|
2ef57ce93d | ||
|
|
65eca25a63 | ||
|
|
bbed4b1f71 | ||
|
|
61d0fa5147 | ||
|
|
fb9b281515 | ||
|
|
9a058fb766 | ||
|
|
15c60bafe7 | ||
|
|
4ae22e003b | ||
|
|
a1d039c0a8 | ||
|
|
63b6f49d1f | ||
|
|
bdabef56d4 | ||
|
|
6c90f5c73a | ||
|
|
bc6cc1a1f9 | ||
|
|
4f8bc49ea0 | ||
|
|
b945793011 | ||
|
|
78d92f5349 | ||
|
|
19c0ff75fc | ||
|
|
bdd19d9b28 | ||
|
|
26ee9476de | ||
|
|
2c01ed5529 | ||
|
|
2b3d4b4cdf | ||
|
|
3b4c04dbaf | ||
|
|
3b1a452406 | ||
|
|
062c3ec700 | ||
|
|
e5966bad8a | ||
|
|
2156a6b23c | ||
|
|
38ed0e5a47 | ||
|
|
831e060caf | ||
|
|
a7ddb0ea45 | ||
|
|
9b52ee4e86 | ||
|
|
6773a51ec3 | ||
|
|
2327947ed6 | ||
|
|
dca6516c10 | ||
|
|
f27fde70ef | ||
|
|
1498f7c24b | ||
|
|
dde1ddade9 | ||
|
|
2ca6450c73 | ||
|
|
e020754249 | ||
|
|
15ea59bbb3 | ||
|
|
7a65aebcfd | ||
|
|
dffecfaf59 | ||
|
|
eff5cee15b | ||
|
|
03d5ae2f93 | ||
|
|
b142266292 | ||
|
|
7dd6a185db | ||
|
|
47ee65c66c | ||
|
|
530fc1e2a4 | ||
|
|
32aca15962 | ||
|
|
8c531ed424 | ||
|
|
cbe447e27a | ||
|
|
19c705ab80 | ||
|
|
42b4433fe4 | ||
|
|
8c8d3d2974 | ||
|
|
5c0319e00e | ||
|
|
9743d70131 | ||
|
|
ba2841ccee | ||
|
|
6f62f91822 | ||
|
|
469d1cc1d6 | ||
|
|
0b2c61a10f | ||
|
|
3e52002406 | ||
|
|
86755f4353 | ||
|
|
25c87c0c26 | ||
|
|
1f64aaf171 | ||
|
|
7a5e281ae1 | ||
|
|
511bfd226c | ||
|
|
73b97d6109 | ||
|
|
bd96771ea9 | ||
|
|
988c57369a | ||
|
|
3d10d4c7e0 | ||
|
|
503c86bf89 | ||
|
|
66ee417697 | ||
|
|
a5b474e824 | ||
|
|
1591e1320a | ||
|
|
4c25b619a6 | ||
|
|
c2c25f1ee3 | ||
|
|
8cf8c8fe63 | ||
|
|
61fdda3e8f | ||
|
|
4a5f89d5c7 | ||
|
|
36fd0e9b37 | ||
|
|
512736542b | ||
|
|
b144900c00 | ||
|
|
dabaa7557a | ||
|
|
c6a794d738 | ||
|
|
aa863bc323 | ||
|
|
e3a79d6c52 | ||
|
|
14ba3ac63e | ||
|
|
6a07825c47 | ||
|
|
70b5e673bb | ||
|
|
6359db712a | ||
|
|
268cd3939c | ||
|
|
3ca62d9432 | ||
|
|
9901700a91 | ||
|
|
d5b088bc26 | ||
|
|
a12de693b0 | ||
|
|
e257981a6d | ||
|
|
ffb96acab0 | ||
|
|
fd0b57f219 | ||
|
|
1e50380fab | ||
|
|
31ba6c203e | ||
|
|
03d16f37d2 | ||
|
|
e501930d38 | ||
|
|
28eb7b0532 | ||
|
|
15e611a0ff | ||
|
|
3176e323e4 | ||
|
|
99a0581d0d | ||
|
|
4e417e21b8 | ||
|
|
e472efbea2 | ||
|
|
886e636b13 | ||
|
|
0450ee9524 | ||
|
|
ce31dc3591 | ||
|
|
15c89c8262 | ||
|
|
dbd72b2265 | ||
|
|
10a9e9c043 | ||
|
|
690271e38c | ||
|
|
fc7ef4cc1c | ||
|
|
f2d1abd0e3 | ||
|
|
e3be323962 | ||
|
|
407747b48c | ||
|
|
17b8b551ac | ||
|
|
4bcbe55828 | ||
|
|
8f84626531 | ||
|
|
69d3a694f4 | ||
|
|
3925c098fb | ||
|
|
75dd6e5a71 | ||
|
|
204c111da1 | ||
|
|
ed9b96ce9e | ||
|
|
0f27712e8f | ||
|
|
b2da0b883d | ||
|
|
4662ab9b63 | ||
|
|
e070bd7bdb | ||
|
|
a8ec0de153 | ||
|
|
34c6e05a82 | ||
|
|
97798a4aad | ||
|
|
837948759f | ||
|
|
8b6fa783f4 | ||
|
|
ed7ae42c10 | ||
|
|
828038d5f6 | ||
|
|
f1a914c0ba | ||
|
|
5eff97c890 | ||
|
|
0039e604a2 | ||
|
|
26176eb108 | ||
|
|
fb82bfa707 | ||
|
|
9b724dca49 | ||
|
|
b52a2aedf1 | ||
|
|
8e671dafc1 | ||
|
|
0491abf4cc | ||
|
|
1655976841 | ||
|
|
0b5a7379f2 | ||
|
|
a5ed8fb65e | ||
|
|
bb631892b2 | ||
|
|
64026ded95 | ||
|
|
e6178f83fe | ||
|
|
ee5403d3ec | ||
|
|
6b77e2ee14 | ||
|
|
075b085cb4 | ||
|
|
cbd017572a | ||
|
|
3f0c863225 | ||
|
|
a459cee938 | ||
|
|
783614a94c | ||
|
|
db1395628a | ||
|
|
5e33a5e778 | ||
|
|
ce502b19ba | ||
|
|
1cfd7160dc | ||
|
|
339174dca0 | ||
|
|
6964a8cd72 | ||
|
|
51a97917e0 | ||
|
|
3ca1cd4dd4 | ||
|
|
c2c0ee7a73 | ||
|
|
739f620152 | ||
|
|
fb379c3b6a | ||
|
|
237688abb3 | ||
|
|
94070cec53 | ||
|
|
e8ef52bc1d | ||
|
|
2f9876a3f9 | ||
|
|
5ca94a8715 | ||
|
|
ffd1d6d8ad | ||
|
|
33c86527e8 | ||
|
|
871f123080 | ||
|
|
3dcf66839e | ||
|
|
78a2237add | ||
|
|
be68c062d7 | ||
|
|
dbf8872817 | ||
|
|
a50e3b3f5f | ||
|
|
063bcb68f2 | ||
|
|
364e8b1a1d | ||
|
|
779f285777 | ||
|
|
4e1a5a210a | ||
|
|
98d78f2fb5 | ||
|
|
a8e70a8546 | ||
|
|
1ca76e8e74 | ||
|
|
16757d16e7 | ||
|
|
d2b2b97c29 | ||
|
|
6bc7bc11d8 | ||
|
|
f3d4daa9e5 | ||
|
|
6c0157aa29 | ||
|
|
a9e0aa22a4 | ||
|
|
56160e990e | ||
|
|
ab83309c7a | ||
|
|
c474ff101c | ||
|
|
54902e848f | ||
|
|
7bec7e6cee | ||
|
|
55224e385e | ||
|
|
75fecf4e4f | ||
|
|
f2f483fedb | ||
|
|
5614ae4241 | ||
|
|
55abf1f3a1 | ||
|
|
0f78f8a66c | ||
|
|
fa4a26a1db | ||
|
|
7ba29f1fa8 | ||
|
|
2f148fdaf4 | ||
|
|
19c31c684a | ||
|
|
c61a20c390 | ||
|
|
4ae3031faf | ||
|
|
72fee2ed78 | ||
|
|
cba1a946d5 | ||
|
|
c55bc8106f | ||
|
|
261f7fd3be | ||
|
|
53894d5ac2 | ||
|
|
c006a6db66 | ||
|
|
a306fdf512 | ||
|
|
825bd6d45e | ||
|
|
922a4d9ba6 | ||
|
|
f20d497f1c | ||
|
|
855bd92f6e | ||
|
|
60d36e1b74 | ||
|
|
9788089efb | ||
|
|
c0e9761b4b | ||
|
|
7e6617be18 | ||
|
|
38b6a7bf4f | ||
|
|
0aec64960b | ||
|
|
eab462f7cf | ||
|
|
5ccdb8c7cd | ||
|
|
dc38746b24 | ||
|
|
66c2bd2a02 | ||
|
|
cbfd276917 | ||
|
|
450a83d0f7 | ||
|
|
b7408e61d2 | ||
|
|
9d333a72e1 | ||
|
|
c5f4fe09aa | ||
|
|
38f2d11c39 | ||
|
|
3c852e79e6 | ||
|
|
019e60517f | ||
|
|
fb51509153 | ||
|
|
f3b9f58b7f | ||
|
|
a49307bc55 | ||
|
|
742292f082 | ||
|
|
bb0f4fdbdf | ||
|
|
5e2ca967c9 | ||
|
|
c8029d1696 | ||
|
|
08aa86e55e | ||
|
|
825c082535 | ||
|
|
4a073e4f7e | ||
|
|
adffa99e05 | ||
|
|
51f03033a4 | ||
|
|
733251866c | ||
|
|
41a7d9e42b | ||
|
|
ddbbf34433 | ||
|
|
6f65dec6a2 | ||
|
|
a66657112c | ||
|
|
f5c3394930 | ||
|
|
84bae64def | ||
|
|
4185b93abb | ||
|
|
b1e9f50fad | ||
|
|
6bd901d9ca | ||
|
|
1c2b8f8d9a | ||
|
|
cb9b288d8b | ||
|
|
69fe33a2b1 | ||
|
|
52b42546ed | ||
|
|
8a285f29ed | ||
|
|
92df6cc36c | ||
|
|
ab91656148 | ||
|
|
1fb1e5b2b2 | ||
|
|
54908b56e5 | ||
|
|
48bc247ef7 | ||
|
|
19d9955125 | ||
|
|
24d79d9e5c | ||
|
|
27d0a4d33d | ||
|
|
48226f71ad | ||
|
|
a4acc16e10 | ||
|
|
d8dd94e3a3 | ||
|
|
eb48dcf0a3 | ||
|
|
adfe537e32 | ||
|
|
0d5d54cbae | ||
|
|
988ad92415 | ||
|
|
5dbcdbc3d8 | ||
|
|
212c6b1266 | ||
|
|
74b06ab677 | ||
|
|
9a1c952ab6 | ||
|
|
f36f90b60f | ||
|
|
a603a4dde8 | ||
|
|
3e033b4f27 | ||
|
|
03be4c67d5 | ||
|
|
b20fe76db7 | ||
|
|
503da640f7 | ||
|
|
bd48dfe3cc | ||
|
|
9b47f587a6 | ||
|
|
3a186dad5d | ||
|
|
7959f2e887 | ||
|
|
4868c95425 | ||
|
|
7fa41e3302 | ||
|
|
f3346437be | ||
|
|
6de6d7f6c0 | ||
|
|
eb15be06e3 | ||
|
|
7748decc60 | ||
|
|
d75750ab01 | ||
|
|
152781226e | ||
|
|
7e3bbb6ace | ||
|
|
3c3eb2f65d | ||
|
|
5a83d9e64d | ||
|
|
97bec607fe | ||
|
|
b56ca98b72 | ||
|
|
eeccdc2d5c | ||
|
|
47827ed45c | ||
|
|
d3f7bdd0b3 | ||
|
|
438c50bf14 | ||
|
|
33d860bcea | ||
|
|
2401a2afe9 | ||
|
|
852f0be0b2 | ||
|
|
18ec438eaf | ||
|
|
f7042c8d1b | ||
|
|
bc73f93e6c | ||
|
|
7091508678 | ||
|
|
6d9d66b88a |
File diff suppressed because it is too large
Load Diff
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1,3 +1,4 @@
|
||||
# `git apply` and friends don't understand CRLF, even on windows. Force those
|
||||
# files to be checked out with LF endings even if core.autocrlf is true.
|
||||
*.patch text eol=lf
|
||||
patches/**/.patches merge=union
|
||||
|
||||
14
.github/CODEOWNERS
vendored
14
.github/CODEOWNERS
vendored
@@ -4,17 +4,19 @@
|
||||
# https://git-scm.com/docs/gitignore
|
||||
|
||||
# Most stuff in here is owned by the Community & Safety WG...
|
||||
/.github/* @electron/wg-community
|
||||
/.github/* @electron/wg-community
|
||||
|
||||
# ...except the Admin WG maintains this file.
|
||||
/.github/CODEOWNERS @electron/wg-admin
|
||||
/.github/CODEOWNERS @electron/wg-admin
|
||||
|
||||
# Upgrades WG
|
||||
/patches/ @electron/wg-upgrades
|
||||
/patches/ @electron/wg-upgrades
|
||||
DEPS @electron/wg-upgrades
|
||||
|
||||
|
||||
# Docs & Tooling WG
|
||||
/default_app/ @electron/wg-docs-tools
|
||||
/docs/ @electron/wg-docs-tools
|
||||
/default_app/ @electron/wg-docs-tools
|
||||
/docs/ @electron/wg-docs-tools
|
||||
|
||||
# Releases WG
|
||||
/npm/ @electron/wg-releases
|
||||
/npm/ @electron/wg-releases
|
||||
|
||||
296
BUILD.gn
296
BUILD.gn
@@ -1,6 +1,7 @@
|
||||
import("//build/config/locales.gni")
|
||||
import("//build/config/ui.gni")
|
||||
import("//build/config/win/manifest.gni")
|
||||
import("//content/public/app/mac_helpers.gni")
|
||||
import("//pdf/features.gni")
|
||||
import("//printing/buildflags/buildflags.gni")
|
||||
import("//third_party/ffmpeg/ffmpeg_options.gni")
|
||||
@@ -10,6 +11,7 @@ import("//tools/grit/repack.gni")
|
||||
import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
|
||||
import("//v8/gni/snapshot_toolchain.gni")
|
||||
import("build/asar.gni")
|
||||
import("build/extract_symbols.gni")
|
||||
import("build/js_wrap.gni")
|
||||
import("build/npm.gni")
|
||||
import("build/tsc.gni")
|
||||
@@ -21,6 +23,7 @@ import("filenames.gni")
|
||||
if (is_mac) {
|
||||
import("//build/config/mac/rules.gni")
|
||||
import("//third_party/icu/config.gni")
|
||||
import("//ui/gl/features.gni")
|
||||
import("//v8/gni/v8.gni")
|
||||
}
|
||||
|
||||
@@ -231,7 +234,7 @@ action("atom_js2c") {
|
||||
"$target_gen_dir/js2c/asar_init.js",
|
||||
]
|
||||
|
||||
inputs = sources
|
||||
inputs = sources + [ "//third_party/electron_node/tools/js2c.py" ]
|
||||
outputs = [
|
||||
"$root_gen_dir/atom_natives.cc",
|
||||
]
|
||||
@@ -546,21 +549,14 @@ static_library("electron_lib") {
|
||||
if (is_mac) {
|
||||
deps += [
|
||||
"//components/remote_cocoa/app_shim",
|
||||
"//third_party/crashpad/crashpad/client",
|
||||
"//content/common:mac_helpers",
|
||||
"//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
|
||||
# the #includes can be agnostic about where crashpad is vendored.
|
||||
"//third_party/crashpad",
|
||||
]
|
||||
if (is_mas_build) {
|
||||
deps -= [ "//third_party/crashpad/crashpad/client" ]
|
||||
sources += [ "atom/browser/api/atom_api_app_mas.mm" ]
|
||||
sources -= [
|
||||
"atom/browser/auto_updater_mac.mm",
|
||||
@@ -590,10 +586,14 @@ static_library("electron_lib") {
|
||||
"//chrome/browser/ui/libgtkui",
|
||||
"//dbus",
|
||||
"//device/bluetooth",
|
||||
"//third_party/breakpad:client",
|
||||
"//ui/events/devices/x11",
|
||||
"//ui/events/platform/x11",
|
||||
"//ui/views/controls/webview",
|
||||
"//ui/wm",
|
||||
]
|
||||
configs += [ ":gio_unix" ]
|
||||
include_dirs += [ "//third_party/breakpad" ]
|
||||
defines += [
|
||||
# Disable warnings for g_settings_list_schemas.
|
||||
"GLIB_DISABLE_DEPRECATION_WARNINGS",
|
||||
@@ -604,20 +604,23 @@ static_library("electron_lib") {
|
||||
if (is_win) {
|
||||
libs += [ "dwmapi.lib" ]
|
||||
deps += [
|
||||
"//third_party/breakpad:breakpad_handler",
|
||||
"//third_party/breakpad:breakpad_sender",
|
||||
"//ui/native_theme:native_theme_browser",
|
||||
"//ui/wm/public",
|
||||
]
|
||||
public_deps += [ "//sandbox/win:sandbox" ]
|
||||
}
|
||||
if (is_linux || is_win) {
|
||||
deps += [
|
||||
"//third_party/breakpad:client",
|
||||
"//ui/views/controls/webview",
|
||||
"//ui/wm",
|
||||
"//ui/wm/public",
|
||||
]
|
||||
include_dirs += [ "//third_party/breakpad" ]
|
||||
public_deps += [
|
||||
"//sandbox/win:sandbox",
|
||||
"//third_party/crashpad/crashpad/handler",
|
||||
]
|
||||
}
|
||||
|
||||
if ((is_mac && !is_mas_build) || is_win) {
|
||||
sources += [
|
||||
"atom/common/crash_reporter/crash_reporter_crashpad.cc",
|
||||
"atom/common/crash_reporter/crash_reporter_crashpad.h",
|
||||
]
|
||||
deps += [ "//third_party/crashpad/crashpad/client" ]
|
||||
}
|
||||
|
||||
if (enable_pdf) {
|
||||
@@ -654,9 +657,7 @@ static_library("electron_lib") {
|
||||
}
|
||||
|
||||
if (enable_desktop_capturer) {
|
||||
if (is_component_build && is_win) {
|
||||
# On windows the implementation relies on unexported
|
||||
# DxgiDuplicatorController class.
|
||||
if (is_component_build && !is_linux) {
|
||||
deps += [ "//third_party/webrtc/modules/desktop_capture" ]
|
||||
}
|
||||
sources += [
|
||||
@@ -712,6 +713,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 = [
|
||||
@@ -759,6 +761,50 @@ if (is_mac) {
|
||||
group("electron_framework_libraries") {
|
||||
}
|
||||
}
|
||||
if (use_egl) {
|
||||
# Add the ANGLE .dylibs in the Libraries directory of the Framework.
|
||||
bundle_data("electron_angle_binaries") {
|
||||
sources = [
|
||||
"$root_out_dir/egl_intermediates/libEGL.dylib",
|
||||
"$root_out_dir/egl_intermediates/libGLESv2.dylib",
|
||||
]
|
||||
outputs = [
|
||||
"{{bundle_contents_dir}}/Libraries/{{source_file_part}}",
|
||||
]
|
||||
public_deps = [
|
||||
"//ui/gl:angle_library_copy",
|
||||
]
|
||||
}
|
||||
|
||||
# Add the SwiftShader .dylibs in the Libraries directory of the Framework.
|
||||
bundle_data("electron_swiftshader_binaries") {
|
||||
sources = [
|
||||
"$root_out_dir/egl_intermediates/libswiftshader_libEGL.dylib",
|
||||
"$root_out_dir/egl_intermediates/libswiftshader_libGLESv2.dylib",
|
||||
]
|
||||
outputs = [
|
||||
"{{bundle_contents_dir}}/Libraries/{{source_file_part}}",
|
||||
]
|
||||
public_deps = [
|
||||
"//ui/gl:swiftshader_library_copy",
|
||||
]
|
||||
}
|
||||
}
|
||||
group("electron_angle_library") {
|
||||
if (use_egl) {
|
||||
deps = [
|
||||
":electron_angle_binaries",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
group("electron_swiftshader_library") {
|
||||
if (use_egl) {
|
||||
deps = [
|
||||
":electron_swiftshader_binaries",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
bundle_data("electron_crashpad_helper") {
|
||||
sources = [
|
||||
@@ -785,8 +831,10 @@ if (is_mac) {
|
||||
":electron_lib",
|
||||
]
|
||||
deps = [
|
||||
":electron_angle_library",
|
||||
":electron_framework_libraries",
|
||||
":electron_framework_resources",
|
||||
":electron_swiftshader_library",
|
||||
":electron_xibs",
|
||||
]
|
||||
if (!is_mas_build) {
|
||||
@@ -794,7 +842,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",
|
||||
@@ -834,35 +881,48 @@ if (is_mac) {
|
||||
}
|
||||
}
|
||||
|
||||
mac_app_bundle("electron_helper_app") {
|
||||
output_name = electron_helper_name
|
||||
deps = [
|
||||
":electron_framework+link",
|
||||
]
|
||||
if (!is_mas_build) {
|
||||
deps += [ "//sandbox/mac:seatbelt" ]
|
||||
}
|
||||
defines = [ "HELPER_EXECUTABLE" ]
|
||||
sources = filenames.app_sources
|
||||
include_dirs = [ "." ]
|
||||
info_plist = "atom/renderer/resources/mac/Info.plist"
|
||||
extra_substitutions = [ "ATOM_BUNDLE_ID=$electron_mac_bundle_id.helper" ]
|
||||
ldflags = [
|
||||
"-rpath",
|
||||
"@executable_path/../../..",
|
||||
]
|
||||
if (is_component_build) {
|
||||
ldflags += [
|
||||
"-rpath",
|
||||
"@executable_path/../../../../../..",
|
||||
template("electron_helper_app") {
|
||||
mac_app_bundle(target_name) {
|
||||
assert(defined(invoker.helper_name_suffix))
|
||||
|
||||
output_name = electron_helper_name + invoker.helper_name_suffix
|
||||
deps = [
|
||||
":electron_framework+link",
|
||||
]
|
||||
if (!is_mas_build) {
|
||||
deps += [ "//sandbox/mac:seatbelt" ]
|
||||
}
|
||||
defines = [ "HELPER_EXECUTABLE" ]
|
||||
sources = filenames.app_sources
|
||||
sources += [ "atom/common/atom_constants.cc" ]
|
||||
include_dirs = [ "." ]
|
||||
info_plist = "atom/renderer/resources/mac/Info.plist"
|
||||
extra_substitutions = [ "ATOM_BUNDLE_ID=$electron_mac_bundle_id.helper" ]
|
||||
ldflags = [
|
||||
"-rpath",
|
||||
"@executable_path/../../..",
|
||||
]
|
||||
if (is_component_build) {
|
||||
ldflags += [
|
||||
"-rpath",
|
||||
"@executable_path/../../../../../..",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach(helper_params, content_mac_helpers) {
|
||||
_helper_target = helper_params[0]
|
||||
_helper_bundle_id = helper_params[1]
|
||||
_helper_suffix = helper_params[2]
|
||||
electron_helper_app("electron_helper_app_${_helper_target}") {
|
||||
helper_name_suffix = _helper_suffix
|
||||
}
|
||||
}
|
||||
|
||||
bundle_data("electron_app_framework_bundle_data") {
|
||||
sources = [
|
||||
"$root_out_dir/$electron_framework_name.framework",
|
||||
"$root_out_dir/$electron_helper_name.app",
|
||||
]
|
||||
if (!is_mas_build) {
|
||||
sources += [
|
||||
@@ -876,8 +936,13 @@ if (is_mac) {
|
||||
]
|
||||
public_deps = [
|
||||
":electron_framework+link",
|
||||
":electron_helper_app",
|
||||
]
|
||||
|
||||
foreach(helper_params, content_mac_helpers) {
|
||||
sources +=
|
||||
[ "$root_out_dir/${electron_helper_name}${helper_params[2]}.app" ]
|
||||
public_deps += [ ":electron_helper_app_${helper_params[0]}" ]
|
||||
}
|
||||
}
|
||||
|
||||
mac_app_bundle("electron_login_helper") {
|
||||
@@ -951,6 +1016,7 @@ if (is_mac) {
|
||||
mac_app_bundle("electron_app") {
|
||||
output_name = electron_product_name
|
||||
sources = filenames.app_sources
|
||||
sources += [ "atom/common/atom_constants.cc" ]
|
||||
include_dirs = [ "." ]
|
||||
deps = [
|
||||
":electron_app_framework_bundle_data",
|
||||
@@ -966,6 +1032,85 @@ 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",
|
||||
]
|
||||
}
|
||||
|
||||
foreach(helper_params, content_mac_helpers) {
|
||||
_helper_target = helper_params[0]
|
||||
_helper_bundle_id = helper_params[1]
|
||||
_helper_suffix = helper_params[2]
|
||||
extract_symbols("electron_helper_syms_${_helper_target}") {
|
||||
binary = "$root_out_dir/$electron_helper_name${_helper_suffix}.app/Contents/MacOS/$electron_helper_name${_helper_suffix}"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/$electron_helper_name${_helper_suffix}.dSYM/Contents/Resources/DWARF/$electron_helper_name${_helper_suffix}"
|
||||
deps = [
|
||||
":electron_helper_app_${_helper_target}",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
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("swiftshader_egl_syms") {
|
||||
binary = "$root_out_dir/libswiftshader_libEGL.dylib"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/libswiftshader_libEGL.dylib.dSYM/Contents/Resources/DWARF/libswiftshader_libEGL.dylib"
|
||||
deps = [
|
||||
"//third_party/swiftshader/src/OpenGL/libEGL:swiftshader_libEGL",
|
||||
]
|
||||
}
|
||||
|
||||
extract_symbols("swiftshader_gles_syms") {
|
||||
binary = "$root_out_dir/libswiftshader_libGLESv2.dylib"
|
||||
symbol_dir = "$root_out_dir/breakpad_symbols"
|
||||
dsym_file = "$root_out_dir/libswiftshader_libGLESv2.dylib.dSYM/Contents/Resources/DWARF/libswiftshader_libGLESv2.dylib"
|
||||
deps = [
|
||||
"//third_party/swiftshader/src/OpenGL/libGLESv2:swiftshader_libGLESv2",
|
||||
]
|
||||
}
|
||||
|
||||
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",
|
||||
":swiftshader_egl_syms",
|
||||
":swiftshader_gles_syms",
|
||||
]
|
||||
|
||||
foreach(helper_params, content_mac_helpers) {
|
||||
_helper_target = helper_params[0]
|
||||
deps += [ ":electron_helper_syms_${_helper_target}" ]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
group("electron_symbols") {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
windows_manifest("electron_app_manifest") {
|
||||
sources = [
|
||||
@@ -1054,6 +1199,49 @@ 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",
|
||||
":swiftshader_egl_symbols",
|
||||
":swiftshader_gles_symbols",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template("dist_zip") {
|
||||
@@ -1160,12 +1348,18 @@ dist_zip("electron_chromedriver_zip") {
|
||||
]
|
||||
}
|
||||
|
||||
mksnapshot_deps = [
|
||||
":licenses",
|
||||
"//tools/v8_context_snapshot:v8_context_snapshot_generator($v8_snapshot_toolchain)",
|
||||
"//v8:mksnapshot($v8_snapshot_toolchain)",
|
||||
]
|
||||
|
||||
group("electron_mksnapshot") {
|
||||
public_deps = mksnapshot_deps
|
||||
}
|
||||
|
||||
dist_zip("electron_mksnapshot_zip") {
|
||||
data_deps = [
|
||||
"//v8:mksnapshot($v8_snapshot_toolchain)",
|
||||
"//tools/v8_context_snapshot:v8_context_snapshot_generator",
|
||||
":licenses",
|
||||
]
|
||||
data_deps = mksnapshot_deps
|
||||
outputs = [
|
||||
"$root_build_dir/mksnapshot.zip",
|
||||
]
|
||||
|
||||
42
DEPS
42
DEPS
@@ -10,9 +10,9 @@ gclient_gn_args = [
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'76.0.3809.22',
|
||||
'76.0.3809.146',
|
||||
'node_version':
|
||||
'a86a4a160dc520c61a602c949a32a1bc4c0fc633',
|
||||
'v12.4.0',
|
||||
|
||||
'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',
|
||||
|
||||
@@ -30,6 +31,9 @@ vars = {
|
||||
# To be able to build clean Chromium from sources.
|
||||
'apply_patches': True,
|
||||
|
||||
# Apply the patches specific to windows on arm64
|
||||
'apply_win_arm64_patches': False,
|
||||
|
||||
# Python interface to Amazon Web Services. Is used for releases only.
|
||||
'checkout_boto': False,
|
||||
|
||||
@@ -43,9 +47,11 @@ vars = {
|
||||
# Python "requests" module is used for releases only.
|
||||
'checkout_requests': False,
|
||||
|
||||
# To allow running hooks without parsing the DEPS tree
|
||||
'process_deps': True,
|
||||
# It is always needed for normal Electron builds,
|
||||
# but might be impossible for custom in-house builds.
|
||||
'download_external_binaries': True,
|
||||
'download_external_binaries': False,
|
||||
|
||||
'checkout_nacl':
|
||||
False,
|
||||
@@ -64,30 +70,30 @@ vars = {
|
||||
deps = {
|
||||
'src': {
|
||||
'url': (Var("chromium_git")) + '/chromium/src.git@' + (Var("chromium_version")),
|
||||
'condition': 'checkout_chromium',
|
||||
'condition': 'checkout_chromium and process_deps',
|
||||
},
|
||||
'src/third_party/electron_node': {
|
||||
'url': (Var("electron_git")) + '/node.git@' + (Var("node_version")),
|
||||
'condition': 'checkout_node',
|
||||
'url': (Var("nodejs_git")) + '/node.git@' + (Var("node_version")),
|
||||
'condition': 'checkout_node and process_deps',
|
||||
},
|
||||
'src/electron/vendor/pyyaml': {
|
||||
'url': (Var("yaml_git")) + '/pyyaml.git@' + (Var("pyyaml_version")),
|
||||
'condition': 'checkout_pyyaml',
|
||||
'condition': 'checkout_pyyaml and process_deps',
|
||||
},
|
||||
'src/electron/vendor/boto': {
|
||||
'url': Var('boto_git') + '/boto.git' + '@' + Var('boto_version'),
|
||||
'condition': 'checkout_boto',
|
||||
'condition': 'checkout_boto and process_deps',
|
||||
},
|
||||
'src/electron/vendor/requests': {
|
||||
'url': Var('requests_git') + '/requests.git' + '@' + Var('requests_version'),
|
||||
'condition': 'checkout_requests',
|
||||
'condition': 'checkout_requests and process_deps',
|
||||
},
|
||||
}
|
||||
|
||||
hooks = [
|
||||
{
|
||||
'name': 'patch_chromium',
|
||||
'condition': 'checkout_chromium and apply_patches',
|
||||
'condition': '(checkout_chromium and apply_patches) and process_deps',
|
||||
'pattern': 'src/electron',
|
||||
'action': [
|
||||
'python',
|
||||
@@ -95,6 +101,16 @@ hooks = [
|
||||
'src/electron/patches/common/config.json',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'patch_chromium',
|
||||
'condition': '(checkout_chromium and apply_patches) and apply_win_arm64_patches',
|
||||
'pattern': 'src/electron',
|
||||
'action': [
|
||||
'python',
|
||||
'src/electron/script/apply_all_patches.py',
|
||||
'src/electron/patches/win_arm64/config.json',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'electron_external_binaries',
|
||||
'pattern': 'src/electron/script/update-external-binaries.py',
|
||||
@@ -116,7 +132,7 @@ hooks = [
|
||||
{
|
||||
'name': 'setup_boto',
|
||||
'pattern': 'src/electron',
|
||||
'condition': 'checkout_boto',
|
||||
'condition': 'checkout_boto and process_deps',
|
||||
'action': [
|
||||
'python',
|
||||
'-c',
|
||||
@@ -126,7 +142,7 @@ hooks = [
|
||||
{
|
||||
'name': 'setup_requests',
|
||||
'pattern': 'src/electron',
|
||||
'condition': 'checkout_requests',
|
||||
'condition': 'checkout_requests and process_deps',
|
||||
'action': [
|
||||
'python',
|
||||
'-c',
|
||||
@@ -138,3 +154,5 @@ hooks = [
|
||||
recursedeps = [
|
||||
'src',
|
||||
]
|
||||
|
||||
# Touch DEPS to bust cache
|
||||
|
||||
@@ -1 +1 @@
|
||||
6.0.0-beta.7
|
||||
6.1.12
|
||||
@@ -2,10 +2,8 @@
|
||||
|
||||
|
||||
[](https://circleci.com/gh/electron/electron/tree/master)
|
||||
[](https://windows-ci.electronjs.org/project/AppVeyor/electron/branch/master)
|
||||
[](https://github.visualstudio.com/electron/_build/latest?definitionId=36)
|
||||
[](https://ci.appveyor.com/project/electron-bot/electron-ljo26/branch/master)
|
||||
[](https://david-dm.org/electron/electron?type=dev)
|
||||
[](https://atom-slack.herokuapp.com/)
|
||||
|
||||
:memo: Available Translations: 🇨🇳 🇹🇼 🇧🇷 🇪🇸 🇰🇷 🇯🇵 🇷🇺 🇫🇷 🇹🇭 🇳🇱 🇹🇷 🇮🇩 🇺🇦 🇨🇿 🇮🇹 🇵🇱.
|
||||
View these docs in other languages at [electron/i18n](https://github.com/electron/i18n/tree/master/content/).
|
||||
|
||||
21
appveyor.yml
21
appveyor.yml
@@ -28,7 +28,6 @@ build_cloud: libcc-20
|
||||
image: libcc-20-vs2017-15.9
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\electron\libcc_cache
|
||||
DISABLE_CRASH_REPORTER_TESTS: true
|
||||
ELECTRON_OUT_DIR: Default
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
build_script:
|
||||
@@ -45,7 +44,7 @@ build_script:
|
||||
- ps: $env:SCCACHE_PATH="$pwd\src\electron\external_binaries\sccache.exe"
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
$env:GCLIENT_EXTRA_ARGS="--custom-var=checkout_boto=True --custom-var=checkout_requests=True"
|
||||
$env:GCLIENT_EXTRA_ARGS="$env:GCLIENT_EXTRA_ARGS --custom-var=checkout_boto=True --custom-var=checkout_requests=True"
|
||||
}
|
||||
- >-
|
||||
gclient config
|
||||
@@ -54,6 +53,8 @@ build_script:
|
||||
%GCLIENT_EXTRA_ARGS%
|
||||
"https://github.com/electron/electron"
|
||||
- gclient sync --with_branch_heads --with_tags --reset
|
||||
# Manually run update-external-binaries.py with system python
|
||||
- python src/electron/script/update-external-binaries.py
|
||||
- cd src
|
||||
- ps: $env:BUILD_CONFIG_PATH="//electron/build/args/%GN_CONFIG%.gn"
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS%"
|
||||
@@ -71,21 +72,27 @@ build_script:
|
||||
- appveyor PushArtifact out/Default/dist.zip
|
||||
- appveyor PushArtifact out/Default/chromedriver.zip
|
||||
- appveyor PushArtifact out/ffmpeg/ffmpeg.zip
|
||||
- 7z a node_headers.zip out\Default\gen\node_headers
|
||||
- appveyor PushArtifact node_headers.zip
|
||||
- appveyor PushArtifact out/Default/mksnapshot.zip
|
||||
- appveyor PushArtifact out/Default/electron.lib
|
||||
- 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:
|
||||
# Workaround for https://github.com/appveyor/ci/issues/2420
|
||||
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
|
||||
- ps: >-
|
||||
if ((-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
|
||||
if ((-Not (Test-Path Env:\TEST_WOA)) -And (-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
|
||||
$env:RUN_TESTS="true"
|
||||
}
|
||||
- ps: >-
|
||||
@@ -96,7 +103,7 @@ test_script:
|
||||
echo "Skipping tests for $env:GN_CONFIG build"
|
||||
}
|
||||
- cd electron
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running test suite & npm run test -- --ci --enable-logging)
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running test suite & node script/yarn test -- --ci --enable-logging)
|
||||
- cd ..
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
|
||||
- echo "About to verify mksnapshot"
|
||||
@@ -113,4 +120,6 @@ deploy_script:
|
||||
Write-Output "Uploading Electron release distribution to github releases"
|
||||
& python script\upload.py
|
||||
}
|
||||
} elseif (Test-Path Env:\TEST_WOA) {
|
||||
node script/ci-release-build.js --job=electron-woa-testing --ci=VSTS --armTest --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "atom/app/atom_content_client.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/options_switches.h"
|
||||
@@ -14,14 +15,13 @@
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/common/content_constants.h"
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
#include "ppapi/buildflags/buildflags.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
#include "url/url_constants.h"
|
||||
// In SHARED_INTERMEDIATE_DIR.
|
||||
#include "widevine_cdm_version.h" // NOLINT(build/include)
|
||||
#include "widevine_cdm_version.h" // NOLINT(build/include_directory)
|
||||
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE)
|
||||
#include "base/native_library.h"
|
||||
@@ -34,6 +34,11 @@
|
||||
#include "pdf/pdf.h"
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
|
||||
#if BUILDFLAG(ENABLE_PLUGINS)
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
#endif // BUILDFLAG(ENABLE_PLUGINS)
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
@@ -140,6 +145,7 @@ void AddPepperFlashFromCommandLine(
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_PEPPER_FLASH)
|
||||
|
||||
#if BUILDFLAG(ENABLE_PLUGINS)
|
||||
void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
content::PepperPluginInfo pdf_info;
|
||||
@@ -160,15 +166,21 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
||||
plugins->push_back(pdf_info);
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_PLUGINS)
|
||||
|
||||
void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
|
||||
const char* separator,
|
||||
const char* cmd_switch) {
|
||||
void AppendDelimitedSwitchToVector(const base::StringPiece cmd_switch,
|
||||
std::vector<std::string>* append_me) {
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto string_with_separator = command_line->GetSwitchValueASCII(cmd_switch);
|
||||
if (!string_with_separator.empty())
|
||||
*vec = base::SplitString(string_with_separator, separator,
|
||||
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
auto switch_value = command_line->GetSwitchValueASCII(cmd_switch);
|
||||
if (!switch_value.empty()) {
|
||||
constexpr base::StringPiece delimiter(",", 1);
|
||||
auto tokens =
|
||||
base::SplitString(switch_value, delimiter, base::TRIM_WHITESPACE,
|
||||
base::SPLIT_WANT_NONEMPTY);
|
||||
append_me->reserve(append_me->size() + tokens.size());
|
||||
std::move(std::begin(tokens), std::end(tokens),
|
||||
std::back_inserter(*append_me));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -200,30 +212,19 @@ base::RefCountedMemory* AtomContentClient::GetDataResourceBytes(
|
||||
}
|
||||
|
||||
void AtomContentClient::AddAdditionalSchemes(Schemes* schemes) {
|
||||
std::vector<std::string> splited;
|
||||
ConvertStringWithSeparatorToVector(&splited, ",",
|
||||
switches::kServiceWorkerSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->service_worker_schemes.push_back(scheme);
|
||||
AppendDelimitedSwitchToVector(switches::kServiceWorkerSchemes,
|
||||
&schemes->service_worker_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kStandardSchemes,
|
||||
&schemes->standard_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kSecureSchemes,
|
||||
&schemes->secure_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kBypassCSPSchemes,
|
||||
&schemes->csp_bypassing_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kCORSSchemes,
|
||||
&schemes->cors_enabled_schemes);
|
||||
|
||||
schemes->service_worker_schemes.push_back(url::kFileScheme);
|
||||
|
||||
ConvertStringWithSeparatorToVector(&splited, ",", switches::kStandardSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->standard_schemes.push_back(scheme);
|
||||
schemes->standard_schemes.push_back("chrome-extension");
|
||||
|
||||
ConvertStringWithSeparatorToVector(&splited, ",", switches::kSecureSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->secure_schemes.push_back(scheme);
|
||||
|
||||
ConvertStringWithSeparatorToVector(&splited, ",",
|
||||
switches::kBypassCSPSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->csp_bypassing_schemes.push_back(scheme);
|
||||
|
||||
ConvertStringWithSeparatorToVector(&splited, ",", switches::kCORSSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->cors_enabled_schemes.push_back(scheme);
|
||||
}
|
||||
|
||||
void AtomContentClient::AddPepperPlugins(
|
||||
@@ -232,7 +233,9 @@ void AtomContentClient::AddPepperPlugins(
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
AddPepperFlashFromCommandLine(command_line, plugins);
|
||||
#endif // BUILDFLAG(ENABLE_PEPPER_FLASH)
|
||||
#if BUILDFLAG(ENABLE_PLUGINS)
|
||||
ComputeBuiltInPlugins(plugins);
|
||||
#endif // BUILDFLAG(ENABLE_PLUGINS)
|
||||
}
|
||||
|
||||
void AtomContentClient::AddContentDecryptionModules(
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "atom/app/atom_main.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@@ -39,6 +40,7 @@
|
||||
|
||||
#include "atom/app/node_main.h"
|
||||
#include "atom/common/atom_command_line.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "base/at_exit.h"
|
||||
#include "base/i18n/icu_util.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
@@ -49,10 +51,6 @@
|
||||
|
||||
namespace {
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
const char kRunAsNode[] = "ELECTRON_RUN_AS_NODE";
|
||||
#endif
|
||||
|
||||
ALLOW_UNUSED_TYPE bool IsEnvSet(const char* name) {
|
||||
#if defined(OS_WIN)
|
||||
size_t required_size;
|
||||
@@ -86,6 +84,11 @@ void FixStdioStreams() {
|
||||
} // namespace
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
namespace crash_reporter {
|
||||
extern const char kCrashpadProcess[];
|
||||
}
|
||||
|
||||
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
struct Arguments {
|
||||
int argc = 0;
|
||||
@@ -122,7 +125,7 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
bool run_as_node = IsEnvSet(kRunAsNode);
|
||||
bool run_as_node = IsEnvSet(atom::kRunAsNode);
|
||||
#else
|
||||
bool run_as_node = false;
|
||||
#endif
|
||||
@@ -131,30 +134,11 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE"))
|
||||
base::RouteStdioToConsole(false);
|
||||
|
||||
#ifndef DEBUG
|
||||
// Chromium has its own TLS subsystem which supports automatic destruction
|
||||
// of thread-local data, and also depends on memory allocation routines
|
||||
// provided by the CRT. The problem is that the auto-destruction mechanism
|
||||
// uses a hidden feature of the OS loader which calls a callback on thread
|
||||
// exit, but only after all loaded DLLs have been detached. Since the CRT is
|
||||
// also a DLL, it happens that by the time Chromium's `OnThreadExit` function
|
||||
// is called, the heap functions, though still in memory, no longer perform
|
||||
// their duties, and when Chromium calls `free` on its buffer, it triggers
|
||||
// an access violation error.
|
||||
// We work around this problem by invoking Chromium's `OnThreadExit` in time
|
||||
// from within the CRT's atexit facility, ensuring the heap functions are
|
||||
// still active. The second invocation from the OS loader will be a no-op.
|
||||
extern void NTAPI OnThreadExit(PVOID module, DWORD reason, PVOID reserved);
|
||||
atexit([]() { OnThreadExit(nullptr, DLL_THREAD_DETACH, nullptr); });
|
||||
#endif
|
||||
|
||||
std::vector<char*> argv(arguments.argc);
|
||||
std::transform(arguments.argv, arguments.argv + arguments.argc, argv.begin(),
|
||||
[](auto& a) { return _strdup(base::WideToUTF8(a).c_str()); });
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
if (run_as_node) {
|
||||
std::vector<char*> argv(arguments.argc);
|
||||
std::transform(
|
||||
arguments.argv, arguments.argv + arguments.argc, argv.begin(),
|
||||
[](auto& a) { return _strdup(base::WideToUTF8(a).c_str()); });
|
||||
|
||||
base::AtExitManager atexit_manager;
|
||||
base::i18n::InitializeICU();
|
||||
auto ret = atom::NodeMain(argv.size(), argv.data());
|
||||
@@ -163,8 +147,11 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) {
|
||||
return crash_service::Main(cmd);
|
||||
base::CommandLine::Init(argv.size(), argv.data());
|
||||
const base::CommandLine& cmd_line = *base::CommandLine::ForCurrentProcess();
|
||||
if (cmd_line.GetSwitchValueASCII("type") ==
|
||||
crash_reporter::kCrashpadProcess) {
|
||||
return crash_service::Main(&argv);
|
||||
}
|
||||
|
||||
if (!atom::CheckCommandLineArguments(arguments.argc, arguments.argv))
|
||||
@@ -187,7 +174,7 @@ int main(int argc, char* argv[]) {
|
||||
FixStdioStreams();
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
if (IsEnvSet(kRunAsNode)) {
|
||||
if (IsEnvSet(atom::kRunAsNode)) {
|
||||
base::i18n::InitializeICU();
|
||||
base::AtExitManager atexit_manager;
|
||||
return atom::NodeMain(argc, argv);
|
||||
@@ -208,7 +195,7 @@ int main(int argc, char* argv[]) {
|
||||
FixStdioStreams();
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
if (IsEnvSet(kRunAsNode)) {
|
||||
if (IsEnvSet(atom::kRunAsNode)) {
|
||||
return AtomInitializeICUandStartNode(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -49,6 +49,9 @@
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/win/win_util.h"
|
||||
#if defined(_WIN64)
|
||||
#include "atom/common/crash_reporter/crash_reporter_win.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
@@ -62,6 +65,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) {
|
||||
@@ -133,6 +141,10 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
|
||||
logging::LoggingSettings settings;
|
||||
#if defined(OS_WIN)
|
||||
#if defined(_WIN64)
|
||||
crash_reporter::CrashReporterWin::SetUnhandledExceptionFilter();
|
||||
#endif
|
||||
|
||||
// On Windows the terminal returns immediately, so we add a new line to
|
||||
// prevent output in the same line as the prompt.
|
||||
if (IsBrowserProcess(command_line))
|
||||
@@ -192,6 +204,14 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
base::win::PinUser32();
|
||||
#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());
|
||||
|
||||
@@ -268,10 +288,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);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "content/common/mac_helpers.h"
|
||||
#include "content/public/common/content_paths.h"
|
||||
|
||||
namespace atom {
|
||||
@@ -26,10 +27,26 @@ base::FilePath GetFrameworksPath() {
|
||||
|
||||
base::FilePath GetHelperAppPath(const base::FilePath& frameworks_path,
|
||||
const std::string& name) {
|
||||
return frameworks_path.Append(name + " Helper.app")
|
||||
// Figure out what helper we are running
|
||||
base::FilePath path;
|
||||
base::PathService::Get(base::FILE_EXE, &path);
|
||||
|
||||
std::string helper_name = "Helper";
|
||||
if (base::EndsWith(path.value(), content::kMacHelperSuffix_renderer,
|
||||
base::CompareCase::SENSITIVE)) {
|
||||
helper_name += content::kMacHelperSuffix_renderer;
|
||||
} else if (base::EndsWith(path.value(), content::kMacHelperSuffix_gpu,
|
||||
base::CompareCase::SENSITIVE)) {
|
||||
helper_name += content::kMacHelperSuffix_gpu;
|
||||
} else if (base::EndsWith(path.value(), content::kMacHelperSuffix_plugin,
|
||||
base::CompareCase::SENSITIVE)) {
|
||||
helper_name += content::kMacHelperSuffix_plugin;
|
||||
}
|
||||
|
||||
return frameworks_path.Append(name + " " + helper_name + ".app")
|
||||
.Append("Contents")
|
||||
.Append("MacOS")
|
||||
.Append(name + " Helper");
|
||||
.Append(name + " " + helper_name);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
#include "gin/v8_initializer.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#if defined(_WIN64)
|
||||
#include "atom/common/crash_reporter/crash_reporter_win.h"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
int NodeMain(int argc, char* argv[]) {
|
||||
@@ -43,6 +47,17 @@ int NodeMain(int argc, char* argv[]) {
|
||||
feature_list->InitializeFromCommandLine("", "");
|
||||
base::FeatureList::SetInstance(std::move(feature_list));
|
||||
|
||||
#if defined(_WIN64)
|
||||
crash_reporter::CrashReporterWin::SetUnhandledExceptionFilter();
|
||||
#endif
|
||||
|
||||
// Explicitly register electron's builtin modules.
|
||||
NodeBindings::RegisterBuiltinModules();
|
||||
|
||||
int exec_argc;
|
||||
const char** exec_argv;
|
||||
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
|
||||
|
||||
gin::V8Initializer::LoadV8Snapshot(
|
||||
gin::V8Initializer::V8SnapshotFileType::kWithAdditionalContext);
|
||||
gin::V8Initializer::LoadV8Natives();
|
||||
@@ -53,21 +68,21 @@ int NodeMain(int argc, char* argv[]) {
|
||||
// Initialize gin::IsolateHolder.
|
||||
JavascriptEnvironment gin_env(loop);
|
||||
|
||||
// Explicitly register electron's builtin modules.
|
||||
NodeBindings::RegisterBuiltinModules();
|
||||
node::IsolateData* isolate_data =
|
||||
node::CreateIsolateData(gin_env.isolate(), loop, gin_env.platform());
|
||||
CHECK_NE(nullptr, isolate_data);
|
||||
|
||||
int exec_argc;
|
||||
const char** exec_argv;
|
||||
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
|
||||
|
||||
node::Environment* env = node::CreateEnvironment(
|
||||
node::CreateIsolateData(gin_env.isolate(), loop, gin_env.platform()),
|
||||
gin_env.context(), argc, argv, exec_argc, exec_argv);
|
||||
node::Environment* env =
|
||||
node::CreateEnvironment(isolate_data, gin_env.context(), argc, argv,
|
||||
exec_argc, exec_argv, false);
|
||||
CHECK_NE(nullptr, env);
|
||||
|
||||
// Enable support for v8 inspector.
|
||||
NodeDebugger node_debugger(env);
|
||||
node_debugger.Start();
|
||||
|
||||
node::BootstrapEnvironment(env);
|
||||
|
||||
mate::Dictionary process(gin_env.isolate(), env->process_object());
|
||||
#if defined(OS_WIN)
|
||||
process.SetMethod("log", &ElectronBindings::Log);
|
||||
@@ -103,12 +118,16 @@ int NodeMain(int argc, char* argv[]) {
|
||||
|
||||
node_debugger.Stop();
|
||||
exit_code = node::EmitExit(env);
|
||||
env->set_can_call_into_js(false);
|
||||
node::RunAtExit(env);
|
||||
gin_env.platform()->DrainTasks(env->isolate());
|
||||
gin_env.platform()->CancelPendingDelayedTasks(env->isolate());
|
||||
gin_env.platform()->UnregisterIsolate(env->isolate());
|
||||
|
||||
v8::Isolate* isolate = env->isolate();
|
||||
node::FreeEnvironment(env);
|
||||
node::FreeIsolateData(isolate_data);
|
||||
|
||||
gin_env.platform()->DrainTasks(isolate);
|
||||
gin_env.platform()->CancelPendingDelayedTasks(isolate);
|
||||
gin_env.platform()->UnregisterIsolate(isolate);
|
||||
}
|
||||
|
||||
// According to "src/gin/shell/gin_main.cc":
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "base/callback.h"
|
||||
#include "base/location.h"
|
||||
#include "base/single_thread_task_runner.h"
|
||||
#include "uv.h" // NOLINT(build/include)
|
||||
#include "uv.h" // NOLINT(build/include_directory)
|
||||
|
||||
namespace atom {
|
||||
|
||||
|
||||
@@ -860,8 +860,15 @@ base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
|
||||
int key = GetPathConstant(name);
|
||||
if (key >= 0)
|
||||
succeed = base::PathService::Get(key, &path);
|
||||
if (!succeed)
|
||||
args->ThrowError("Failed to get '" + name + "' path");
|
||||
if (!succeed) {
|
||||
if (name == "logs") {
|
||||
args->ThrowError("Failed to get '" + name +
|
||||
"' path: setAppLogsPath() must be called first.");
|
||||
} else {
|
||||
args->ThrowError("Failed to get '" + name + "' path");
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@@ -1279,6 +1286,13 @@ std::string App::GetUserAgentFallback() {
|
||||
return AtomBrowserClient::Get()->GetUserAgent();
|
||||
}
|
||||
|
||||
void App::SetBrowserClientCanUseCustomSiteInstance(bool should_disable) {
|
||||
AtomBrowserClient::Get()->SetCanUseCustomSiteInstance(should_disable);
|
||||
}
|
||||
bool App::CanBrowserClientUseCustomSiteInstance() {
|
||||
return AtomBrowserClient::Get()->CanUseCustomSiteInstance();
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool App::MoveToApplicationsFolder(mate::Arguments* args) {
|
||||
return ui::cocoa::AtomBundleMover::Move(args);
|
||||
@@ -1288,8 +1302,11 @@ bool App::IsInApplicationsFolder() {
|
||||
return ui::cocoa::AtomBundleMover::IsCurrentAppInApplicationsFolder();
|
||||
}
|
||||
|
||||
int DockBounce(const std::string& type) {
|
||||
int DockBounce(mate::Arguments* args) {
|
||||
int request_id = -1;
|
||||
std::string type = "informational";
|
||||
args->GetNext(&type);
|
||||
|
||||
if (type == "critical")
|
||||
request_id = Browser::Get()->DockBounce(Browser::BOUNCE_CRITICAL);
|
||||
else if (type == "informational")
|
||||
@@ -1441,7 +1458,10 @@ void App::BuildPrototype(v8::Isolate* isolate,
|
||||
#endif
|
||||
.SetProperty("userAgentFallback", &App::GetUserAgentFallback,
|
||||
&App::SetUserAgentFallback)
|
||||
.SetMethod("enableSandbox", &App::EnableSandbox);
|
||||
.SetMethod("enableSandbox", &App::EnableSandbox)
|
||||
.SetProperty("allowRendererProcessReuse",
|
||||
&App::CanBrowserClientUseCustomSiteInstance,
|
||||
&App::SetBrowserClientCanUseCustomSiteInstance);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -212,6 +212,8 @@ class App : public AtomBrowserClient::Delegate,
|
||||
void EnableSandbox(mate::Arguments* args);
|
||||
void SetUserAgentFallback(const std::string& user_agent);
|
||||
std::string GetUserAgentFallback();
|
||||
void SetBrowserClientCanUseCustomSiteInstance(bool should_disable);
|
||||
bool CanBrowserClientUseCustomSiteInstance();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool MoveToApplicationsFolder(mate::Arguments* args);
|
||||
|
||||
@@ -67,7 +67,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());
|
||||
|
||||
@@ -85,8 +85,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.
|
||||
@@ -94,7 +93,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())
|
||||
@@ -308,6 +309,16 @@ void BrowserWindow::SetBackgroundColor(const std::string& color_name) {
|
||||
auto* view = web_contents()->GetRenderWidgetHostView();
|
||||
if (view)
|
||||
view->SetBackgroundColor(ParseHexColor(color_name));
|
||||
// Also update the web preferences object otherwise the view will be reset on
|
||||
// the next load URL call
|
||||
if (api_web_contents_) {
|
||||
auto* web_preferences =
|
||||
WebContentsPreferences::From(api_web_contents_->web_contents());
|
||||
if (web_preferences) {
|
||||
web_preferences->preference()->SetStringKey(options::kBackgroundColor,
|
||||
color_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserWindow::SetBrowserView(v8::Local<v8::Value> value) {
|
||||
|
||||
@@ -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_;
|
||||
|
||||
|
||||
@@ -291,7 +291,7 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
EXCLUDE_FAILURE_TO_STORE);
|
||||
return;
|
||||
}
|
||||
if (url.is_empty()) {
|
||||
if (!url.is_valid()) {
|
||||
std::move(completion_callback)
|
||||
.Run(net::CanonicalCookie::CookieInclusionStatus::
|
||||
EXCLUDE_INVALID_DOMAIN);
|
||||
|
||||
@@ -73,19 +73,13 @@ bool GlobalShortcut::RegisterAll(
|
||||
std::vector<ui::Accelerator> registered;
|
||||
|
||||
for (auto& accelerator : accelerators) {
|
||||
#if defined(OS_MACOSX)
|
||||
if (RegisteringMediaKeyForUntrustedClient(accelerator))
|
||||
return false;
|
||||
|
||||
GlobalShortcutListener* listener = GlobalShortcutListener::GetInstance();
|
||||
if (!listener->RegisterAccelerator(accelerator, this)) {
|
||||
if (!Register(accelerator, callback)) {
|
||||
// unregister all shortcuts if any failed
|
||||
UnregisterSome(registered);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
registered.push_back(accelerator);
|
||||
accelerator_callback_map_[accelerator] = callback;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,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();
|
||||
}
|
||||
|
||||
@@ -4,16 +4,26 @@
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/common/native_mate_converters/accelerator_converter.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/once_callback.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
namespace {
|
||||
// We need this map to keep references to currently opened menus.
|
||||
// Without this menus would be destroyed by js garbage collector
|
||||
// even when they are still displayed.
|
||||
std::map<uint32_t, v8::Global<v8::Object>> g_menus;
|
||||
} // unnamed namespace
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -192,13 +202,25 @@ bool Menu::WorksWhenHiddenAt(int index) const {
|
||||
}
|
||||
|
||||
void Menu::OnMenuWillClose() {
|
||||
g_menus.erase(weak_map_id());
|
||||
Emit("menu-will-close");
|
||||
}
|
||||
|
||||
void Menu::OnMenuWillShow() {
|
||||
g_menus[weak_map_id()] = v8::Global<v8::Object>(isolate(), GetWrapper());
|
||||
Emit("menu-will-show");
|
||||
}
|
||||
|
||||
base::OnceClosure Menu::BindSelfToClosure(base::OnceClosure callback) {
|
||||
// return ((callback, ref) => { callback() }).bind(null, callback, this)
|
||||
v8::Global<v8::Value> ref(isolate(), GetWrapper());
|
||||
return base::BindOnce(
|
||||
[](base::OnceClosure callback, v8::Global<v8::Value> ref) {
|
||||
std::move(callback).Run();
|
||||
},
|
||||
std::move(callback), std::move(ref));
|
||||
}
|
||||
|
||||
// static
|
||||
void Menu::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "atom/browser/api/atom_api_top_level_window.h"
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/ui/atom_menu_model.h"
|
||||
#include "atom/common/api/locker.h"
|
||||
#include "base/callback.h"
|
||||
|
||||
namespace atom {
|
||||
@@ -60,7 +61,7 @@ class Menu : public mate::TrackableObject<Menu>,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
const base::Closure& callback) = 0;
|
||||
base::OnceClosure callback) = 0;
|
||||
virtual void ClosePopupAt(int32_t window_id) = 0;
|
||||
|
||||
std::unique_ptr<AtomMenuModel> model_;
|
||||
@@ -70,6 +71,11 @@ class Menu : public mate::TrackableObject<Menu>,
|
||||
void OnMenuWillClose() override;
|
||||
void OnMenuWillShow() override;
|
||||
|
||||
protected:
|
||||
// Returns a new callback which keeps references of the JS wrapper until the
|
||||
// passed |callback| is called.
|
||||
base::OnceClosure BindSelfToClosure(base::OnceClosure callback);
|
||||
|
||||
private:
|
||||
void InsertItemAt(int index, int command_id, const base::string16& label);
|
||||
void InsertSeparatorAt(int index);
|
||||
|
||||
@@ -27,19 +27,19 @@ class MenuMac : public Menu {
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
const base::Closure& callback) override;
|
||||
base::OnceClosure callback) override;
|
||||
void PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
int32_t window_id,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::Closure callback);
|
||||
base::OnceClosure callback);
|
||||
void ClosePopupAt(int32_t window_id) override;
|
||||
|
||||
private:
|
||||
friend class Menu;
|
||||
|
||||
void OnClosed(int32_t window_id, base::Closure callback);
|
||||
void OnClosed(int32_t window_id, base::OnceClosure callback);
|
||||
|
||||
scoped_nsobject<AtomMenuController> menu_controller_;
|
||||
|
||||
|
||||
@@ -36,15 +36,20 @@ void MenuMac::PopupAt(TopLevelWindow* window,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
const base::Closure& callback) {
|
||||
base::OnceClosure callback) {
|
||||
NativeWindow* native_window = window->window();
|
||||
if (!native_window)
|
||||
return;
|
||||
|
||||
auto popup = base::Bind(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(),
|
||||
native_window->GetWeakPtr(), window->weak_map_id(), x,
|
||||
y, positioning_item, callback);
|
||||
base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, popup);
|
||||
// Make sure the Menu object would not be garbage-collected until the callback
|
||||
// has run.
|
||||
base::OnceClosure callback_with_ref = BindSelfToClosure(std::move(callback));
|
||||
|
||||
auto popup =
|
||||
base::BindOnce(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(),
|
||||
native_window->GetWeakPtr(), window->weak_map_id(), x, y,
|
||||
positioning_item, std::move(callback_with_ref));
|
||||
base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(popup));
|
||||
}
|
||||
|
||||
void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
@@ -52,16 +57,17 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::Closure callback) {
|
||||
base::OnceClosure callback) {
|
||||
if (!native_window)
|
||||
return;
|
||||
NSWindow* nswindow = native_window->GetNativeWindow().GetNativeNSWindow();
|
||||
|
||||
auto close_callback = base::Bind(
|
||||
&MenuMac::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
|
||||
popup_controllers_[window_id] = base::scoped_nsobject<AtomMenuController>([
|
||||
[AtomMenuController alloc] initWithModel:model()
|
||||
useDefaultAccelerator:NO]);
|
||||
base::OnceClosure close_callback =
|
||||
base::BindOnce(&MenuMac::OnClosed, weak_factory_.GetWeakPtr(), window_id,
|
||||
std::move(callback));
|
||||
popup_controllers_[window_id] = base::scoped_nsobject<AtomMenuController>(
|
||||
[[AtomMenuController alloc] initWithModel:model()
|
||||
useDefaultAccelerator:NO]);
|
||||
NSMenu* menu = [popup_controllers_[window_id] menu];
|
||||
NSView* view = [nswindow contentView];
|
||||
|
||||
@@ -96,7 +102,7 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
if (rightmostMenuPoint > screenRight)
|
||||
position.x = position.x - [menu size].width;
|
||||
|
||||
[popup_controllers_[window_id] setCloseCallback:close_callback];
|
||||
[popup_controllers_[window_id] setCloseCallback:std::move(close_callback)];
|
||||
// Make sure events can be pumped while the menu is up.
|
||||
base::MessageLoopCurrent::ScopedNestableTaskAllower allow;
|
||||
|
||||
@@ -127,17 +133,17 @@ void MenuMac::ClosePopupAt(int32_t window_id) {
|
||||
}
|
||||
}
|
||||
|
||||
void MenuMac::OnClosed(int32_t window_id, base::Closure callback) {
|
||||
void MenuMac::OnClosed(int32_t window_id, base::OnceClosure callback) {
|
||||
popup_controllers_.erase(window_id);
|
||||
callback.Run();
|
||||
std::move(callback).Run();
|
||||
}
|
||||
|
||||
// static
|
||||
void Menu::SetApplicationMenu(Menu* base_menu) {
|
||||
MenuMac* menu = static_cast<MenuMac*>(base_menu);
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller([
|
||||
[AtomMenuController alloc] initWithModel:menu->model_.get()
|
||||
useDefaultAccelerator:YES]);
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller(
|
||||
[[AtomMenuController alloc] initWithModel:menu->model_.get()
|
||||
useDefaultAccelerator:YES]);
|
||||
|
||||
NSRunLoop* currentRunLoop = [NSRunLoop currentRunLoop];
|
||||
[currentRunLoop cancelPerformSelector:@selector(setMainMenu:)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "atom/browser/api/atom_api_menu_views.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
@@ -25,7 +26,7 @@ void MenuViews::PopupAt(TopLevelWindow* window,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
const base::Closure& callback) {
|
||||
base::OnceClosure callback) {
|
||||
auto* native_window = static_cast<NativeWindowViews*>(window->window());
|
||||
if (!native_window)
|
||||
return;
|
||||
@@ -44,12 +45,21 @@ void MenuViews::PopupAt(TopLevelWindow* window,
|
||||
// Don't emit unresponsive event when showing menu.
|
||||
atom::UnresponsiveSuppressor suppressor;
|
||||
|
||||
// Make sure the Menu object would not be garbage-collected until the callback
|
||||
// has run.
|
||||
base::OnceClosure callback_with_ref = BindSelfToClosure(std::move(callback));
|
||||
|
||||
// Show the menu.
|
||||
//
|
||||
// Note that while views::MenuRunner accepts RepeatingCallback as close
|
||||
// callback, it is fine passing OnceCallback to it because we reset the
|
||||
// menu runner immediately when the menu is closed.
|
||||
int32_t window_id = window->weak_map_id();
|
||||
auto close_callback = base::Bind(
|
||||
&MenuViews::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
|
||||
auto close_callback = base::AdaptCallbackForRepeating(
|
||||
base::BindOnce(&MenuViews::OnClosed, weak_factory_.GetWeakPtr(),
|
||||
window_id, std::move(callback_with_ref)));
|
||||
menu_runners_[window_id] =
|
||||
std::make_unique<MenuRunner>(model(), flags, close_callback);
|
||||
std::make_unique<MenuRunner>(model(), flags, std::move(close_callback));
|
||||
menu_runners_[window_id]->RunMenuAt(
|
||||
native_window->widget(), NULL, gfx::Rect(location, gfx::Size()),
|
||||
views::MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_MOUSE);
|
||||
@@ -69,9 +79,9 @@ void MenuViews::ClosePopupAt(int32_t window_id) {
|
||||
}
|
||||
}
|
||||
|
||||
void MenuViews::OnClosed(int32_t window_id, base::Closure callback) {
|
||||
void MenuViews::OnClosed(int32_t window_id, base::OnceClosure callback) {
|
||||
menu_runners_.erase(window_id);
|
||||
callback.Run();
|
||||
std::move(callback).Run();
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -27,11 +27,11 @@ class MenuViews : public Menu {
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
const base::Closure& callback) override;
|
||||
base::OnceClosure callback) override;
|
||||
void ClosePopupAt(int32_t window_id) override;
|
||||
|
||||
private:
|
||||
void OnClosed(int32_t window_id, base::Closure callback);
|
||||
void OnClosed(int32_t window_id, base::OnceClosure callback);
|
||||
|
||||
// window ID -> open context menu
|
||||
std::map<int32_t, std::unique_ptr<views::MenuRunner>> menu_runners_;
|
||||
|
||||
@@ -189,6 +189,7 @@ void Notification::NotificationClosed() {
|
||||
void Notification::Close() {
|
||||
if (notification_) {
|
||||
notification_->Dismiss();
|
||||
notification_->set_delegate(nullptr);
|
||||
notification_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,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)
|
||||
@@ -100,16 +113,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
|
||||
|
||||
@@ -50,8 +50,6 @@
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/base/completion_repeating_callback.h"
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/disk_cache/disk_cache.h"
|
||||
#include "net/dns/host_cache.h" // nogncheck
|
||||
#include "net/http/http_auth_handler_factory.h"
|
||||
#include "net/http/http_auth_preferences.h"
|
||||
#include "net/http/http_cache.h"
|
||||
@@ -210,73 +208,6 @@ const char kPersistPrefix[] = "persist:";
|
||||
// Referenced session objects.
|
||||
std::map<uint32_t, v8::Global<v8::Object>> g_sessions;
|
||||
|
||||
void ResolveOrRejectPromiseInUI(util::Promise promise, int net_error) {
|
||||
if (net_error != net::OK) {
|
||||
std::string err_msg = net::ErrorToString(net_error);
|
||||
util::Promise::RejectPromise(std::move(promise), std::move(err_msg));
|
||||
} else {
|
||||
util::Promise::ResolveEmptyPromise(std::move(promise));
|
||||
}
|
||||
}
|
||||
|
||||
// Callback of HttpCache::GetBackend.
|
||||
void OnGetBackend(disk_cache::Backend** backend_ptr,
|
||||
Session::CacheAction action,
|
||||
const util::CopyablePromise& promise,
|
||||
int result) {
|
||||
if (result != net::OK) {
|
||||
std::string err_msg =
|
||||
"Failed to retrieve cache backend: " + net::ErrorToString(result);
|
||||
util::Promise::RejectPromise(promise.GetPromise(), std::move(err_msg));
|
||||
} else if (backend_ptr && *backend_ptr) {
|
||||
if (action == Session::CacheAction::CLEAR) {
|
||||
auto success =
|
||||
(*backend_ptr)
|
||||
->DoomAllEntries(base::BindOnce(&ResolveOrRejectPromiseInUI,
|
||||
promise.GetPromise()));
|
||||
if (success != net::ERR_IO_PENDING)
|
||||
ResolveOrRejectPromiseInUI(promise.GetPromise(), success);
|
||||
} else if (action == Session::CacheAction::STATS) {
|
||||
base::StringPairs stats;
|
||||
(*backend_ptr)->GetStats(&stats);
|
||||
for (const auto& stat : stats) {
|
||||
if (stat.first == "Current size") {
|
||||
int current_size;
|
||||
base::StringToInt(stat.second, ¤t_size);
|
||||
util::Promise::ResolvePromise<int>(promise.GetPromise(),
|
||||
current_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoCacheActionInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
Session::CacheAction action,
|
||||
util::Promise promise) {
|
||||
auto* request_context = context_getter->GetURLRequestContext();
|
||||
|
||||
auto* http_cache = request_context->http_transaction_factory()->GetCache();
|
||||
if (!http_cache) {
|
||||
std::string err_msg =
|
||||
"Failed to retrieve cache: " + net::ErrorToString(net::ERR_FAILED);
|
||||
util::Promise::RejectPromise(std::move(promise), std::move(err_msg));
|
||||
return;
|
||||
}
|
||||
|
||||
// Call GetBackend and make the backend's ptr accessable in OnGetBackend.
|
||||
using BackendPtr = disk_cache::Backend*;
|
||||
auto** backend_ptr = new BackendPtr(nullptr);
|
||||
net::CompletionRepeatingCallback on_get_backend =
|
||||
base::Bind(&OnGetBackend, base::Owned(backend_ptr), action,
|
||||
util::CopyablePromise(promise));
|
||||
int rv = http_cache->GetBackend(backend_ptr, on_get_backend);
|
||||
if (rv != net::ERR_IO_PENDING)
|
||||
on_get_backend.Run(net::OK);
|
||||
}
|
||||
|
||||
void SetCertVerifyProcInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
const AtomCertVerifier::VerifyProc& proc) {
|
||||
@@ -438,17 +369,39 @@ v8::Local<v8::Promise> Session::ResolveProxy(mate::Arguments* args) {
|
||||
return handle;
|
||||
}
|
||||
|
||||
template <Session::CacheAction action>
|
||||
v8::Local<v8::Promise> Session::DoCacheAction() {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
util::Promise promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
v8::Local<v8::Promise> Session::GetCacheSize() {
|
||||
auto* isolate = v8::Isolate::GetCurrent();
|
||||
auto promise = util::Promise(isolate);
|
||||
auto handle = promise.GetHandle();
|
||||
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(&DoCacheActionInIO,
|
||||
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||
action, std::move(promise)));
|
||||
content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
|
||||
->GetNetworkContext()
|
||||
->ComputeHttpCacheSize(base::Time(), base::Time::Max(),
|
||||
base::BindOnce(
|
||||
[](util::Promise promise, bool is_upper_bound,
|
||||
int64_t size_or_error) {
|
||||
if (size_or_error < 0) {
|
||||
promise.RejectWithErrorMessage(
|
||||
net::ErrorToString(size_or_error));
|
||||
} else {
|
||||
promise.Resolve(size_or_error);
|
||||
}
|
||||
},
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Session::ClearCache() {
|
||||
auto* isolate = v8::Isolate::GetCurrent();
|
||||
auto promise = util::Promise(isolate);
|
||||
auto handle = promise.GetHandle();
|
||||
|
||||
content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
|
||||
->GetNetworkContext()
|
||||
->ClearHttpCache(base::Time(), base::Time::Max(), nullptr,
|
||||
base::BindOnce(util::Promise::ResolveEmptyPromise,
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
@@ -559,6 +512,10 @@ void WrapVerifyProc(base::Callback<void(const VerifyRequestParams& request,
|
||||
base::Callback<void(int)>)> proc,
|
||||
const VerifyRequestParams& request,
|
||||
base::OnceCallback<void(int)> cb) {
|
||||
if (proc.is_null()) {
|
||||
LOG(ERROR) << "WrapVerifyProc (proc=null)";
|
||||
return;
|
||||
}
|
||||
proc.Run(request, base::AdaptCallbackForRepeating(std::move(cb)));
|
||||
}
|
||||
|
||||
@@ -581,11 +538,6 @@ void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
|
||||
|
||||
void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
using StatusCallback =
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)>;
|
||||
using RequestHandler =
|
||||
base::Callback<void(content::WebContents*, content::PermissionType,
|
||||
StatusCallback, const base::DictionaryValue&)>;
|
||||
auto* permission_manager = static_cast<AtomPermissionManager*>(
|
||||
browser_context()->GetPermissionControllerDelegate());
|
||||
if (val->IsNull()) {
|
||||
@@ -593,6 +545,11 @@ void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
|
||||
AtomPermissionManager::RequestHandler());
|
||||
return;
|
||||
}
|
||||
using StatusCallback =
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)>;
|
||||
using RequestHandler =
|
||||
base::Callback<void(content::WebContents*, content::PermissionType,
|
||||
StatusCallback, const base::Value&)>;
|
||||
auto handler = std::make_unique<RequestHandler>();
|
||||
if (!mate::ConvertFromV8(args->isolate(), val, handler.get())) {
|
||||
args->ThrowError("Must pass null or function");
|
||||
@@ -602,7 +559,7 @@ void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
|
||||
[](RequestHandler* handler, content::WebContents* web_contents,
|
||||
content::PermissionType permission_type,
|
||||
AtomPermissionManager::StatusCallback callback,
|
||||
const base::DictionaryValue& details) {
|
||||
const base::Value& details) {
|
||||
handler->Run(web_contents, permission_type,
|
||||
base::AdaptCallbackForRepeating(std::move(callback)),
|
||||
details);
|
||||
@@ -812,8 +769,8 @@ void Session::BuildPrototype(v8::Isolate* isolate,
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
.SetMethod("resolveProxy", &Session::ResolveProxy)
|
||||
.SetMethod("getCacheSize", &Session::DoCacheAction<CacheAction::STATS>)
|
||||
.SetMethod("clearCache", &Session::DoCacheAction<CacheAction::CLEAR>)
|
||||
.SetMethod("getCacheSize", &Session::GetCacheSize)
|
||||
.SetMethod("clearCache", &Session::ClearCache)
|
||||
.SetMethod("clearStorageData", &Session::ClearStorageData)
|
||||
.SetMethod("flushStorageData", &Session::FlushStorageData)
|
||||
.SetMethod("setProxy", &Session::SetProxy)
|
||||
|
||||
@@ -63,8 +63,8 @@ class Session : public mate::TrackableObject<Session>,
|
||||
|
||||
// Methods.
|
||||
v8::Local<v8::Promise> ResolveProxy(mate::Arguments* args);
|
||||
template <CacheAction action>
|
||||
v8::Local<v8::Promise> DoCacheAction();
|
||||
v8::Local<v8::Promise> GetCacheSize();
|
||||
v8::Local<v8::Promise> ClearCache();
|
||||
v8::Local<v8::Promise> ClearStorageData(mate::Arguments* args);
|
||||
void FlushStorageData();
|
||||
v8::Local<v8::Promise> SetProxy(mate::Arguments* args);
|
||||
|
||||
@@ -25,6 +25,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 <>
|
||||
@@ -625,6 +626,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"];
|
||||
|
||||
@@ -198,7 +198,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(),
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "atom/common/color_util.h"
|
||||
#include "atom/common/mouse_util.h"
|
||||
#include "atom/common/native_mate_converters/blink_converter.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/content_converter.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
@@ -43,6 +42,7 @@
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/native_mate_converters/network_converter.h"
|
||||
#include "atom/common/native_mate_converters/once_callback.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
@@ -85,6 +85,7 @@
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "ppapi/buildflags/buildflags.h"
|
||||
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
|
||||
#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h"
|
||||
#include "third_party/blink/public/platform/web_cursor_info.h"
|
||||
@@ -99,6 +100,12 @@
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
#include "ui/aura/window.h"
|
||||
#else
|
||||
#include "ui/base/cocoa/defaults_utils.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#include "ui/views/linux_ui/linux_ui.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_LINUX) || defined(OS_WIN)
|
||||
@@ -268,7 +275,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);
|
||||
@@ -283,7 +292,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());
|
||||
@@ -291,8 +302,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_);
|
||||
|
||||
@@ -319,6 +330,12 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
// Whether to enable DevTools.
|
||||
options.Get("devTools", &enable_devtools_);
|
||||
|
||||
// BrowserViews are not attached to a window initially so they should start
|
||||
// off as hidden. This is also important for compositor recycling. See:
|
||||
// https://github.com/electron/electron/pull/21372
|
||||
bool initially_shown = type_ != Type::BROWSER_VIEW;
|
||||
options.Get(options::kShow, &initially_shown);
|
||||
|
||||
// Obtain the session.
|
||||
std::string partition;
|
||||
mate::Handle<api::Session> session;
|
||||
@@ -371,6 +388,7 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
#endif
|
||||
} else {
|
||||
content::WebContents::CreateParams params(session->browser_context());
|
||||
params.initially_hidden = !initially_shown;
|
||||
web_contents = content::WebContents::Create(params);
|
||||
}
|
||||
|
||||
@@ -415,6 +433,25 @@ void WebContents::InitWithSessionAndOptions(
|
||||
prefs->subpixel_rendering = params->subpixel_rendering;
|
||||
#endif
|
||||
|
||||
// Honor the system's cursor blink rate settings
|
||||
#if defined(OS_MACOSX)
|
||||
base::TimeDelta interval;
|
||||
if (ui::TextInsertionCaretBlinkPeriod(&interval))
|
||||
prefs->caret_blink_interval = interval;
|
||||
#elif defined(OS_LINUX)
|
||||
views::LinuxUI* linux_ui = views::LinuxUI::instance();
|
||||
if (linux_ui)
|
||||
prefs->caret_blink_interval = linux_ui->GetCursorBlinkInterval();
|
||||
#elif defined(OS_WIN)
|
||||
const auto system_msec = ::GetCaretBlinkTime();
|
||||
if (system_msec != 0) {
|
||||
prefs->caret_blink_interval =
|
||||
(system_msec == INFINITE)
|
||||
? base::TimeDelta()
|
||||
: base::TimeDelta::FromMilliseconds(system_msec);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Save the preferences in C++.
|
||||
new WebContentsPreferences(web_contents(), options);
|
||||
|
||||
@@ -766,11 +803,20 @@ void WebContents::BeforeUnloadFired(bool proceed,
|
||||
}
|
||||
|
||||
void WebContents::RenderViewCreated(content::RenderViewHost* render_view_host) {
|
||||
auto* const impl = content::RenderWidgetHostImpl::FromID(
|
||||
render_view_host->GetProcess()->GetID(),
|
||||
render_view_host->GetRoutingID());
|
||||
if (impl)
|
||||
impl->disable_hidden_ = !background_throttling_;
|
||||
if (!background_throttling_)
|
||||
render_view_host->SetSchedulerThrottling(false);
|
||||
}
|
||||
|
||||
void WebContents::RenderFrameCreated(
|
||||
content::RenderFrameHost* render_frame_host) {
|
||||
auto* rwhv = render_frame_host->GetView();
|
||||
if (!rwhv)
|
||||
return;
|
||||
|
||||
auto* rwh_impl =
|
||||
static_cast<content::RenderWidgetHostImpl*>(rwhv->GetRenderWidgetHost());
|
||||
if (rwh_impl)
|
||||
rwh_impl->disable_hidden_ = !background_throttling_;
|
||||
}
|
||||
|
||||
void WebContents::RenderViewHostChanged(content::RenderViewHost* old_host,
|
||||
@@ -804,10 +850,12 @@ void WebContents::RenderProcessGone(base::TerminationStatus status) {
|
||||
|
||||
void WebContents::PluginCrashed(const base::FilePath& plugin_path,
|
||||
base::ProcessId plugin_pid) {
|
||||
#if BUILDFLAG(ENABLE_PLUGINS)
|
||||
content::WebPluginInfo info;
|
||||
auto* plugin_service = content::PluginService::GetInstance();
|
||||
plugin_service->GetPluginInfoByPath(plugin_path, &info);
|
||||
Emit("plugin-crashed", info.name, info.version);
|
||||
#endif // BUILDFLAG(ENABLE_PLUIGNS)
|
||||
}
|
||||
|
||||
void WebContents::MediaStartedPlaying(const MediaPlayerInfo& video_type,
|
||||
@@ -837,6 +885,10 @@ void WebContents::OnInterfaceRequestFromFrame(
|
||||
registry_.TryBindInterface(interface_name, interface_pipe, render_frame_host);
|
||||
}
|
||||
|
||||
void WebContents::DidAcquireFullscreen(content::RenderFrameHost* rfh) {
|
||||
set_fullscreen_frame(rfh);
|
||||
}
|
||||
|
||||
void WebContents::DocumentLoadedInFrame(
|
||||
content::RenderFrameHost* render_frame_host) {
|
||||
if (!render_frame_host->GetParent())
|
||||
@@ -1191,31 +1243,24 @@ void WebContents::NavigationEntryCommitted(
|
||||
void WebContents::SetBackgroundThrottling(bool allowed) {
|
||||
background_throttling_ = allowed;
|
||||
|
||||
auto* contents = web_contents();
|
||||
if (!contents) {
|
||||
auto* rfh = web_contents()->GetMainFrame();
|
||||
if (!rfh)
|
||||
return;
|
||||
}
|
||||
|
||||
auto* render_view_host = contents->GetRenderViewHost();
|
||||
if (!render_view_host) {
|
||||
auto* rwhv = rfh->GetView();
|
||||
if (!rwhv)
|
||||
return;
|
||||
}
|
||||
|
||||
auto* render_process_host = render_view_host->GetProcess();
|
||||
if (!render_process_host) {
|
||||
auto* rwh_impl =
|
||||
static_cast<content::RenderWidgetHostImpl*>(rwhv->GetRenderWidgetHost());
|
||||
if (!rwh_impl)
|
||||
return;
|
||||
}
|
||||
|
||||
auto* render_widget_host_impl = content::RenderWidgetHostImpl::FromID(
|
||||
render_process_host->GetID(), render_view_host->GetRoutingID());
|
||||
if (!render_widget_host_impl) {
|
||||
return;
|
||||
}
|
||||
rwh_impl->disable_hidden_ = !background_throttling_;
|
||||
web_contents()->GetRenderViewHost()->SetSchedulerThrottling(allowed);
|
||||
|
||||
render_widget_host_impl->disable_hidden_ = !background_throttling_;
|
||||
|
||||
if (render_widget_host_impl->is_hidden()) {
|
||||
render_widget_host_impl->WasShown(base::nullopt);
|
||||
if (rwh_impl->is_hidden()) {
|
||||
rwh_impl->WasShown(base::nullopt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,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
|
||||
@@ -411,7 +413,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
// content::WebContentsObserver:
|
||||
void BeforeUnloadFired(bool proceed,
|
||||
const base::TimeTicks& proceed_time) override;
|
||||
void RenderViewCreated(content::RenderViewHost*) override;
|
||||
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
|
||||
void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
|
||||
void RenderViewHostChanged(content::RenderViewHost* old_host,
|
||||
content::RenderViewHost* new_host) override;
|
||||
void RenderViewDeleted(content::RenderViewHost*) override;
|
||||
@@ -455,6 +458,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const std::string& interface_name,
|
||||
mojo::ScopedMessagePipeHandle* interface_pipe) override;
|
||||
void DidAcquireFullscreen(content::RenderFrameHost* rfh) override;
|
||||
|
||||
// InspectableWebContentsDelegate:
|
||||
void DevToolsReloadPage() override;
|
||||
@@ -558,6 +562,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
std::map<content::RenderFrameHost*, std::vector<mojo::BindingId>>
|
||||
frame_to_bindings_map_;
|
||||
|
||||
base::WeakPtrFactory<WebContents> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContents);
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -78,8 +78,13 @@
|
||||
#include "services/network/public/cpp/resource_request_body.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
#include "ui/native_theme/native_theme.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "sandbox/win/src/sandbox_policy.h"
|
||||
#endif
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
#include "net/ssl/client_cert_store_nss.h"
|
||||
#elif defined(OS_WIN)
|
||||
@@ -109,6 +114,11 @@
|
||||
#include "chrome/browser/printing/printing_message_filter.h"
|
||||
#endif // BUILDFLAG(ENABLE_PRINTING)
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "content/common/mac_helpers.h"
|
||||
#include "content/public/common/child_process_host.h"
|
||||
#endif
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace atom {
|
||||
@@ -388,6 +398,11 @@ void AtomBrowserClient::OverrideWebkitPrefs(content::RenderViewHost* host,
|
||||
prefs->default_maximum_page_scale_factor = 1.f;
|
||||
prefs->navigate_on_drag_drop = false;
|
||||
|
||||
ui::NativeTheme* native_theme = ui::NativeTheme::GetInstanceForNativeUi();
|
||||
prefs->preferred_color_scheme = native_theme->SystemDarkModeEnabled()
|
||||
? blink::PreferredColorScheme::kDark
|
||||
: blink::PreferredColorScheme::kLight;
|
||||
|
||||
SetFontDefaults(prefs);
|
||||
|
||||
// Custom preferences of guest page.
|
||||
@@ -397,12 +412,21 @@ void AtomBrowserClient::OverrideWebkitPrefs(content::RenderViewHost* host,
|
||||
web_preferences->OverrideWebkitPrefs(prefs);
|
||||
}
|
||||
|
||||
void AtomBrowserClient::SetCanUseCustomSiteInstance(bool should_disable) {
|
||||
disable_process_restart_tricks_ = should_disable;
|
||||
}
|
||||
|
||||
bool AtomBrowserClient::CanUseCustomSiteInstance() {
|
||||
return disable_process_restart_tricks_;
|
||||
}
|
||||
|
||||
content::ContentBrowserClient::SiteInstanceForNavigationType
|
||||
AtomBrowserClient::ShouldOverrideSiteInstanceForNavigation(
|
||||
content::RenderFrameHost* current_rfh,
|
||||
content::RenderFrameHost* speculative_rfh,
|
||||
content::BrowserContext* browser_context,
|
||||
const GURL& url,
|
||||
bool has_navigation_started,
|
||||
bool has_response_started,
|
||||
content::SiteInstance** affinity_site_instance) const {
|
||||
if (g_suppress_renderer_process_restart) {
|
||||
@@ -437,6 +461,13 @@ AtomBrowserClient::ShouldOverrideSiteInstanceForNavigation(
|
||||
return SiteInstanceForNavigationType::FORCE_CURRENT;
|
||||
}
|
||||
|
||||
if (!has_navigation_started) {
|
||||
// If the navigation didn't start yet, ignore any candidate site instance.
|
||||
// If such instance exists, it belongs to a previous navigation still
|
||||
// taking place. Fixes https://github.com/electron/electron/issues/17576.
|
||||
return SiteInstanceForNavigationType::FORCE_NEW;
|
||||
}
|
||||
|
||||
return SiteInstanceForNavigationType::FORCE_CANDIDATE_OR_NEW;
|
||||
}
|
||||
|
||||
@@ -457,11 +488,28 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||
int process_id) {
|
||||
// Make sure we're about to launch a known executable
|
||||
{
|
||||
base::FilePath child_path;
|
||||
base::PathService::Get(content::CHILD_PROCESS_EXE, &child_path);
|
||||
|
||||
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
||||
CHECK(base::MakeAbsoluteFilePath(command_line->GetProgram()) == child_path);
|
||||
base::FilePath child_path;
|
||||
base::FilePath program =
|
||||
base::MakeAbsoluteFilePath(command_line->GetProgram());
|
||||
#if defined(OS_MACOSX)
|
||||
auto renderer_child_path = content::ChildProcessHost::GetChildPath(
|
||||
content::ChildProcessHost::CHILD_RENDERER);
|
||||
auto gpu_child_path = content::ChildProcessHost::GetChildPath(
|
||||
content::ChildProcessHost::CHILD_GPU);
|
||||
auto plugin_child_path = content::ChildProcessHost::GetChildPath(
|
||||
content::ChildProcessHost::CHILD_PLUGIN);
|
||||
if (program != renderer_child_path && program != gpu_child_path &&
|
||||
program != plugin_child_path) {
|
||||
child_path = content::ChildProcessHost::GetChildPath(
|
||||
content::ChildProcessHost::CHILD_NORMAL);
|
||||
CHECK_EQ(program, child_path)
|
||||
<< "Aborted from launching unexpected helper executable";
|
||||
}
|
||||
#else
|
||||
base::PathService::Get(content::CHILD_PROCESS_EXE, &child_path);
|
||||
CHECK_EQ(program, child_path);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string process_type =
|
||||
@@ -503,6 +551,10 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||
web_preferences->AppendCommandLineSwitches(command_line);
|
||||
SessionPreferences::AppendExtraCommandLineSwitches(
|
||||
web_contents->GetBrowserContext(), command_line);
|
||||
if (CanUseCustomSiteInstance()) {
|
||||
command_line->AppendSwitch(
|
||||
switches::kDisableElectronSiteInstanceOverrides);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -895,6 +947,18 @@ void AtomBrowserClient::SetUserAgent(const std::string& user_agent) {
|
||||
user_agent_override_ = user_agent;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool AtomBrowserClient::PreSpawnRenderer(sandbox::TargetPolicy* policy) {
|
||||
// Allow crashpad to communicate via named pipe.
|
||||
sandbox::ResultCode result = policy->AddRule(
|
||||
sandbox::TargetPolicy::SUBSYS_FILES,
|
||||
sandbox::TargetPolicy::FILES_ALLOW_ANY, L"\\??\\pipe\\crashpad_*");
|
||||
if (result != sandbox::SBOX_ALL_OK)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
std::string AtomBrowserClient::GetApplicationLocale() {
|
||||
if (BrowserThread::CurrentlyOn(BrowserThread::IO))
|
||||
return g_io_thread_application_locale.Get();
|
||||
|
||||
@@ -67,6 +67,9 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
||||
std::string GetUserAgent() const override;
|
||||
void SetUserAgent(const std::string& user_agent);
|
||||
|
||||
void SetCanUseCustomSiteInstance(bool should_disable);
|
||||
bool CanUseCustomSiteInstance() override;
|
||||
|
||||
protected:
|
||||
void RenderProcessWillLaunch(
|
||||
content::RenderProcessHost* host,
|
||||
@@ -81,6 +84,7 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
||||
content::RenderFrameHost* speculative_rfh,
|
||||
content::BrowserContext* browser_context,
|
||||
const GURL& url,
|
||||
bool has_navigation_started,
|
||||
bool has_request_started,
|
||||
content::SiteInstance** affinity_site_instance) const override;
|
||||
void RegisterPendingSiteInstance(
|
||||
@@ -159,6 +163,9 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
||||
network::mojom::NetworkService* network_service) override;
|
||||
bool ShouldBypassCORB(int render_process_id) const override;
|
||||
std::string GetProduct() const override;
|
||||
#if defined(OS_WIN)
|
||||
bool PreSpawnRenderer(sandbox::TargetPolicy* policy) override;
|
||||
#endif
|
||||
|
||||
// content::RenderProcessHostObserver:
|
||||
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
|
||||
@@ -234,6 +241,8 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
||||
|
||||
std::string user_agent_override_ = "";
|
||||
|
||||
bool disable_process_restart_tricks_ = false;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
|
||||
};
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "services/device/public/mojom/constants.mojom.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "services/service_manager/public/cpp/connector.h"
|
||||
#include "third_party/blink/public/common/features.h"
|
||||
#include "ui/base/idle/idle.h"
|
||||
#include "ui/base/material_design/material_design_controller.h"
|
||||
#include "ui/base/ui_base_switches.h"
|
||||
@@ -209,6 +210,9 @@ void AtomBrowserMainParts::InitializeFeatureList() {
|
||||
// when node integration is enabled.
|
||||
disable_features +=
|
||||
std::string(",") + features::kSpareRendererForSitePerProcess.name;
|
||||
// Disable LayoutNG as it still isn't fully enabled in Chrome and currently
|
||||
// is still causing crashes during every day use such as text selection.
|
||||
disable_features += std::string(",") + blink::features::kLayoutNG.name;
|
||||
auto feature_list = std::make_unique<base::FeatureList>();
|
||||
feature_list->InitializeFromCommandLine(enable_features, disable_features);
|
||||
base::FeatureList::SetInstance(std::move(feature_list));
|
||||
@@ -302,13 +306,44 @@ void AtomBrowserMainParts::PostEarlyInitialization() {
|
||||
node_bindings_->Initialize();
|
||||
// Create the global environment.
|
||||
node::Environment* env = node_bindings_->CreateEnvironment(
|
||||
js_env_->context(), js_env_->platform());
|
||||
js_env_->context(), js_env_->platform(), false);
|
||||
node_env_.reset(new NodeEnvironment(env));
|
||||
|
||||
/**
|
||||
* 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨
|
||||
* UNSAFE ENVIRONMENT BLOCK BEGINS
|
||||
*
|
||||
* DO NOT USE node::Environment inside this block, bad things will happen
|
||||
* and you won't be able to figure out why. Just don't touch it, the only
|
||||
* thing that can use it is NodeDebugger and that is ONLY allowed to access
|
||||
* the inspector agent.
|
||||
*
|
||||
* This is unsafe because the environment is not yet bootstrapped, it's a race
|
||||
* condition where we can't bootstrap before intializing the inspector agent.
|
||||
*
|
||||
* Long term we should figure out how to get node to initialize the inspector
|
||||
* agent in the correct place without us splitting the bootstrap up, but for
|
||||
* now this works.
|
||||
* 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨
|
||||
*/
|
||||
|
||||
// Enable support for v8 inspector
|
||||
node_debugger_.reset(new NodeDebugger(env));
|
||||
node_debugger_->Start();
|
||||
|
||||
// Only run the node bootstrapper after we have initialized the inspector
|
||||
// TODO(MarshallOfSound): Figured out a better way to init the inspector
|
||||
// before bootstrapping
|
||||
node::BootstrapEnvironment(env);
|
||||
|
||||
/**
|
||||
* ✅ ✅ ✅ ✅ ✅ ✅ ✅
|
||||
* UNSAFE ENVIRONMENT BLOCK ENDS
|
||||
*
|
||||
* Do whatever you want now with that env, it's safe again
|
||||
* ✅ ✅ ✅ ✅ ✅ ✅ ✅
|
||||
*/
|
||||
|
||||
// Add Electron extended APIs.
|
||||
electron_bindings_->BindTo(js_env_->isolate(), env->process_object());
|
||||
|
||||
|
||||
@@ -188,12 +188,13 @@ int AtomPermissionManager::RequestPermissionsWithDetails(
|
||||
const auto callback =
|
||||
base::BindRepeating(&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.SetStringKey(
|
||||
"requestingUrl", render_frame_host->GetLastCommittedURL().spec());
|
||||
mutable_details.SetBoolKey("isMainFrame",
|
||||
render_frame_host->GetParent() == nullptr);
|
||||
request_handler_.Run(web_contents, permission, callback, mutable_details);
|
||||
}
|
||||
|
||||
return request_id;
|
||||
@@ -246,8 +247,14 @@ bool AtomPermissionManager::CheckPermissionWithDetails(
|
||||
}
|
||||
auto* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(render_frame_host);
|
||||
auto mutable_details =
|
||||
details == nullptr ? base::DictionaryValue() : details->Clone();
|
||||
mutable_details.SetStringKey("requestingUrl",
|
||||
render_frame_host->GetLastCommittedURL().spec());
|
||||
mutable_details.SetBoolKey("isMainFrame",
|
||||
render_frame_host->GetParent() == nullptr);
|
||||
return check_handler_.Run(web_contents, permission, requesting_origin,
|
||||
*details);
|
||||
mutable_details);
|
||||
}
|
||||
|
||||
blink::mojom::PermissionStatus
|
||||
|
||||
@@ -32,11 +32,11 @@ class AtomPermissionManager : public content::PermissionControllerDelegate {
|
||||
using RequestHandler = base::Callback<void(content::WebContents*,
|
||||
content::PermissionType,
|
||||
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);
|
||||
|
||||
@@ -25,6 +25,21 @@
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
// Call |quit| after Chromium is fully started.
|
||||
//
|
||||
// This is important for quitting immediately in the "ready" event, when
|
||||
// certain initialization task may still be pending, and quitting at that time
|
||||
// could end up with crash on exit.
|
||||
void RunQuitClosure(base::OnceClosure quit) {
|
||||
// On Linux/Windows the "ready" event is emitted in "PreMainMessageLoopRun",
|
||||
// make sure we quit after message loop has run for once.
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(quit));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Browser::LoginItemSettings::LoginItemSettings() = default;
|
||||
Browser::LoginItemSettings::~LoginItemSettings() = default;
|
||||
Browser::LoginItemSettings::LoginItemSettings(const LoginItemSettings& other) =
|
||||
@@ -93,7 +108,7 @@ void Browser::Shutdown() {
|
||||
observer.OnQuit();
|
||||
|
||||
if (quit_main_message_loop_) {
|
||||
std::move(quit_main_message_loop_).Run();
|
||||
RunQuitClosure(std::move(quit_main_message_loop_));
|
||||
} else {
|
||||
// There is no message loop available so we are in early stage, wait until
|
||||
// the quit_main_message_loop_ is available.
|
||||
@@ -195,7 +210,7 @@ void Browser::PreMainMessageLoopRun() {
|
||||
|
||||
void Browser::SetMainMessageLoopQuitClosure(base::OnceClosure quit_closure) {
|
||||
if (is_shutdown_)
|
||||
std::move(quit_closure).Run();
|
||||
RunQuitClosure(std::move(quit_closure));
|
||||
else
|
||||
quit_main_message_loop_ = std::move(quit_closure);
|
||||
}
|
||||
|
||||
@@ -149,7 +149,8 @@ bool Browser::IsEmojiPanelSupported() {
|
||||
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());
|
||||
@@ -161,7 +162,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);
|
||||
@@ -172,7 +178,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) {
|
||||
|
||||
@@ -386,11 +386,18 @@ void Browser::ShowAboutPanel() {
|
||||
NSDictionary* options = DictionaryValueToNSDictionary(about_panel_options_);
|
||||
|
||||
// Credits must be a NSAttributedString instead of NSString
|
||||
id credits = options[@"Credits"];
|
||||
NSString* credits = (NSString*)options[@"Credits"];
|
||||
if (credits != nil) {
|
||||
NSMutableDictionary* mutable_options = [options mutableCopy];
|
||||
mutable_options[@"Credits"] = [[[NSAttributedString alloc]
|
||||
initWithString:(NSString*)credits] autorelease];
|
||||
base::scoped_nsobject<NSMutableDictionary> mutable_options(
|
||||
[options mutableCopy]);
|
||||
base::scoped_nsobject<NSAttributedString> creditString(
|
||||
[[NSAttributedString alloc]
|
||||
initWithString:credits
|
||||
attributes:@{
|
||||
NSForegroundColorAttributeName : [NSColor textColor]
|
||||
}]);
|
||||
|
||||
[mutable_options setValue:creditString forKey:@"Credits"];
|
||||
options = [NSDictionary dictionaryWithDictionary:mutable_options];
|
||||
}
|
||||
|
||||
|
||||
@@ -96,9 +96,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));
|
||||
@@ -111,13 +108,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) {
|
||||
|
||||
@@ -328,9 +328,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(
|
||||
@@ -339,7 +342,13 @@ void CommonWebContentsDelegate::ExitFullscreenModeForTab(
|
||||
return;
|
||||
SetHtmlApiFullscreen(false);
|
||||
owner_window_->NotifyWindowLeaveHtmlFullScreen();
|
||||
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
|
||||
|
||||
if (native_fullscreen_) {
|
||||
// Explicitly trigger a view resize, as the size is not actually changing if
|
||||
// the browser is fullscreened, too. Chrome does this indirectly from
|
||||
// `chrome/browser/ui/exclusive_access/fullscreen_controller.cc`.
|
||||
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
|
||||
}
|
||||
}
|
||||
|
||||
bool CommonWebContentsDelegate::IsFullscreenForTabOrPending(
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
@@ -30,7 +30,7 @@ JavascriptEnvironment::JavascriptEnvironment(uv_loop_t* event_loop)
|
||||
isolate_scope_(isolate_),
|
||||
locker_(isolate_),
|
||||
handle_scope_(isolate_),
|
||||
context_(isolate_, v8::Context::New(isolate_)),
|
||||
context_(isolate_, node::NewContext(isolate_)),
|
||||
context_scope_(v8::Local<v8::Context>::New(isolate_, context_)) {}
|
||||
|
||||
JavascriptEnvironment::~JavascriptEnvironment() = default;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "gin/public/isolate_holder.h"
|
||||
#include "uv.h" // NOLINT(build/include)
|
||||
#include "uv.h" // NOLINT(build/include_directory)
|
||||
|
||||
namespace node {
|
||||
class Environment;
|
||||
|
||||
@@ -29,7 +29,7 @@ struct Product {
|
||||
std::string formattedPrice;
|
||||
|
||||
// Downloadable Content Information
|
||||
bool downloadable = false;
|
||||
bool isDownloadable = false;
|
||||
|
||||
Product(const Product&);
|
||||
Product();
|
||||
|
||||
@@ -146,9 +146,7 @@
|
||||
}
|
||||
|
||||
// Downloadable Content Information
|
||||
if (product.downloadable == true) {
|
||||
productStruct.downloadable = true;
|
||||
}
|
||||
productStruct.isDownloadable = [product downloadable];
|
||||
|
||||
return productStruct;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
@class AtomPreviewItem;
|
||||
@class AtomTouchBar;
|
||||
@class CustomWindowButtonView;
|
||||
@class FullSizeContentView;
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -158,7 +157,7 @@ class NativeWindowMac : public NativeWindow {
|
||||
AtomTouchBar* touch_bar() const { return touch_bar_.get(); }
|
||||
bool zoom_to_page_width() const { return zoom_to_page_width_; }
|
||||
bool fullscreen_window_title() const { return fullscreen_window_title_; }
|
||||
bool simple_fullscreen() const { return always_simple_fullscreen_; }
|
||||
bool always_simple_fullscreen() const { return always_simple_fullscreen_; }
|
||||
|
||||
protected:
|
||||
// views::WidgetDelegate:
|
||||
@@ -182,10 +181,12 @@ class NativeWindowMac : public NativeWindow {
|
||||
// Event monitor for scroll wheel event.
|
||||
id wheel_event_monitor_;
|
||||
|
||||
// The view that will fill the whole frameless window.
|
||||
base::scoped_nsobject<FullSizeContentView> container_view_;
|
||||
// The NSView that used as contentView of window.
|
||||
//
|
||||
// For frameless window it would fill the whole window.
|
||||
base::scoped_nsobject<NSView> container_view_;
|
||||
|
||||
// The view that fills the client area.
|
||||
// The views::View that fills the client area.
|
||||
std::unique_ptr<RootViewMac> root_view_;
|
||||
|
||||
bool is_kiosk_ = false;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/mac/mac_util.h"
|
||||
#include "base/mac/scoped_cftyperef.h"
|
||||
#include "base/numerics/ranges.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "components/remote_cocoa/app_shim/bridged_native_widget_impl.h"
|
||||
#include "content/public/browser/browser_accessibility_state.h"
|
||||
@@ -30,8 +31,59 @@
|
||||
#include "ui/gfx/skia_util.h"
|
||||
#include "ui/gl/gpu_switching_manager.h"
|
||||
#include "ui/views/background.h"
|
||||
#include "ui/views/cocoa/bridged_native_widget_host_impl.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
|
||||
// This view would inform Chromium to resize the hosted views::View.
|
||||
//
|
||||
// The overrided methods should behave the same with BridgedContentView.
|
||||
@interface ElectronAdapatedContentView : NSView {
|
||||
@private
|
||||
views::BridgedNativeWidgetHostImpl* bridge_host_;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation ElectronAdapatedContentView
|
||||
|
||||
- (id)initWithShell:(atom::NativeWindowMac*)shell {
|
||||
if ((self = [self init])) {
|
||||
bridge_host_ = views::BridgedNativeWidgetHostImpl::GetFromNativeWindow(
|
||||
shell->GetNativeWindow());
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidMoveToWindow {
|
||||
// When this view is added to a window, AppKit calls setFrameSize before it is
|
||||
// added to the window, so the behavior in setFrameSize is not triggered.
|
||||
NSWindow* window = [self window];
|
||||
if (window)
|
||||
[self setFrameSize:NSZeroSize];
|
||||
}
|
||||
|
||||
- (void)setFrameSize:(NSSize)newSize {
|
||||
// The size passed in here does not always use
|
||||
// -[NSWindow contentRectForFrameRect]. The following ensures that the
|
||||
// contentView for a frameless window can extend over the titlebar of the new
|
||||
// window containing it, since AppKit requires a titlebar to give frameless
|
||||
// windows correct shadows and rounded corners.
|
||||
NSWindow* window = [self window];
|
||||
if (window && [window contentView] == self) {
|
||||
newSize = [window contentRectForFrameRect:[window frame]].size;
|
||||
// Ensure that the window geometry be updated on the host side before the
|
||||
// view size is updated.
|
||||
bridge_host_->bridge_impl()->UpdateWindowGeometry();
|
||||
}
|
||||
|
||||
[super setFrameSize:newSize];
|
||||
|
||||
// The OnViewSizeChanged is marked private in derived class.
|
||||
static_cast<remote_cocoa::mojom::BridgedNativeWidgetHost*>(bridge_host_)
|
||||
->OnViewSizeChanged(gfx::Size(newSize.width, newSize.height));
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// This view always takes the size of its superview. It is intended to be used
|
||||
// as a NSWindow's contentView. It is needed because NSWindow's implementation
|
||||
// explicitly resizes the contentView at inopportune times.
|
||||
@@ -493,6 +545,8 @@ void NativeWindowMac::Close() {
|
||||
// When this is a sheet showing, performClose won't work.
|
||||
if (is_modal() && parent() && IsVisible()) {
|
||||
[parent()->GetNativeWindow().GetNativeNSWindow() endSheet:window_];
|
||||
// Manually emit close event (not triggered from close fn)
|
||||
NotifyWindowCloseButtonClicked();
|
||||
CloseImmediately();
|
||||
return;
|
||||
}
|
||||
@@ -825,6 +879,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);
|
||||
|
||||
@@ -851,12 +906,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]);
|
||||
}
|
||||
|
||||
// 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() {
|
||||
@@ -1036,7 +1101,8 @@ bool NativeWindowMac::HasShadow() {
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetOpacity(const double opacity) {
|
||||
[window_ setAlphaValue:opacity];
|
||||
const double boundedOpacity = base::ClampToRange(opacity, 0.0, 1.0);
|
||||
[window_ setAlphaValue:boundedOpacity];
|
||||
}
|
||||
|
||||
double NativeWindowMac::GetOpacity() {
|
||||
@@ -1483,10 +1549,15 @@ void NativeWindowMac::OverrideNSWindowContentView() {
|
||||
// `BridgedContentView` as content view, which does not support draggable
|
||||
// regions. In order to make draggable regions work, we have to replace the
|
||||
// content view with a simple NSView.
|
||||
container_view_.reset([[FullSizeContentView alloc] init]);
|
||||
if (has_frame()) {
|
||||
container_view_.reset(
|
||||
[[ElectronAdapatedContentView alloc] initWithShell:this]);
|
||||
} else {
|
||||
container_view_.reset([[FullSizeContentView alloc] init]);
|
||||
[container_view_ setFrame:[[[window_ contentView] superview] bounds]];
|
||||
}
|
||||
[container_view_
|
||||
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||
[container_view_ setFrame:[[[window_ contentView] superview] bounds]];
|
||||
[window_ setContentView:container_view_];
|
||||
AddContentViewLayers(IsMinimizable(), IsClosable());
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "atom/common/draggable_region.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/numerics/ranges.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
@@ -301,7 +302,6 @@ NativeWindowViews::NativeWindowViews(const mate::Dictionary& options,
|
||||
last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
|
||||
else
|
||||
last_window_state_ = ui::SHOW_STATE_NORMAL;
|
||||
last_normal_bounds_ = GetBounds();
|
||||
#endif
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
@@ -754,10 +754,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() {
|
||||
@@ -862,6 +866,7 @@ bool NativeWindowViews::HasShadow() {
|
||||
|
||||
void NativeWindowViews::SetOpacity(const double opacity) {
|
||||
#if defined(OS_WIN)
|
||||
const double boundedOpacity = base::ClampToRange(opacity, 0.0, 1.0);
|
||||
HWND hwnd = GetAcceleratedWidget();
|
||||
if (!layered_) {
|
||||
LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||
@@ -869,9 +874,11 @@ void NativeWindowViews::SetOpacity(const double opacity) {
|
||||
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
|
||||
layered_ = true;
|
||||
}
|
||||
::SetLayeredWindowAttributes(hwnd, 0, opacity * 255, LWA_ALPHA);
|
||||
::SetLayeredWindowAttributes(hwnd, 0, boundedOpacity * 255, LWA_ALPHA);
|
||||
opacity_ = boundedOpacity;
|
||||
#else
|
||||
opacity_ = 1.0; // setOpacity unsupported on Linux
|
||||
#endif
|
||||
opacity_ = opacity;
|
||||
}
|
||||
|
||||
double NativeWindowViews::GetOpacity() {
|
||||
@@ -915,6 +922,7 @@ void NativeWindowViews::SetContentProtection(bool enable) {
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetFocusable(bool focusable) {
|
||||
widget()->widget_delegate()->SetCanActivate(focusable);
|
||||
#if defined(OS_WIN)
|
||||
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
|
||||
if (focusable)
|
||||
|
||||
@@ -241,23 +241,6 @@ class NativeWindowViews : public NativeWindow,
|
||||
|
||||
gfx::Rect last_normal_placement_bounds_;
|
||||
|
||||
// There's an issue with restore on Windows, that sometimes causes the Window
|
||||
// to receive the wrong size (#2498). To circumvent that, we keep tabs on the
|
||||
// size of the window while in the normal state (not maximized, minimized or
|
||||
// fullscreen), so we restore it correctly.
|
||||
gfx::Rect last_normal_bounds_;
|
||||
gfx::Rect last_normal_bounds_before_move_;
|
||||
|
||||
// last_normal_bounds_ may or may not require update on WM_MOVE. When a
|
||||
// window is maximized, it is moved (WM_MOVE) to maximum size first and then
|
||||
// sized (WM_SIZE). In this case, last_normal_bounds_ should not update. We
|
||||
// keep last_normal_bounds_candidate_ as a candidate which will become valid
|
||||
// last_normal_bounds_ if the moves are consecutive with no WM_SIZE event in
|
||||
// between.
|
||||
gfx::Rect last_normal_bounds_candidate_;
|
||||
|
||||
bool consecutive_moves_;
|
||||
|
||||
// In charge of running taskbar related APIs.
|
||||
TaskbarHost taskbar_host_;
|
||||
|
||||
@@ -280,6 +263,9 @@ class NativeWindowViews : public NativeWindow,
|
||||
bool forwarding_mouse_messages_ = false;
|
||||
HWND legacy_window_ = NULL;
|
||||
bool layered_ = false;
|
||||
|
||||
// Whether to block Chromium from handling window messages.
|
||||
bool block_chromium_message_handler_ = false;
|
||||
#endif
|
||||
|
||||
// Handles unhandled keyboard messages coming back from the renderer process.
|
||||
|
||||
@@ -143,153 +143,28 @@ bool IsScreenReaderActive() {
|
||||
return screenReader && UiaClientsAreListening();
|
||||
}
|
||||
|
||||
// We use "enum" instead of "enum class" because we need to do bitwise compare.
|
||||
enum AppbarAutohideEdge {
|
||||
TOP = 1 << 0,
|
||||
LEFT = 1 << 1,
|
||||
BOTTOM = 1 << 2,
|
||||
RIGHT = 1 << 3,
|
||||
};
|
||||
|
||||
// The thickness of an auto-hide taskbar in pixel.
|
||||
constexpr int kAutoHideTaskbarThicknessPx = 2;
|
||||
|
||||
// Code is copied from chrome_views_delegate_win.cc.
|
||||
bool MonitorHasAutohideTaskbarForEdge(UINT edge, HMONITOR monitor) {
|
||||
APPBARDATA taskbar_data = {sizeof(APPBARDATA), NULL, 0, edge};
|
||||
taskbar_data.hWnd = ::GetForegroundWindow();
|
||||
|
||||
// MSDN documents an ABM_GETAUTOHIDEBAREX, which supposedly takes a monitor
|
||||
// rect and returns autohide bars on that monitor. This sounds like a good
|
||||
// idea for multi-monitor systems. Unfortunately, it appears to not work at
|
||||
// least some of the time (erroneously returning NULL) and there's almost no
|
||||
// online documentation or other sample code using it that suggests ways to
|
||||
// address this problem. We do the following:-
|
||||
// 1. Use the ABM_GETAUTOHIDEBAR message. If it works, i.e. returns a valid
|
||||
// window we are done.
|
||||
// 2. If the ABM_GETAUTOHIDEBAR message does not work we query the auto hide
|
||||
// state of the taskbar and then retrieve its position. That call returns
|
||||
// the edge on which the taskbar is present. If it matches the edge we
|
||||
// are looking for, we are done.
|
||||
// NOTE: This call spins a nested run loop.
|
||||
HWND taskbar = reinterpret_cast<HWND>(
|
||||
SHAppBarMessage(ABM_GETAUTOHIDEBAR, &taskbar_data));
|
||||
if (!::IsWindow(taskbar)) {
|
||||
APPBARDATA taskbar_data = {sizeof(APPBARDATA), 0, 0, 0};
|
||||
unsigned int taskbar_state = SHAppBarMessage(ABM_GETSTATE, &taskbar_data);
|
||||
if (!(taskbar_state & ABS_AUTOHIDE))
|
||||
return false;
|
||||
|
||||
taskbar_data.hWnd = ::FindWindow(L"Shell_TrayWnd", NULL);
|
||||
if (!::IsWindow(taskbar_data.hWnd))
|
||||
return false;
|
||||
|
||||
SHAppBarMessage(ABM_GETTASKBARPOS, &taskbar_data);
|
||||
if (taskbar_data.uEdge == edge)
|
||||
taskbar = taskbar_data.hWnd;
|
||||
}
|
||||
|
||||
// There is a potential race condition here:
|
||||
// 1. A maximized chrome window is fullscreened.
|
||||
// 2. It is switched back to maximized.
|
||||
// 3. In the process the window gets a WM_NCCACLSIZE message which calls us to
|
||||
// get the autohide state.
|
||||
// 4. The worker thread is invoked. It calls the API to get the autohide
|
||||
// state. On Windows versions earlier than Windows 7, taskbars could
|
||||
// easily be always on top or not.
|
||||
// This meant that we only want to look for taskbars which have the topmost
|
||||
// bit set. However this causes problems in cases where the window on the
|
||||
// main thread is still in the process of switching away from fullscreen.
|
||||
// In this case the taskbar might not yet have the topmost bit set.
|
||||
// 5. The main thread resumes and does not leave space for the taskbar and
|
||||
// hence it does not pop when hovered.
|
||||
//
|
||||
// To address point 4 above, it is best to not check for the WS_EX_TOPMOST
|
||||
// window style on the taskbar, as starting from Windows 7, the topmost
|
||||
// style is always set. We don't support XP and Vista anymore.
|
||||
if (::IsWindow(taskbar)) {
|
||||
if (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONEAREST) == monitor)
|
||||
return true;
|
||||
// In some cases like when the autohide taskbar is on the left of the
|
||||
// secondary monitor, the MonitorFromWindow call above fails to return the
|
||||
// correct monitor the taskbar is on. We fallback to MonitorFromPoint for
|
||||
// the cursor position in that case, which seems to work well.
|
||||
POINT cursor_pos = {0};
|
||||
GetCursorPos(&cursor_pos);
|
||||
if (MonitorFromPoint(cursor_pos, MONITOR_DEFAULTTONEAREST) == monitor)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int GetAppbarAutohideEdges(HWND hwnd) {
|
||||
HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
|
||||
if (!monitor)
|
||||
return 0;
|
||||
|
||||
int edges = 0;
|
||||
if (MonitorHasAutohideTaskbarForEdge(ABE_LEFT, monitor))
|
||||
edges |= AppbarAutohideEdge::LEFT;
|
||||
if (MonitorHasAutohideTaskbarForEdge(ABE_TOP, monitor))
|
||||
edges |= AppbarAutohideEdge::TOP;
|
||||
if (MonitorHasAutohideTaskbarForEdge(ABE_RIGHT, monitor))
|
||||
edges |= AppbarAutohideEdge::RIGHT;
|
||||
if (MonitorHasAutohideTaskbarForEdge(ABE_BOTTOM, monitor))
|
||||
edges |= AppbarAutohideEdge::BOTTOM;
|
||||
return edges;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::set<NativeWindowViews*> NativeWindowViews::forwarding_windows_;
|
||||
HHOOK NativeWindowViews::mouse_hook_ = NULL;
|
||||
|
||||
void NativeWindowViews::Maximize() {
|
||||
int autohide_edges = 0;
|
||||
if (!has_frame())
|
||||
autohide_edges = GetAppbarAutohideEdges(GetAcceleratedWidget());
|
||||
|
||||
// Only use Maximize() when:
|
||||
// 1. window has WS_THICKFRAME style;
|
||||
// 2. and window is not frameless when there is autohide taskbar.
|
||||
if ((::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME) &&
|
||||
(has_frame() || autohide_edges == 0)) {
|
||||
if (::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME) {
|
||||
if (IsVisible())
|
||||
widget()->Maximize();
|
||||
else
|
||||
widget()->native_widget_private()->Show(ui::SHOW_STATE_MAXIMIZED,
|
||||
gfx::Rect());
|
||||
return;
|
||||
} else {
|
||||
restore_bounds_ = GetBounds();
|
||||
auto display =
|
||||
display::Screen::GetScreen()->GetDisplayNearestPoint(GetPosition());
|
||||
SetBounds(display.work_area(), false);
|
||||
}
|
||||
|
||||
gfx::Insets insets;
|
||||
if (!has_frame()) {
|
||||
// When taskbar is autohide, we need to leave some space so the window
|
||||
// isn't treated as a "fullscreen app", which would cause the taskbars
|
||||
// to disappear.
|
||||
//
|
||||
// This trick comes from hwnd_message_handler.cc. While Chromium already
|
||||
// does this for normal window, somehow it is not applying the trick when
|
||||
// using frameless window, and we have to do it ourselves.
|
||||
float scale_factor =
|
||||
display::win::ScreenWin::GetScaleFactorForHWND(GetAcceleratedWidget());
|
||||
int thickness = std::ceil(kAutoHideTaskbarThicknessPx / scale_factor);
|
||||
if (autohide_edges & AppbarAutohideEdge::LEFT)
|
||||
insets.set_left(-thickness);
|
||||
if (autohide_edges & AppbarAutohideEdge::TOP)
|
||||
insets.set_top(-thickness);
|
||||
if (autohide_edges & AppbarAutohideEdge::RIGHT)
|
||||
insets.set_right(thickness);
|
||||
if (autohide_edges & AppbarAutohideEdge::BOTTOM)
|
||||
insets.set_bottom(thickness);
|
||||
}
|
||||
|
||||
restore_bounds_ = GetBounds();
|
||||
auto display =
|
||||
display::Screen::GetScreen()->GetDisplayNearestPoint(GetPosition());
|
||||
gfx::Rect bounds = display.work_area();
|
||||
bounds.Inset(insets);
|
||||
SetBounds(bounds, false);
|
||||
}
|
||||
|
||||
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
|
||||
@@ -305,6 +180,14 @@ bool NativeWindowViews::PreHandleMSG(UINT message,
|
||||
LRESULT* result) {
|
||||
NotifyWindowMessage(message, w_param, l_param);
|
||||
|
||||
// See code below for why blocking Chromium from handling messages.
|
||||
if (block_chromium_message_handler_) {
|
||||
// Handle the message with default proc.
|
||||
*result = DefWindowProc(GetAcceleratedWidget(), message, w_param, l_param);
|
||||
// Tell Chromium to ignore this message.
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (message) {
|
||||
// Screen readers send WM_GETOBJECT in order to get the accessibility
|
||||
// object, so take this opportunity to push Chromium into accessible
|
||||
@@ -346,37 +229,25 @@ bool NativeWindowViews::PreHandleMSG(UINT message,
|
||||
// use the proper display to calculate the scale factor to use.
|
||||
if (!last_normal_placement_bounds_.IsEmpty() &&
|
||||
GetWindowPlacement(GetAcceleratedWidget(), &wp)) {
|
||||
last_normal_placement_bounds_.set_size(gfx::Size(0, 0));
|
||||
wp.rcNormalPosition = last_normal_placement_bounds_.ToRECT();
|
||||
|
||||
// When calling SetWindowPlacement, Chromium would do window messages
|
||||
// handling. But since we are already in PreHandleMSG this would cause
|
||||
// crash in Chromium under some cases.
|
||||
//
|
||||
// We work around the crash by prevent Chromium from handling window
|
||||
// messages until the SetWindowPlacement call is done.
|
||||
//
|
||||
// See https://github.com/electron/electron/issues/21614 for more.
|
||||
block_chromium_message_handler_ = true;
|
||||
SetWindowPlacement(GetAcceleratedWidget(), &wp);
|
||||
block_chromium_message_handler_ = false;
|
||||
|
||||
last_normal_placement_bounds_ = gfx::Rect();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
case WM_NCCALCSIZE: {
|
||||
if (!has_frame() && w_param == TRUE) {
|
||||
NCCALCSIZE_PARAMS* params =
|
||||
reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param);
|
||||
RECT PROPOSED = params->rgrc[0];
|
||||
RECT BEFORE = params->rgrc[1];
|
||||
|
||||
// We need to call the default to have cascade and tile windows
|
||||
// working
|
||||
// (https://github.com/rossy/borderless-window/blob/master/borderless-window.c#L239),
|
||||
// but we need to provide the proposed original value as suggested in
|
||||
// https://blogs.msdn.microsoft.com/wpfsdk/2008/09/08/custom-window-chrome-in-wpf/
|
||||
DefWindowProcW(GetAcceleratedWidget(), WM_NCCALCSIZE, w_param, l_param);
|
||||
|
||||
params->rgrc[0] = PROPOSED;
|
||||
params->rgrc[1] = BEFORE;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
case WM_COMMAND:
|
||||
// Handle thumbar button click message.
|
||||
if (HIWORD(w_param) == THBN_CLICKED)
|
||||
@@ -396,10 +267,6 @@ bool NativeWindowViews::PreHandleMSG(UINT message,
|
||||
case WM_SIZE: {
|
||||
// Handle window state change.
|
||||
HandleSizeEvent(w_param, l_param);
|
||||
|
||||
consecutive_moves_ = false;
|
||||
last_normal_bounds_before_move_ = last_normal_bounds_;
|
||||
|
||||
return false;
|
||||
}
|
||||
case WM_MOVING: {
|
||||
@@ -415,15 +282,6 @@ bool NativeWindowViews::PreHandleMSG(UINT message,
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case WM_MOVE: {
|
||||
if (last_window_state_ == ui::SHOW_STATE_NORMAL) {
|
||||
if (consecutive_moves_)
|
||||
last_normal_bounds_ = last_normal_bounds_candidate_;
|
||||
last_normal_bounds_candidate_ = GetBounds();
|
||||
consecutive_moves_ = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case WM_ENDSESSION: {
|
||||
if (w_param) {
|
||||
NotifyWindowEndSession();
|
||||
@@ -453,26 +311,7 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
|
||||
// window state and notify the user accordingly.
|
||||
switch (w_param) {
|
||||
case SIZE_MAXIMIZED: {
|
||||
// Frameless maximized windows are size compensated by Windows for a
|
||||
// border that's not actually there, so we must conter-compensate.
|
||||
// https://blogs.msdn.microsoft.com/wpfsdk/2008/09/08/custom-window-chrome-in-wpf/
|
||||
if (!has_frame()) {
|
||||
float scale_factor = display::win::ScreenWin::GetScaleFactorForHWND(
|
||||
GetAcceleratedWidget());
|
||||
|
||||
int border =
|
||||
GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
|
||||
if (!thick_frame_) {
|
||||
border -= GetSystemMetrics(SM_CXBORDER);
|
||||
}
|
||||
root_view_->SetInsets(gfx::Insets(border).Scale(1.0f / scale_factor));
|
||||
}
|
||||
|
||||
last_window_state_ = ui::SHOW_STATE_MAXIMIZED;
|
||||
if (consecutive_moves_) {
|
||||
last_normal_bounds_ = last_normal_bounds_before_move_;
|
||||
}
|
||||
|
||||
NotifyWindowMaximize();
|
||||
break;
|
||||
}
|
||||
@@ -489,36 +328,22 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
|
||||
NotifyWindowMinimize();
|
||||
break;
|
||||
case SIZE_RESTORED:
|
||||
if (last_window_state_ == ui::SHOW_STATE_NORMAL) {
|
||||
// Window was resized so we save it's new size.
|
||||
last_normal_bounds_ = GetBounds();
|
||||
last_normal_bounds_before_move_ = last_normal_bounds_;
|
||||
} else {
|
||||
switch (last_window_state_) {
|
||||
case ui::SHOW_STATE_MAXIMIZED:
|
||||
switch (last_window_state_) {
|
||||
case ui::SHOW_STATE_MAXIMIZED:
|
||||
last_window_state_ = ui::SHOW_STATE_NORMAL;
|
||||
NotifyWindowUnmaximize();
|
||||
break;
|
||||
case ui::SHOW_STATE_MINIMIZED:
|
||||
if (IsFullscreen()) {
|
||||
last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
|
||||
NotifyWindowEnterFullScreen();
|
||||
} else {
|
||||
last_window_state_ = ui::SHOW_STATE_NORMAL;
|
||||
root_view_->SetInsets(gfx::Insets(0));
|
||||
NotifyWindowUnmaximize();
|
||||
break;
|
||||
case ui::SHOW_STATE_MINIMIZED:
|
||||
if (IsFullscreen()) {
|
||||
last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
|
||||
NotifyWindowEnterFullScreen();
|
||||
} else {
|
||||
last_window_state_ = ui::SHOW_STATE_NORMAL;
|
||||
|
||||
// When the window is restored we resize it to the previous known
|
||||
// normal size.
|
||||
if (has_frame()) {
|
||||
SetBounds(last_normal_bounds_, false);
|
||||
}
|
||||
|
||||
NotifyWindowRestore();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
NotifyWindowRestore();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,20 @@ 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->FindDictKey("headers");
|
||||
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,
|
||||
|
||||
@@ -37,13 +37,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;
|
||||
|
||||
options_parser.Parse(&args, &exec_args, &v8_args, &options,
|
||||
node::options_parser::kDisallowedInEnvironment, &errors);
|
||||
node::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?
|
||||
@@ -60,8 +60,10 @@ void NodeDebugger::Start() {
|
||||
|
||||
void NodeDebugger::Stop() {
|
||||
auto* inspector = env_->inspector_agent();
|
||||
if (inspector && inspector->IsListening())
|
||||
if (inspector && inspector->IsListening()) {
|
||||
inspector->WaitForDisconnect();
|
||||
inspector->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -270,10 +270,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);
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>electron.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>6.0.0-beta.7</string>
|
||||
<string>6.1.12</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>6.0.0-beta.7</string>
|
||||
<string>6.1.12</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
@@ -32,5 +32,9 @@
|
||||
<true/>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>This app needs access to the microphone</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>This app needs access to the camera</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 6,0,0,7
|
||||
PRODUCTVERSION 6,0,0,7
|
||||
FILEVERSION 6,1,12,0
|
||||
PRODUCTVERSION 6,1,12,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -68,12 +68,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "6.0.0"
|
||||
VALUE "FileVersion", "6.1.12"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "6.0.0"
|
||||
VALUE "ProductVersion", "6.1.12"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -28,7 +28,7 @@ class AtomMenuModel;
|
||||
base::scoped_nsobject<NSMenu> menu_;
|
||||
BOOL isMenuOpen_;
|
||||
BOOL useDefaultAccelerator_;
|
||||
base::Callback<void()> closeCallback;
|
||||
base::OnceClosure closeCallback;
|
||||
}
|
||||
|
||||
@property(nonatomic, assign) atom::AtomMenuModel* model;
|
||||
@@ -37,7 +37,7 @@ class AtomMenuModel;
|
||||
// to the contents of the model after calling this will not be noticed.
|
||||
- (id)initWithModel:(atom::AtomMenuModel*)model useDefaultAccelerator:(BOOL)use;
|
||||
|
||||
- (void)setCloseCallback:(const base::Callback<void()>&)callback;
|
||||
- (void)setCloseCallback:(base::OnceClosure)callback;
|
||||
|
||||
// Populate current NSMenu with |model|.
|
||||
- (void)populateWithModel:(atom::AtomMenuModel*)model;
|
||||
|
||||
@@ -118,19 +118,21 @@ static base::scoped_nsobject<NSMenu> recentDocumentsMenuSwap_;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)setCloseCallback:(const base::Callback<void()>&)callback {
|
||||
closeCallback = callback;
|
||||
- (void)setCloseCallback:(base::OnceClosure)callback {
|
||||
closeCallback = std::move(callback);
|
||||
}
|
||||
|
||||
- (void)populateWithModel:(atom::AtomMenuModel*)model {
|
||||
if (!menu_)
|
||||
return;
|
||||
|
||||
// Locate & retain the recent documents menu item
|
||||
if (!recentDocumentsMenuItem_) {
|
||||
// Locate & retain the recent documents menu item
|
||||
recentDocumentsMenuItem_.reset(
|
||||
[[[[[NSApp mainMenu] itemWithTitle:@"Electron"] submenu]
|
||||
itemWithTitle:@"Open Recent"] retain]);
|
||||
base::string16 title = base::ASCIIToUTF16("Open Recent");
|
||||
NSString* openTitle = l10n_util::FixUpWindowsStyleLabel(title);
|
||||
|
||||
recentDocumentsMenuItem_.reset([[[[[NSApp mainMenu]
|
||||
itemWithTitle:@"Electron"] submenu] itemWithTitle:openTitle] retain]);
|
||||
}
|
||||
|
||||
model_ = model;
|
||||
@@ -151,7 +153,8 @@ static base::scoped_nsobject<NSMenu> recentDocumentsMenuSwap_;
|
||||
isMenuOpen_ = NO;
|
||||
model_->MenuWillClose();
|
||||
if (!closeCallback.is_null()) {
|
||||
base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, closeCallback);
|
||||
base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
|
||||
std::move(closeCallback));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -193,8 +196,17 @@ static base::scoped_nsobject<NSMenu> recentDocumentsMenuSwap_;
|
||||
// Replaces the item's submenu instance with the singleton recent documents
|
||||
// menu. Previously replaced menu items will be recovered.
|
||||
- (void)replaceSubmenuShowingRecentDocuments:(NSMenuItem*)item {
|
||||
NSMenu* recentDocumentsMenu =
|
||||
[[[recentDocumentsMenuItem_ submenu] retain] autorelease];
|
||||
NSMenu* recentDocumentsMenu = [recentDocumentsMenuItem_ submenu];
|
||||
if (!recentDocumentsMenu) {
|
||||
base::string16 title = base::ASCIIToUTF16("Clear Menu");
|
||||
NSString* clearTitle = l10n_util::FixUpWindowsStyleLabel(title);
|
||||
recentDocumentsMenu = [[[NSMenu alloc] initWithTitle:@""] autorelease];
|
||||
[recentDocumentsMenu
|
||||
addItem:[[[NSMenuItem alloc]
|
||||
initWithTitle:clearTitle
|
||||
action:@selector(clearRecentDocuments:)
|
||||
keyEquivalent:@""] autorelease]];
|
||||
}
|
||||
|
||||
// Remove menu items in recent documents back to swap menu
|
||||
[self moveMenuItems:recentDocumentsMenu to:recentDocumentsMenuSwap_];
|
||||
@@ -211,6 +223,9 @@ static base::scoped_nsobject<NSMenu> recentDocumentsMenuSwap_;
|
||||
// Replace submenu
|
||||
[item setSubmenu:recentDocumentsMenu];
|
||||
|
||||
DCHECK_EQ([item action], @selector(submenuAction:));
|
||||
DCHECK_EQ([item target], recentDocumentsMenu);
|
||||
|
||||
// Remember the new menu item that carries the recent documents menu
|
||||
recentDocumentsMenuItem_.reset([item retain]);
|
||||
}
|
||||
@@ -372,11 +387,13 @@ static base::scoped_nsobject<NSMenu> recentDocumentsMenuSwap_;
|
||||
- (void)menuDidClose:(NSMenu*)menu {
|
||||
if (isMenuOpen_) {
|
||||
isMenuOpen_ = NO;
|
||||
model_->MenuWillClose();
|
||||
if (model_)
|
||||
model_->MenuWillClose();
|
||||
// Post async task so that itemSelected runs before the close callback
|
||||
// deletes the controller from the map which deallocates it
|
||||
if (!closeCallback.is_null()) {
|
||||
base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, closeCallback);
|
||||
base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
|
||||
std::move(closeCallback));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,8 +99,6 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute {
|
||||
if ([attribute isEqual:NSAccessibilityTitleAttribute])
|
||||
return base::SysUTF8ToNSString(shell_->GetTitle());
|
||||
if ([attribute isEqual:NSAccessibilityEnabledAttribute])
|
||||
return [NSNumber numberWithBool:YES];
|
||||
if (![attribute isEqualToString:@"AXChildren"])
|
||||
@@ -121,6 +119,10 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
return [children filteredArrayUsingPredicate:predicate];
|
||||
}
|
||||
|
||||
- (NSString*)accessibilityTitle {
|
||||
return base::SysUTF8ToNSString(shell_->GetTitle());
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeMainWindow {
|
||||
return !self.disableKeyOrMainWindow;
|
||||
}
|
||||
@@ -174,8 +176,14 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
}
|
||||
|
||||
- (void)toggleFullScreenMode:(id)sender {
|
||||
if (shell_->simple_fullscreen())
|
||||
shell_->SetSimpleFullScreen(!shell_->IsSimpleFullScreen());
|
||||
bool is_simple_fs = shell_->IsSimpleFullScreen();
|
||||
bool always_simple_fs = shell_->always_simple_fullscreen();
|
||||
|
||||
// If we're in simple fullscreen mode and trying to exit it
|
||||
// we need to ensure we exit it properly to prevent a crash
|
||||
// with NSWindowStyleMaskTitled mode
|
||||
if (is_simple_fs || always_simple_fs)
|
||||
shell_->SetSimpleFullScreen(!is_simple_fs);
|
||||
else
|
||||
[super toggleFullScreen:sender];
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "atom/browser/ui/cocoa/atom_touch_bar.h"
|
||||
#include "base/mac/mac_util.h"
|
||||
#include "components/remote_cocoa/app_shim/bridged_native_widget_impl.h"
|
||||
#include "ui/gfx/mac/coordinate_conversion.h"
|
||||
#include "ui/views/cocoa/bridged_native_widget_host_impl.h"
|
||||
#include "ui/views/widget/native_widget_mac.h"
|
||||
|
||||
@@ -116,8 +117,10 @@
|
||||
|
||||
{
|
||||
bool prevent_default = false;
|
||||
gfx::Rect new_bounds(gfx::Point(sender.frame.origin), gfx::Size(newSize));
|
||||
shell_->NotifyWindowWillResize(new_bounds, &prevent_default);
|
||||
NSRect new_bounds = NSMakeRect(sender.frame.origin.x, sender.frame.origin.y,
|
||||
newSize.width, newSize.height);
|
||||
shell_->NotifyWindowWillResize(gfx::ScreenRectFromNSRect(new_bounds),
|
||||
&prevent_default);
|
||||
if (prevent_default) {
|
||||
return sender.frame.size;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
|
||||
#include <glib/gi18n.h> // _() macro
|
||||
#include "atom/browser/ui/util_gtk.h"
|
||||
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
@@ -46,18 +45,18 @@ class FileChooserDialog {
|
||||
FileChooserDialog(GtkFileChooserAction action, const DialogSettings& settings)
|
||||
: parent_(static_cast<atom::NativeWindowViews*>(settings.parent_window)),
|
||||
filters_(settings.filters) {
|
||||
const char* confirm_text = _("_OK");
|
||||
const char* confirm_text = util_gtk::kOkLabel;
|
||||
|
||||
if (!settings.button_label.empty())
|
||||
confirm_text = settings.button_label.c_str();
|
||||
else if (action == GTK_FILE_CHOOSER_ACTION_SAVE)
|
||||
confirm_text = _("_Save");
|
||||
confirm_text = util_gtk::kSaveLabel;
|
||||
else if (action == GTK_FILE_CHOOSER_ACTION_OPEN)
|
||||
confirm_text = _("_Open");
|
||||
confirm_text = util_gtk::kOpenLabel;
|
||||
|
||||
dialog_ = gtk_file_chooser_dialog_new(
|
||||
settings.title.c_str(), NULL, action, _("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||
confirm_text, GTK_RESPONSE_ACCEPT, NULL);
|
||||
settings.title.c_str(), NULL, action, util_gtk::kCancelLabel,
|
||||
GTK_RESPONSE_CANCEL, confirm_text, GTK_RESPONSE_ACCEPT, NULL);
|
||||
if (parent_) {
|
||||
parent_->SetEnabled(false);
|
||||
libgtkui::SetGtkTransientForAura(dialog_, parent_->GetNativeWindow());
|
||||
|
||||
@@ -25,6 +25,8 @@ namespace atom {
|
||||
class InspectableWebContentsDelegate;
|
||||
class InspectableWebContentsView;
|
||||
|
||||
// TODO(zcbenz): Remove this abstract wrapper and rename
|
||||
// InspectableWebContentsImpl to InspectableWebContents instead.
|
||||
class InspectableWebContents {
|
||||
public:
|
||||
// The returned InspectableWebContents takes ownership of the passed-in
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE-CHROMIUM file.
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents_impl.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents_impl.h"
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents_delegate.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view_delegate.h"
|
||||
@@ -75,6 +75,9 @@ const char kTitleFormat[] = "Developer Tools - %s";
|
||||
|
||||
const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4;
|
||||
|
||||
// Stores all instances of InspectableWebContentsImpl.
|
||||
InspectableWebContentsImpl::List g_web_contents_instances_;
|
||||
|
||||
base::Value RectToDictionary(const gfx::Rect& bounds) {
|
||||
base::Value dict(base::Value::Type::DICTIONARY);
|
||||
dict.SetKey("x", base::Value(bounds.x()));
|
||||
@@ -227,6 +230,12 @@ class InspectableWebContentsImpl::NetworkResourceLoader
|
||||
InspectableWebContentsView* CreateInspectableContentsView(
|
||||
InspectableWebContentsImpl* inspectable_web_contents_impl);
|
||||
|
||||
// static
|
||||
const InspectableWebContentsImpl::List& InspectableWebContentsImpl::GetAll() {
|
||||
return g_web_contents_instances_;
|
||||
}
|
||||
|
||||
// static
|
||||
void InspectableWebContentsImpl::RegisterPrefs(PrefRegistrySimple* registry) {
|
||||
registry->RegisterDictionaryPref(kDevToolsBoundsPref,
|
||||
RectToDictionary(gfx::Rect(0, 0, 800, 600)));
|
||||
@@ -270,9 +279,11 @@ InspectableWebContentsImpl::InspectableWebContentsImpl(
|
||||
display.y() + (display.height() - devtools_bounds_.height()) / 2);
|
||||
}
|
||||
}
|
||||
g_web_contents_instances_.push_back(this);
|
||||
}
|
||||
|
||||
InspectableWebContentsImpl::~InspectableWebContentsImpl() {
|
||||
g_web_contents_instances_.remove(this);
|
||||
// Unsubscribe from devtools and Clean up resources.
|
||||
if (GetDevToolsWebContents()) {
|
||||
if (managed_devtools_web_contents_)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#ifndef ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_IMPL_H_
|
||||
#define ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_IMPL_H_
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
@@ -38,6 +39,9 @@ class InspectableWebContentsImpl
|
||||
public content::WebContentsDelegate,
|
||||
public DevToolsEmbedderMessageDispatcher::Delegate {
|
||||
public:
|
||||
using List = std::list<InspectableWebContentsImpl*>;
|
||||
|
||||
static const List& GetAll();
|
||||
static void RegisterPrefs(PrefRegistrySimple* pref_registry);
|
||||
|
||||
InspectableWebContentsImpl(content::WebContents* web_contents,
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_window_observer.h"
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "atom/browser/ui/util_gtk.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/strings/string_util.h"
|
||||
@@ -127,13 +128,13 @@ class GtkMessageBox : public NativeWindowObserver {
|
||||
const char* TranslateToStock(int id, const std::string& text) {
|
||||
const std::string lower = base::ToLowerASCII(text);
|
||||
if (lower == "cancel")
|
||||
return _("_Cancel");
|
||||
return util_gtk::kCancelLabel;
|
||||
if (lower == "no")
|
||||
return _("_No");
|
||||
return util_gtk::kNoLabel;
|
||||
if (lower == "ok")
|
||||
return _("_OK");
|
||||
return util_gtk::kOkLabel;
|
||||
if (lower == "yes")
|
||||
return _("_Yes");
|
||||
return util_gtk::kYesLabel;
|
||||
return text.c_str();
|
||||
}
|
||||
|
||||
@@ -235,8 +236,8 @@ void ShowMessageBox(NativeWindow* parent,
|
||||
|
||||
void ShowErrorBox(const base::string16& title, const base::string16& content) {
|
||||
if (Browser::Get()->is_ready()) {
|
||||
GtkMessageBox(nullptr, MESSAGE_BOX_TYPE_ERROR, {"OK"}, -1, 0, "Error",
|
||||
base::UTF16ToUTF8(title).c_str(),
|
||||
GtkMessageBox(nullptr, MESSAGE_BOX_TYPE_ERROR, {util_gtk::kOkLabel}, -1, 0,
|
||||
"Error", base::UTF16ToUTF8(title).c_str(),
|
||||
base::UTF16ToUTF8(content).c_str(), "", false,
|
||||
gfx::ImageSkia())
|
||||
.RunSynchronous();
|
||||
|
||||
@@ -61,7 +61,9 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window,
|
||||
int button_count = static_cast<int>([ns_buttons count]);
|
||||
|
||||
if (default_id >= 0 && default_id < button_count) {
|
||||
// Focus the button at default_id if the user opted to do so.
|
||||
// Highlight the button at default_id
|
||||
[[ns_buttons objectAtIndex:default_id] highlight:YES];
|
||||
|
||||
// The first button added gets set as the default selected.
|
||||
// So remove that default, and make the requested button the default.
|
||||
[[ns_buttons objectAtIndex:0] setKeyEquivalent:@""];
|
||||
|
||||
@@ -30,6 +30,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;
|
||||
@@ -49,6 +50,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);
|
||||
};
|
||||
|
||||
|
||||
@@ -4,13 +4,20 @@
|
||||
|
||||
#include "atom/browser/ui/tray_icon_cocoa.h"
|
||||
|
||||
#include "atom/browser/mac/atom_application.h"
|
||||
#include "atom/browser/ui/cocoa/NSString+ANSI.h"
|
||||
#include "atom/browser/ui/cocoa/atom_menu_controller.h"
|
||||
#include "base/mac/sdk_forward_declarations.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/events/cocoa/cocoa_event_utils.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
#include "ui/gfx/mac/coordinate_conversion.h"
|
||||
#include "ui/native_theme/native_theme.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -143,6 +150,9 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
}
|
||||
|
||||
- (BOOL)isDarkMode {
|
||||
if (@available(macOS 10.15, *)) {
|
||||
return ui::NativeTheme::GetInstanceForNativeUi()->SystemDarkModeEnabled();
|
||||
}
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSString* mode = [defaults stringForKey:@"AppleInterfaceStyle"];
|
||||
return mode && [mode isEqualToString:@"Dark"];
|
||||
@@ -324,13 +334,17 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
}
|
||||
|
||||
- (void)popUpContextMenu:(atom::AtomMenuModel*)menu_model {
|
||||
// Make sure events can be pumped while the menu is up.
|
||||
base::MessageLoopCurrent::ScopedNestableTaskAllower allow;
|
||||
|
||||
// Show a custom menu.
|
||||
if (menu_model) {
|
||||
base::scoped_nsobject<AtomMenuController> menuController([
|
||||
[AtomMenuController alloc] initWithModel:menu_model
|
||||
useDefaultAccelerator:NO]);
|
||||
base::scoped_nsobject<AtomMenuController> menuController(
|
||||
[[AtomMenuController alloc] initWithModel:menu_model
|
||||
useDefaultAccelerator:NO]);
|
||||
forceHighlight_ = YES; // Should highlight when showing menu.
|
||||
[self setNeedsDisplay:YES];
|
||||
|
||||
[statusItem_ popUpStatusItemMenu:[menuController menu]];
|
||||
forceHighlight_ = NO;
|
||||
[self setNeedsDisplay:YES];
|
||||
@@ -338,8 +352,12 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
}
|
||||
|
||||
if (menuController_ && ![menuController_ isMenuOpen]) {
|
||||
// Ensure the UI can update while the menu is fading out.
|
||||
base::ScopedPumpMessagesInPrivateModes pump_private;
|
||||
|
||||
// Redraw the tray icon to show highlight if it is enabled.
|
||||
[self setNeedsDisplay:YES];
|
||||
|
||||
[statusItem_ popUpStatusItemMenu:[menuController_ menu]];
|
||||
// The popUpStatusItemMenu returns only after the showing menu is closed.
|
||||
// When it returns, we need to redraw the tray icon to not show highlight.
|
||||
@@ -437,7 +455,7 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
|
||||
namespace atom {
|
||||
|
||||
TrayIconCocoa::TrayIconCocoa() {
|
||||
TrayIconCocoa::TrayIconCocoa() : weak_factory_(this) {
|
||||
status_item_view_.reset([[StatusItemView alloc] initWithIcon:this]);
|
||||
}
|
||||
|
||||
@@ -479,9 +497,16 @@ bool TrayIconCocoa::GetIgnoreDoubleClickEvents() {
|
||||
return [status_item_view_ getIgnoreDoubleClickEvents];
|
||||
}
|
||||
|
||||
void TrayIconCocoa::PopUpOnUI(AtomMenuModel* menu_model) {
|
||||
[status_item_view_ popUpContextMenu:menu_model];
|
||||
}
|
||||
|
||||
void TrayIconCocoa::PopUpContextMenu(const gfx::Point& pos,
|
||||
AtomMenuModel* menu_model) {
|
||||
[status_item_view_ popUpContextMenu:menu_model];
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {content::BrowserThread::UI},
|
||||
base::BindOnce(&TrayIconCocoa::PopUpOnUI, weak_factory_.GetWeakPtr(),
|
||||
base::Unretained(menu_model)));
|
||||
}
|
||||
|
||||
void TrayIconCocoa::SetContextMenu(AtomMenuModel* menu_model) {
|
||||
|
||||
36
atom/browser/ui/util_gtk.cc
Normal file
36
atom/browser/ui/util_gtk.cc
Normal file
@@ -0,0 +1,36 @@
|
||||
// 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/ui/util_gtk.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
namespace util_gtk {
|
||||
|
||||
// Copied from L40-L55 in
|
||||
// https://cs.chromium.org/chromium/src/chrome/browser/ui/libgtkui/select_file_dialog_impl_gtk.cc
|
||||
#if GTK_CHECK_VERSION(3, 90, 0)
|
||||
// GTK stock items have been deprecated. The docs say to switch to using the
|
||||
// strings "_Open", etc. However this breaks i18n. We could supply our own
|
||||
// internationalized strings, but the "_" in these strings is significant: it's
|
||||
// the keyboard shortcut to select these actions. TODO: Provide
|
||||
// internationalized strings when GTK provides support for it.
|
||||
const char* const kCancelLabel = "_Cancel";
|
||||
const char* const kNoLabel = "_No";
|
||||
const char* const kOkLabel = "_OK";
|
||||
const char* const kOpenLabel = "_Open";
|
||||
const char* const kSaveLabel = "_Save";
|
||||
const char* const kYesLabel = "_Yes";
|
||||
#else
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
const char* const kCancelLabel = GTK_STOCK_CANCEL;
|
||||
const char* const kNoLabel = GTK_STOCK_NO;
|
||||
const char* const kOkLabel = GTK_STOCK_OK;
|
||||
const char* const kOpenLabel = GTK_STOCK_OPEN;
|
||||
const char* const kSaveLabel = GTK_STOCK_SAVE;
|
||||
const char* const kYesLabel = GTK_STOCK_YES;
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
#endif
|
||||
|
||||
} // namespace util_gtk
|
||||
21
atom/browser/ui/util_gtk.h
Normal file
21
atom/browser/ui/util_gtk.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// 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_UI_UTIL_GTK_H_
|
||||
#define ATOM_BROWSER_UI_UTIL_GTK_H_
|
||||
|
||||
namespace util_gtk {
|
||||
|
||||
/* These are `const char*` rather than the project-preferred `const char[]`
|
||||
because they must fit the type of an external dependency */
|
||||
extern const char* const kCancelLabel;
|
||||
extern const char* const kNoLabel;
|
||||
extern const char* const kOkLabel;
|
||||
extern const char* const kOpenLabel;
|
||||
extern const char* const kSaveLabel;
|
||||
extern const char* const kYesLabel;
|
||||
|
||||
} // namespace util_gtk
|
||||
|
||||
#endif // ATOM_BROWSER_UI_UTIL_GTK_H_
|
||||
@@ -53,22 +53,7 @@ void ViewsDelegate::NotifyMenuItemFocused(const base::string16& menu_name,
|
||||
int item_count,
|
||||
bool has_submenu) {}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
HICON ViewsDelegate::GetDefaultWindowIcon() const {
|
||||
// Use current exe's icon as default window icon.
|
||||
return LoadIcon(GetModuleHandle(NULL),
|
||||
MAKEINTRESOURCE(1 /* IDR_MAINFRAME */));
|
||||
}
|
||||
|
||||
HICON ViewsDelegate::GetSmallWindowIcon() const {
|
||||
return GetDefaultWindowIcon();
|
||||
}
|
||||
|
||||
bool ViewsDelegate::IsWindowInMetro(gfx::NativeWindow window) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
#elif defined(OS_LINUX) && !defined(OS_CHROMEOS)
|
||||
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
|
||||
gfx::ImageSkia* ViewsDelegate::GetDefaultWindowIcon() const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef ATOM_BROWSER_UI_VIEWS_ATOM_VIEWS_DELEGATE_H_
|
||||
#define ATOM_BROWSER_UI_VIEWS_ATOM_VIEWS_DELEGATE_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
@@ -37,6 +38,8 @@ class ViewsDelegate : public views::ViewsDelegate {
|
||||
HICON GetDefaultWindowIcon() const override;
|
||||
HICON GetSmallWindowIcon() const override;
|
||||
bool IsWindowInMetro(gfx::NativeWindow window) const override;
|
||||
int GetAppbarAutohideEdges(HMONITOR monitor,
|
||||
base::OnceClosure callback) override;
|
||||
#elif defined(OS_LINUX) && !defined(OS_CHROMEOS)
|
||||
gfx::ImageSkia* GetDefaultWindowIcon() const override;
|
||||
#endif
|
||||
@@ -50,6 +53,24 @@ class ViewsDelegate : public views::ViewsDelegate {
|
||||
bool WindowManagerProvidesTitleBar(bool maximized) override;
|
||||
|
||||
private:
|
||||
#if defined(OS_WIN)
|
||||
using AppbarAutohideEdgeMap = std::map<HMONITOR, int>;
|
||||
|
||||
// Callback on main thread with the edges. |returned_edges| is the value that
|
||||
// was returned from the call to GetAutohideEdges() that initiated the lookup.
|
||||
void OnGotAppbarAutohideEdges(base::OnceClosure callback,
|
||||
HMONITOR monitor,
|
||||
int returned_edges,
|
||||
int edges);
|
||||
|
||||
AppbarAutohideEdgeMap appbar_autohide_edge_map_;
|
||||
// If true we're in the process of notifying a callback from
|
||||
// GetAutohideEdges().start a new query.
|
||||
bool in_autohide_edges_callback_ = false;
|
||||
|
||||
base::WeakPtrFactory<ViewsDelegate> weak_factory_{this};
|
||||
#endif
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ViewsDelegate);
|
||||
};
|
||||
|
||||
|
||||
156
atom/browser/ui/views/atom_views_delegate_win.cc
Normal file
156
atom/browser/ui/views/atom_views_delegate_win.cc
Normal file
@@ -0,0 +1,156 @@
|
||||
// Copyright (c) 2017 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE-CHROMIUM file.
|
||||
|
||||
#include "atom/browser/ui/views/atom_views_delegate.h"
|
||||
|
||||
#include <dwmapi.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/task/post_task.h"
|
||||
|
||||
namespace {
|
||||
|
||||
bool MonitorHasAutohideTaskbarForEdge(UINT edge, HMONITOR monitor) {
|
||||
APPBARDATA taskbar_data = {sizeof(APPBARDATA), NULL, 0, edge};
|
||||
taskbar_data.hWnd = ::GetForegroundWindow();
|
||||
|
||||
// MSDN documents an ABM_GETAUTOHIDEBAREX, which supposedly takes a monitor
|
||||
// rect and returns autohide bars on that monitor. This sounds like a good
|
||||
// idea for multi-monitor systems. Unfortunately, it appears to not work at
|
||||
// least some of the time (erroneously returning NULL) and there's almost no
|
||||
// online documentation or other sample code using it that suggests ways to
|
||||
// address this problem. We do the following:-
|
||||
// 1. Use the ABM_GETAUTOHIDEBAR message. If it works, i.e. returns a valid
|
||||
// window we are done.
|
||||
// 2. If the ABM_GETAUTOHIDEBAR message does not work we query the auto hide
|
||||
// state of the taskbar and then retrieve its position. That call returns
|
||||
// the edge on which the taskbar is present. If it matches the edge we
|
||||
// are looking for, we are done.
|
||||
// NOTE: This call spins a nested run loop.
|
||||
HWND taskbar = reinterpret_cast<HWND>(
|
||||
SHAppBarMessage(ABM_GETAUTOHIDEBAR, &taskbar_data));
|
||||
if (!::IsWindow(taskbar)) {
|
||||
APPBARDATA taskbar_data = {sizeof(APPBARDATA), 0, 0, 0};
|
||||
unsigned int taskbar_state = SHAppBarMessage(ABM_GETSTATE, &taskbar_data);
|
||||
if (!(taskbar_state & ABS_AUTOHIDE))
|
||||
return false;
|
||||
|
||||
taskbar_data.hWnd = ::FindWindow(L"Shell_TrayWnd", NULL);
|
||||
if (!::IsWindow(taskbar_data.hWnd))
|
||||
return false;
|
||||
|
||||
SHAppBarMessage(ABM_GETTASKBARPOS, &taskbar_data);
|
||||
if (taskbar_data.uEdge == edge)
|
||||
taskbar = taskbar_data.hWnd;
|
||||
}
|
||||
|
||||
// There is a potential race condition here:
|
||||
// 1. A maximized chrome window is fullscreened.
|
||||
// 2. It is switched back to maximized.
|
||||
// 3. In the process the window gets a WM_NCCACLSIZE message which calls us to
|
||||
// get the autohide state.
|
||||
// 4. The worker thread is invoked. It calls the API to get the autohide
|
||||
// state. On Windows versions earlier than Windows 7, taskbars could
|
||||
// easily be always on top or not.
|
||||
// This meant that we only want to look for taskbars which have the topmost
|
||||
// bit set. However this causes problems in cases where the window on the
|
||||
// main thread is still in the process of switching away from fullscreen.
|
||||
// In this case the taskbar might not yet have the topmost bit set.
|
||||
// 5. The main thread resumes and does not leave space for the taskbar and
|
||||
// hence it does not pop when hovered.
|
||||
//
|
||||
// To address point 4 above, it is best to not check for the WS_EX_TOPMOST
|
||||
// window style on the taskbar, as starting from Windows 7, the topmost
|
||||
// style is always set. We don't support XP and Vista anymore.
|
||||
if (::IsWindow(taskbar)) {
|
||||
if (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONEAREST) == monitor)
|
||||
return true;
|
||||
// In some cases like when the autohide taskbar is on the left of the
|
||||
// secondary monitor, the MonitorFromWindow call above fails to return the
|
||||
// correct monitor the taskbar is on. We fallback to MonitorFromPoint for
|
||||
// the cursor position in that case, which seems to work well.
|
||||
POINT cursor_pos = {0};
|
||||
GetCursorPos(&cursor_pos);
|
||||
if (MonitorFromPoint(cursor_pos, MONITOR_DEFAULTTONEAREST) == monitor)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int GetAppbarAutohideEdgesOnWorkerThread(HMONITOR monitor) {
|
||||
DCHECK(monitor);
|
||||
|
||||
int edges = 0;
|
||||
if (MonitorHasAutohideTaskbarForEdge(ABE_LEFT, monitor))
|
||||
edges |= views::ViewsDelegate::EDGE_LEFT;
|
||||
if (MonitorHasAutohideTaskbarForEdge(ABE_TOP, monitor))
|
||||
edges |= views::ViewsDelegate::EDGE_TOP;
|
||||
if (MonitorHasAutohideTaskbarForEdge(ABE_RIGHT, monitor))
|
||||
edges |= views::ViewsDelegate::EDGE_RIGHT;
|
||||
if (MonitorHasAutohideTaskbarForEdge(ABE_BOTTOM, monitor))
|
||||
edges |= views::ViewsDelegate::EDGE_BOTTOM;
|
||||
return edges;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace atom {
|
||||
|
||||
HICON ViewsDelegate::GetDefaultWindowIcon() const {
|
||||
// Use current exe's icon as default window icon.
|
||||
return LoadIcon(GetModuleHandle(NULL),
|
||||
MAKEINTRESOURCE(1 /* IDR_MAINFRAME */));
|
||||
}
|
||||
|
||||
HICON ViewsDelegate::GetSmallWindowIcon() const {
|
||||
return GetDefaultWindowIcon();
|
||||
}
|
||||
|
||||
bool ViewsDelegate::IsWindowInMetro(gfx::NativeWindow window) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
int ViewsDelegate::GetAppbarAutohideEdges(HMONITOR monitor,
|
||||
base::OnceClosure callback) {
|
||||
// Initialize the map with EDGE_BOTTOM. This is important, as if we return an
|
||||
// initial value of 0 (no auto-hide edges) then we'll go fullscreen and
|
||||
// windows will automatically remove WS_EX_TOPMOST from the appbar resulting
|
||||
// in us thinking there is no auto-hide edges. By returning at least one edge
|
||||
// we don't initially go fullscreen until we figure out the real auto-hide
|
||||
// edges.
|
||||
if (!appbar_autohide_edge_map_.count(monitor))
|
||||
appbar_autohide_edge_map_[monitor] = EDGE_BOTTOM;
|
||||
|
||||
// We use the SHAppBarMessage API to get the taskbar autohide state. This API
|
||||
// spins a modal loop which could cause callers to be reentered. To avoid
|
||||
// that we retrieve the taskbar state in a worker thread.
|
||||
if (monitor && !in_autohide_edges_callback_) {
|
||||
// TODO(robliao): Annotate this task with .WithCOM() once supported.
|
||||
// https://crbug.com/662122
|
||||
base::PostTaskWithTraitsAndReplyWithResult(
|
||||
FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING},
|
||||
base::BindOnce(&GetAppbarAutohideEdgesOnWorkerThread, monitor),
|
||||
base::BindOnce(&ViewsDelegate::OnGotAppbarAutohideEdges,
|
||||
weak_factory_.GetWeakPtr(), std::move(callback), monitor,
|
||||
appbar_autohide_edge_map_[monitor]));
|
||||
}
|
||||
return appbar_autohide_edge_map_[monitor];
|
||||
}
|
||||
|
||||
void ViewsDelegate::OnGotAppbarAutohideEdges(base::OnceClosure callback,
|
||||
HMONITOR monitor,
|
||||
int returned_edges,
|
||||
int edges) {
|
||||
appbar_autohide_edge_map_[monitor] = edges;
|
||||
if (returned_edges == edges)
|
||||
return;
|
||||
|
||||
base::AutoReset<bool> in_callback_setter(&in_autohide_edges_callback_, true);
|
||||
std::move(callback).Run();
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "atom/common/keyboard_util.h"
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/base/models/menu_model.h"
|
||||
#include "ui/native_theme/common_theme.h"
|
||||
#include "ui/views/background.h"
|
||||
#include "ui/views/layout/box_layout.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
@@ -274,9 +275,6 @@ void MenuBar::OnMenuButtonClicked(views::Button* source,
|
||||
return;
|
||||
}
|
||||
|
||||
GetFocusManager()->SetFocusedViewWithReason(
|
||||
source, views::FocusManager::kReasonFocusTraversal);
|
||||
|
||||
// Deleted in MenuDelegate::OnMenuClosed
|
||||
MenuDelegate* menu_delegate = new MenuDelegate(this);
|
||||
menu_delegate->RunMenu(menu_model_->GetSubmenuModelAt(id), source,
|
||||
@@ -297,12 +295,9 @@ void MenuBar::RefreshColorCache() {
|
||||
"GtkMenuBar#menubar GtkMenuItem#menuitem:disabled GtkLabel");
|
||||
#else
|
||||
background_color_ =
|
||||
theme->GetSystemColor(ui::NativeTheme::kColorId_MenuBackgroundColor);
|
||||
ui::GetAuraColor(ui::NativeTheme::kColorId_MenuBackgroundColor, theme);
|
||||
#endif
|
||||
}
|
||||
#if defined(OS_WIN)
|
||||
background_color_ = color_utils::GetSysSkColor(COLOR_MENUBAR);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MenuBar::OnThemeChanged() {
|
||||
|
||||
@@ -175,18 +175,14 @@ void RootView::Layout() {
|
||||
return;
|
||||
|
||||
const auto menu_bar_bounds =
|
||||
menu_bar_visible_
|
||||
? gfx::Rect(insets_.left(), insets_.top(),
|
||||
size().width() - insets_.width(), kMenuBarHeight)
|
||||
: gfx::Rect();
|
||||
menu_bar_visible_ ? gfx::Rect(0, 0, size().width(), kMenuBarHeight)
|
||||
: gfx::Rect();
|
||||
if (menu_bar_)
|
||||
menu_bar_->SetBoundsRect(menu_bar_bounds);
|
||||
|
||||
window_->content_view()->SetBoundsRect(
|
||||
gfx::Rect(insets_.left(),
|
||||
menu_bar_visible_ ? menu_bar_bounds.bottom() : insets_.top(),
|
||||
size().width() - insets_.width(),
|
||||
size().height() - menu_bar_bounds.height() - insets_.height()));
|
||||
gfx::Rect(0, menu_bar_visible_ ? menu_bar_bounds.bottom() : 0,
|
||||
size().width(), size().height() - menu_bar_bounds.height()));
|
||||
}
|
||||
|
||||
gfx::Size RootView::GetMinimumSize() const {
|
||||
@@ -223,11 +219,4 @@ void RootView::UnregisterAcceleratorsWithFocusManager() {
|
||||
focus_manager->UnregisterAccelerators(this);
|
||||
}
|
||||
|
||||
void RootView::SetInsets(const gfx::Insets& insets) {
|
||||
if (insets != insets_) {
|
||||
insets_ = insets;
|
||||
Layout();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -40,8 +40,6 @@ class RootView : public views::View {
|
||||
// Register/Unregister accelerators supported by the menu model.
|
||||
void RegisterAcceleratorsWithFocusManager(AtomMenuModel* menu_model);
|
||||
void UnregisterAcceleratorsWithFocusManager();
|
||||
void SetInsets(const gfx::Insets& insets);
|
||||
gfx::Insets insets() const { return insets_; }
|
||||
|
||||
// views::View:
|
||||
void Layout() override;
|
||||
@@ -59,8 +57,6 @@ class RootView : public views::View {
|
||||
bool menu_bar_visible_ = false;
|
||||
bool menu_bar_alt_pressed_ = false;
|
||||
|
||||
gfx::Insets insets_;
|
||||
|
||||
// Map from accelerator to menu item's command id.
|
||||
accelerator_util::AcceleratorTable accelerator_table_;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h"
|
||||
|
||||
#include "ui/base/win/hwnd_metrics.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
AtomDesktopWindowTreeHostWin::AtomDesktopWindowTreeHostWin(
|
||||
@@ -29,4 +31,17 @@ bool AtomDesktopWindowTreeHostWin::HasNativeFrame() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtomDesktopWindowTreeHostWin::GetClientAreaInsets(gfx::Insets* insets,
|
||||
HMONITOR monitor) const {
|
||||
if (IsMaximized() && !native_window_view_->has_frame()) {
|
||||
// Windows automatically adds a standard width border to all sides when a
|
||||
// window is maximized.
|
||||
int frame_thickness = ui::GetFrameThickness(monitor) - 1;
|
||||
*insets = gfx::Insets(frame_thickness, frame_thickness, frame_thickness,
|
||||
frame_thickness);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -25,6 +25,8 @@ class AtomDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin {
|
||||
LPARAM l_param,
|
||||
LRESULT* result) override;
|
||||
bool HasNativeFrame() const override;
|
||||
bool GetClientAreaInsets(gfx::Insets* insets,
|
||||
HMONITOR monitor) const override;
|
||||
|
||||
private:
|
||||
NativeWindowViews* native_window_view_; // weak ref
|
||||
|
||||
@@ -147,8 +147,6 @@ WebContentsPreferences::WebContentsPreferences(
|
||||
#endif
|
||||
SetDefaultBoolIfUndefined(options::kOffscreen, false);
|
||||
|
||||
SetDefaults();
|
||||
|
||||
// If this is a <webview> tag, and the embedder is offscreen-rendered, then
|
||||
// this WebContents is also offscreen-rendered.
|
||||
int guest_instance_id = 0;
|
||||
@@ -166,7 +164,7 @@ WebContentsPreferences::WebContentsPreferences(
|
||||
}
|
||||
}
|
||||
|
||||
last_preference_ = preference_.Clone();
|
||||
SetDefaults();
|
||||
}
|
||||
|
||||
WebContentsPreferences::~WebContentsPreferences() {
|
||||
@@ -178,6 +176,8 @@ void WebContentsPreferences::SetDefaults() {
|
||||
if (IsEnabled(options::kSandbox)) {
|
||||
SetBool(options::kNativeWindowOpen, true);
|
||||
}
|
||||
|
||||
last_preference_ = preference_.Clone();
|
||||
}
|
||||
|
||||
bool WebContentsPreferences::SetDefaultBoolIfUndefined(
|
||||
|
||||
@@ -10,6 +10,8 @@ interface ElectronRenderer {
|
||||
mojo_base.mojom.ListValue arguments,
|
||||
int32 sender_id);
|
||||
|
||||
UpdateCrashpadPipeName(string pipe_name);
|
||||
|
||||
TakeHeapSnapshot(handle file) => (bool success);
|
||||
};
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/asar/archive.h"
|
||||
#include "atom/common/asar/asar_util.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
@@ -14,7 +15,7 @@
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
#include "third_party/electron_node/src/node_native_module.h"
|
||||
#include "third_party/electron_node/src/node_native_module_env.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -122,17 +123,32 @@ void InitAsarSupport(v8::Isolate* isolate, v8::Local<v8::Value> require) {
|
||||
std::vector<v8::Local<v8::String>> asar_init_params = {
|
||||
node::FIXED_ONE_BYTE_STRING(isolate, "require")};
|
||||
std::vector<v8::Local<v8::Value>> asar_init_args = {require};
|
||||
node::per_process::native_module_loader.CompileAndCall(
|
||||
node::native_module::NativeModuleEnv::CompileAndCall(
|
||||
isolate->GetCurrentContext(), "electron/js2c/asar_init",
|
||||
&asar_init_params, &asar_init_args, nullptr);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> SplitPath(v8::Isolate* isolate,
|
||||
const base::FilePath& path) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
base::FilePath asar_path, file_path;
|
||||
if (asar::GetAsarArchivePath(path, &asar_path, &file_path, true)) {
|
||||
dict.Set("isAsar", true);
|
||||
dict.Set("asarPath", asar_path);
|
||||
dict.Set("filePath", file_path);
|
||||
} else {
|
||||
dict.Set("isAsar", false);
|
||||
}
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("createArchive", &Archive::Create);
|
||||
dict.SetMethod("splitPath", &SplitPath);
|
||||
dict.SetMethod("initAsarSupport", &InitAsarSupport);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "base/process/process_metrics.h"
|
||||
#include "base/strings/string16.h"
|
||||
#include "native_mate/arguments.h"
|
||||
#include "uv.h" // NOLINT(build/include)
|
||||
#include "uv.h" // NOLINT(build/include_directory)
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
@@ -16,19 +16,23 @@ namespace atom {
|
||||
// static
|
||||
void RemoteCallbackFreer::BindTo(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
int frame_id,
|
||||
const std::string& context_id,
|
||||
int object_id,
|
||||
content::WebContents* web_contents) {
|
||||
new RemoteCallbackFreer(isolate, target, context_id, object_id, web_contents);
|
||||
new RemoteCallbackFreer(isolate, target, frame_id, context_id, object_id,
|
||||
web_contents);
|
||||
}
|
||||
|
||||
RemoteCallbackFreer::RemoteCallbackFreer(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
int frame_id,
|
||||
const std::string& context_id,
|
||||
int object_id,
|
||||
content::WebContents* web_contents)
|
||||
: ObjectLifeMonitor(isolate, target),
|
||||
content::WebContentsObserver(web_contents),
|
||||
frame_id_(frame_id),
|
||||
context_id_(context_id),
|
||||
object_id_(object_id) {}
|
||||
|
||||
@@ -40,10 +44,15 @@ void RemoteCallbackFreer::RunDestructor() {
|
||||
int32_t sender_id = 0;
|
||||
args.AppendString(context_id_);
|
||||
args.AppendInteger(object_id_);
|
||||
auto* frame_host = web_contents()->GetMainFrame();
|
||||
if (frame_host) {
|
||||
|
||||
auto frames = web_contents()->GetAllFrames();
|
||||
auto iter = std::find_if(frames.begin(), frames.end(), [this](auto* f) {
|
||||
return f->GetRoutingID() == frame_id_;
|
||||
});
|
||||
|
||||
if (iter != frames.end() && (*iter)->IsRenderFrameLive()) {
|
||||
mojom::ElectronRendererAssociatedPtr electron_ptr;
|
||||
frame_host->GetRemoteAssociatedInterfaces()->GetInterface(
|
||||
(*iter)->GetRemoteAssociatedInterfaces()->GetInterface(
|
||||
mojo::MakeRequest(&electron_ptr));
|
||||
electron_ptr->Message(true /* internal */, false /* send_to_all */, channel,
|
||||
args.Clone(), sender_id);
|
||||
|
||||
@@ -17,6 +17,7 @@ class RemoteCallbackFreer : public ObjectLifeMonitor,
|
||||
public:
|
||||
static void BindTo(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
int frame_id,
|
||||
const std::string& context_id,
|
||||
int object_id,
|
||||
content::WebContents* web_conents);
|
||||
@@ -24,6 +25,7 @@ class RemoteCallbackFreer : public ObjectLifeMonitor,
|
||||
protected:
|
||||
RemoteCallbackFreer(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
int frame_id,
|
||||
const std::string& context_id,
|
||||
int object_id,
|
||||
content::WebContents* web_conents);
|
||||
@@ -35,6 +37,7 @@ class RemoteCallbackFreer : public ObjectLifeMonitor,
|
||||
void RenderViewDeleted(content::RenderViewHost*) override;
|
||||
|
||||
private:
|
||||
int frame_id_;
|
||||
std::string context_id_;
|
||||
int object_id_;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "base/values.h"
|
||||
#include "content/public/renderer/render_frame.h"
|
||||
#include "electron/atom/common/api/api.mojom.h"
|
||||
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
|
||||
#include "services/service_manager/public/cpp/interface_provider.h"
|
||||
#include "third_party/blink/public/web/web_local_frame.h"
|
||||
|
||||
using blink::WebLocalFrame;
|
||||
@@ -77,8 +77,8 @@ void RemoteObjectFreer::RunDestructor() {
|
||||
if (ref_mapper_[context_id_].empty())
|
||||
ref_mapper_.erase(context_id_);
|
||||
|
||||
mojom::ElectronBrowserAssociatedPtr electron_ptr;
|
||||
render_frame->GetRemoteAssociatedInterfaces()->GetInterface(
|
||||
mojom::ElectronBrowserPtr electron_ptr;
|
||||
render_frame->GetRemoteInterfaces()->GetInterface(
|
||||
mojo::MakeRequest(&electron_ptr));
|
||||
electron_ptr->Message(true, channel, args.Clone());
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "base/lazy_instance.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/threading/thread_local.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
|
||||
namespace asar {
|
||||
|
||||
@@ -25,6 +26,17 @@ base::LazyInstance<base::ThreadLocalPointer<ArchiveMap>>::Leaky
|
||||
|
||||
const base::FilePath::CharType kAsarExtension[] = FILE_PATH_LITERAL(".asar");
|
||||
|
||||
std::map<base::FilePath, bool> g_is_directory_cache;
|
||||
|
||||
bool IsDirectoryCached(const base::FilePath& path) {
|
||||
auto it = g_is_directory_cache.find(path);
|
||||
if (it != g_is_directory_cache.end()) {
|
||||
return it->second;
|
||||
}
|
||||
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
||||
return g_is_directory_cache[path] = base::DirectoryExists(path);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::shared_ptr<Archive> GetOrCreateAsarArchive(const base::FilePath& path) {
|
||||
@@ -47,11 +59,12 @@ void ClearArchives() {
|
||||
|
||||
bool GetAsarArchivePath(const base::FilePath& full_path,
|
||||
base::FilePath* asar_path,
|
||||
base::FilePath* relative_path) {
|
||||
base::FilePath* relative_path,
|
||||
bool allow_root) {
|
||||
base::FilePath iter = full_path;
|
||||
while (true) {
|
||||
base::FilePath dirname = iter.DirName();
|
||||
if (iter.MatchesExtension(kAsarExtension))
|
||||
if (iter.MatchesExtension(kAsarExtension) && !IsDirectoryCached(iter))
|
||||
break;
|
||||
else if (iter == dirname)
|
||||
return false;
|
||||
@@ -59,7 +72,8 @@ bool GetAsarArchivePath(const base::FilePath& full_path,
|
||||
}
|
||||
|
||||
base::FilePath tail;
|
||||
if (!iter.AppendRelativePath(full_path, &tail))
|
||||
if (!((allow_root && iter == full_path) ||
|
||||
iter.AppendRelativePath(full_path, &tail)))
|
||||
return false;
|
||||
|
||||
*asar_path = iter;
|
||||
|
||||
@@ -25,7 +25,8 @@ void ClearArchives();
|
||||
// Separates the path to Archive out.
|
||||
bool GetAsarArchivePath(const base::FilePath& full_path,
|
||||
base::FilePath* asar_path,
|
||||
base::FilePath* relative_path);
|
||||
base::FilePath* relative_path,
|
||||
bool allow_root = false);
|
||||
|
||||
// Same with base::ReadFileToString but supports asar Archive.
|
||||
bool ReadFileToString(const base::FilePath& path, std::string* contents);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "atom/common/atom_command_line.h"
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "uv.h" // NOLINT(build/include)
|
||||
#include "uv.h" // NOLINT(build/include_directory)
|
||||
|
||||
namespace atom {
|
||||
|
||||
|
||||
@@ -27,6 +27,14 @@ const char kSecureProtocolDescription[] =
|
||||
"The connection to this site is using a strong protocol version "
|
||||
"and cipher suite.";
|
||||
|
||||
#if defined(OS_WIN)
|
||||
const char kCrashpadPipeName[] = "ELECTRON_CRASHPAD_PIPE_NAME";
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
const char kRunAsNode[] = "ELECTRON_RUN_AS_NODE";
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
const char kPdfPluginMimeType[] = "application/x-google-chrome-pdf";
|
||||
const char kPdfPluginPath[] = "chrome://pdf-viewer/";
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef ATOM_COMMON_ATOM_CONSTANTS_H_
|
||||
#define ATOM_COMMON_ATOM_CONSTANTS_H_
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
|
||||
namespace atom {
|
||||
@@ -26,6 +27,15 @@ extern const char kValidCertificateDescription[];
|
||||
extern const char kSecureProtocol[];
|
||||
extern const char kSecureProtocolDescription[];
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Crashpad pipe name.
|
||||
extern const char kCrashpadPipeName[];
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
extern const char kRunAsNode[];
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
// The MIME type used for the PDF plugin.
|
||||
extern const char kPdfPluginMimeType[];
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
#define ATOM_COMMON_ATOM_VERSION_H_
|
||||
|
||||
#define ATOM_MAJOR_VERSION 6
|
||||
#define ATOM_MINOR_VERSION 0
|
||||
#define ATOM_PATCH_VERSION 0
|
||||
#define ATOM_MINOR_VERSION 1
|
||||
#define ATOM_PATCH_VERSION 12
|
||||
// clang-format off
|
||||
#define ATOM_PRE_RELEASE_VERSION -beta.7
|
||||
// #define ATOM_PRE_RELEASE_VERSION
|
||||
// clang-format on
|
||||
|
||||
#ifndef ATOM_STRINGIFY
|
||||
|
||||
@@ -4,10 +4,14 @@
|
||||
|
||||
#include "atom/common/crash_reporter/crash_reporter.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_split.h"
|
||||
@@ -16,13 +20,31 @@
|
||||
|
||||
namespace crash_reporter {
|
||||
|
||||
const char kCrashpadProcess[] = "crash-handler";
|
||||
const char kCrashesDirectoryKey[] = "crashes-directory";
|
||||
|
||||
CrashReporter::CrashReporter() {
|
||||
auto* cmd = base::CommandLine::ForCurrentProcess();
|
||||
is_browser_ = cmd->GetSwitchValueASCII(switches::kProcessType).empty();
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
bool run_as_node = base::Environment::Create()->HasVar(atom::kRunAsNode);
|
||||
#else
|
||||
bool run_as_node = false;
|
||||
#endif
|
||||
|
||||
if (run_as_node) {
|
||||
process_type_ = "node";
|
||||
} else {
|
||||
auto* cmd = base::CommandLine::ForCurrentProcess();
|
||||
process_type_ = cmd->GetSwitchValueASCII(switches::kProcessType);
|
||||
}
|
||||
// process_type_ will be empty for browser process
|
||||
}
|
||||
|
||||
CrashReporter::~CrashReporter() {}
|
||||
|
||||
bool CrashReporter::IsInitialized() {
|
||||
return is_initialized_;
|
||||
}
|
||||
|
||||
void CrashReporter::Start(const std::string& product_name,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
@@ -30,15 +52,19 @@ void CrashReporter::Start(const std::string& product_name,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler,
|
||||
const StringMap& extra_parameters) {
|
||||
is_initialized_ = true;
|
||||
SetUploadParameters(extra_parameters);
|
||||
|
||||
InitBreakpad(product_name, ATOM_VERSION_STRING, company_name, submit_url,
|
||||
crashes_dir, upload_to_server, skip_system_crash_handler);
|
||||
Init(product_name, company_name, submit_url, crashes_dir, upload_to_server,
|
||||
skip_system_crash_handler);
|
||||
}
|
||||
|
||||
void CrashReporter::SetUploadParameters(const StringMap& parameters) {
|
||||
upload_parameters_ = parameters;
|
||||
upload_parameters_["process_type"] = is_browser_ ? "browser" : "renderer";
|
||||
upload_parameters_["process_type"] =
|
||||
process_type_.empty() ? "browser" : process_type_;
|
||||
upload_parameters_["prod"] = ATOM_PRODUCT_NAME;
|
||||
upload_parameters_["ver"] = ATOM_VERSION_STRING;
|
||||
|
||||
// Setting platform dependent parameters.
|
||||
SetUploadParameters();
|
||||
@@ -74,13 +100,12 @@ CrashReporter::GetUploadedReports(const base::FilePath& crashes_dir) {
|
||||
return result;
|
||||
}
|
||||
|
||||
void CrashReporter::InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) {}
|
||||
void CrashReporter::Init(const std::string& product_name,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) {}
|
||||
|
||||
void CrashReporter::SetUploadParameters() {}
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
namespace crash_reporter {
|
||||
|
||||
extern const char kCrashpadProcess[];
|
||||
extern const char kCrashesDirectoryKey[];
|
||||
|
||||
class CrashReporter {
|
||||
public:
|
||||
typedef std::map<std::string, std::string> StringMap;
|
||||
@@ -24,6 +27,7 @@ class CrashReporter {
|
||||
static CrashReporter* GetInstance();
|
||||
static void StartInstance(const mate::Dictionary& options);
|
||||
|
||||
bool IsInitialized();
|
||||
void Start(const std::string& product_name,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
@@ -46,19 +50,19 @@ class CrashReporter {
|
||||
CrashReporter();
|
||||
virtual ~CrashReporter();
|
||||
|
||||
virtual void InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler);
|
||||
virtual void Init(const std::string& product_name,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool upload_to_server,
|
||||
bool skip_system_crash_handler);
|
||||
virtual void SetUploadParameters();
|
||||
|
||||
StringMap upload_parameters_;
|
||||
bool is_browser_;
|
||||
std::string process_type_;
|
||||
|
||||
private:
|
||||
bool is_initialized_ = false;
|
||||
void SetUploadParameters(const StringMap& parameters);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CrashReporter);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user