mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
298 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
126b468eb7 | ||
|
|
0035a7b663 | ||
|
|
74644e53e8 | ||
|
|
308ee50831 | ||
|
|
4f26aab86f | ||
|
|
1ebd9761fb | ||
|
|
67c7554b80 | ||
|
|
d158cce9a3 | ||
|
|
5a73ec2ec8 | ||
|
|
a03da04578 | ||
|
|
d45c29087b | ||
|
|
00200c707e | ||
|
|
b228166900 | ||
|
|
d281859cf5 | ||
|
|
e00d217cfb | ||
|
|
00f40e84db | ||
|
|
dde5b3abe6 | ||
|
|
97bffde34c | ||
|
|
a6a1cc3bbb | ||
|
|
22e71497ec | ||
|
|
a32529b8fa | ||
|
|
732f053acd | ||
|
|
90fc709194 | ||
|
|
1d2b926962 | ||
|
|
fbc7b7f8ad | ||
|
|
4279f2f3f8 | ||
|
|
b8eec43b31 | ||
|
|
ce30d6c11f | ||
|
|
9f1e674f30 | ||
|
|
2f2761fa47 | ||
|
|
411f2be579 | ||
|
|
28a160fc1f | ||
|
|
2663d3e10d | ||
|
|
e55d7d6f1e | ||
|
|
092796f5f4 | ||
|
|
3f6d86c872 | ||
|
|
bdc9faa083 | ||
|
|
3e35f77da4 | ||
|
|
464f144a2b | ||
|
|
8f92396ed4 | ||
|
|
4e41a79404 | ||
|
|
d3c153e85a | ||
|
|
503b488153 | ||
|
|
005a65da79 | ||
|
|
36da7dcd5f | ||
|
|
0e5f734a1a | ||
|
|
3aeaf10e64 | ||
|
|
d70942190c | ||
|
|
ac400e5cb9 | ||
|
|
333d5fb5d2 | ||
|
|
f2c12ccbf5 | ||
|
|
79af1ea6f1 | ||
|
|
1ed7875b0b | ||
|
|
67a690e536 | ||
|
|
5f3bedd1e0 | ||
|
|
670a875792 | ||
|
|
faf82245dc | ||
|
|
066eeb5b5f | ||
|
|
77ec86b894 | ||
|
|
bf82dc7896 | ||
|
|
b4c5a30469 | ||
|
|
7ed6e2b909 | ||
|
|
8edd18be90 | ||
|
|
3bc9ae7f5b | ||
|
|
760c2327b4 | ||
|
|
fcb5069d24 | ||
|
|
221ab080a1 | ||
|
|
addf069f26 | ||
|
|
80221e52d9 | ||
|
|
3403b4a4de | ||
|
|
a1ac930f4d | ||
|
|
ed8396c6f5 | ||
|
|
a457d8823a | ||
|
|
2d44dcb8be | ||
|
|
85da731867 | ||
|
|
3af5fdb831 | ||
|
|
f1b197acbb | ||
|
|
d483c81887 | ||
|
|
3ef980ae2b | ||
|
|
36e68b46df | ||
|
|
f611dfdb5c | ||
|
|
148d0d8d29 | ||
|
|
79a1382126 | ||
|
|
b0d5ba1996 | ||
|
|
088dc70dae | ||
|
|
ad686cca68 | ||
|
|
48a4b58cc1 | ||
|
|
c1ef824e4c | ||
|
|
a2eb532720 | ||
|
|
0cb53ceb9d | ||
|
|
afe4e610ae | ||
|
|
74d90fbb33 | ||
|
|
f3bd8f6133 | ||
|
|
863c511fbf | ||
|
|
03d8689ded | ||
|
|
ff2bc1d705 | ||
|
|
a1df8befde | ||
|
|
75909685f7 | ||
|
|
2e0a015168 | ||
|
|
740b2797c5 | ||
|
|
5f372f7ecc | ||
|
|
e4f4a1d9f9 | ||
|
|
bdc255fa9e | ||
|
|
e8e542b3e8 | ||
|
|
dd89aa6c77 | ||
|
|
79caff69f5 | ||
|
|
67b10135b6 | ||
|
|
6a86831b7c | ||
|
|
dffd17ab70 | ||
|
|
cf98934dd9 | ||
|
|
2fff138740 | ||
|
|
82bc83c1de | ||
|
|
3a699741da | ||
|
|
237ad9a49d | ||
|
|
45158bdad5 | ||
|
|
cf4861b575 | ||
|
|
a76adba2b3 | ||
|
|
6689dce5ba | ||
|
|
9667b835ca | ||
|
|
58295a3198 | ||
|
|
b60125f782 | ||
|
|
2af6d9ced7 | ||
|
|
664c184fcb | ||
|
|
c125576d48 | ||
|
|
6030146b45 | ||
|
|
17297d85f8 | ||
|
|
65bbf21c08 | ||
|
|
00da6ab43b | ||
|
|
d6d2a46821 | ||
|
|
423bdda1b1 | ||
|
|
849aeced8f | ||
|
|
05a7485880 | ||
|
|
3db1b5a49a | ||
|
|
1c272503c3 | ||
|
|
1ebb8975a8 | ||
|
|
fcf4c9cef1 | ||
|
|
3e5349bf39 | ||
|
|
66988adb0e | ||
|
|
91be3f343f | ||
|
|
475006c10d | ||
|
|
d71a7d89bb | ||
|
|
abcba2b509 | ||
|
|
d06c20f836 | ||
|
|
3ab99663eb | ||
|
|
a253323ea1 | ||
|
|
4abe5a2963 | ||
|
|
aada5fb167 | ||
|
|
4efed0f5ed | ||
|
|
475a1e30d9 | ||
|
|
4aedc2c21a | ||
|
|
71668858db | ||
|
|
2573d52860 | ||
|
|
989c2605b3 | ||
|
|
afcfd473d0 | ||
|
|
1499bafe59 | ||
|
|
419fae76b4 | ||
|
|
c7b85a104a | ||
|
|
c6ea424858 | ||
|
|
ba23c0d600 | ||
|
|
d4e716477e | ||
|
|
34dbe5f176 | ||
|
|
a09fa53d80 | ||
|
|
c140c84b32 | ||
|
|
55ab1d7370 | ||
|
|
cfa247967f | ||
|
|
311f7ac6bb | ||
|
|
52a44facfd | ||
|
|
5acb7a0226 | ||
|
|
afcf94a85c | ||
|
|
c42b468966 | ||
|
|
e0257acdf5 | ||
|
|
b555434aa0 | ||
|
|
9574a4f472 | ||
|
|
2f167ce3d1 | ||
|
|
8655d5e9ae | ||
|
|
2e06e0eccd | ||
|
|
773f08ca43 | ||
|
|
13850b9dff | ||
|
|
1c57c76496 | ||
|
|
e459b38c5d | ||
|
|
9796513b83 | ||
|
|
d3e5f430c7 | ||
|
|
df22eccfc1 | ||
|
|
214c352f71 | ||
|
|
0070637b5a | ||
|
|
72b944f862 | ||
|
|
2fbb371689 | ||
|
|
e2e70e9b1e | ||
|
|
324b769751 | ||
|
|
e1d54d55be | ||
|
|
1d54032ba4 | ||
|
|
c6e4de16de | ||
|
|
f39cc1cc46 | ||
|
|
6af89eb260 | ||
|
|
d33b71cc2d | ||
|
|
d0bbf3fb3c | ||
|
|
289db66fee | ||
|
|
6b90807cb8 | ||
|
|
cf4f078aca | ||
|
|
4eedd1455d | ||
|
|
9c167b63f2 | ||
|
|
d18ab0ca08 | ||
|
|
724cbc967c | ||
|
|
b9d589439f | ||
|
|
f37bc4a9d4 | ||
|
|
597c8964f6 | ||
|
|
652f83fc88 | ||
|
|
d432038aab | ||
|
|
5d8f36c53c | ||
|
|
85dfdd6665 | ||
|
|
de428ebec0 | ||
|
|
c6c49b9e4b | ||
|
|
98495fabfb | ||
|
|
06c33c7e56 | ||
|
|
33aad6ae11 | ||
|
|
6c00b37dd1 | ||
|
|
d209e59c30 | ||
|
|
14f8a2a0e8 | ||
|
|
65e1252da0 | ||
|
|
2903d7608c | ||
|
|
0bc72961ab | ||
|
|
b55a24c025 | ||
|
|
51bca764f7 | ||
|
|
35976a0a07 | ||
|
|
283ab23524 | ||
|
|
2343f7c287 | ||
|
|
8991ad31d8 | ||
|
|
fae6167308 | ||
|
|
bd25a5f453 | ||
|
|
c80021924e | ||
|
|
0cc4584352 | ||
|
|
706f0c436d | ||
|
|
663e1e059b | ||
|
|
433aba34e6 | ||
|
|
bd33e7198e | ||
|
|
e1b19140e5 | ||
|
|
4632ade7ae | ||
|
|
b32f332ce3 | ||
|
|
6ff0d744ee | ||
|
|
37cbf5e4f1 | ||
|
|
f48f486412 | ||
|
|
018b676efd | ||
|
|
c9e5d17950 | ||
|
|
b1dd013425 | ||
|
|
7a91c5668f | ||
|
|
2f47b71211 | ||
|
|
e8a7cc576e | ||
|
|
c00b1ac669 | ||
|
|
c4bde8853f | ||
|
|
ab77b55a90 | ||
|
|
05b0948dd0 | ||
|
|
c9e2140bca | ||
|
|
9843ce743e | ||
|
|
c846f677c9 | ||
|
|
643dd55e07 | ||
|
|
d2045b93b7 | ||
|
|
c22d53be5c | ||
|
|
e9d28f9b14 | ||
|
|
7e53a4c72c | ||
|
|
515fbb6fc3 | ||
|
|
af4dfcf6fe | ||
|
|
176abdbd80 | ||
|
|
cda7b8ccc8 | ||
|
|
1a43ba50b6 | ||
|
|
1174fc0ab8 | ||
|
|
3c5ba35d63 | ||
|
|
0f143fdba0 | ||
|
|
99ae56b782 | ||
|
|
5471bc313f | ||
|
|
b0077241ee | ||
|
|
bb40bc4aca | ||
|
|
76fb7ee87c | ||
|
|
bfc0e3f266 | ||
|
|
48e068997b | ||
|
|
f443974f3d | ||
|
|
36505ae00e | ||
|
|
b330ff8004 | ||
|
|
6cda9460ea | ||
|
|
2cac654974 | ||
|
|
5a210f3d7a | ||
|
|
4bb10c10e4 | ||
|
|
c0076d9c52 | ||
|
|
95539c5b63 | ||
|
|
4f8ca2f03a | ||
|
|
c9b92aebd3 | ||
|
|
6d3f60374e | ||
|
|
8703298e9d | ||
|
|
a42057aabd | ||
|
|
bd2ab27c25 | ||
|
|
1e6d7295cf | ||
|
|
1918da7c2e | ||
|
|
38345c7267 | ||
|
|
c4742df1ee | ||
|
|
5fc485043b | ||
|
|
967dcd3471 | ||
|
|
96f800552c | ||
|
|
afcbb589b6 | ||
|
|
4159103467 |
@@ -3,7 +3,7 @@ version: 2
|
||||
jobs:
|
||||
electron-linux-arm:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.4
|
||||
- image: electronbuilds/electron:0.0.7
|
||||
environment:
|
||||
TARGET_ARCH: arm
|
||||
resource_class: 2xlarge
|
||||
@@ -58,6 +58,29 @@ jobs:
|
||||
else
|
||||
echo 'Skipping upload distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Optionally finish release
|
||||
shell: /bin/sh
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then
|
||||
echo 'Trying to finish release'
|
||||
node script/release.js --validateRelease --automaticRelease
|
||||
releaseExitCode=$?
|
||||
if [ $releaseExitCode -eq 0 ]; then
|
||||
echo 'Release is ready to go; releasing'
|
||||
node script/release.js--automaticRelease
|
||||
if [ $releaseExitCode -eq 0 ]; then
|
||||
echo 'Release successful, now publishing to npm'
|
||||
echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc
|
||||
npm run publish-to-npm
|
||||
echo 'Release has been published to npm'
|
||||
fi
|
||||
else
|
||||
echo 'Release is not complete, skipping publish for now'
|
||||
fi
|
||||
else
|
||||
echo 'Skipping finishing release because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Zip out directory
|
||||
command: |
|
||||
@@ -83,7 +106,7 @@ jobs:
|
||||
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
docker run -it \
|
||||
--mount type=bind,source=/tmp/workspace,target=/tmp/workspace \
|
||||
--rm electronbuilds/electronarm7:0.0.4 > version.txt
|
||||
--rm electronbuilds/electronarm7:0.0.5 > version.txt
|
||||
cat version.txt
|
||||
if grep -q `script/get-version.py` version.txt; then
|
||||
echo "Versions match"
|
||||
@@ -96,7 +119,7 @@ jobs:
|
||||
fi
|
||||
electron-linux-arm64:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.4
|
||||
- image: electronbuilds/electron:0.0.7
|
||||
environment:
|
||||
TARGET_ARCH: arm64
|
||||
resource_class: 2xlarge
|
||||
@@ -151,6 +174,29 @@ jobs:
|
||||
else
|
||||
echo 'Skipping upload distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Optionally finish release
|
||||
shell: /bin/sh
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then
|
||||
echo 'Trying to finish release'
|
||||
node script/release.js --validateRelease --automaticRelease
|
||||
releaseExitCode=$?
|
||||
if [ $releaseExitCode -eq 0 ]; then
|
||||
echo 'Release is ready to go; releasing'
|
||||
node script/release.js--automaticRelease
|
||||
if [ $releaseExitCode -eq 0 ]; then
|
||||
echo 'Release successful, now publishing to npm'
|
||||
echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc
|
||||
npm run publish-to-npm
|
||||
echo 'Release has been published to npm'
|
||||
fi
|
||||
else
|
||||
echo 'Release is not complete, skipping publish for now'
|
||||
fi
|
||||
else
|
||||
echo 'Skipping finishing release because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Zip out directory
|
||||
command: |
|
||||
@@ -176,7 +222,7 @@ jobs:
|
||||
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
docker run -it \
|
||||
--mount type=bind,source=/tmp/workspace,target=/tmp/workspace \
|
||||
--rm electronbuilds/electronarm64:0.0.5 > version.txt
|
||||
--rm electronbuilds/electronarm64:0.0.6 > version.txt
|
||||
cat version.txt
|
||||
if grep -q `script/get-version.py` version.txt; then
|
||||
echo "Versions match"
|
||||
@@ -189,7 +235,7 @@ jobs:
|
||||
fi
|
||||
electron-linux-ia32:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.4
|
||||
- image: electronbuilds/electron:0.0.7
|
||||
environment:
|
||||
TARGET_ARCH: ia32
|
||||
DISPLAY: ':99.0'
|
||||
@@ -248,6 +294,29 @@ jobs:
|
||||
else
|
||||
echo 'Skipping upload distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Optionally finish release
|
||||
shell: /bin/sh
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then
|
||||
echo 'Trying to finish release'
|
||||
node script/release.js --validateRelease --automaticRelease
|
||||
releaseExitCode=$?
|
||||
if [ $releaseExitCode -eq 0 ]; then
|
||||
echo 'Release is ready to go; releasing'
|
||||
node script/release.js--automaticRelease
|
||||
if [ $releaseExitCode -eq 0 ]; then
|
||||
echo 'Release successful, now publishing to npm'
|
||||
echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc
|
||||
npm run publish-to-npm
|
||||
echo 'Release has been published to npm'
|
||||
fi
|
||||
else
|
||||
echo 'Release is not complete, skipping publish for now'
|
||||
fi
|
||||
else
|
||||
echo 'Skipping finishing release because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Test
|
||||
environment:
|
||||
@@ -273,7 +342,7 @@ jobs:
|
||||
fi
|
||||
electron-linux-mips64el:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.4
|
||||
- image: electronbuilds/electron:0.0.7
|
||||
environment:
|
||||
TARGET_ARCH: mips64el
|
||||
resource_class: xlarge
|
||||
@@ -328,10 +397,33 @@ jobs:
|
||||
else
|
||||
echo 'Skipping upload distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Optionally finish release
|
||||
shell: /bin/sh
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then
|
||||
echo 'Trying to finish release'
|
||||
node script/release.js --validateRelease --automaticRelease
|
||||
releaseExitCode=$?
|
||||
if [ $releaseExitCode -eq 0 ]; then
|
||||
echo 'Release is ready to go; releasing'
|
||||
node script/release.js--automaticRelease
|
||||
if [ $releaseExitCode -eq 0 ]; then
|
||||
echo 'Release successful, now publishing to npm'
|
||||
echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc
|
||||
npm run publish-to-npm
|
||||
echo 'Release has been published to npm'
|
||||
fi
|
||||
else
|
||||
echo 'Release is not complete, skipping publish for now'
|
||||
fi
|
||||
else
|
||||
echo 'Skipping finishing release because build is not for release'
|
||||
fi
|
||||
|
||||
electron-linux-x64:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.4
|
||||
- image: electronbuilds/electron:0.0.7
|
||||
environment:
|
||||
TARGET_ARCH: x64
|
||||
DISPLAY: ':99.0'
|
||||
@@ -359,6 +451,224 @@ jobs:
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
||||
fi
|
||||
- run: npm run lint
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Building Electron for release'
|
||||
script/build.py -c R
|
||||
else
|
||||
echo 'Building Electron for debug'
|
||||
script/build.py -c D
|
||||
fi
|
||||
- run:
|
||||
name: Create distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Creating Electron release distribution'
|
||||
script/create-dist.py
|
||||
else
|
||||
echo 'Skipping create distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Upload distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then
|
||||
echo 'Uploading Electron release distribution to github releases'
|
||||
script/upload.py
|
||||
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then
|
||||
echo 'Uploading Electron release distribution to s3'
|
||||
script/upload.py --upload_to_s3
|
||||
else
|
||||
echo 'Skipping upload distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Optionally finish release
|
||||
shell: /bin/sh
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then
|
||||
echo 'Trying to finish release'
|
||||
node script/release.js --validateRelease --automaticRelease
|
||||
releaseExitCode=$?
|
||||
if [ $releaseExitCode -eq 0 ]; then
|
||||
echo 'Release is ready to go; releasing'
|
||||
node script/release.js--automaticRelease
|
||||
if [ $releaseExitCode -eq 0 ]; then
|
||||
echo 'Release successful, now publishing to npm'
|
||||
echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc
|
||||
npm run publish-to-npm
|
||||
echo 'Release has been published to npm'
|
||||
fi
|
||||
else
|
||||
echo 'Release is not complete, skipping publish for now'
|
||||
fi
|
||||
else
|
||||
echo 'Skipping finishing release because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Test
|
||||
environment:
|
||||
MOCHA_FILE: junit/test-results.xml
|
||||
MOCHA_REPORTER: mocha-junit-reporter
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||
echo 'Testing Electron debug build'
|
||||
mkdir junit
|
||||
script/test.py --ci --rebuild_native_modules
|
||||
else
|
||||
echo 'Skipping testing on release build'
|
||||
fi
|
||||
- run:
|
||||
name: Verify FFmpeg
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||
echo 'Verifying ffmpeg on debug build'
|
||||
script/verify-ffmpeg.py
|
||||
else
|
||||
echo 'Skipping verify ffmpeg on release build'
|
||||
fi
|
||||
- run:
|
||||
name: Generate Typescript Definitions
|
||||
command: npm run create-typescript-definitions
|
||||
- store_test_results:
|
||||
path: junit
|
||||
- store_artifacts:
|
||||
path: junit
|
||||
- store_artifacts:
|
||||
path: out/electron.d.ts
|
||||
- store_artifacts:
|
||||
path: out/electron-api.json
|
||||
|
||||
electron-osx-x64:
|
||||
environment:
|
||||
TARGET_ARCH: x64
|
||||
macos:
|
||||
xcode: "9.0"
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Reclaim disk space
|
||||
command: |
|
||||
df -h
|
||||
sudo rm -rf /Library/Developer/CoreSimulator
|
||||
df -h
|
||||
sysctl -n hw.ncpu
|
||||
- run:
|
||||
name: Check for release
|
||||
command: |
|
||||
if [ -n "${RUN_RELEASE_BUILD}" ]; then
|
||||
echo 'release build triggered from api'
|
||||
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
|
||||
fi
|
||||
- run:
|
||||
name: Bootstrap
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Bootstrapping Electron for release build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
||||
else
|
||||
echo 'Bootstrapping Electron for debug build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
||||
fi
|
||||
- run: npm run lint
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Building Electron for release'
|
||||
script/build.py -c R
|
||||
else
|
||||
echo 'Building Electron for debug'
|
||||
script/build.py -c D
|
||||
fi
|
||||
- run:
|
||||
name: Create distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Creating Electron release distribution'
|
||||
script/create-dist.py
|
||||
else
|
||||
echo 'Skipping create distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Upload distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then
|
||||
echo 'Uploading Electron release distribution to github releases'
|
||||
script/upload.py
|
||||
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then
|
||||
echo 'Uploading Electron release distribution to s3'
|
||||
script/upload.py --upload_to_s3
|
||||
else
|
||||
echo 'Skipping upload distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Test
|
||||
environment:
|
||||
MOCHA_FILE: junit/test-results.xml
|
||||
MOCHA_REPORTER: mocha-junit-reporter
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||
echo 'Testing Electron debug build'
|
||||
mkdir junit
|
||||
script/test.py --ci --rebuild_native_modules
|
||||
else
|
||||
echo 'Skipping testing on release build'
|
||||
fi
|
||||
- run:
|
||||
name: Verify FFmpeg
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||
echo 'Verifying ffmpeg on debug build'
|
||||
script/verify-ffmpeg.py
|
||||
else
|
||||
echo 'Skipping verify ffmpeg on release build'
|
||||
fi
|
||||
- run:
|
||||
name: Generate Typescript Definitions
|
||||
command: npm run create-typescript-definitions
|
||||
- store_test_results:
|
||||
path: junit
|
||||
- store_artifacts:
|
||||
path: junit
|
||||
- store_artifacts:
|
||||
path: out/electron.d.ts
|
||||
- store_artifacts:
|
||||
path: out/electron-api.json
|
||||
|
||||
electron-mas-x64:
|
||||
environment:
|
||||
TARGET_ARCH: x64
|
||||
MAS_BUILD: 1
|
||||
macos:
|
||||
xcode: "9.0"
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Reclaim disk space
|
||||
command: |
|
||||
df -h
|
||||
sudo rm -rf /Library/Developer/CoreSimulator
|
||||
df -h
|
||||
sysctl -n hw.ncpu
|
||||
- run:
|
||||
name: Check for release
|
||||
command: |
|
||||
if [ -n "${RUN_RELEASE_BUILD}" ]; then
|
||||
echo 'release build triggered from api'
|
||||
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
|
||||
fi
|
||||
- run:
|
||||
name: Bootstrap
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Bootstrapping Electron for release build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
||||
else
|
||||
echo 'Bootstrapping Electron for debug build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
||||
fi
|
||||
- run: npm run lint
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
@@ -442,5 +752,11 @@ workflows:
|
||||
jobs:
|
||||
- electron-linux-ia32
|
||||
build-x64:
|
||||
jobs:
|
||||
- electron-linux-x64
|
||||
jobs:
|
||||
- electron-linux-x64
|
||||
build-osx-x64:
|
||||
jobs:
|
||||
- electron-osx-x64
|
||||
build-mas-x64:
|
||||
jobs:
|
||||
- electron-mas-x64
|
||||
|
||||
7
.env.example
Normal file
7
.env.example
Normal file
@@ -0,0 +1,7 @@
|
||||
# These env vars are only necessary for creating Electron releases.
|
||||
# See docs/development/releasing.md
|
||||
|
||||
APPVEYOR_TOKEN=
|
||||
CIRCLE_TOKEN=
|
||||
ELECTRON_GITHUB_TOKEN=
|
||||
VSTS_TOKEN=
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -43,6 +43,8 @@
|
||||
/vendor/llvm/
|
||||
/vendor/npm/
|
||||
/vendor/python_26/
|
||||
/vendor/native_mksnapshot
|
||||
/vendor/LICENSES.chromium.html
|
||||
node_modules/
|
||||
SHASUMS256.txt
|
||||
**/package-lock.json
|
||||
|
||||
@@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [electron@github.com](mailto:electron@github.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [coc@electronjs.org](mailto:coc@electronjs.org). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md).
|
||||
By participating, you are expected to uphold this code. Please report unacceptable
|
||||
behavior to electron@github.com.
|
||||
behavior to coc@electronjs.org.
|
||||
|
||||
The following is a set of guidelines for contributing to Electron.
|
||||
These are just guidelines, not rules, use your best judgment and feel free to
|
||||
|
||||
@@ -7,7 +7,7 @@ ENV HOME=/home
|
||||
RUN chmod a+rwx /home
|
||||
|
||||
# Install node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
|
||||
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
|
||||
RUN apt-get update && apt-get install -y nodejs
|
||||
|
||||
# Install wget used by crash reporter
|
||||
@@ -16,6 +16,9 @@ RUN apt-get install -y wget
|
||||
# Install python-dbusmock
|
||||
RUN apt-get install -y python-dbusmock
|
||||
|
||||
# Install libnotify
|
||||
RUN apt-get install -y libnotify-bin
|
||||
|
||||
# Add xvfb init script
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
|
||||
@@ -16,6 +16,7 @@ RUN apt-get update && apt-get install -y\
|
||||
libgnome-keyring-dev \
|
||||
libgtk-3-0 \
|
||||
libgtk-3-dev \
|
||||
libnotify-bin \
|
||||
libnotify-dev \
|
||||
libnss3 \
|
||||
libnss3-dev \
|
||||
|
||||
63
Dockerfile.arm64v8
Normal file
63
Dockerfile.arm64v8
Normal file
@@ -0,0 +1,63 @@
|
||||
FROM arm64v8/ubuntu:16.04
|
||||
|
||||
RUN groupadd --gid 1000 builduser \
|
||||
&& useradd --uid 1000 --gid builduser --shell /bin/bash --create-home builduser
|
||||
|
||||
RUN groupadd --gid 114 jenkins \
|
||||
&& useradd --uid 110 --gid jenkins --shell /bin/bash --create-home jenkins
|
||||
|
||||
# Set up TEMP directory
|
||||
ENV TEMP=/tmp
|
||||
RUN chmod a+rwx /tmp
|
||||
|
||||
RUN apt-get update && apt-get install -y\
|
||||
bison \
|
||||
build-essential \
|
||||
clang \
|
||||
curl \
|
||||
gperf \
|
||||
git \
|
||||
libasound2 \
|
||||
libasound2-dev \
|
||||
libcap-dev \
|
||||
libcups2-dev \
|
||||
libdbus-1-dev \
|
||||
libgconf-2-4 \
|
||||
libgconf2-dev \
|
||||
libgnome-keyring-dev \
|
||||
libgtk2.0-0 \
|
||||
libgtk2.0-dev \
|
||||
libgtk-3-0 \
|
||||
libgtk-3-dev \
|
||||
libnotify-dev \
|
||||
libnss3 \
|
||||
libnss3-dev \
|
||||
libx11-xcb-dev \
|
||||
libxss1 \
|
||||
libxtst-dev \
|
||||
libxtst6 \
|
||||
lsb-release \
|
||||
locales \
|
||||
ninja \
|
||||
python-setuptools \
|
||||
python-pip \
|
||||
python-dbusmock \
|
||||
wget \
|
||||
xvfb
|
||||
|
||||
# Install node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
|
||||
RUN apt-get update && apt-get install -y nodejs
|
||||
|
||||
# Install crcmod
|
||||
RUN pip install -U crcmod
|
||||
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
|
||||
# Install ninja in /usr/local
|
||||
RUN cd /usr/local && git clone https://github.com/martine/ninja.git -b v1.5.3
|
||||
RUN cd /usr/local/ninja && ./configure.py --bootstrap
|
||||
|
||||
USER builduser
|
||||
WORKDIR /home/builduser
|
||||
@@ -16,6 +16,7 @@ RUN apt-get update && apt-get install -y\
|
||||
libgnome-keyring-dev \
|
||||
libgtk-3-0 \
|
||||
libgtk-3-dev \
|
||||
libnotify-bin \
|
||||
libnotify-dev \
|
||||
libnss3 \
|
||||
libnss3-dev \
|
||||
@@ -28,13 +29,8 @@ RUN apt-get update && apt-get install -y\
|
||||
wget \
|
||||
xvfb
|
||||
|
||||
# Install node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
|
||||
RUN apt-get update && apt-get install -y nodejs
|
||||
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
ADD tools/run-electron.sh /run-electron.sh
|
||||
RUN chmod a+x /run-electron.sh
|
||||
|
||||
CMD sh /run-electron.sh
|
||||
|
||||
@@ -3,7 +3,7 @@ FROM electronbuilds/libchromiumcontent:0.0.4
|
||||
USER root
|
||||
|
||||
# Install node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
|
||||
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
|
||||
RUN apt-get update && apt-get install -y nodejs
|
||||
|
||||
# Install wget used by crash reporter
|
||||
@@ -12,6 +12,9 @@ RUN apt-get install -y wget
|
||||
# Install python-dbusmock
|
||||
RUN apt-get install -y python-dbusmock
|
||||
|
||||
# Install libnotify
|
||||
RUN apt-get install -y libnotify-bin
|
||||
|
||||
# Add xvfb init script
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
|
||||
36
Jenkinsfile.arm64
Normal file
36
Jenkinsfile.arm64
Normal file
@@ -0,0 +1,36 @@
|
||||
pipeline {
|
||||
agent {
|
||||
docker {
|
||||
image 'electronbuilds/arm64v8:0.0.2'
|
||||
args '--privileged'
|
||||
}
|
||||
}
|
||||
environment {
|
||||
TARGET_ARCH='arm64'
|
||||
DISPLAY=':99.0'
|
||||
MOCHA_TIMEOUT='60000'
|
||||
}
|
||||
stages {
|
||||
stage('Bootstrap') {
|
||||
steps {
|
||||
sh 'script/bootstrap.py -v --dev --target_arch=$TARGET_ARCH'
|
||||
}
|
||||
}
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh 'script/build.py -c D --ninja-path /usr/local/ninja/ninja'
|
||||
}
|
||||
}
|
||||
stage('Test') {
|
||||
steps {
|
||||
sh '/etc/init.d/xvfb start'
|
||||
sh 'script/test.py --ci'
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
}
|
||||
20
README.md
20
README.md
@@ -21,7 +21,7 @@ announcements.
|
||||
This project adheres to the Contributor Covenant
|
||||
[code of conduct](https://github.com/electron/electron/tree/master/CODE_OF_CONDUCT.md).
|
||||
By participating, you are expected to uphold this code. Please report unacceptable
|
||||
behavior to [electron@github.com](mailto:electron@github.com).
|
||||
behavior to [coc@electronjs.org](mailto:coc@electronjs.org).
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -89,22 +89,8 @@ Find documentation translations in [electron/electron-i18n](https://github.com/e
|
||||
|
||||
## Community
|
||||
|
||||
You can ask questions and interact with the community in the following
|
||||
locations:
|
||||
- [`electron`](https://discuss.atom.io/c/electron) category on the Atom
|
||||
forums
|
||||
- `#atom-shell` channel on Freenode
|
||||
- [`Atom`](https://atom-slack.herokuapp.com) channel on Slack
|
||||
- [`electron-ru`](https://telegram.me/electron_ru) *(Russian)*
|
||||
- [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)*
|
||||
- [`electron-kr`](https://electron-kr.github.io/electron-kr) *(Korean)*
|
||||
- [`electron-jp`](https://electron-jp.slack.com) *(Japanese)*
|
||||
- [`electron-tr`](https://electron-tr.herokuapp.com) *(Turkish)*
|
||||
- [`electron-id`](https://electron-id.slack.com) *(Indonesia)*
|
||||
- [`electron-pl`](https://electronpl.github.io) *(Poland)*
|
||||
|
||||
Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron)
|
||||
for a community maintained list of useful example apps, tools and resources.
|
||||
Info on reporting bugs, getting help, finding third-party tools and sample apps,
|
||||
and more can be found in the [support document](docs/tutorial/support.md#finding-support).
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
The Electron team and community take security bugs in Electron seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
|
||||
|
||||
To report a security issue, email [electron@github.com](mailto:electron@github.com) and include the word "SECURITY" in the subject line.
|
||||
To report a security issue, email [security@electronjs.org](mailto:security@electronjs.org) and include the word "SECURITY" in the subject line.
|
||||
|
||||
The Electron team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
|
||||
|
||||
|
||||
69
appveyor.yml
Normal file
69
appveyor.yml
Normal file
@@ -0,0 +1,69 @@
|
||||
build_cloud: electron-16
|
||||
image: electron-16-vs2015
|
||||
build_script:
|
||||
- ps: >-
|
||||
if($env:SKIP_GYP_BUILD -eq "true") {
|
||||
Write-warning "Skipping debug build for older branch"; Exit-AppveyorBuild
|
||||
} elseif(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
|
||||
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
|
||||
} else {
|
||||
Add-Path "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64"
|
||||
$env:path = "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64;$env:path"
|
||||
if($env:APPVEYOR_SCHEDULED_BUILD -eq 'True') {
|
||||
$env:RUN_RELEASE_BUILD = "1"
|
||||
}
|
||||
$Message = (git log --format=%B -n 1 HEAD) | Out-String
|
||||
if ((Test-Path Env:\RUN_RELEASE_BUILD)) {
|
||||
$env:ELECTRON_RELEASE = '1'
|
||||
Write-Output "release build triggered from api"
|
||||
}
|
||||
if ((Test-Path Env:\ELECTRON_RELEASE)) {
|
||||
Write-Output "Running release build"
|
||||
python script\bootstrap.py --target_arch=$env:TARGET_ARCH
|
||||
python script\build.py -c R
|
||||
python script\create-dist.py
|
||||
} else {
|
||||
Write-Output "Running debug build"
|
||||
python script\bootstrap.py --target_arch=$env:TARGET_ARCH --dev
|
||||
python script\build.py -c D
|
||||
}
|
||||
if ($? -ne 'True') {
|
||||
throw "Build failed with exit code $?"
|
||||
} else {
|
||||
"Build succeeded."
|
||||
}
|
||||
Push-AppveyorArtifact out
|
||||
}
|
||||
test_script:
|
||||
- ps: >-
|
||||
if (Test-Path Env:\ELECTRON_RELEASE) {
|
||||
Write-Output "Skipping tests for release build"
|
||||
} else {
|
||||
Write-Output "Running tests for debug build"
|
||||
python script\test.py --ci --rebuild_native_modules
|
||||
if ($LASTEXITCODE -ne '0') {
|
||||
throw "Tests failed with exit code $LASTEXITCODE"
|
||||
} else {
|
||||
Write-Output "Tests succeeded."
|
||||
}
|
||||
python script\verify-ffmpeg.py
|
||||
if ($LASTEXITCODE -ne '0') {
|
||||
throw "Verify ffmpeg failed with exit code $LASTEXITCODE"
|
||||
} else {
|
||||
"Verify ffmpeg succeeded."
|
||||
}
|
||||
}
|
||||
artifacts:
|
||||
- path: test-results.xml
|
||||
name: test-results.xml
|
||||
deploy_script:
|
||||
- ps: >-
|
||||
if (Test-Path Env:\ELECTRON_RELEASE) {
|
||||
if (Test-Path Env:\RUN_RELEASE_BUILD) {
|
||||
Write-Output "Uploading Electron release distribution to s3"
|
||||
& python script\upload.py --upload_to_s3
|
||||
} else {
|
||||
Write-Output "Uploading Electron release distribution to github releases"
|
||||
& python script\upload.py
|
||||
}
|
||||
}
|
||||
@@ -43,12 +43,12 @@ bool IsUrlArg(const base::CommandLine::CharType* arg) {
|
||||
* Update the list by pasting the following command into bash
|
||||
* in libchromiumcontent/src/:
|
||||
|
||||
(find ./ -name "*switches.cc" | \
|
||||
xargs grep -P --no-filename "\"\S+\";" | \
|
||||
perl -pe 's|^.*?"(\S+)";| "$1",|'; \
|
||||
(find ./ \( -name "*switches.cc" -o -name "*switch_list.h" \) | \
|
||||
xargs grep -P --no-filename '"\S+"[);]$' | \
|
||||
perl -pe 's|^.*?"(\S+)"[);]$| "$1",|'; \
|
||||
echo ' "inspect",'; \
|
||||
echo ' "inspect-brk",') | \
|
||||
LANG=C sort | \
|
||||
LANG="C" sort | \
|
||||
uniq > blacklist-switches.txt
|
||||
|
||||
*/
|
||||
@@ -62,7 +62,10 @@ const char* kBlacklist[] = {
|
||||
"/prefetch:8",
|
||||
"0",
|
||||
"?",
|
||||
"BlacklistOnly",
|
||||
"ChromeOSMemoryPressureHandling",
|
||||
"Disabled",
|
||||
"OnlineCheckOnly",
|
||||
"SafeSites",
|
||||
"accept-resource-provider",
|
||||
"account-consistency",
|
||||
@@ -72,7 +75,6 @@ const char* kBlacklist[] = {
|
||||
"aggressive",
|
||||
"aggressive-cache-discard",
|
||||
"aggressive-tab-discard",
|
||||
"all",
|
||||
"all-toolchains",
|
||||
"allarticles",
|
||||
"allow-cross-origin-auth-prompt",
|
||||
@@ -113,7 +115,6 @@ const char* kBlacklist[] = {
|
||||
"always-on",
|
||||
"always-use-complex-text",
|
||||
"alwaystrue",
|
||||
"amd-switchable",
|
||||
"android-fonts-path",
|
||||
"android-stderr-port",
|
||||
"android-stdin-port",
|
||||
@@ -141,11 +142,12 @@ const char* kBlacklist[] = {
|
||||
"arc-transition-migration-required",
|
||||
"args",
|
||||
"artifacts-dir",
|
||||
"ash-animate-from-boot-splash-screen",
|
||||
"ash-constrain-pointer-to-root",
|
||||
"ash-copy-host-background-at-boot",
|
||||
"ash-debug-shortcuts",
|
||||
"ash-dev-shortcuts",
|
||||
"ash-disable-smooth-screen-rotation",
|
||||
"ash-disable-tablet-autohide-titlebars",
|
||||
"ash-disable-touch-exploration-mode",
|
||||
"ash-enable-magnifier-key-scroller",
|
||||
"ash-enable-mirrored-screen",
|
||||
@@ -174,8 +176,6 @@ const char* kBlacklist[] = {
|
||||
"autoplay-policy",
|
||||
"blink-settings",
|
||||
"bootstrap",
|
||||
"browser",
|
||||
"browser-startup-dialog",
|
||||
"browser-subprocess-path",
|
||||
"browser-test",
|
||||
"bwsi",
|
||||
@@ -220,6 +220,7 @@ const char* kBlacklist[] = {
|
||||
"crash-test",
|
||||
"crashpad-handler",
|
||||
"create-browser-on-startup-for-tests",
|
||||
"create-default-gl-context",
|
||||
"cros-gaia-api-v1",
|
||||
"cros-region",
|
||||
"cros-regions-mode",
|
||||
@@ -228,7 +229,6 @@ const char* kBlacklist[] = {
|
||||
"custom-devtools-frontend",
|
||||
"custom-launcher-page",
|
||||
"custom_summary",
|
||||
"d3d-support",
|
||||
"d3d11",
|
||||
"d3d9",
|
||||
"daemon",
|
||||
@@ -254,6 +254,7 @@ const char* kBlacklist[] = {
|
||||
"default-wallpaper-is-oem",
|
||||
"default-wallpaper-large",
|
||||
"default-wallpaper-small",
|
||||
"delay-reload-stop-button-change",
|
||||
"demo",
|
||||
"derelict-detection-timeout",
|
||||
"derelict-idle-timeout",
|
||||
@@ -267,7 +268,6 @@ const char* kBlacklist[] = {
|
||||
"diagnostics-format",
|
||||
"diagnostics-recovery",
|
||||
"dice",
|
||||
"dice_fix_auth_errors",
|
||||
"disable",
|
||||
"disable-2d-canvas-clip-aa",
|
||||
"disable-2d-canvas-image-chromium",
|
||||
@@ -289,6 +289,7 @@ const char* kBlacklist[] = {
|
||||
"disable-backgrounding-occluded-windows",
|
||||
"disable-backing-store-limit",
|
||||
"disable-blink-features",
|
||||
"disable-bookmark-reordering",
|
||||
"disable-boot-animation",
|
||||
"disable-breakpad",
|
||||
"disable-browser-task-scheduler",
|
||||
@@ -316,6 +317,7 @@ const char* kBlacklist[] = {
|
||||
"disable-direct-composition",
|
||||
"disable-direct-composition-layers",
|
||||
"disable-directwrite-for-ui",
|
||||
"disable-display-color-calibration",
|
||||
"disable-display-list-2d-canvas",
|
||||
"disable-distance-field-text",
|
||||
"disable-domain-blocking-for-3d-apis",
|
||||
@@ -330,6 +332,7 @@ const char* kBlacklist[] = {
|
||||
"disable-extensions-except",
|
||||
"disable-extensions-file-access-check",
|
||||
"disable-extensions-http-throttling",
|
||||
"disable-fast-web-scroll-view-insets",
|
||||
"disable-features",
|
||||
"disable-field-trial-config",
|
||||
"disable-file-manager-touch-mode",
|
||||
@@ -364,11 +367,14 @@ const char* kBlacklist[] = {
|
||||
"disable-histogram-customizer",
|
||||
"disable-hosted-app-shim-creation",
|
||||
"disable-hosted-apps-in-windows",
|
||||
"disable-http2",
|
||||
"disable-in-process-stack-traces",
|
||||
"disable-infobars",
|
||||
"disable-input-ime-api",
|
||||
"disable-input-view",
|
||||
"disable-ios-password-generation",
|
||||
"disable-ios-password-suggestions",
|
||||
"disable-ios-physical-web",
|
||||
"disable-javascript-harmony-shipping",
|
||||
"disable-kill-after-bad-ipc",
|
||||
"disable-lcd-text",
|
||||
@@ -382,6 +388,7 @@ const char* kBlacklist[] = {
|
||||
"disable-low-end-device-mode",
|
||||
"disable-low-latency-dxva",
|
||||
"disable-low-res-tiling",
|
||||
"disable-lru-snapshot-cache",
|
||||
"disable-mac-overlays",
|
||||
"disable-mac-views-native-app-windows",
|
||||
"disable-machine-cert-request",
|
||||
@@ -398,6 +405,7 @@ const char* kBlacklist[] = {
|
||||
"disable-namespace-sandbox",
|
||||
"disable-native-gpu-memory-buffers",
|
||||
"disable-network-portal-notification",
|
||||
"disable-new-channel-switcher-ui",
|
||||
"disable-new-korean-ime",
|
||||
"disable-new-virtual-keyboard-behavior",
|
||||
"disable-new-zip-unpacker",
|
||||
@@ -417,7 +425,6 @@ const char* kBlacklist[] = {
|
||||
"disable-password-generation",
|
||||
"disable-pepper-3d",
|
||||
"disable-pepper-3d-image-chromium",
|
||||
"disable-per-user-timezone",
|
||||
"disable-permission-action-reporting",
|
||||
"disable-permissions-api",
|
||||
"disable-physical-keyboard-autocorrect",
|
||||
@@ -431,12 +438,15 @@ const char* kBlacklist[] = {
|
||||
"disable-proximity-auth-bluetooth-low-energy-discovery",
|
||||
"disable-pull-to-refresh-effect",
|
||||
"disable-push-api-background-mode",
|
||||
"disable-quic",
|
||||
"disable-reading-from-canvas",
|
||||
"disable-remote-core-animation",
|
||||
"disable-remote-fonts",
|
||||
"disable-remote-playback-api",
|
||||
"disable-renderer-accessibility",
|
||||
"disable-renderer-backgrounding",
|
||||
"disable-renderer-priority-management",
|
||||
"disable-request-mobile-site",
|
||||
"disable-resize-lock",
|
||||
"disable-rgba-4444-textures",
|
||||
"disable-rollback-option",
|
||||
@@ -444,6 +454,7 @@ const char* kBlacklist[] = {
|
||||
"disable-screen-orientation-lock",
|
||||
"disable-search-geolocation-disclosure",
|
||||
"disable-seccomp-filter-sandbox",
|
||||
"disable-settings-window",
|
||||
"disable-setuid-sandbox",
|
||||
"disable-shader-name-hashing",
|
||||
"disable-shared-workers",
|
||||
@@ -457,17 +468,16 @@ const char* kBlacklist[] = {
|
||||
"disable-software-rasterizer",
|
||||
"disable-speech-api",
|
||||
"disable-suggestions-ui",
|
||||
"disable-surface-references",
|
||||
"disable-sync",
|
||||
"disable-sync-app-list",
|
||||
"disable-sync-types",
|
||||
"disable-system-timezone-automatic-detection",
|
||||
"disable-tab-for-desktop-share",
|
||||
"disable-tab-strip-autoscroll-new-tabs",
|
||||
"disable-third-party-keyboard-workaround",
|
||||
"disable-threaded-animation",
|
||||
"disable-threaded-compositing",
|
||||
"disable-threaded-scrolling",
|
||||
"disable-timeouts-for-profiling",
|
||||
"disable-touch-adjustment",
|
||||
"disable-touch-drag-drop",
|
||||
"disable-translate-new-ux",
|
||||
@@ -528,18 +538,16 @@ const char* kBlacklist[] = {
|
||||
"enable-appcontainer",
|
||||
"enable-arc",
|
||||
"enable-arc-oobe-optin",
|
||||
"enable-async-event-targeting",
|
||||
"enable-audio-debug-recordings-from-extension",
|
||||
"enable-audio-focus",
|
||||
"enable-automation",
|
||||
"enable-background-fetch-persistence",
|
||||
"enable-benchmarking",
|
||||
"enable-ble-advertising-in-apps",
|
||||
"enable-blink-features",
|
||||
"enable-bookmark-reordering",
|
||||
"enable-bookmark-undo",
|
||||
"enable-browser-side-navigation",
|
||||
"enable-browser-task-scheduler",
|
||||
"enable-cast-receiver",
|
||||
"enable-checker-imaging",
|
||||
"enable-chromevox-arc-support",
|
||||
"enable-clear-browsing-data-counters",
|
||||
@@ -579,8 +587,8 @@ const char* kBlacklist[] = {
|
||||
"enable-extension-activity-log-testing",
|
||||
"enable-extension-activity-logging",
|
||||
"enable-extension-assets-sharing",
|
||||
"enable-external-drive-rename",
|
||||
"enable-fast-unload",
|
||||
"enable-fast-web-scroll-view-insets",
|
||||
"enable-features",
|
||||
"enable-file-manager-touch-mode",
|
||||
"enable-first-run-ui-transitions",
|
||||
@@ -603,6 +611,7 @@ const char* kBlacklist[] = {
|
||||
"enable-gpu-service-tracing",
|
||||
"enable-hardware-overlays",
|
||||
"enable-harfbuzz-rendertext",
|
||||
"enable-hdr",
|
||||
"enable-heap-profiling",
|
||||
"enable-hosted-app-quit-notification",
|
||||
"enable-hosted-apps-in-windows",
|
||||
@@ -610,9 +619,10 @@ const char* kBlacklist[] = {
|
||||
"enable-hung-renderer-infobar",
|
||||
"enable-inband-text-tracks",
|
||||
"enable-input-ime-api",
|
||||
"enable-instant-tethering",
|
||||
"enable-internal-media-session",
|
||||
"enable-ios-handoff-to-other-devices",
|
||||
"enable-ios-password-generation",
|
||||
"enable-ios-physical-web",
|
||||
"enable-layer-lists",
|
||||
"enable-lcd-text",
|
||||
"enable-leak-detection",
|
||||
@@ -622,9 +632,11 @@ const char* kBlacklist[] = {
|
||||
"enable-longpress-drag-selection",
|
||||
"enable-low-end-device-mode",
|
||||
"enable-low-res-tiling",
|
||||
"enable-lru-snapshot-cache",
|
||||
"enable-mac-views-native-app-windows",
|
||||
"enable-main-frame-before-activation",
|
||||
"enable-md-feedback",
|
||||
"enable-md-policy-page",
|
||||
"enable-media-suspend",
|
||||
"enable-merge-key-char-events",
|
||||
"enable-message-center-always-scroll-up-upon-notification-removal",
|
||||
@@ -645,7 +657,6 @@ const char* kBlacklist[] = {
|
||||
"enable-offer-upload-credit-cards",
|
||||
"enable-offline-auto-reload",
|
||||
"enable-offline-auto-reload-visible-only",
|
||||
"enable-oop-rasterization",
|
||||
"enable-osk-overscroll",
|
||||
"enable-override-bookmarks-ui",
|
||||
"enable-partial-raster",
|
||||
@@ -655,7 +666,6 @@ const char* kBlacklist[] = {
|
||||
"enable-physical-keyboard-autocorrect",
|
||||
"enable-picture-in-picture",
|
||||
"enable-pinch",
|
||||
"enable-pixel-canvas-recording",
|
||||
"enable-pixel-output-in-tests",
|
||||
"enable-plugin-placeholder-testing",
|
||||
"enable-potentially-annoying-security-features",
|
||||
@@ -667,6 +677,8 @@ const char* kBlacklist[] = {
|
||||
"enable-profile-shortcut-manager",
|
||||
"enable-profiling",
|
||||
"enable-push-api-background-mode",
|
||||
"enable-quic",
|
||||
"enable-reader-mode-toolbar-icon",
|
||||
"enable-refresh-token-annotation-request",
|
||||
"enable-request-tablet-site",
|
||||
"enable-rgba-4444-textures",
|
||||
@@ -676,6 +688,7 @@ const char* kBlacklist[] = {
|
||||
"enable-scripts-require-action",
|
||||
"enable-scroll-prediction",
|
||||
"enable-service-manager-tracing",
|
||||
"enable-settings-window",
|
||||
"enable-sgi-video-sync",
|
||||
"enable-signin-promo",
|
||||
"enable-single-click-autofill",
|
||||
@@ -718,6 +731,7 @@ const char* kBlacklist[] = {
|
||||
"enable-translate-new-ux",
|
||||
"enable-ui-devtools",
|
||||
"enable-use-zoom-for-dsf",
|
||||
"enable-user-controlled-alternate-protocol-ports",
|
||||
"enable-user-metrics",
|
||||
"enable-usermedia-screen-capturing",
|
||||
"enable-video-player-chromecast-support",
|
||||
@@ -734,9 +748,8 @@ const char* kBlacklist[] = {
|
||||
"enable-webgl-image-chromium",
|
||||
"enable-webrtc-event-logging-from-extension",
|
||||
"enable-webrtc-srtp-aes-gcm",
|
||||
"enable-webrtc-srtp-encrypted-headers",
|
||||
"enable-webrtc-stun-origin",
|
||||
"enable-webview-variations",
|
||||
"enable-webview-finch",
|
||||
"enable-webvr",
|
||||
"enable-wifi-credential-sync",
|
||||
"enable-win7-webrtc-hw-h264-decoding",
|
||||
@@ -759,8 +772,6 @@ const char* kBlacklist[] = {
|
||||
"enterprise-enrollment-initial-modulus",
|
||||
"enterprise-enrollment-modulus-limit",
|
||||
"error-console",
|
||||
"evaluate-type",
|
||||
"evaluate_capability",
|
||||
"experiment",
|
||||
"explicitly-allowed-ports",
|
||||
"expose-internals-for-testing",
|
||||
@@ -808,7 +819,6 @@ const char* kBlacklist[] = {
|
||||
"force-overlay-fullscreen-video",
|
||||
"force-password-reauth",
|
||||
"force-pnacl-subzero",
|
||||
"force-presentation-receiver-for-testing",
|
||||
"force-renderer-accessibility",
|
||||
"force-show-update-menu-badge",
|
||||
"force-show-update-menu-item",
|
||||
@@ -838,6 +848,7 @@ const char* kBlacklist[] = {
|
||||
"gpu-active-device-id",
|
||||
"gpu-active-vendor-id",
|
||||
"gpu-device-id",
|
||||
"gpu-driver-bug-workarounds",
|
||||
"gpu-driver-date",
|
||||
"gpu-driver-vendor",
|
||||
"gpu-driver-version",
|
||||
@@ -863,7 +874,6 @@ const char* kBlacklist[] = {
|
||||
"gpu-testing-secondary-vendor-ids",
|
||||
"gpu-testing-vendor-id",
|
||||
"gpu-vendor-id",
|
||||
"graphics-buffer-count",
|
||||
"guest-wallpaper-large",
|
||||
"guest-wallpaper-small",
|
||||
"h",
|
||||
@@ -881,6 +891,7 @@ const char* kBlacklist[] = {
|
||||
"host",
|
||||
"host-pairing-oobe",
|
||||
"host-resolver-rules",
|
||||
"host-rules",
|
||||
"icu-data-dir",
|
||||
"ignore-autocomplete-off-autofill",
|
||||
"ignore-autoplay-restrictions",
|
||||
@@ -928,10 +939,6 @@ const char* kBlacklist[] = {
|
||||
"login-manager",
|
||||
"login-profile",
|
||||
"login-user",
|
||||
"loopback-i2s-bits",
|
||||
"loopback-i2s-bus-name",
|
||||
"loopback-i2s-channels",
|
||||
"loopback-i2s-rate-hz",
|
||||
"lso-url",
|
||||
"ltr",
|
||||
"main-frame-resizes-are-orientation-changes",
|
||||
@@ -953,11 +960,11 @@ const char* kBlacklist[] = {
|
||||
"media-cache-size",
|
||||
"mem-pressure-system-reserved-kb",
|
||||
"memlog",
|
||||
"memlog-pipe",
|
||||
"memory-pressure-off",
|
||||
"memory-pressure-thresholds",
|
||||
"memory-pressure-thresholds-mb",
|
||||
"message-center-changes-while-open",
|
||||
"method",
|
||||
"metrics-client-id",
|
||||
"metrics-recording-only",
|
||||
"mhtml-generator-option",
|
||||
@@ -1013,6 +1020,7 @@ const char* kBlacklist[] = {
|
||||
"normal_vibrant",
|
||||
"note-taking-app-ids",
|
||||
"ntp-snippets-add-incomplete",
|
||||
"ntp-switch-to-existing-tab",
|
||||
"null",
|
||||
"num-raster-threads",
|
||||
"oauth2-client-id",
|
||||
@@ -1026,6 +1034,7 @@ const char* kBlacklist[] = {
|
||||
"oobe-timer-interval",
|
||||
"open-ash",
|
||||
"opengraph",
|
||||
"origin-to-force-quic-on",
|
||||
"origin-trial-disabled-features",
|
||||
"origin-trial-disabled-tokens",
|
||||
"origin-trial-public-key",
|
||||
@@ -1058,6 +1067,7 @@ const char* kBlacklist[] = {
|
||||
"ppapi-plugin-launcher",
|
||||
"ppapi-startup-dialog",
|
||||
"ppapi-subpixel-rendering-setting",
|
||||
"prerender-from-omnibox",
|
||||
"previous-app",
|
||||
"primary",
|
||||
"print-to-pdf",
|
||||
@@ -1067,6 +1077,7 @@ const char* kBlacklist[] = {
|
||||
"product-version",
|
||||
"profile-directory",
|
||||
"profiler-timing",
|
||||
"profiling",
|
||||
"profiling-at-start",
|
||||
"profiling-file",
|
||||
"profiling-flush",
|
||||
@@ -1077,8 +1088,10 @@ const char* kBlacklist[] = {
|
||||
"proxy-bypass-list",
|
||||
"proxy-pac-url",
|
||||
"proxy-server",
|
||||
"pull-to-refresh",
|
||||
"q",
|
||||
"quic-connection-options",
|
||||
"quic-max-packet-length",
|
||||
"quic-version",
|
||||
"rdp_desktop_session",
|
||||
"reader-mode-feedback",
|
||||
"reader-mode-heuristics",
|
||||
@@ -1110,7 +1123,6 @@ const char* kBlacklist[] = {
|
||||
"root",
|
||||
"root-layer-scrolls",
|
||||
"rtl",
|
||||
"run-all-compositor-stages-before-draw",
|
||||
"run-layout-test",
|
||||
"runtime-deps-list-file",
|
||||
"safebrowsing-disable-auto-update",
|
||||
@@ -1123,6 +1135,7 @@ const char* kBlacklist[] = {
|
||||
"screenshot",
|
||||
"script-executable",
|
||||
"scripts-require-action",
|
||||
"scroll-end-effect",
|
||||
"search-provider-logo-url",
|
||||
"secondary",
|
||||
"secondary-display-layout",
|
||||
@@ -1169,7 +1182,6 @@ const char* kBlacklist[] = {
|
||||
"skip-reencoding-on-skp-capture",
|
||||
"slow",
|
||||
"slow-connections-only",
|
||||
"slow-down-compositing-scale-factor",
|
||||
"slow-down-raster-scale-factor",
|
||||
"sms-test-messages",
|
||||
"spdy-proxy-auth-fallback",
|
||||
@@ -1192,6 +1204,7 @@ const char* kBlacklist[] = {
|
||||
"started",
|
||||
"stub",
|
||||
"stub-cros-settings",
|
||||
"supports-dual-gpus",
|
||||
"surface",
|
||||
"swiftshader",
|
||||
"swiftshader-webgl",
|
||||
@@ -1208,7 +1221,6 @@ const char* kBlacklist[] = {
|
||||
"system-log-upload-frequency",
|
||||
"tab-management-experiment-type-disabled",
|
||||
"tab-management-experiment-type-elderberry",
|
||||
"task-manager-show-extra-renderers",
|
||||
"task-profiler",
|
||||
"team-drives",
|
||||
"test-auto-update-ui",
|
||||
@@ -1240,7 +1252,6 @@ const char* kBlacklist[] = {
|
||||
"testing-fixed-http-port",
|
||||
"testing-fixed-https-port",
|
||||
"tether-stub",
|
||||
"third-party-doodle-url",
|
||||
"threads",
|
||||
"time",
|
||||
"timeout",
|
||||
@@ -1300,6 +1311,7 @@ const char* kBlacklist[] = {
|
||||
"unsafely-treat-insecure-origin-as-secure",
|
||||
"use-angle",
|
||||
"use-cras",
|
||||
"use-double-buffering",
|
||||
"use-fake-device-for-media-stream",
|
||||
"use-fake-jpeg-decode-accelerator",
|
||||
"use-fake-ui-for-media-stream",
|
||||
@@ -1312,10 +1324,9 @@ const char* kBlacklist[] = {
|
||||
"use-mobile-user-agent",
|
||||
"use-mock-keychain",
|
||||
"use-passthrough-cmd-decoder",
|
||||
"use-skia-renderer",
|
||||
"use-simple-cache-backend",
|
||||
"use-system-default-printer",
|
||||
"use-test-config",
|
||||
"use-viz-hit-test",
|
||||
"user-agent",
|
||||
"user-always-affiliated",
|
||||
"user-data-dir",
|
||||
@@ -1325,8 +1336,6 @@ const char* kBlacklist[] = {
|
||||
"utility-allowed-dir",
|
||||
"utility-cmd-prefix",
|
||||
"utility-run-elevated",
|
||||
"utility-sandbox-type",
|
||||
"utility-startup-dialog",
|
||||
"v",
|
||||
"v2-sandbox",
|
||||
"v2-sandbox-enabled",
|
||||
@@ -1350,6 +1359,7 @@ const char* kBlacklist[] = {
|
||||
"watcher",
|
||||
"waveout-buffers",
|
||||
"webapk-server-url",
|
||||
"webrtc-max-cpu-consumption-percentage",
|
||||
"webrtc-stun-probe-trial",
|
||||
"webview-enable-safebrowsing-support",
|
||||
"webview-sandboxed-renderer",
|
||||
|
||||
@@ -68,8 +68,8 @@ void BrowserView::Init(v8::Isolate* isolate,
|
||||
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||
api_web_contents_ = web_contents.get();
|
||||
|
||||
view_.reset(NativeBrowserView::Create(
|
||||
api_web_contents_->managed_web_contents()->GetView()));
|
||||
view_.reset(
|
||||
NativeBrowserView::Create(api_web_contents_->managed_web_contents()));
|
||||
|
||||
InitWith(isolate, wrapper);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,12 @@
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace {
|
||||
|
||||
static scoped_nsobject<NSMenu> applicationMenu_;
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -135,7 +141,18 @@ void Menu::SetApplicationMenu(Menu* base_menu) {
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller(
|
||||
[[AtomMenuController alloc] initWithModel:menu->model_.get()
|
||||
useDefaultAccelerator:YES]);
|
||||
[NSApp setMainMenu:[menu_controller menu]];
|
||||
|
||||
NSRunLoop* currentRunLoop = [NSRunLoop currentRunLoop];
|
||||
[currentRunLoop cancelPerformSelector:@selector(setMainMenu:)
|
||||
target:NSApp
|
||||
argument:applicationMenu_];
|
||||
applicationMenu_.reset([[menu_controller menu] retain]);
|
||||
[[NSRunLoop currentRunLoop]
|
||||
performSelector:@selector(setMainMenu:)
|
||||
target:NSApp
|
||||
argument:applicationMenu_
|
||||
order:0
|
||||
modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
|
||||
|
||||
// Ensure the menu_controller_ is destroyed after main menu is set.
|
||||
menu_controller.swap(menu->menu_controller_);
|
||||
|
||||
@@ -23,20 +23,16 @@ MenuViews::MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
||||
|
||||
void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item,
|
||||
const base::Closure& callback) {
|
||||
NativeWindow* native_window = static_cast<NativeWindow*>(window->window());
|
||||
auto* native_window = static_cast<NativeWindowViews*>(window->window());
|
||||
if (!native_window)
|
||||
return;
|
||||
auto* web_contents = native_window->inspectable_web_contents();
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
// (-1, -1) means showing on mouse location.
|
||||
gfx::Point location;
|
||||
if (x == -1 || y == -1) {
|
||||
location = display::Screen::GetScreen()->GetCursorScreenPoint();
|
||||
} else {
|
||||
auto* view = web_contents->GetView()->GetWebView();
|
||||
gfx::Point origin = view->bounds().origin();
|
||||
gfx::Point origin = native_window->GetContentBounds().origin();
|
||||
location = gfx::Point(origin.x() + x, origin.y() + y);
|
||||
}
|
||||
|
||||
@@ -52,7 +48,7 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item,
|
||||
menu_runners_[window_id] = std::unique_ptr<MenuRunner>(new MenuRunner(
|
||||
model(), flags, close_callback));
|
||||
menu_runners_[window_id]->RunMenuAt(
|
||||
static_cast<NativeWindowViews*>(window->window())->widget(),
|
||||
native_window->widget(),
|
||||
NULL,
|
||||
gfx::Rect(location, gfx::Size()),
|
||||
views::MENU_ANCHOR_TOPLEFT,
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
//TODO(codebytere): deprecated; remove in 3.0
|
||||
int Screen::getMenuBarHeight() {
|
||||
return [[NSApp mainMenu] menuBarHeight];
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "base/guid.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "brightray/browser/media/media_device_id_salt.h"
|
||||
#include "brightray/browser/net/devtools_network_conditions.h"
|
||||
#include "brightray/browser/net/devtools_network_controller_handle.h"
|
||||
@@ -47,7 +46,6 @@
|
||||
#include "net/http/http_auth_handler_factory.h"
|
||||
#include "net/http/http_auth_preferences.h"
|
||||
#include "net/proxy/proxy_config_service_fixed.h"
|
||||
#include "net/proxy/proxy_service.h"
|
||||
#include "net/url_request/static_http_user_agent_settings.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
@@ -232,59 +230,6 @@ const char kPersistPrefix[] = "persist:";
|
||||
// Referenced session objects.
|
||||
std::map<uint32_t, v8::Global<v8::Object>> g_sessions;
|
||||
|
||||
class ResolveProxyHelper {
|
||||
public:
|
||||
ResolveProxyHelper(AtomBrowserContext* browser_context,
|
||||
const GURL& url,
|
||||
const Session::ResolveProxyCallback& callback)
|
||||
: callback_(callback),
|
||||
original_thread_(base::ThreadTaskRunnerHandle::Get()) {
|
||||
scoped_refptr<net::URLRequestContextGetter> context_getter =
|
||||
browser_context->url_request_context_getter();
|
||||
context_getter->GetNetworkTaskRunner()->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&ResolveProxyHelper::ResolveProxy,
|
||||
base::Unretained(this), context_getter, url));
|
||||
}
|
||||
|
||||
void OnResolveProxyCompleted(int result) {
|
||||
std::string proxy;
|
||||
if (result == net::OK)
|
||||
proxy = proxy_info_.ToPacString();
|
||||
original_thread_->PostTask(FROM_HERE,
|
||||
base::Bind(callback_, proxy));
|
||||
delete this;
|
||||
}
|
||||
|
||||
private:
|
||||
void ResolveProxy(scoped_refptr<net::URLRequestContextGetter> context_getter,
|
||||
const GURL& url) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
|
||||
net::ProxyService* proxy_service =
|
||||
context_getter->GetURLRequestContext()->proxy_service();
|
||||
net::CompletionCallback completion_callback =
|
||||
base::Bind(&ResolveProxyHelper::OnResolveProxyCompleted,
|
||||
base::Unretained(this));
|
||||
|
||||
// Start the request.
|
||||
int result = proxy_service->ResolveProxy(
|
||||
url, "GET", &proxy_info_, completion_callback, &pac_req_, nullptr,
|
||||
net::NetLogWithSource());
|
||||
|
||||
// Completed synchronously.
|
||||
if (result != net::ERR_IO_PENDING)
|
||||
completion_callback.Run(result);
|
||||
}
|
||||
|
||||
Session::ResolveProxyCallback callback_;
|
||||
net::ProxyInfo proxy_info_;
|
||||
net::ProxyService::PacRequest* pac_req_;
|
||||
scoped_refptr<base::SingleThreadTaskRunner> original_thread_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper);
|
||||
};
|
||||
|
||||
// Runs the callback in UI thread.
|
||||
void RunCallbackInUI(const base::Callback<void()>& callback) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
|
||||
@@ -441,14 +386,15 @@ void DownloadIdCallback(content::DownloadManager* download_manager,
|
||||
}
|
||||
|
||||
void SetDevToolsNetworkEmulationClientIdInIO(
|
||||
brightray::URLRequestContextGetter* context_getter,
|
||||
brightray::URLRequestContextGetter* url_request_context_getter,
|
||||
const std::string& client_id) {
|
||||
if (!context_getter)
|
||||
if (!url_request_context_getter)
|
||||
return;
|
||||
auto network_delegate =
|
||||
static_cast<AtomNetworkDelegate*>(context_getter->network_delegate());
|
||||
if (network_delegate)
|
||||
network_delegate->SetDevToolsNetworkEmulationClientId(client_id);
|
||||
net::URLRequestContext* context =
|
||||
url_request_context_getter->GetURLRequestContext();
|
||||
AtomNetworkDelegate* network_delegate =
|
||||
static_cast<AtomNetworkDelegate*>(context->network_delegate());
|
||||
network_delegate->SetDevToolsNetworkEmulationClientId(client_id);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -489,8 +435,10 @@ void Session::OnDownloadCreated(content::DownloadManager* manager,
|
||||
}
|
||||
}
|
||||
|
||||
void Session::ResolveProxy(const GURL& url, ResolveProxyCallback callback) {
|
||||
new ResolveProxyHelper(browser_context(), url, callback);
|
||||
void Session::ResolveProxy(
|
||||
const GURL& url,
|
||||
const ResolveProxyHelper::ResolveProxyCallback& callback) {
|
||||
browser_context_->GetResolveProxyHelper()->ResolveProxy(url, callback);
|
||||
}
|
||||
|
||||
template<Session::CacheAction action>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/atom_blob_reader.h"
|
||||
#include "atom/browser/net/resolve_proxy_helper.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/download_manager.h"
|
||||
#include "native_mate/handle.h"
|
||||
@@ -39,8 +40,6 @@ namespace api {
|
||||
class Session: public mate::TrackableObject<Session>,
|
||||
public content::DownloadManager::Observer {
|
||||
public:
|
||||
using ResolveProxyCallback = base::Callback<void(std::string)>;
|
||||
|
||||
enum class CacheAction {
|
||||
CLEAR,
|
||||
STATS,
|
||||
@@ -62,7 +61,8 @@ class Session: public mate::TrackableObject<Session>,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
// Methods.
|
||||
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
|
||||
void ResolveProxy(const GURL& url,
|
||||
const ResolveProxyHelper::ResolveProxyCallback& callback);
|
||||
template<CacheAction action>
|
||||
void DoCacheAction(const net::CompletionCallback& callback);
|
||||
void ClearStorageData(mate::Arguments* args);
|
||||
|
||||
@@ -206,7 +206,7 @@ void Tray::PopUpContextMenu(mate::Arguments* args) {
|
||||
|
||||
void Tray::SetContextMenu(v8::Isolate* isolate, mate::Handle<Menu> menu) {
|
||||
menu_.Reset(isolate, menu.ToV8());
|
||||
tray_icon_->SetContextMenu(menu->model());
|
||||
tray_icon_->SetContextMenu(menu.IsEmpty() ? nullptr : menu->model());
|
||||
}
|
||||
|
||||
gfx::Rect Tray::GetBounds() {
|
||||
|
||||
@@ -113,7 +113,7 @@ struct Converter<atom::SetSizeParams> {
|
||||
return false;
|
||||
bool autosize;
|
||||
if (params.Get("enableAutoSize", &autosize))
|
||||
out->enable_auto_size.reset(new bool(true));
|
||||
out->enable_auto_size.reset(new bool(autosize));
|
||||
gfx::Size size;
|
||||
if (params.Get("min", &size))
|
||||
out->min_size.reset(new gfx::Size(size));
|
||||
@@ -272,11 +272,35 @@ content::ServiceWorkerContext* GetServiceWorkerContext(
|
||||
void OnCapturePageDone(const base::Callback<void(const gfx::Image&)>& callback,
|
||||
const SkBitmap& bitmap,
|
||||
content::ReadbackResponse response) {
|
||||
// Hack to enable transparency in captured image
|
||||
// TODO(nitsakh) Remove hack once fixed in chromium
|
||||
const_cast<SkBitmap&>(bitmap).setAlphaType(kPremul_SkAlphaType);
|
||||
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
struct WebContents::FrameDispatchHelper {
|
||||
WebContents* api_web_contents;
|
||||
content::RenderFrameHost* rfh;
|
||||
|
||||
bool Send(IPC::Message* msg) { return rfh->Send(msg); }
|
||||
|
||||
void OnSetTemporaryZoomLevel(double level, IPC::Message* reply_msg) {
|
||||
api_web_contents->OnSetTemporaryZoomLevel(rfh, level, reply_msg);
|
||||
}
|
||||
|
||||
void OnGetZoomLevel(IPC::Message* reply_msg) {
|
||||
api_web_contents->OnGetZoomLevel(rfh, reply_msg);
|
||||
}
|
||||
|
||||
void OnRendererMessageSync(const base::string16& channel,
|
||||
const base::ListValue& args,
|
||||
IPC::Message* message) {
|
||||
api_web_contents->OnRendererMessageSync(rfh, channel, args, message);
|
||||
}
|
||||
};
|
||||
|
||||
WebContents::WebContents(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents,
|
||||
Type type)
|
||||
@@ -286,7 +310,8 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
type_(type),
|
||||
request_id_(0),
|
||||
background_throttling_(true),
|
||||
enable_devtools_(true) {
|
||||
enable_devtools_(true),
|
||||
is_dom_ready_(false) {
|
||||
const mate::Dictionary options = mate::Dictionary::CreateEmpty(isolate);
|
||||
if (type == REMOTE) {
|
||||
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
|
||||
@@ -775,8 +800,10 @@ void WebContents::DidChangeThemeColor(SkColor theme_color) {
|
||||
|
||||
void WebContents::DocumentLoadedInFrame(
|
||||
content::RenderFrameHost* render_frame_host) {
|
||||
if (!render_frame_host->GetParent())
|
||||
if (!render_frame_host->GetParent()) {
|
||||
is_dom_ready_ = true;
|
||||
Emit("dom-ready");
|
||||
}
|
||||
}
|
||||
|
||||
void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
|
||||
@@ -798,6 +825,7 @@ void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
|
||||
}
|
||||
|
||||
void WebContents::DidStartLoading() {
|
||||
is_dom_ready_ = false;
|
||||
Emit("did-start-loading");
|
||||
}
|
||||
|
||||
@@ -923,13 +951,6 @@ void WebContents::ShowAutofillPopup(content::RenderFrameHost* frame_host,
|
||||
bool WebContents::OnMessageReceived(const IPC::Message& message) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(WebContents, message)
|
||||
IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage)
|
||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync,
|
||||
OnRendererMessageSync)
|
||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_SetTemporaryZoomLevel,
|
||||
OnSetTemporaryZoomLevel)
|
||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_GetZoomLevel,
|
||||
OnGetZoomLevel)
|
||||
IPC_MESSAGE_HANDLER_CODE(ViewHostMsg_SetCursor, OnCursorChange,
|
||||
handled = false)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
@@ -939,17 +960,28 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
|
||||
}
|
||||
|
||||
bool WebContents::OnMessageReceived(const IPC::Message& message,
|
||||
content::RenderFrameHost* frame_host) {
|
||||
content::RenderFrameHost* frame_host) {
|
||||
bool handled = true;
|
||||
FrameDispatchHelper helper = {this, frame_host};
|
||||
auto relay = NativeWindowRelay::FromWebContents(web_contents());
|
||||
if (!relay)
|
||||
return false;
|
||||
if (relay) {
|
||||
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(NativeWindow, message, frame_host)
|
||||
IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_HidePopup,
|
||||
relay->window.get(), NativeWindow::HideAutofillPopup)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
}
|
||||
|
||||
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(WebContents, message, frame_host)
|
||||
IPC_MESSAGE_HANDLER(AtomFrameHostMsg_Message, OnRendererMessage)
|
||||
IPC_MESSAGE_FORWARD_DELAY_REPLY(AtomFrameHostMsg_Message_Sync, &helper,
|
||||
FrameDispatchHelper::OnRendererMessageSync)
|
||||
IPC_MESSAGE_FORWARD_DELAY_REPLY(
|
||||
AtomFrameHostMsg_SetTemporaryZoomLevel, &helper,
|
||||
FrameDispatchHelper::OnSetTemporaryZoomLevel)
|
||||
IPC_MESSAGE_FORWARD_DELAY_REPLY(AtomFrameHostMsg_GetZoomLevel, &helper,
|
||||
FrameDispatchHelper::OnGetZoomLevel)
|
||||
IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_ShowPopup, ShowAutofillPopup)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(NativeWindow, message, frame_host)
|
||||
IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_HidePopup,
|
||||
relay->window.get(), NativeWindow::HideAutofillPopup)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
|
||||
@@ -989,13 +1021,17 @@ void WebContents::NavigationEntryCommitted(
|
||||
details.is_same_document, details.did_replace_entry);
|
||||
}
|
||||
|
||||
int64_t WebContents::GetID() const {
|
||||
int64_t process_id = web_contents()->GetRenderProcessHost()->GetID();
|
||||
int64_t routing_id = web_contents()->GetRenderViewHost()->GetRoutingID();
|
||||
int64_t WebContents::GetIDForContents(content::WebContents* web_contents) {
|
||||
int64_t process_id = web_contents->GetRenderProcessHost()->GetID();
|
||||
int64_t routing_id = web_contents->GetMainFrame()->GetRoutingID();
|
||||
int64_t rv = (process_id << 32) + routing_id;
|
||||
return rv;
|
||||
}
|
||||
|
||||
int64_t WebContents::GetID() const {
|
||||
return WebContents::GetIDForContents(web_contents());
|
||||
}
|
||||
|
||||
int WebContents::GetProcessID() const {
|
||||
return web_contents()->GetRenderProcessHost()->GetID();
|
||||
}
|
||||
@@ -1311,6 +1347,10 @@ bool WebContents::IsAudioMuted() {
|
||||
return web_contents()->IsAudioMuted();
|
||||
}
|
||||
|
||||
bool WebContents::IsDOMReady() const {
|
||||
return is_dom_ready_;
|
||||
}
|
||||
|
||||
void WebContents::Print(mate::Arguments* args) {
|
||||
PrintSettings settings = { false, false, base::string16() };
|
||||
if (args->Length() >= 1 && !args->GetNext(&settings)) {
|
||||
@@ -1468,7 +1508,12 @@ void WebContents::TabTraverse(bool reverse) {
|
||||
bool WebContents::SendIPCMessage(bool all_frames,
|
||||
const base::string16& channel,
|
||||
const base::ListValue& args) {
|
||||
return Send(new AtomViewMsg_Message(routing_id(), all_frames, channel, args));
|
||||
auto frame_host = web_contents()->GetMainFrame();
|
||||
if (frame_host) {
|
||||
return frame_host->Send(new AtomFrameMsg_Message(
|
||||
frame_host->GetRoutingID(), all_frames, channel, args));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void WebContents::SendInputEvent(v8::Isolate* isolate,
|
||||
@@ -1752,25 +1797,38 @@ double WebContents::GetZoomFactor() {
|
||||
return content::ZoomLevelToZoomFactor(level);
|
||||
}
|
||||
|
||||
void WebContents::OnSetTemporaryZoomLevel(double level,
|
||||
void WebContents::OnSetTemporaryZoomLevel(content::RenderFrameHost* rfh,
|
||||
double level,
|
||||
IPC::Message* reply_msg) {
|
||||
zoom_controller_->SetTemporaryZoomLevel(level);
|
||||
double new_level = zoom_controller_->GetZoomLevel();
|
||||
AtomViewHostMsg_SetTemporaryZoomLevel::WriteReplyParams(reply_msg, new_level);
|
||||
Send(reply_msg);
|
||||
AtomFrameHostMsg_SetTemporaryZoomLevel::WriteReplyParams(reply_msg,
|
||||
new_level);
|
||||
rfh->Send(reply_msg);
|
||||
}
|
||||
|
||||
void WebContents::OnGetZoomLevel(IPC::Message* reply_msg) {
|
||||
AtomViewHostMsg_GetZoomLevel::WriteReplyParams(reply_msg, GetZoomLevel());
|
||||
Send(reply_msg);
|
||||
void WebContents::OnGetZoomLevel(content::RenderFrameHost* rfh,
|
||||
IPC::Message* reply_msg) {
|
||||
AtomFrameHostMsg_GetZoomLevel::WriteReplyParams(reply_msg, GetZoomLevel());
|
||||
rfh->Send(reply_msg);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) {
|
||||
WebContentsPreferences* web_preferences =
|
||||
WebContentsPreferences::FromWebContents(web_contents());
|
||||
if (!web_preferences)
|
||||
return v8::Null(isolate);
|
||||
return mate::ConvertToV8(isolate, *web_preferences->web_preferences());
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebContents::GetLastWebPreferences(v8::Isolate* isolate) {
|
||||
WebContentsPreferences* web_preferences =
|
||||
WebContentsPreferences::FromWebContents(web_contents());
|
||||
if (!web_preferences)
|
||||
return v8::Null(isolate);
|
||||
return mate::ConvertToV8(isolate, *web_preferences->last_web_preferences());
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() {
|
||||
if (owner_window())
|
||||
return Window::From(isolate(), owner_window());
|
||||
@@ -1884,6 +1942,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
&WebContents::SetIgnoreMenuShortcuts)
|
||||
.SetMethod("setAudioMuted", &WebContents::SetAudioMuted)
|
||||
.SetMethod("isAudioMuted", &WebContents::IsAudioMuted)
|
||||
.SetMethod("isDomReady", &WebContents::IsDOMReady)
|
||||
.SetMethod("undo", &WebContents::Undo)
|
||||
.SetMethod("redo", &WebContents::Redo)
|
||||
.SetMethod("cut", &WebContents::Cut)
|
||||
@@ -1907,9 +1966,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("startDrag", &WebContents::StartDrag)
|
||||
.SetMethod("setSize", &WebContents::SetSize)
|
||||
.SetMethod("isGuest", &WebContents::IsGuest)
|
||||
#if defined(ENABLE_OSR)
|
||||
.SetMethod("isOffscreen", &WebContents::IsOffScreen)
|
||||
#endif
|
||||
.SetMethod("startPainting", &WebContents::StartPainting)
|
||||
.SetMethod("stopPainting", &WebContents::StopPainting)
|
||||
.SetMethod("isPainting", &WebContents::IsPainting)
|
||||
@@ -1922,6 +1979,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("_getZoomFactor", &WebContents::GetZoomFactor)
|
||||
.SetMethod("getType", &WebContents::GetType)
|
||||
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
|
||||
.SetMethod("getLastWebPreferences", &WebContents::GetLastWebPreferences)
|
||||
.SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
|
||||
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
|
||||
.SetMethod("unregisterServiceWorker",
|
||||
@@ -1955,17 +2013,19 @@ AtomBrowserContext* WebContents::GetBrowserContext() const {
|
||||
return static_cast<AtomBrowserContext*>(web_contents()->GetBrowserContext());
|
||||
}
|
||||
|
||||
void WebContents::OnRendererMessage(const base::string16& channel,
|
||||
void WebContents::OnRendererMessage(content::RenderFrameHost* frame_host,
|
||||
const base::string16& channel,
|
||||
const base::ListValue& args) {
|
||||
// webContents.emit(channel, new Event(), args...);
|
||||
Emit(base::UTF16ToUTF8(channel), args);
|
||||
}
|
||||
|
||||
void WebContents::OnRendererMessageSync(const base::string16& channel,
|
||||
void WebContents::OnRendererMessageSync(content::RenderFrameHost* frame_host,
|
||||
const base::string16& channel,
|
||||
const base::ListValue& args,
|
||||
IPC::Message* message) {
|
||||
// webContents.emit(channel, new Event(sender, message), args...);
|
||||
EmitWithSender(base::UTF16ToUTF8(channel), web_contents(), message, args);
|
||||
EmitWithSender(base::UTF16ToUTF8(channel), frame_host, message, args);
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -79,6 +79,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
static int64_t GetIDForContents(content::WebContents* web_contents);
|
||||
|
||||
// Notifies to destroy any guest web contents before destroying self.
|
||||
void DestroyWebContents(bool async);
|
||||
|
||||
@@ -123,6 +125,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void SetIgnoreMenuShortcuts(bool ignore);
|
||||
void SetAudioMuted(bool muted);
|
||||
bool IsAudioMuted();
|
||||
bool IsDOMReady() const;
|
||||
void Print(mate::Arguments* args);
|
||||
std::vector<printing::PrinterBasicInfo> GetPrinterList();
|
||||
void SetEmbedder(const WebContents* embedder);
|
||||
@@ -214,6 +217,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
|
||||
// Returns the web preferences of current WebContents.
|
||||
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate);
|
||||
|
||||
// Returns the owner window.
|
||||
v8::Local<v8::Value> GetOwnerBrowserWindow();
|
||||
@@ -367,6 +371,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
const std::vector<base::string16>& labels);
|
||||
|
||||
private:
|
||||
struct FrameDispatchHelper;
|
||||
AtomBrowserContext* GetBrowserContext() const;
|
||||
|
||||
uint32_t GetNextRequestId() {
|
||||
@@ -377,21 +382,26 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void OnCursorChange(const content::WebCursor& cursor);
|
||||
|
||||
// Called when received a message from renderer.
|
||||
void OnRendererMessage(const base::string16& channel,
|
||||
void OnRendererMessage(content::RenderFrameHost* frame_host,
|
||||
const base::string16& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
// Called when received a synchronous message from renderer.
|
||||
void OnRendererMessageSync(const base::string16& channel,
|
||||
void OnRendererMessageSync(content::RenderFrameHost* frame_host,
|
||||
const base::string16& channel,
|
||||
const base::ListValue& args,
|
||||
IPC::Message* message);
|
||||
|
||||
// Called when received a synchronous message from renderer to
|
||||
// set temporary zoom level.
|
||||
void OnSetTemporaryZoomLevel(double level, IPC::Message* reply_msg);
|
||||
void OnSetTemporaryZoomLevel(content::RenderFrameHost* frame_host,
|
||||
double level,
|
||||
IPC::Message* reply_msg);
|
||||
|
||||
// Called when received a synchronous message from renderer to
|
||||
// get the zoom level.
|
||||
void OnGetZoomLevel(IPC::Message* reply_msg);
|
||||
void OnGetZoomLevel(content::RenderFrameHost* frame_host,
|
||||
IPC::Message* reply_msg);
|
||||
|
||||
void InitZoomController(content::WebContents* web_contents,
|
||||
const mate::Dictionary& options);
|
||||
@@ -421,6 +431,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
// Whether to enable devtools.
|
||||
bool enable_devtools_;
|
||||
|
||||
// Whether page's document is ready.
|
||||
bool is_dom_ready_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContents);
|
||||
};
|
||||
|
||||
|
||||
@@ -37,6 +37,26 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename Method, typename Event, typename Listener>
|
||||
void CallNetworkDelegateMethod(
|
||||
brightray::URLRequestContextGetter* url_request_context_getter,
|
||||
Method method,
|
||||
Event type,
|
||||
URLPatterns patterns,
|
||||
Listener listener) {
|
||||
// Force creating network delegate.
|
||||
net::URLRequestContext* context =
|
||||
url_request_context_getter->GetURLRequestContext();
|
||||
// Then call the method.
|
||||
AtomNetworkDelegate* network_delegate =
|
||||
static_cast<AtomNetworkDelegate*>(context->network_delegate());
|
||||
(network_delegate->*method)(type, std::move(patterns), std::move(listener));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
WebRequest::WebRequest(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {
|
||||
@@ -74,16 +94,15 @@ void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto url_request_context_getter =
|
||||
brightray::URLRequestContextGetter* url_request_context_getter =
|
||||
browser_context_->url_request_context_getter();
|
||||
if (!url_request_context_getter)
|
||||
return;
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(method,
|
||||
base::Unretained(static_cast<AtomNetworkDelegate*>(
|
||||
url_request_context_getter->network_delegate())),
|
||||
type, patterns, listener));
|
||||
base::Bind(&CallNetworkDelegateMethod<Method, Event, Listener>,
|
||||
base::RetainedRef(url_request_context_getter),
|
||||
method, type, std::move(patterns), std::move(listener)));
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -450,9 +450,11 @@ gfx::Rect Window::GetContentBounds() {
|
||||
}
|
||||
|
||||
void Window::SetSize(int width, int height, mate::Arguments* args) {
|
||||
gfx::Size size = window_->GetMinimumSize();
|
||||
size.SetToMax(gfx::Size(width, height));
|
||||
bool animate = false;
|
||||
args->GetNext(&animate);
|
||||
window_->SetSize(gfx::Size(width, height), animate);
|
||||
window_->SetSize(size, animate);
|
||||
}
|
||||
|
||||
std::vector<int> Window::GetSize() {
|
||||
@@ -893,6 +895,8 @@ void Window::SetBrowserView(v8::Local<v8::Value> value) {
|
||||
window_->SetBrowserView(browser_view->view());
|
||||
browser_view->web_contents()->SetOwnerWindow(window_.get());
|
||||
browser_view_.Reset(isolate(), value);
|
||||
|
||||
window_->UpdateDraggableRegionViews();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -952,8 +956,11 @@ void Window::ToggleTabBar() {
|
||||
window_->ToggleTabBar();
|
||||
}
|
||||
|
||||
void Window::AddTabbedWindow(NativeWindow* window) {
|
||||
window_->AddTabbedWindow(window);
|
||||
void Window::AddTabbedWindow(NativeWindow* window,
|
||||
mate::Arguments* args) {
|
||||
const bool windowAdded = window_->AddTabbedWindow(window);
|
||||
if (!windowAdded)
|
||||
args->ThrowError("AddTabbedWindow cannot be called by a window on itself.");
|
||||
}
|
||||
|
||||
void Window::SetVibrancy(mate::Arguments* args) {
|
||||
|
||||
@@ -222,7 +222,7 @@ class Window : public mate::TrackableObject<Window>,
|
||||
void MergeAllWindows();
|
||||
void MoveTabToNewWindow();
|
||||
void ToggleTabBar();
|
||||
void AddTabbedWindow(NativeWindow* window);
|
||||
void AddTabbedWindow(NativeWindow* window, mate::Arguments* args);
|
||||
|
||||
void SetVibrancy(mate::Arguments* args);
|
||||
void SetTouchBar(const std::vector<mate::PersistentDictionary>& items);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
@@ -20,17 +21,32 @@ Event::Event(v8::Isolate* isolate)
|
||||
Event::~Event() {
|
||||
}
|
||||
|
||||
void Event::SetSenderAndMessage(content::WebContents* sender,
|
||||
void Event::SetSenderAndMessage(content::RenderFrameHost* sender,
|
||||
IPC::Message* message) {
|
||||
DCHECK(!sender_);
|
||||
DCHECK(!message_);
|
||||
sender_ = sender;
|
||||
message_ = message;
|
||||
|
||||
Observe(sender);
|
||||
Observe(content::WebContents::FromRenderFrameHost(sender));
|
||||
}
|
||||
|
||||
void Event::WebContentsDestroyed() {
|
||||
void Event::RenderFrameDeleted(content::RenderFrameHost* rfh) {
|
||||
if (sender_ != rfh)
|
||||
return;
|
||||
sender_ = nullptr;
|
||||
message_ = nullptr;
|
||||
}
|
||||
|
||||
void Event::RenderFrameHostChanged(content::RenderFrameHost* old_rfh,
|
||||
content::RenderFrameHost* new_rfh) {
|
||||
if (sender_ && sender_ == old_rfh)
|
||||
sender_ = new_rfh;
|
||||
}
|
||||
|
||||
void Event::FrameDeleted(content::RenderFrameHost* rfh) {
|
||||
if (sender_ != rfh)
|
||||
return;
|
||||
sender_ = nullptr;
|
||||
message_ = nullptr;
|
||||
}
|
||||
@@ -44,7 +60,7 @@ bool Event::SendReply(const base::string16& json) {
|
||||
if (message_ == nullptr || sender_ == nullptr)
|
||||
return false;
|
||||
|
||||
AtomViewHostMsg_Message_Sync::WriteReplyParams(message_, json);
|
||||
AtomFrameHostMsg_Message_Sync::WriteReplyParams(message_, json);
|
||||
bool success = sender_->Send(message_);
|
||||
message_ = nullptr;
|
||||
sender_ = nullptr;
|
||||
|
||||
@@ -24,7 +24,8 @@ class Event : public Wrappable<Event>,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
// Pass the sender and message to be replied.
|
||||
void SetSenderAndMessage(content::WebContents* sender, IPC::Message* message);
|
||||
void SetSenderAndMessage(content::RenderFrameHost* sender,
|
||||
IPC::Message* message);
|
||||
|
||||
// event.PreventDefault().
|
||||
void PreventDefault(v8::Isolate* isolate);
|
||||
@@ -37,11 +38,14 @@ class Event : public Wrappable<Event>,
|
||||
~Event() override;
|
||||
|
||||
// content::WebContentsObserver implementations:
|
||||
void WebContentsDestroyed() override;
|
||||
void RenderFrameDeleted(content::RenderFrameHost* rfh) override;
|
||||
void RenderFrameHostChanged(content::RenderFrameHost* old_rfh,
|
||||
content::RenderFrameHost* new_rfh) override;
|
||||
void FrameDeleted(content::RenderFrameHost* rfh) override;
|
||||
|
||||
private:
|
||||
// Replyer for the synchronous messages.
|
||||
content::WebContents* sender_;
|
||||
content::RenderFrameHost* sender_;
|
||||
IPC::Message* message_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Event);
|
||||
|
||||
@@ -39,11 +39,10 @@ v8::Local<v8::Object> CreateEventObject(v8::Isolate* isolate) {
|
||||
|
||||
namespace internal {
|
||||
|
||||
v8::Local<v8::Object> CreateJSEvent(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> object,
|
||||
content::WebContents* sender,
|
||||
IPC::Message* message) {
|
||||
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> object,
|
||||
content::RenderFrameHost* sender,
|
||||
IPC::Message* message) {
|
||||
v8::Local<v8::Object> event;
|
||||
bool use_native_event = sender && message;
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "native_mate/wrappable.h"
|
||||
|
||||
namespace content {
|
||||
class WebContents;
|
||||
class RenderFrameHost;
|
||||
}
|
||||
|
||||
namespace IPC {
|
||||
@@ -24,7 +24,7 @@ namespace internal {
|
||||
|
||||
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> object,
|
||||
content::WebContents* sender,
|
||||
content::RenderFrameHost* sender,
|
||||
IPC::Message* message);
|
||||
v8::Local<v8::Object> CreateCustomEvent(
|
||||
v8::Isolate* isolate,
|
||||
@@ -74,9 +74,9 @@ class EventEmitter : public Wrappable<T> {
|
||||
}
|
||||
|
||||
// this.emit(name, new Event(sender, message), args...);
|
||||
template<typename... Args>
|
||||
template <typename... Args>
|
||||
bool EmitWithSender(const base::StringPiece& name,
|
||||
content::WebContents* sender,
|
||||
content::RenderFrameHost* sender,
|
||||
IPC::Message* message,
|
||||
const Args&... args) {
|
||||
v8::Locker locker(isolate());
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "atom/browser/api/atom_api_app.h"
|
||||
#include "atom/browser/api/atom_api_protocol.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_quota_permission_context.h"
|
||||
@@ -318,6 +319,11 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||
web_contents, command_line);
|
||||
SessionPreferences::AppendExtraCommandLineSwitches(
|
||||
web_contents->GetBrowserContext(), command_line);
|
||||
|
||||
auto context_id = atom::api::WebContents::GetIDForContents(
|
||||
web_contents);
|
||||
command_line->AppendSwitchASCII(switches::kContextId,
|
||||
base::IntToString(context_id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,7 +448,6 @@ void AtomBrowserClient::SiteInstanceDeleting(
|
||||
|
||||
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
|
||||
const content::MainFunctionParams&) {
|
||||
v8::V8::Initialize(); // Init V8 before creating main parts.
|
||||
return new AtomBrowserMainParts;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "atom/browser/net/atom_network_delegate.h"
|
||||
#include "atom/browser/net/atom_url_request_job_factory.h"
|
||||
#include "atom/browser/net/http_protocol_handler.h"
|
||||
#include "atom/browser/net/resolve_proxy_helper.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "atom/common/chrome_version.h"
|
||||
@@ -226,6 +227,14 @@ AtomBlobReader* AtomBrowserContext::GetBlobReader() {
|
||||
return blob_reader_.get();
|
||||
}
|
||||
|
||||
ResolveProxyHelper* AtomBrowserContext::GetResolveProxyHelper() {
|
||||
if (!resolve_proxy_helper_.get()) {
|
||||
resolve_proxy_helper_ =
|
||||
base::MakeRefCounted<ResolveProxyHelper>(url_request_context_getter());
|
||||
}
|
||||
return resolve_proxy_helper_.get();
|
||||
}
|
||||
|
||||
// static
|
||||
scoped_refptr<AtomBrowserContext> AtomBrowserContext::From(
|
||||
const std::string& partition, bool in_memory,
|
||||
|
||||
@@ -18,6 +18,7 @@ class AtomBlobReader;
|
||||
class AtomDownloadManagerDelegate;
|
||||
class AtomNetworkDelegate;
|
||||
class AtomPermissionManager;
|
||||
class ResolveProxyHelper;
|
||||
class WebViewManager;
|
||||
|
||||
class AtomBrowserContext : public brightray::BrowserContext {
|
||||
@@ -51,6 +52,8 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
// brightray::BrowserContext:
|
||||
void RegisterPrefs(PrefRegistrySimple* pref_registry) override;
|
||||
|
||||
ResolveProxyHelper* GetResolveProxyHelper();
|
||||
|
||||
AtomBlobReader* GetBlobReader();
|
||||
AtomCookieDelegate* cookie_delegate() const {
|
||||
return cookie_delegate_.get();
|
||||
@@ -62,6 +65,7 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
~AtomBrowserContext() override;
|
||||
|
||||
private:
|
||||
scoped_refptr<ResolveProxyHelper> resolve_proxy_helper_;
|
||||
std::unique_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
|
||||
std::unique_ptr<WebViewManager> guest_manager_;
|
||||
std::unique_ptr<AtomPermissionManager> permission_manager_;
|
||||
|
||||
@@ -151,6 +151,14 @@ void AtomBrowserMainParts::PostEarlyInitialization() {
|
||||
|
||||
// Wrap the uv loop with global env.
|
||||
node_bindings_->set_uv_env(env);
|
||||
|
||||
// We already initialized the feature list in
|
||||
// brightray::BrowserMainParts::PreEarlyInitialization(), but
|
||||
// the user JS script would not have had a chance to alter the command-line
|
||||
// switches at that point. Lets reinitialize it here to pick up the
|
||||
// command-line changes.
|
||||
base::FeatureList::ClearInstanceForTesting();
|
||||
brightray::BrowserMainParts::InitializeFeatureList();
|
||||
}
|
||||
|
||||
int AtomBrowserMainParts::PreCreateThreads() {
|
||||
|
||||
@@ -108,14 +108,13 @@ void Browser::SetVersion(const std::string& version) {
|
||||
}
|
||||
|
||||
std::string Browser::GetName() const {
|
||||
std::string ret = name_override_;
|
||||
std::string ret = brightray::GetOverriddenApplicationName();
|
||||
if (ret.empty())
|
||||
ret = GetExecutableFileProductName();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Browser::SetName(const std::string& name) {
|
||||
name_override_ = name;
|
||||
brightray::OverrideApplicationName(name);
|
||||
}
|
||||
|
||||
|
||||
@@ -273,8 +273,6 @@ class Browser : public WindowListObserver {
|
||||
// The browser is being shutdown.
|
||||
bool is_shutdown_;
|
||||
|
||||
std::string name_override_;
|
||||
|
||||
int badge_count_ = 0;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
|
||||
@@ -77,6 +77,11 @@ bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol,
|
||||
}
|
||||
}
|
||||
|
||||
// No other app was found set it to none instead of setting it back to itself.
|
||||
if ([identifier isEqualToString:(__bridge NSString*)other]) {
|
||||
other = base::mac::NSToCFCast(@"None");
|
||||
}
|
||||
|
||||
OSStatus return_code = LSSetDefaultHandlerForURLScheme(protocol_cf, other);
|
||||
return return_code == noErr;
|
||||
}
|
||||
@@ -210,6 +215,65 @@ Browser::LoginItemSettings Browser::GetLoginItemSettings(
|
||||
return settings;
|
||||
}
|
||||
|
||||
// copied from GetLoginItemForApp in base/mac/mac_util.mm
|
||||
LSSharedFileListItemRef GetLoginItemForApp() {
|
||||
base::ScopedCFTypeRef<LSSharedFileListRef> login_items(
|
||||
LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL));
|
||||
if (!login_items.get()) {
|
||||
LOG(ERROR) << "Couldn't get a Login Items list.";
|
||||
return NULL;
|
||||
}
|
||||
base::scoped_nsobject<NSArray> login_items_array(
|
||||
base::mac::CFToNSCast(LSSharedFileListCopySnapshot(login_items, NULL)));
|
||||
NSURL* url = [NSURL fileURLWithPath:[base::mac::MainBundle() bundlePath]];
|
||||
for (NSUInteger i = 0; i < [login_items_array count]; ++i) {
|
||||
LSSharedFileListItemRef item =
|
||||
reinterpret_cast<LSSharedFileListItemRef>(login_items_array[i]);
|
||||
CFURLRef item_url_ref = NULL;
|
||||
if (LSSharedFileListItemResolve(item, 0, &item_url_ref, NULL) == noErr &&
|
||||
item_url_ref) {
|
||||
base::ScopedCFTypeRef<CFURLRef> item_url(item_url_ref);
|
||||
if (CFEqual(item_url, url)) {
|
||||
CFRetain(item);
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void RemoveFromLoginItems() {
|
||||
base::ScopedCFTypeRef<LSSharedFileListRef> list(
|
||||
LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL));
|
||||
if (!list) {
|
||||
LOG(ERROR) << "Unable to access shared file list";
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetLoginItemForApp() != NULL) {
|
||||
base::scoped_nsobject<NSArray> login_items_array(
|
||||
base::mac::CFToNSCast(LSSharedFileListCopySnapshot(list, NULL)));
|
||||
|
||||
if (!login_items_array) {
|
||||
LOG(ERROR) << "No items in list of auto-loaded apps";
|
||||
return;
|
||||
}
|
||||
|
||||
for (NSUInteger i = 0; i < [login_items_array count]; ++i) {
|
||||
LSSharedFileListItemRef item =
|
||||
reinterpret_cast<LSSharedFileListItemRef>(login_items_array[i]);
|
||||
CFURLRef url_ref = NULL;
|
||||
if (LSSharedFileListItemResolve(item, 0, &url_ref, NULL) == noErr &&
|
||||
item) {
|
||||
base::ScopedCFTypeRef<CFURLRef> url(url_ref);
|
||||
if ([[base::mac::CFToNSCast(url.get()) path]
|
||||
hasPrefix:[[NSBundle mainBundle] bundlePath]])
|
||||
LSSharedFileListItemRemove(list, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Browser::SetLoginItemSettings(LoginItemSettings settings) {
|
||||
#if defined(MAS_BUILD)
|
||||
platform_util::SetLoginItemEnabled(settings.open_at_login);
|
||||
@@ -217,7 +281,7 @@ void Browser::SetLoginItemSettings(LoginItemSettings settings) {
|
||||
if (settings.open_at_login)
|
||||
base::mac::AddToLoginItems(settings.open_as_hidden);
|
||||
else
|
||||
base::mac::RemoveFromLoginItems();
|
||||
RemoveFromLoginItems();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <unistd.h>
|
||||
#include <uv.h>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "device/bluetooth/dbus/dbus_thread_manager_linux.h"
|
||||
@@ -23,7 +24,7 @@ std::string get_executable_basename() {
|
||||
if (!uv_exepath(buf, &buf_size)) {
|
||||
rv = strrchr(static_cast<const char*>(buf), '/') + 1;
|
||||
}
|
||||
return std::move(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -32,39 +33,37 @@ namespace atom {
|
||||
|
||||
PowerObserverLinux::PowerObserverLinux()
|
||||
: lock_owner_name_(get_executable_basename()), weak_ptr_factory_(this) {
|
||||
auto dbus_thread_manager = bluez::DBusThreadManagerLinux::Get();
|
||||
if (dbus_thread_manager) {
|
||||
bus_ = dbus_thread_manager->GetSystemBus();
|
||||
if (bus_) {
|
||||
logind_ = bus_->GetObjectProxy(kLogindServiceName,
|
||||
dbus::ObjectPath(kLogindObjectPath));
|
||||
logind_->WaitForServiceToBeAvailable(
|
||||
base::Bind(&PowerObserverLinux::OnLoginServiceAvailable,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
} else {
|
||||
LOG(WARNING) << "Failed to get system bus connection";
|
||||
}
|
||||
} else {
|
||||
LOG(WARNING) << "DBusThreadManagerLinux instance isn't available";
|
||||
auto* bus = bluez::DBusThreadManagerLinux::Get()->GetSystemBus();
|
||||
if (!bus) {
|
||||
LOG(WARNING) << "Failed to get system bus connection";
|
||||
return;
|
||||
}
|
||||
|
||||
// set up the logind proxy
|
||||
|
||||
const auto weakThis = weak_ptr_factory_.GetWeakPtr();
|
||||
|
||||
logind_ = bus->GetObjectProxy(kLogindServiceName,
|
||||
dbus::ObjectPath(kLogindObjectPath));
|
||||
logind_->ConnectToSignal(
|
||||
kLogindManagerInterface, "PrepareForShutdown",
|
||||
base::BindRepeating(&PowerObserverLinux::OnPrepareForShutdown, weakThis),
|
||||
base::BindRepeating(&PowerObserverLinux::OnSignalConnected, weakThis));
|
||||
logind_->ConnectToSignal(
|
||||
kLogindManagerInterface, "PrepareForSleep",
|
||||
base::BindRepeating(&PowerObserverLinux::OnPrepareForSleep, weakThis),
|
||||
base::BindRepeating(&PowerObserverLinux::OnSignalConnected, weakThis));
|
||||
logind_->WaitForServiceToBeAvailable(base::BindRepeating(
|
||||
&PowerObserverLinux::OnLoginServiceAvailable, weakThis));
|
||||
}
|
||||
|
||||
PowerObserverLinux::~PowerObserverLinux() = default;
|
||||
|
||||
void PowerObserverLinux::OnLoginServiceAvailable(bool service_available) {
|
||||
if (!service_available) {
|
||||
LOG(WARNING) << kLogindServiceName << " not available";
|
||||
return;
|
||||
}
|
||||
// Connect to PrepareForShutdown/PrepareForSleep signals
|
||||
logind_->ConnectToSignal(kLogindManagerInterface, "PrepareForShutdown",
|
||||
base::Bind(&PowerObserverLinux::OnPrepareForShutdown,
|
||||
weak_ptr_factory_.GetWeakPtr()),
|
||||
base::Bind(&PowerObserverLinux::OnSignalConnected,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
logind_->ConnectToSignal(kLogindManagerInterface, "PrepareForSleep",
|
||||
base::Bind(&PowerObserverLinux::OnPrepareForSleep,
|
||||
weak_ptr_factory_.GetWeakPtr()),
|
||||
base::Bind(&PowerObserverLinux::OnSignalConnected,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
// Take sleep inhibit lock
|
||||
BlockSleep();
|
||||
}
|
||||
@@ -120,8 +119,10 @@ void PowerObserverLinux::SetShutdownHandler(base::Callback<bool()> handler) {
|
||||
|
||||
void PowerObserverLinux::OnInhibitResponse(base::ScopedFD* scoped_fd,
|
||||
dbus::Response* response) {
|
||||
dbus::MessageReader reader(response);
|
||||
reader.PopFileDescriptor(scoped_fd);
|
||||
if (response != nullptr) {
|
||||
dbus::MessageReader reader(response);
|
||||
reader.PopFileDescriptor(scoped_fd);
|
||||
}
|
||||
}
|
||||
|
||||
void PowerObserverLinux::OnPrepareForSleep(dbus::Signal* signal) {
|
||||
@@ -156,7 +157,7 @@ void PowerObserverLinux::OnPrepareForShutdown(dbus::Signal* signal) {
|
||||
}
|
||||
}
|
||||
|
||||
void PowerObserverLinux::OnSignalConnected(const std::string& interface,
|
||||
void PowerObserverLinux::OnSignalConnected(const std::string& /*interface*/,
|
||||
const std::string& signal,
|
||||
bool success) {
|
||||
LOG_IF(WARNING, !success) << "Failed to connect to " << signal;
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace atom {
|
||||
class PowerObserverLinux : public base::PowerObserver {
|
||||
public:
|
||||
PowerObserverLinux();
|
||||
~PowerObserverLinux() override;
|
||||
|
||||
protected:
|
||||
void BlockSleep();
|
||||
@@ -39,7 +40,6 @@ class PowerObserverLinux : public base::PowerObserver {
|
||||
|
||||
base::Callback<bool()> should_shutdown_;
|
||||
|
||||
scoped_refptr<dbus::Bus> bus_;
|
||||
scoped_refptr<dbus::ObjectProxy> logind_;
|
||||
std::string lock_owner_name_;
|
||||
base::ScopedFD sleep_lock_;
|
||||
|
||||
@@ -7,14 +7,23 @@
|
||||
#include "atom/browser/native_browser_view.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
NativeBrowserView::NativeBrowserView(
|
||||
brightray::InspectableWebContentsView* web_contents_view)
|
||||
: web_contents_view_(web_contents_view) {}
|
||||
brightray::InspectableWebContents* inspectable_web_contents)
|
||||
: inspectable_web_contents_(inspectable_web_contents) {}
|
||||
|
||||
NativeBrowserView::~NativeBrowserView() {}
|
||||
|
||||
brightray::InspectableWebContentsView*
|
||||
NativeBrowserView::GetInspectableWebContentsView() {
|
||||
return inspectable_web_contents_->GetView();
|
||||
}
|
||||
|
||||
content::WebContents* NativeBrowserView::GetWebContents() {
|
||||
return inspectable_web_contents_->GetWebContents();
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -9,9 +9,11 @@
|
||||
|
||||
#include "atom/common/draggable_region.h"
|
||||
#include "base/macros.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "third_party/skia/include/core/SkColor.h"
|
||||
|
||||
namespace brightray {
|
||||
class InspectableWebContents;
|
||||
class InspectableWebContentsView;
|
||||
}
|
||||
|
||||
@@ -31,12 +33,15 @@ class NativeBrowserView {
|
||||
virtual ~NativeBrowserView();
|
||||
|
||||
static NativeBrowserView* Create(
|
||||
brightray::InspectableWebContentsView* web_contents_view);
|
||||
brightray::InspectableWebContents* inspectable_web_contents);
|
||||
|
||||
brightray::InspectableWebContentsView* GetInspectableWebContentsView() {
|
||||
return web_contents_view_;
|
||||
brightray::InspectableWebContents* GetInspectableWebContents() {
|
||||
return inspectable_web_contents_;
|
||||
}
|
||||
|
||||
brightray::InspectableWebContentsView* GetInspectableWebContentsView();
|
||||
content::WebContents* GetWebContents();
|
||||
|
||||
virtual void SetAutoResizeFlags(uint8_t flags) = 0;
|
||||
virtual void SetBounds(const gfx::Rect& bounds) = 0;
|
||||
virtual void SetBackgroundColor(SkColor color) = 0;
|
||||
@@ -47,9 +52,9 @@ class NativeBrowserView {
|
||||
|
||||
protected:
|
||||
explicit NativeBrowserView(
|
||||
brightray::InspectableWebContentsView* web_contents_view);
|
||||
brightray::InspectableWebContents* inspectable_web_contents);
|
||||
|
||||
brightray::InspectableWebContentsView* web_contents_view_;
|
||||
brightray::InspectableWebContents* inspectable_web_contents_;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(NativeBrowserView);
|
||||
|
||||
@@ -17,12 +17,13 @@ namespace atom {
|
||||
class NativeBrowserViewMac : public NativeBrowserView {
|
||||
public:
|
||||
explicit NativeBrowserViewMac(
|
||||
brightray::InspectableWebContentsView* web_contents_view);
|
||||
brightray::InspectableWebContents* inspectable_web_contents);
|
||||
~NativeBrowserViewMac() override;
|
||||
|
||||
void SetAutoResizeFlags(uint8_t flags) override;
|
||||
void SetBounds(const gfx::Rect& bounds) override;
|
||||
void SetBackgroundColor(SkColor color) override;
|
||||
|
||||
void UpdateDraggableRegions(
|
||||
const std::vector<gfx::Rect>& system_drag_exclude_areas) override;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "atom/browser/native_browser_view_mac.h"
|
||||
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
#include "skia/ext/skia_utils_mac.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
@@ -156,8 +157,8 @@ const NSAutoresizingMaskOptions kDefaultAutoResizingMask =
|
||||
namespace atom {
|
||||
|
||||
NativeBrowserViewMac::NativeBrowserViewMac(
|
||||
brightray::InspectableWebContentsView* web_contents_view)
|
||||
: NativeBrowserView(web_contents_view) {
|
||||
brightray::InspectableWebContents* inspectable_web_contents)
|
||||
: NativeBrowserView(inspectable_web_contents) {
|
||||
auto* view = GetInspectableWebContentsView()->GetNativeView();
|
||||
view.autoresizingMask = kDefaultAutoResizingMask;
|
||||
}
|
||||
@@ -193,62 +194,46 @@ void NativeBrowserViewMac::SetBackgroundColor(SkColor color) {
|
||||
}
|
||||
|
||||
void NativeBrowserViewMac::UpdateDraggableRegions(
|
||||
const std::vector<gfx::Rect>& system_drag_exclude_areas) {
|
||||
NSView* webView = GetInspectableWebContentsView()->GetNativeView();
|
||||
const std::vector<gfx::Rect>& drag_exclude_rects) {
|
||||
NSView* web_view = GetWebContents()->GetNativeView();
|
||||
NSView* inspectable_view = GetInspectableWebContentsView()->GetNativeView();
|
||||
NSView* window_content_view = inspectable_view.superview;
|
||||
const auto window_content_view_height = NSHeight(window_content_view.bounds);
|
||||
|
||||
NSInteger superViewHeight = NSHeight([webView.superview bounds]);
|
||||
NSInteger webViewHeight = NSHeight([webView bounds]);
|
||||
NSInteger webViewWidth = NSWidth([webView bounds]);
|
||||
NSInteger webViewX = NSMinX([webView frame]);
|
||||
NSInteger webViewY = 0;
|
||||
|
||||
// Apple's NSViews have their coordinate system originate at the bottom left,
|
||||
// meaning that we need to be a bit smarter when it comes to calculating our
|
||||
// current top offset
|
||||
if (webViewHeight > superViewHeight) {
|
||||
webViewY = std::abs(webViewHeight - superViewHeight - (std::abs(NSMinY([webView frame]))));
|
||||
} else {
|
||||
webViewY = superViewHeight - NSMaxY([webView frame]);
|
||||
}
|
||||
|
||||
// Remove all DraggableRegionViews that are added last time.
|
||||
// Note that [webView subviews] returns the view's mutable internal array and
|
||||
// it should be copied to avoid mutating the original array while enumerating
|
||||
// it.
|
||||
base::scoped_nsobject<NSArray> subviews([[webView subviews] copy]);
|
||||
for (NSView* subview in subviews.get())
|
||||
if ([subview isKindOfClass:[DragRegionView class]])
|
||||
// Remove all DragRegionViews that were added last time. Note that we need
|
||||
// to copy the `subviews` array to avoid mutation during iteration.
|
||||
base::scoped_nsobject<NSArray> subviews([[web_view subviews] copy]);
|
||||
for (NSView* subview in subviews.get()) {
|
||||
if ([subview isKindOfClass:[DragRegionView class]]) {
|
||||
[subview removeFromSuperview];
|
||||
}
|
||||
}
|
||||
|
||||
// Create one giant NSView that is draggable.
|
||||
base::scoped_nsobject<NSView> dragRegion(
|
||||
[[DragRegionView alloc] initWithFrame:NSZeroRect]);
|
||||
[dragRegion setFrame:NSMakeRect(0,
|
||||
0,
|
||||
webViewWidth,
|
||||
webViewHeight)];
|
||||
base::scoped_nsobject<NSView> drag_region_view(
|
||||
[[DragRegionView alloc] initWithFrame:web_view.bounds]);
|
||||
[web_view addSubview:drag_region_view];
|
||||
|
||||
// Then, on top of that, add "exclusion zones"
|
||||
for (auto iter = system_drag_exclude_areas.begin();
|
||||
iter != system_drag_exclude_areas.end();
|
||||
++iter) {
|
||||
base::scoped_nsobject<NSView> controlRegion(
|
||||
[[ExcludeDragRegionView alloc] initWithFrame:NSZeroRect]);
|
||||
[controlRegion setFrame:NSMakeRect(iter->x() - webViewX,
|
||||
webViewHeight - iter->bottom() + webViewY,
|
||||
iter->width(),
|
||||
iter->height())];
|
||||
[dragRegion addSubview:controlRegion];
|
||||
}
|
||||
for (const auto& rect : drag_exclude_rects) {
|
||||
const auto window_content_view_exclude_rect =
|
||||
NSMakeRect(rect.x(), window_content_view_height - rect.bottom(),
|
||||
rect.width(), rect.height());
|
||||
const auto drag_region_view_exclude_rect =
|
||||
[window_content_view convertRect:window_content_view_exclude_rect
|
||||
toView:drag_region_view];
|
||||
|
||||
// Add the DragRegion to the WebView
|
||||
[webView addSubview:dragRegion];
|
||||
base::scoped_nsobject<NSView> exclude_drag_region_view(
|
||||
[[ExcludeDragRegionView alloc]
|
||||
initWithFrame:drag_region_view_exclude_rect]);
|
||||
[drag_region_view addSubview:exclude_drag_region_view];
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
NativeBrowserView* NativeBrowserView::Create(
|
||||
brightray::InspectableWebContentsView* web_contents_view) {
|
||||
return new NativeBrowserViewMac(web_contents_view);
|
||||
brightray::InspectableWebContents* inspectable_web_contents) {
|
||||
return new NativeBrowserViewMac(inspectable_web_contents);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
namespace atom {
|
||||
|
||||
NativeBrowserViewViews::NativeBrowserViewViews(
|
||||
brightray::InspectableWebContentsView* web_contents_view)
|
||||
: NativeBrowserView(web_contents_view) {}
|
||||
brightray::InspectableWebContents* inspectable_web_contents)
|
||||
: NativeBrowserView(inspectable_web_contents) {}
|
||||
|
||||
NativeBrowserViewViews::~NativeBrowserViewViews() {}
|
||||
|
||||
@@ -29,8 +29,8 @@ void NativeBrowserViewViews::SetBackgroundColor(SkColor color) {
|
||||
|
||||
// static
|
||||
NativeBrowserView* NativeBrowserView::Create(
|
||||
brightray::InspectableWebContentsView* web_contents_view) {
|
||||
return new NativeBrowserViewViews(web_contents_view);
|
||||
brightray::InspectableWebContents* inspectable_web_contents) {
|
||||
return new NativeBrowserViewViews(inspectable_web_contents);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace atom {
|
||||
class NativeBrowserViewViews : public NativeBrowserView {
|
||||
public:
|
||||
explicit NativeBrowserViewViews(
|
||||
brightray::InspectableWebContentsView* web_contents_view);
|
||||
brightray::InspectableWebContents* inspectable_web_contents);
|
||||
~NativeBrowserViewViews() override;
|
||||
|
||||
uint8_t GetAutoResizeFlags() { return auto_resize_flags_; }
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -47,10 +48,35 @@
|
||||
#include "ui/gfx/font_render_params.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "ui/base/win/shell.h"
|
||||
#include "ui/display/win/screen_win.h"
|
||||
#endif
|
||||
|
||||
DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay);
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(OS_WIN)
|
||||
gfx::Size GetExpandedWindowSize(const NativeWindow* window, gfx::Size size) {
|
||||
if (!window->transparent() || !ui::win::IsAeroGlassEnabled())
|
||||
return size;
|
||||
|
||||
gfx::Size min_size = display::win::ScreenWin::ScreenToDIPSize(
|
||||
window->GetAcceleratedWidget(), gfx::Size(64, 64));
|
||||
|
||||
// Some AMD drivers can't display windows that are less than 64x64 pixels,
|
||||
// so expand them to be at least that size. http://crbug.com/286609
|
||||
gfx::Size expanded(std::max(size.width(), min_size.width()),
|
||||
std::max(size.height(), min_size.height()));
|
||||
return expanded;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
NativeWindow::NativeWindow(
|
||||
brightray::InspectableWebContents* inspectable_web_contents,
|
||||
const mate::Dictionary& options,
|
||||
@@ -307,6 +333,21 @@ gfx::Size NativeWindow::GetMaximumSize() const {
|
||||
return GetSizeConstraints().GetMaximumSize();
|
||||
}
|
||||
|
||||
gfx::Size NativeWindow::GetContentMinimumSize() const {
|
||||
return GetContentSizeConstraints().GetMinimumSize();
|
||||
}
|
||||
|
||||
gfx::Size NativeWindow::GetContentMaximumSize() const {
|
||||
gfx::Size maximum_size = GetContentSizeConstraints().GetMaximumSize();
|
||||
#if defined(OS_WIN)
|
||||
return GetContentSizeConstraints().HasMaximumSize()
|
||||
? GetExpandedWindowSize(this, maximum_size)
|
||||
: maximum_size;
|
||||
#else
|
||||
return maximum_size;
|
||||
#endif
|
||||
}
|
||||
|
||||
void NativeWindow::SetSheetOffset(const double offsetX, const double offsetY) {
|
||||
sheet_offset_x_ = offsetX;
|
||||
sheet_offset_y_ = offsetY;
|
||||
@@ -362,7 +403,8 @@ void NativeWindow::MoveTabToNewWindow() {
|
||||
void NativeWindow::ToggleTabBar() {
|
||||
}
|
||||
|
||||
void NativeWindow::AddTabbedWindow(NativeWindow* window) {
|
||||
bool NativeWindow::AddTabbedWindow(NativeWindow* window) {
|
||||
return true; // for non-Mac platforms
|
||||
}
|
||||
|
||||
void NativeWindow::SetVibrancy(const std::string& filename) {
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace gfx {
|
||||
class Point;
|
||||
class Rect;
|
||||
class Size;
|
||||
}
|
||||
} // namespace gfx
|
||||
|
||||
namespace mate {
|
||||
class Dictionary;
|
||||
@@ -109,6 +109,8 @@ class NativeWindow : public base::SupportsUserData,
|
||||
virtual gfx::Size GetMinimumSize() const;
|
||||
virtual void SetMaximumSize(const gfx::Size& size);
|
||||
virtual gfx::Size GetMaximumSize() const;
|
||||
virtual gfx::Size GetContentMinimumSize() const;
|
||||
virtual gfx::Size GetContentMaximumSize() const;
|
||||
virtual void SetSheetOffset(const double offsetX, const double offsetY);
|
||||
virtual double GetSheetOffsetX();
|
||||
virtual double GetSheetOffsetY();
|
||||
@@ -160,15 +162,14 @@ class NativeWindow : public base::SupportsUserData,
|
||||
|
||||
// Taskbar/Dock APIs.
|
||||
enum ProgressState {
|
||||
PROGRESS_NONE, // no progress, no marking
|
||||
PROGRESS_INDETERMINATE, // progress, indeterminate
|
||||
PROGRESS_ERROR, // progress, errored (red)
|
||||
PROGRESS_PAUSED, // progress, paused (yellow)
|
||||
PROGRESS_NORMAL, // progress, not marked (green)
|
||||
PROGRESS_NONE, // no progress, no marking
|
||||
PROGRESS_INDETERMINATE, // progress, indeterminate
|
||||
PROGRESS_ERROR, // progress, errored (red)
|
||||
PROGRESS_PAUSED, // progress, paused (yellow)
|
||||
PROGRESS_NORMAL, // progress, not marked (green)
|
||||
};
|
||||
|
||||
virtual void SetProgressBar(double progress,
|
||||
const ProgressState state) = 0;
|
||||
virtual void SetProgressBar(double progress, const ProgressState state) = 0;
|
||||
virtual void SetOverlayIcon(const gfx::Image& overlay,
|
||||
const std::string& description) = 0;
|
||||
|
||||
@@ -193,7 +194,7 @@ class NativeWindow : public base::SupportsUserData,
|
||||
virtual void MergeAllWindows();
|
||||
virtual void MoveTabToNewWindow();
|
||||
virtual void ToggleTabBar();
|
||||
virtual void AddTabbedWindow(NativeWindow* window);
|
||||
virtual bool AddTabbedWindow(NativeWindow* window);
|
||||
|
||||
// Webview APIs.
|
||||
virtual void FocusOnWebView();
|
||||
@@ -230,14 +231,15 @@ class NativeWindow : public base::SupportsUserData,
|
||||
virtual void HandleKeyboardEvent(
|
||||
content::WebContents*,
|
||||
const content::NativeWebKeyboardEvent& event) {}
|
||||
virtual void ShowAutofillPopup(
|
||||
content::RenderFrameHost* frame_host,
|
||||
content::WebContents* web_contents,
|
||||
const gfx::RectF& bounds,
|
||||
const std::vector<base::string16>& values,
|
||||
const std::vector<base::string16>& labels) {}
|
||||
virtual void ShowAutofillPopup(content::RenderFrameHost* frame_host,
|
||||
content::WebContents* web_contents,
|
||||
const gfx::RectF& bounds,
|
||||
const std::vector<base::string16>& values,
|
||||
const std::vector<base::string16>& labels) {}
|
||||
virtual void HideAutofillPopup(content::RenderFrameHost* frame_host) {}
|
||||
|
||||
virtual void UpdateDraggableRegionViews() {}
|
||||
|
||||
// Public API used by platform-dependent delegates and observers to send UI
|
||||
// related notifications.
|
||||
void NotifyWindowClosed();
|
||||
@@ -268,13 +270,11 @@ class NativeWindow : public base::SupportsUserData,
|
||||
const base::DictionaryValue& details);
|
||||
void NotifyNewWindowForTab();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#if defined(OS_WIN)
|
||||
void NotifyWindowMessage(UINT message, WPARAM w_param, LPARAM l_param);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void AddObserver(NativeWindowObserver* obs) {
|
||||
observers_.AddObserver(obs);
|
||||
}
|
||||
void AddObserver(NativeWindowObserver* obs) { observers_.AddObserver(obs); }
|
||||
void RemoveObserver(NativeWindowObserver* obs) {
|
||||
observers_.RemoveObserver(obs);
|
||||
}
|
||||
@@ -388,11 +388,11 @@ class NativeWindow : public base::SupportsUserData,
|
||||
};
|
||||
|
||||
// This class provides a hook to get a NativeWindow from a WebContents.
|
||||
class NativeWindowRelay :
|
||||
public content::WebContentsUserData<NativeWindowRelay> {
|
||||
class NativeWindowRelay
|
||||
: public content::WebContentsUserData<NativeWindowRelay> {
|
||||
public:
|
||||
explicit NativeWindowRelay(base::WeakPtr<NativeWindow> window)
|
||||
: key(UserDataKey()), window(window) {}
|
||||
: key(UserDataKey()), window(window) {}
|
||||
|
||||
static void* UserDataKey() {
|
||||
return content::WebContentsUserData<NativeWindowRelay>::UserDataKey();
|
||||
|
||||
@@ -111,7 +111,7 @@ class NativeWindowMac : public NativeWindow,
|
||||
void MergeAllWindows() override;
|
||||
void MoveTabToNewWindow() override;
|
||||
void ToggleTabBar() override;
|
||||
void AddTabbedWindow(NativeWindow* window) override;
|
||||
bool AddTabbedWindow(NativeWindow* window) override;
|
||||
|
||||
void SetVibrancy(const std::string& type) override;
|
||||
void SetTouchBar(
|
||||
@@ -127,7 +127,7 @@ class NativeWindowMac : public NativeWindow,
|
||||
content::RenderViewHost* new_host) override;
|
||||
|
||||
// Refresh the DraggableRegion views.
|
||||
void UpdateDraggableRegionViews() {
|
||||
void UpdateDraggableRegionViews() override {
|
||||
UpdateDraggableRegionViews(draggable_regions_);
|
||||
}
|
||||
|
||||
@@ -213,6 +213,7 @@ class NativeWindowMac : public NativeWindow,
|
||||
bool was_maximizable_;
|
||||
bool was_movable_;
|
||||
NSRect original_frame_;
|
||||
NSInteger original_level_;
|
||||
NSUInteger simple_fullscreen_mask_;
|
||||
|
||||
base::scoped_nsobject<NSColor> background_color_before_vibrancy_;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "skia/ext/skia_utils_mac.h"
|
||||
#include "third_party/skia/include/core/SkRegion.h"
|
||||
#include "ui/gfx/skia_util.h"
|
||||
#include "ui/gl/gpu_switching_manager.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -379,6 +380,7 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
|
||||
// Set window style to hide the toolbar, otherwise the toolbar will show in
|
||||
// fullscreen mode.
|
||||
[window setTitlebarAppearsTransparent:NO];
|
||||
shell_->SetStyleMask(true, NSFullSizeContentViewWindowMask);
|
||||
}
|
||||
}
|
||||
@@ -396,6 +398,7 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
// Turn off the style for toolbar.
|
||||
if (base::mac::IsAtLeastOS10_10() &&
|
||||
shell_->title_bar_style() == atom::NativeWindowMac::HIDDEN_INSET) {
|
||||
[window setTitlebarAppearsTransparent:YES];
|
||||
shell_->SetStyleMask(false, NSFullSizeContentViewWindowMask);
|
||||
}
|
||||
}
|
||||
@@ -727,10 +730,20 @@ enum {
|
||||
|
||||
// Custom window button methods
|
||||
|
||||
- (BOOL)windowShouldClose:(id)sender { return YES; }
|
||||
|
||||
- (void)performClose:(id)sender {
|
||||
if (shell_->title_bar_style() == atom::NativeWindowMac::CUSTOM_BUTTONS_ON_HOVER)
|
||||
if (shell_->title_bar_style() ==
|
||||
atom::NativeWindowMac::CUSTOM_BUTTONS_ON_HOVER) {
|
||||
[[self delegate] windowShouldClose:self];
|
||||
else
|
||||
} else if (shell_->IsSimpleFullScreen()) {
|
||||
if([[self delegate] respondsToSelector:@selector(windowShouldClose:)]) {
|
||||
if(![[self delegate] windowShouldClose:self]) return;
|
||||
} else if([self respondsToSelector:@selector(windowShouldClose:)]) {
|
||||
if(![self windowShouldClose:self]) return;
|
||||
}
|
||||
[self close];
|
||||
} else
|
||||
[super performClose:sender];
|
||||
}
|
||||
|
||||
@@ -1044,6 +1057,10 @@ NativeWindowMac::NativeWindowMac(
|
||||
|
||||
RegisterInputEventObserver(
|
||||
web_contents->GetWebContents()->GetRenderViewHost());
|
||||
|
||||
original_frame_ = [window_ frame];
|
||||
original_level_ = [window_ level];
|
||||
|
||||
}
|
||||
|
||||
NativeWindowMac::~NativeWindowMac() {
|
||||
@@ -1068,6 +1085,11 @@ void NativeWindowMac::Close() {
|
||||
}
|
||||
|
||||
void NativeWindowMac::CloseImmediately() {
|
||||
// Retain the child window before closing it. If the last reference to the
|
||||
// NSWindow goes away inside -[NSWindow close], then bad stuff can happen.
|
||||
// See e.g. http://crbug.com/616701.
|
||||
base::scoped_nsobject<NSWindow> child_window(window_,
|
||||
base::scoped_policy::RETAIN);
|
||||
[window_ close];
|
||||
}
|
||||
|
||||
@@ -1138,12 +1160,12 @@ bool NativeWindowMac::IsEnabled() {
|
||||
|
||||
void NativeWindowMac::SetEnabled(bool enable) {
|
||||
if (enable) {
|
||||
[window_ endSheet: [window_ attachedSheet]];
|
||||
} else {
|
||||
[window_ beginSheet: window_ completionHandler:^(NSModalResponse returnCode) {
|
||||
NSLog(@"modal enabled");
|
||||
return;
|
||||
}];
|
||||
} else {
|
||||
[window_ endSheet: [window_ attachedSheet]];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1410,8 +1432,9 @@ void NativeWindowMac::SetSimpleFullScreen(bool simple_fullscreen) {
|
||||
if (simple_fullscreen && !is_simple_fullscreen_) {
|
||||
is_simple_fullscreen_ = true;
|
||||
|
||||
// Take note of the current window size
|
||||
// Take note of the current window size and level
|
||||
original_frame_ = [window frame];
|
||||
original_level_ = [window level];
|
||||
|
||||
simple_fullscreen_options_ = [NSApp currentSystemPresentationOptions];
|
||||
simple_fullscreen_mask_ = [window styleMask];
|
||||
@@ -1427,6 +1450,13 @@ void NativeWindowMac::SetSimpleFullScreen(bool simple_fullscreen) {
|
||||
|
||||
NSRect fullscreenFrame = [window.screen frame];
|
||||
|
||||
// If our app has dock hidden, set the window level higher so another app's
|
||||
// menu bar doesn't appear on top of our fullscreen app.
|
||||
if ([[NSRunningApplication currentApplication] activationPolicy] !=
|
||||
NSApplicationActivationPolicyRegular) {
|
||||
window.level = NSPopUpMenuWindowLevel;
|
||||
}
|
||||
|
||||
if ( !fullscreen_window_title() ) {
|
||||
// Hide the titlebar
|
||||
SetStyleMask(false, NSTitledWindowMask);
|
||||
@@ -1461,6 +1491,7 @@ void NativeWindowMac::SetSimpleFullScreen(bool simple_fullscreen) {
|
||||
}
|
||||
|
||||
[window setFrame:original_frame_ display: YES animate: YES];
|
||||
window.level = original_level_;
|
||||
|
||||
[NSApp setPresentationOptions:simple_fullscreen_options_];
|
||||
|
||||
@@ -1677,10 +1708,14 @@ void NativeWindowMac::ToggleTabBar() {
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::AddTabbedWindow(NativeWindow* window) {
|
||||
if ([window_ respondsToSelector:@selector(addTabbedWindow:ordered:)]) {
|
||||
[window_ addTabbedWindow:window->GetNativeWindow() ordered:NSWindowAbove];
|
||||
bool NativeWindowMac::AddTabbedWindow(NativeWindow* window) {
|
||||
if (window_.get() == window->GetNativeWindow()) {
|
||||
return false;
|
||||
} else {
|
||||
if ([window_ respondsToSelector:@selector(addTabbedWindow:ordered:)])
|
||||
[window_ addTabbedWindow:window->GetNativeWindow() ordered:NSWindowAbove];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetRenderWidgetHostOpaque(bool opaque) {
|
||||
@@ -1712,6 +1747,7 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
|
||||
|
||||
[vibrant_view removeFromSuperview];
|
||||
[window_ setVibrantView:nil];
|
||||
ui::GpuSwitchingManager::SetTransparent(transparent());
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1719,9 +1755,12 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
|
||||
SetRenderWidgetHostOpaque(false);
|
||||
background_color_before_vibrancy_.reset([window_ backgroundColor]);
|
||||
transparency_before_vibrancy_ = [window_ titlebarAppearsTransparent];
|
||||
ui::GpuSwitchingManager::SetTransparent(true);
|
||||
|
||||
[window_ setTitlebarAppearsTransparent:YES];
|
||||
[window_ setBackgroundColor:[NSColor clearColor]];
|
||||
if (title_bar_style_ != NORMAL) {
|
||||
[window_ setTitlebarAppearsTransparent:YES];
|
||||
[window_ setBackgroundColor:[NSColor clearColor]];
|
||||
}
|
||||
|
||||
NSVisualEffectView* effect_view = (NSVisualEffectView*)vibrant_view;
|
||||
if (effect_view == nil) {
|
||||
@@ -1971,25 +2010,20 @@ void NativeWindowMac::UpdateDraggableRegionViews(
|
||||
|
||||
// Draggable regions is implemented by having the whole web view draggable
|
||||
// (mouseDownCanMoveWindow) and overlaying regions that are not draggable.
|
||||
std::vector<gfx::Rect> system_drag_exclude_areas =
|
||||
std::vector<gfx::Rect> drag_exclude_rects =
|
||||
CalculateNonDraggableRegions(regions, webViewWidth, webViewHeight);
|
||||
|
||||
if (browser_view_) {
|
||||
browser_view_->UpdateDraggableRegions(system_drag_exclude_areas);
|
||||
browser_view_->UpdateDraggableRegions(drag_exclude_rects);
|
||||
}
|
||||
|
||||
// Create and add a ControlRegionView for each region that needs to be
|
||||
// excluded from the dragging.
|
||||
for (std::vector<gfx::Rect>::const_iterator iter =
|
||||
system_drag_exclude_areas.begin();
|
||||
iter != system_drag_exclude_areas.end();
|
||||
++iter) {
|
||||
for (const auto& rect : drag_exclude_rects) {
|
||||
base::scoped_nsobject<NSView> controlRegion(
|
||||
[[ControlRegionView alloc] initWithFrame:NSZeroRect]);
|
||||
[controlRegion setFrame:NSMakeRect(iter->x(),
|
||||
webViewHeight - iter->bottom(),
|
||||
iter->width(),
|
||||
iter->height())];
|
||||
[controlRegion setFrame:NSMakeRect(rect.x(), webViewHeight - rect.bottom(),
|
||||
rect.width(), rect.height())];
|
||||
[webView addSubview:controlRegion];
|
||||
}
|
||||
|
||||
|
||||
@@ -608,6 +608,7 @@ void NativeWindowViews::SetResizable(bool resizable) {
|
||||
// both the minimum and maximum size to the window size to achieve it.
|
||||
if (resizable) {
|
||||
SetContentSizeConstraints(old_size_constraints_);
|
||||
SetMaximizable(maximizable_);
|
||||
} else {
|
||||
old_size_constraints_ = GetContentSizeConstraints();
|
||||
resizable_ = false;
|
||||
@@ -1139,6 +1140,8 @@ void NativeWindowViews::OnWidgetActivationChanged(
|
||||
// Hide menu bar when window is blured.
|
||||
if (!active && menu_bar_autohide_ && menu_bar_visible_)
|
||||
SetMenuBarVisibility(false);
|
||||
|
||||
menu_bar_alt_pressed_ = false;
|
||||
}
|
||||
|
||||
void NativeWindowViews::OnWidgetBoundsChanged(
|
||||
@@ -1336,7 +1339,7 @@ void NativeWindowViews::HandleKeyboardEvent(
|
||||
if (event.GetType() == blink::WebInputEvent::kRawKeyDown &&
|
||||
!IsAltKey(event) && IsAltModifier(event)) {
|
||||
if (!menu_bar_visible_ &&
|
||||
(menu_bar_->GetAcceleratorIndex(event.windows_key_code) != -1))
|
||||
(menu_bar_->HasAccelerator(event.windows_key_code)))
|
||||
SetMenuBarVisibility(true);
|
||||
menu_bar_->ActivateAccelerator(event.windows_key_code);
|
||||
return;
|
||||
@@ -1444,12 +1447,9 @@ void NativeWindowViews::RegisterAccelerators(AtomMenuModel* menu_model) {
|
||||
|
||||
// Register accelerators with focus manager.
|
||||
accelerator_util::GenerateAcceleratorTable(&accelerator_table_, menu_model);
|
||||
accelerator_util::AcceleratorTable::const_iterator iter;
|
||||
for (iter = accelerator_table_.begin();
|
||||
iter != accelerator_table_.end();
|
||||
++iter) {
|
||||
for (const auto& iter : accelerator_table_) {
|
||||
focus_manager->RegisterAccelerator(
|
||||
iter->first, ui::AcceleratorManager::kNormalPriority, this);
|
||||
iter.first, ui::AcceleratorManager::kNormalPriority, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -241,10 +241,21 @@ void URLRequestAsarJob::FetchMetaInfo(const base::FilePath& file_path,
|
||||
meta_info->is_directory = file_info.is_directory;
|
||||
}
|
||||
}
|
||||
// On Windows GetMimeTypeFromFile() goes to the registry. Thus it should be
|
||||
// done in WorkerPool.
|
||||
meta_info->mime_type_result =
|
||||
net::GetMimeTypeFromFile(file_path, &meta_info->mime_type);
|
||||
|
||||
// We use GetWellKnownMimeTypeFromExtension() to ensure that configurations
|
||||
// that may have been set by other programs on a user's machine don't affect
|
||||
// the mime type returned (in particular, JS should always be
|
||||
// (application/javascript). See https://crbug.com/797712. Using an accurate
|
||||
// mime type is necessary at least for modules and sw, which enforce strict
|
||||
// mime type requirements.
|
||||
// TODO(deepak1556): Revert this when sw support is removed for file scheme.
|
||||
base::FilePath::StringType file_extension = file_path.Extension();
|
||||
if (file_extension.empty()) {
|
||||
meta_info->mime_type_result = false;
|
||||
} else {
|
||||
meta_info->mime_type_result = net::GetWellKnownMimeTypeFromExtension(
|
||||
file_extension.substr(1), &meta_info->mime_type);
|
||||
}
|
||||
}
|
||||
|
||||
void URLRequestAsarJob::DidFetchMetaInfo(const FileMetaInfo* meta_info) {
|
||||
|
||||
@@ -227,22 +227,22 @@ AtomNetworkDelegate::~AtomNetworkDelegate() {
|
||||
|
||||
void AtomNetworkDelegate::SetSimpleListenerInIO(
|
||||
SimpleEvent type,
|
||||
const URLPatterns& patterns,
|
||||
const SimpleListener& callback) {
|
||||
URLPatterns patterns,
|
||||
SimpleListener callback) {
|
||||
if (callback.is_null())
|
||||
simple_listeners_.erase(type);
|
||||
else
|
||||
simple_listeners_[type] = { patterns, callback };
|
||||
simple_listeners_[type] = { std::move(patterns), std::move(callback) };
|
||||
}
|
||||
|
||||
void AtomNetworkDelegate::SetResponseListenerInIO(
|
||||
ResponseEvent type,
|
||||
const URLPatterns& patterns,
|
||||
const ResponseListener& callback) {
|
||||
URLPatterns patterns,
|
||||
ResponseListener callback) {
|
||||
if (callback.is_null())
|
||||
response_listeners_.erase(type);
|
||||
else
|
||||
response_listeners_[type] = { patterns, callback };
|
||||
response_listeners_[type] = { std::move(patterns), std::move(callback) };
|
||||
}
|
||||
|
||||
void AtomNetworkDelegate::SetDevToolsNetworkEmulationClientId(
|
||||
|
||||
@@ -62,11 +62,11 @@ class AtomNetworkDelegate : public brightray::NetworkDelegate {
|
||||
~AtomNetworkDelegate() override;
|
||||
|
||||
void SetSimpleListenerInIO(SimpleEvent type,
|
||||
const URLPatterns& patterns,
|
||||
const SimpleListener& callback);
|
||||
URLPatterns patterns,
|
||||
SimpleListener callback);
|
||||
void SetResponseListenerInIO(ResponseEvent type,
|
||||
const URLPatterns& patterns,
|
||||
const ResponseListener& callback);
|
||||
URLPatterns patterns,
|
||||
ResponseListener callback);
|
||||
|
||||
void SetDevToolsNetworkEmulationClientId(const std::string& client_id);
|
||||
|
||||
|
||||
85
atom/browser/net/resolve_proxy_helper.cc
Normal file
85
atom/browser/net/resolve_proxy_helper.cc
Normal file
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/net/resolve_proxy_helper.h"
|
||||
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
ResolveProxyHelper::ResolveProxyHelper(net::URLRequestContextGetter* getter)
|
||||
: context_getter_(getter),
|
||||
original_thread_(base::ThreadTaskRunnerHandle::Get()) {}
|
||||
|
||||
ResolveProxyHelper::~ResolveProxyHelper() {
|
||||
// Clear all pending requests if the ProxyService is still alive.
|
||||
pending_requests_.clear();
|
||||
}
|
||||
|
||||
void ResolveProxyHelper::ResolveProxy(const GURL& url,
|
||||
const ResolveProxyCallback& callback) {
|
||||
// Enqueue the pending request.
|
||||
pending_requests_.push_back(PendingRequest(url, callback));
|
||||
|
||||
// If nothing is in progress, start.
|
||||
if (pending_requests_.size() == 1)
|
||||
StartPendingRequest();
|
||||
}
|
||||
|
||||
void ResolveProxyHelper::SendProxyResult(const std::string& proxy) {
|
||||
CHECK(!pending_requests_.empty());
|
||||
|
||||
const auto& completed_request = pending_requests_.front();
|
||||
if (!completed_request.callback.is_null())
|
||||
completed_request.callback.Run(proxy);
|
||||
|
||||
// Clear the current (completed) request.
|
||||
pending_requests_.pop_front();
|
||||
|
||||
// Start the next request.
|
||||
if (!pending_requests_.empty())
|
||||
StartPendingRequest();
|
||||
}
|
||||
|
||||
void ResolveProxyHelper::StartPendingRequest() {
|
||||
auto& request = pending_requests_.front();
|
||||
context_getter_->GetNetworkTaskRunner()->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(&ResolveProxyHelper::StartPendingRequestInIO,
|
||||
base::Unretained(this), request.url, request.pac_req));
|
||||
}
|
||||
|
||||
void ResolveProxyHelper::OnResolveProxyCompleted(int result) {
|
||||
std::string proxy;
|
||||
if (result == net::OK)
|
||||
proxy = proxy_info_.ToPacString();
|
||||
|
||||
original_thread_->PostTask(
|
||||
FROM_HERE, base::BindOnce(&ResolveProxyHelper::SendProxyResult,
|
||||
base::Unretained(this), proxy));
|
||||
}
|
||||
|
||||
void ResolveProxyHelper::StartPendingRequestInIO(
|
||||
const GURL& url,
|
||||
net::ProxyService::PacRequest* pac_req) {
|
||||
// Verify the request wasn't started yet.
|
||||
DCHECK(nullptr == pac_req);
|
||||
|
||||
auto proxy_service = context_getter_->GetURLRequestContext()->proxy_service();
|
||||
|
||||
// Start the request.
|
||||
int result = proxy_service->ResolveProxy(
|
||||
url, std::string(), &proxy_info_,
|
||||
base::Bind(&ResolveProxyHelper::OnResolveProxyCompleted,
|
||||
base::Unretained(this)),
|
||||
&pac_req, nullptr, net::NetLogWithSource());
|
||||
|
||||
// Completed synchronously.
|
||||
if (result != net::ERR_IO_PENDING)
|
||||
OnResolveProxyCompleted(result);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
59
atom/browser/net/resolve_proxy_helper.h
Normal file
59
atom/browser/net/resolve_proxy_helper.h
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_
|
||||
#define ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_
|
||||
|
||||
#include <deque>
|
||||
#include <string>
|
||||
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "net/proxy/proxy_service.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace net {
|
||||
class URLRequestContextGetter;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class ResolveProxyHelper
|
||||
: public base::RefCountedThreadSafe<ResolveProxyHelper> {
|
||||
public:
|
||||
using ResolveProxyCallback = base::Callback<void(std::string)>;
|
||||
explicit ResolveProxyHelper(net::URLRequestContextGetter* getter);
|
||||
|
||||
void ResolveProxy(const GURL& url, const ResolveProxyCallback& callback);
|
||||
|
||||
private:
|
||||
friend class base::RefCountedThreadSafe<ResolveProxyHelper>;
|
||||
struct PendingRequest {
|
||||
public:
|
||||
PendingRequest(const GURL& url, const ResolveProxyCallback& callback)
|
||||
: url(url), callback(callback), pac_req(nullptr) {}
|
||||
|
||||
GURL url;
|
||||
ResolveProxyCallback callback;
|
||||
net::ProxyService::PacRequest* pac_req;
|
||||
};
|
||||
|
||||
~ResolveProxyHelper();
|
||||
|
||||
void StartPendingRequest();
|
||||
void StartPendingRequestInIO(const GURL& request,
|
||||
net::ProxyService::PacRequest* pac_req);
|
||||
void SendProxyResult(const std::string& proxy);
|
||||
void OnResolveProxyCompleted(int result);
|
||||
|
||||
net::ProxyInfo proxy_info_;
|
||||
std::deque<PendingRequest> pending_requests_;
|
||||
scoped_refptr<net::URLRequestContextGetter> context_getter_;
|
||||
scoped_refptr<base::SingleThreadTaskRunner> original_thread_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "atom/browser/node_debugger.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "libplatform/libplatform.h"
|
||||
@@ -28,10 +30,15 @@ void NodeDebugger::Start(node::NodePlatform* platform) {
|
||||
node::DebugOptions options;
|
||||
for (auto& arg : base::CommandLine::ForCurrentProcess()->argv()) {
|
||||
#if defined(OS_WIN)
|
||||
options.ParseOption("Electron", base::UTF16ToUTF8(arg));
|
||||
const std::string nice_arg = base::UTF16ToUTF8(arg);
|
||||
#else
|
||||
options.ParseOption("Electron", arg);
|
||||
const std::string& nice_arg = arg;
|
||||
#endif
|
||||
// Stop handling arguments after a "--" to be consistent with Chromium
|
||||
if (nice_arg == "--")
|
||||
break;
|
||||
|
||||
options.ParseOption("Electron", nice_arg);
|
||||
}
|
||||
|
||||
if (options.inspector_enabled()) {
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>electron.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.8.2</string>
|
||||
<string>2.0.14</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.8.2</string>
|
||||
<string>2.0.14</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@@ -56,8 +56,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,8,2,2
|
||||
PRODUCTVERSION 1,8,2,2
|
||||
FILEVERSION 2,0,14,0
|
||||
PRODUCTVERSION 2,0,14,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -74,12 +74,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "1.8.2"
|
||||
VALUE "FileVersion", "2.0.14"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "1.8.2"
|
||||
VALUE "ProductVersion", "2.0.14"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -91,7 +91,9 @@ bool TriggerAcceleratorTableCommand(AcceleratorTable* table,
|
||||
if (base::ContainsKey(*table, accelerator)) {
|
||||
const accelerator_util::MenuItem& item = (*table)[accelerator];
|
||||
if (item.model->IsEnabledAt(item.position)) {
|
||||
item.model->ActivatedAt(item.position);
|
||||
const auto event_flags =
|
||||
accelerator.MaskOutKeyEventFlags(accelerator.modifiers());
|
||||
item.model->ActivatedAt(item.position, event_flags);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,12 +9,15 @@
|
||||
#include "base/logging.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "ui/base/accelerators/accelerator.h"
|
||||
#include "ui/base/accelerators/platform_accelerator_cocoa.h"
|
||||
#include "ui/base/l10n/l10n_util_mac.h"
|
||||
#include "ui/events/cocoa/cocoa_event_utils.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace {
|
||||
|
||||
struct Role {
|
||||
@@ -120,7 +123,9 @@ static base::scoped_nsobject<NSMenu> recentDocumentsMenuSwap_;
|
||||
[menu_ cancelTracking];
|
||||
isMenuOpen_ = NO;
|
||||
model_->MenuWillClose();
|
||||
closeCallback.Run();
|
||||
if (!closeCallback.is_null()) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, closeCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,7 +340,11 @@ static base::scoped_nsobject<NSMenu> recentDocumentsMenuSwap_;
|
||||
if (isMenuOpen_) {
|
||||
isMenuOpen_ = NO;
|
||||
model_->MenuWillClose();
|
||||
closeCallback.Run();
|
||||
// Post async task so that itemSelected runs before the close callback
|
||||
// deletes the controller from the map which deallocates it
|
||||
if (!closeCallback.is_null()) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, closeCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,72 +15,99 @@
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
|
||||
@interface PopUpButtonHandler : NSObject
|
||||
@property (nonatomic, strong) NSSavePanel *savePanel;
|
||||
@property (nonatomic, strong) NSArray *fileTypes;
|
||||
- (instancetype)initWithPanel:(NSSavePanel *)panel andTypes:(NSArray *)types;
|
||||
|
||||
@property(nonatomic, assign) NSSavePanel* savePanel;
|
||||
@property(nonatomic, strong) NSArray* fileTypesList;
|
||||
|
||||
- (instancetype)initWithPanel:(NSSavePanel*)panel
|
||||
andTypesList:(NSArray*)typesList;
|
||||
- (void)selectFormat:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
@implementation PopUpButtonHandler
|
||||
- (instancetype)initWithPanel:(NSSavePanel *)panel andTypes:(NSArray *)types {
|
||||
|
||||
- (instancetype)initWithPanel:(NSSavePanel*)panel
|
||||
andTypesList:(NSArray*)typesList {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_savePanel = panel;
|
||||
_fileTypes = types;
|
||||
[self setSavePanel:panel];
|
||||
[self setFileTypesList:typesList];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)selectFormat:(id)sender {
|
||||
NSPopUpButton *button = (NSPopUpButton *)sender;
|
||||
NSPopUpButton* button = (NSPopUpButton*)sender;
|
||||
NSInteger selectedItemIndex = [button indexOfSelectedItem];
|
||||
NSString *nameFieldString = [[self savePanel] nameFieldStringValue];
|
||||
NSString *trimmedNameFieldString = [nameFieldString stringByDeletingPathExtension];
|
||||
NSString *extension = [[self fileTypes] objectAtIndex: selectedItemIndex];
|
||||
NSArray* list = [self fileTypesList];
|
||||
NSArray* fileTypes = [list objectAtIndex:selectedItemIndex];
|
||||
|
||||
NSString *nameFieldStringWithExt = [NSString stringWithFormat:@"%@.%@", trimmedNameFieldString, extension];
|
||||
[[self savePanel] setNameFieldStringValue:nameFieldStringWithExt];
|
||||
[[self savePanel] setAllowedFileTypes:@[extension]];
|
||||
// If we meet a '*' file extension, we allow all the file types and no
|
||||
// need to set the specified file types.
|
||||
if ([fileTypes count] == 0 || [fileTypes containsObject:@"*"])
|
||||
[[self savePanel] setAllowedFileTypes:nil];
|
||||
else
|
||||
[[self savePanel] setAllowedFileTypes:fileTypes];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// Manages the PopUpButtonHandler.
|
||||
@interface AtomAccessoryView : NSView
|
||||
@end
|
||||
|
||||
@implementation AtomAccessoryView
|
||||
|
||||
- (void)dealloc {
|
||||
auto* popupButton = static_cast<NSPopUpButton*>([[self subviews] objectAtIndex: 1]);
|
||||
[[popupButton target] release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace file_dialog {
|
||||
|
||||
namespace {
|
||||
|
||||
static PopUpButtonHandler *popUpButtonHandler;
|
||||
|
||||
void SetAllowedFileTypes(NSSavePanel* dialog, const Filters& filters) {
|
||||
NSMutableSet* file_type_set = [NSMutableSet set];
|
||||
for (size_t i = 0; i < filters.size(); ++i) {
|
||||
const Filter& filter = filters[i];
|
||||
for (size_t j = 0; j < filter.second.size(); ++j) {
|
||||
// If we meet a '*' file extension, we allow all the file types and no
|
||||
// need to set the specified file types.
|
||||
NSMutableArray* file_types_list = [NSMutableArray array];
|
||||
NSMutableArray* filter_names = [NSMutableArray array];
|
||||
|
||||
if (filter.second[j] == "*") {
|
||||
[dialog setAllowsOtherFileTypes:YES];
|
||||
return;
|
||||
}
|
||||
base::ScopedCFTypeRef<CFStringRef> ext_cf(
|
||||
base::SysUTF8ToCFStringRef(filter.second[j]));
|
||||
// Create array to keep file types and their name.
|
||||
for (const Filter& filter : filters) {
|
||||
NSMutableSet* file_type_set = [NSMutableSet set];
|
||||
base::ScopedCFTypeRef<CFStringRef> name_cf(
|
||||
base::SysUTF8ToCFStringRef(filter.first));
|
||||
[filter_names addObject:base::mac::CFToNSCast(name_cf.get())];
|
||||
for (const std::string& ext : filter.second) {
|
||||
base::ScopedCFTypeRef<CFStringRef> ext_cf(base::SysUTF8ToCFStringRef(ext));
|
||||
[file_type_set addObject:base::mac::CFToNSCast(ext_cf.get())];
|
||||
}
|
||||
[file_types_list addObject:[file_type_set allObjects]];
|
||||
}
|
||||
|
||||
// Passing empty array to setAllowedFileTypes will cause exception.
|
||||
NSArray* file_types = nil;
|
||||
if ([file_type_set count])
|
||||
file_types = [file_type_set allObjects];
|
||||
|
||||
NSUInteger count = [file_types_list count];
|
||||
if (count > 0) {
|
||||
file_types = [[file_types_list objectAtIndex:0] allObjects];
|
||||
// If we meet a '*' file extension, we allow all the file types and no
|
||||
// need to set the specified file types.
|
||||
if ([file_types count] == 0 || [file_types containsObject:@"*"])
|
||||
file_types = nil;
|
||||
}
|
||||
[dialog setAllowedFileTypes:file_types];
|
||||
|
||||
if (!popUpButtonHandler)
|
||||
popUpButtonHandler = [[PopUpButtonHandler alloc] initWithPanel:dialog andTypes:file_types];
|
||||
if (count <= 1)
|
||||
return; // don't add file format picker
|
||||
|
||||
// add file format picker
|
||||
NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)];
|
||||
NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)];
|
||||
// Add file format picker.
|
||||
AtomAccessoryView* accessoryView =
|
||||
[[AtomAccessoryView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)];
|
||||
NSTextField* label =
|
||||
[[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)];
|
||||
|
||||
[label setEditable:NO];
|
||||
[label setStringValue:@"Format:"];
|
||||
@@ -88,15 +115,18 @@ void SetAllowedFileTypes(NSSavePanel* dialog, const Filters& filters) {
|
||||
[label setBezeled:NO];
|
||||
[label setDrawsBackground:NO];
|
||||
|
||||
NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO];
|
||||
[popupButton addItemsWithTitles:file_types];
|
||||
NSPopUpButton* popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0)
|
||||
pullsDown:NO];
|
||||
PopUpButtonHandler* popUpButtonHandler = [[PopUpButtonHandler alloc] initWithPanel:dialog
|
||||
andTypesList:file_types_list];
|
||||
[popupButton addItemsWithTitles:filter_names];
|
||||
[popupButton setTarget:popUpButtonHandler];
|
||||
[popupButton setAction:@selector(selectFormat:)];
|
||||
|
||||
[accessoryView addSubview:label];
|
||||
[accessoryView addSubview:popupButton];
|
||||
[accessoryView addSubview:[label autorelease]];
|
||||
[accessoryView addSubview:[popupButton autorelease]];
|
||||
|
||||
[dialog setAccessoryView:accessoryView];
|
||||
[dialog setAccessoryView:[accessoryView autorelease]];
|
||||
}
|
||||
|
||||
void SetupDialog(NSSavePanel* dialog,
|
||||
@@ -118,6 +148,7 @@ void SetupDialog(NSSavePanel* dialog,
|
||||
NSString* default_dir = nil;
|
||||
NSString* default_filename = nil;
|
||||
if (!settings.default_path.empty()) {
|
||||
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
||||
if (base::DirectoryExists(settings.default_path)) {
|
||||
default_dir = base::SysUTF8ToNSString(settings.default_path.value());
|
||||
} else {
|
||||
@@ -283,8 +314,9 @@ void ShowOpenDialog(const DialogSettings& settings,
|
||||
|
||||
if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
|
||||
settings.force_detached) {
|
||||
int chosen = [dialog runModal];
|
||||
OpenDialogCompletion(chosen, dialog, settings, callback);
|
||||
[dialog beginWithCompletionHandler:^(NSInteger chosen) {
|
||||
OpenDialogCompletion(chosen, dialog, settings, callback);
|
||||
}];
|
||||
} else {
|
||||
NSWindow* window = settings.parent_window->GetNativeWindow();
|
||||
[dialog beginSheetModalForWindow:window
|
||||
@@ -343,8 +375,9 @@ void ShowSaveDialog(const DialogSettings& settings,
|
||||
|
||||
if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
|
||||
settings.force_detached) {
|
||||
int chosen = [dialog runModal];
|
||||
SaveDialogCompletion(chosen, dialog, settings, callback);
|
||||
[dialog beginWithCompletionHandler:^(NSInteger chosen) {
|
||||
SaveDialogCompletion(chosen, dialog, settings, callback);
|
||||
}];
|
||||
} else {
|
||||
NSWindow* window = settings.parent_window->GetNativeWindow();
|
||||
[dialog beginSheetModalForWindow:window
|
||||
|
||||
@@ -39,7 +39,8 @@ class GtkMessageBox : public NativeWindowObserver {
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool checkbox_checked)
|
||||
bool checkbox_checked,
|
||||
const gfx::ImageSkia& icon)
|
||||
: cancel_id_(cancel_id),
|
||||
checkbox_checked_(false),
|
||||
parent_(static_cast<NativeWindow*>(parent_window)) {
|
||||
@@ -56,6 +57,21 @@ class GtkMessageBox : public NativeWindowObserver {
|
||||
if (!title.empty())
|
||||
gtk_window_set_title(GTK_WINDOW(dialog_), title.c_str());
|
||||
|
||||
if (!icon.isNull()) {
|
||||
// No easy way to obtain this programmatically, but GTK+'s docs
|
||||
// define GTK_ICON_SIZE_DIALOG to be 48 pixels
|
||||
static constexpr int pixel_width = 48;
|
||||
static constexpr int pixel_height = 48;
|
||||
GdkPixbuf* pixbuf = libgtkui::GdkPixbufFromSkBitmap(*icon.bitmap());
|
||||
GdkPixbuf* scaled_pixbuf = gdk_pixbuf_scale_simple(
|
||||
pixbuf, pixel_width, pixel_height, GDK_INTERP_BILINEAR);
|
||||
GtkWidget* w = gtk_image_new_from_pixbuf(scaled_pixbuf);
|
||||
gtk_message_dialog_set_image(GTK_MESSAGE_DIALOG(dialog_), w);
|
||||
gtk_widget_show(w);
|
||||
g_clear_pointer(&scaled_pixbuf, gdk_pixbuf_unref);
|
||||
g_clear_pointer(&pixbuf, gdk_pixbuf_unref);
|
||||
}
|
||||
|
||||
if (!checkbox_label.empty()) {
|
||||
GtkWidget* message_area =
|
||||
gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(dialog_));
|
||||
@@ -66,15 +82,15 @@ class GtkMessageBox : public NativeWindowObserver {
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_button),
|
||||
checkbox_checked);
|
||||
gtk_container_add(GTK_CONTAINER(message_area), check_button);
|
||||
gtk_widget_show(check_button);
|
||||
}
|
||||
|
||||
// Add buttons.
|
||||
GtkDialog* dialog = GTK_DIALOG(dialog_);
|
||||
for (size_t i = 0; i < buttons.size(); ++i) {
|
||||
GtkWidget* button = gtk_dialog_add_button(
|
||||
GTK_DIALOG(dialog_), TranslateToStock(i, buttons[i]), i);
|
||||
if (static_cast<int>(i) == default_id)
|
||||
gtk_widget_grab_focus(button);
|
||||
gtk_dialog_add_button(dialog, TranslateToStock(i, buttons[i]), i);
|
||||
}
|
||||
gtk_dialog_set_default_response(dialog, default_id);
|
||||
|
||||
// Parent window.
|
||||
if (parent_) {
|
||||
@@ -122,7 +138,7 @@ class GtkMessageBox : public NativeWindowObserver {
|
||||
}
|
||||
|
||||
void Show() {
|
||||
gtk_widget_show_all(dialog_);
|
||||
gtk_widget_show(dialog_);
|
||||
// We need to call gtk_window_present after making the widgets visible to
|
||||
// make sure window gets correctly raised and gets focus.
|
||||
int time = ui::X11EventSource::GetInstance()->GetTimestamp();
|
||||
@@ -195,9 +211,9 @@ int ShowMessageBox(NativeWindow* parent,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const gfx::ImageSkia& /*icon*/) {
|
||||
const gfx::ImageSkia& icon) {
|
||||
return GtkMessageBox(parent, type, buttons, default_id, cancel_id, title,
|
||||
message, detail, "", false)
|
||||
message, detail, "", false, icon)
|
||||
.RunSynchronous();
|
||||
}
|
||||
|
||||
@@ -212,10 +228,10 @@ void ShowMessageBox(NativeWindow* parent,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool checkbox_checked,
|
||||
const gfx::ImageSkia& /*icon*/,
|
||||
const gfx::ImageSkia& icon,
|
||||
const MessageBoxCallback& callback) {
|
||||
(new GtkMessageBox(parent, type, buttons, default_id, cancel_id, title,
|
||||
message, detail, checkbox_label, checkbox_checked))
|
||||
message, detail, checkbox_label, checkbox_checked, icon))
|
||||
->RunAsynchronous(callback);
|
||||
}
|
||||
|
||||
@@ -223,7 +239,8 @@ 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(),
|
||||
base::UTF16ToUTF8(content).c_str(), "", false)
|
||||
base::UTF16ToUTF8(content).c_str(), "", false,
|
||||
gfx::ImageSkia())
|
||||
.RunSynchronous();
|
||||
} else {
|
||||
fprintf(stderr, ANSI_TEXT_BOLD ANSI_BACKGROUND_GRAY ANSI_FOREGROUND_RED
|
||||
|
||||
@@ -96,11 +96,6 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window,
|
||||
NSArray* ns_buttons = [alert buttons];
|
||||
int button_count = static_cast<int>([ns_buttons count]);
|
||||
|
||||
// Bind cancel id button to escape key if there is more than one button
|
||||
if (button_count > 1 && cancel_id >= 0 && cancel_id < button_count) {
|
||||
[[ns_buttons objectAtIndex:cancel_id] setKeyEquivalent:@"\e"];
|
||||
}
|
||||
|
||||
if (default_id >= 0 && default_id < button_count) {
|
||||
// Focus the button at default_id if the user opted to do so.
|
||||
// The first button added gets set as the default selected.
|
||||
@@ -109,6 +104,11 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window,
|
||||
[[ns_buttons objectAtIndex:default_id] setKeyEquivalent:@"\r"];
|
||||
}
|
||||
|
||||
// Bind cancel id button to escape key if there is more than one button
|
||||
if (button_count > 1 && cancel_id >= 0 && cancel_id < button_count) {
|
||||
[[ns_buttons objectAtIndex:cancel_id] setKeyEquivalent:@"\e"];
|
||||
}
|
||||
|
||||
if (!checkbox_label.empty()) {
|
||||
alert.showsSuppressionButton = YES;
|
||||
alert.suppressionButton.title = base::SysUTF8ToNSString(checkbox_label);
|
||||
|
||||
@@ -40,9 +40,16 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
|
||||
@implementation StatusItemView
|
||||
|
||||
- (void)dealloc {
|
||||
trayIcon_ = nil;
|
||||
menuController_ = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)initWithImage:(NSImage*)image icon:(atom::TrayIconCocoa*)icon {
|
||||
image_.reset([image copy]);
|
||||
trayIcon_ = icon;
|
||||
menuController_ = nil;
|
||||
highlight_mode_ = atom::TrayIcon::HighlightMode::SELECTION;
|
||||
forceHighlight_ = NO;
|
||||
inMouseEventSequence_ = NO;
|
||||
@@ -85,6 +92,7 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
trackingArea_.reset();
|
||||
}
|
||||
[[NSStatusBar systemStatusBar] removeStatusItem:statusItem_];
|
||||
[statusItem_ setView:nil];
|
||||
statusItem_.reset();
|
||||
}
|
||||
|
||||
@@ -98,7 +106,7 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
|
||||
// Draw the system bar background.
|
||||
[statusItem_ drawStatusBarBackgroundInRect:self.bounds
|
||||
withHighlight:[self isHighlighted]];
|
||||
withHighlight:[self shouldHighlight]];
|
||||
|
||||
// Determine which image to use.
|
||||
NSImage* image = image_.get();
|
||||
@@ -230,8 +238,13 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
// check title_ being nil
|
||||
NSString *title = @"";
|
||||
if (title_)
|
||||
title = title_;
|
||||
|
||||
attributedTitle_.reset([[NSMutableAttributedString alloc]
|
||||
initWithString:title_
|
||||
initWithString:title
|
||||
attributes:attributes]);
|
||||
|
||||
//NSFontAttributeName:[NSFont menuBarFontOfSize:0],
|
||||
@@ -384,6 +397,11 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)setNeedsDisplay:(BOOL)display {
|
||||
[self updateAttributedTitle];
|
||||
[super setNeedsDisplay:display];
|
||||
}
|
||||
|
||||
- (BOOL)shouldHighlight {
|
||||
switch (highlight_mode_) {
|
||||
case atom::TrayIcon::HighlightMode::ALWAYS:
|
||||
@@ -444,11 +462,18 @@ void TrayIconCocoa::SetContextMenu(AtomMenuModel* menu_model) {
|
||||
// Substribe to MenuClosed event.
|
||||
if (menu_model_)
|
||||
menu_model_->RemoveObserver(this);
|
||||
menu_model->AddObserver(this);
|
||||
|
||||
// Create native menu.
|
||||
menu_.reset([[AtomMenuController alloc] initWithModel:menu_model
|
||||
useDefaultAccelerator:NO]);
|
||||
menu_model_ = menu_model;
|
||||
|
||||
if (menu_model) {
|
||||
menu_model->AddObserver(this);
|
||||
// Create native menu.
|
||||
menu_.reset([[AtomMenuController alloc] initWithModel:menu_model
|
||||
useDefaultAccelerator:NO]);
|
||||
} else {
|
||||
menu_.reset();
|
||||
}
|
||||
|
||||
[status_item_view_ setMenuController:menu_.get()];
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "atom/browser/browser.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "brightray/common/application_info.h"
|
||||
#include "chrome/browser/ui/libgtkui/app_indicator_icon.h"
|
||||
#include "chrome/browser/ui/libgtkui/gtk_status_icon.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
@@ -32,16 +33,17 @@ void TrayIconGtk::SetImage(const gfx::Image& image) {
|
||||
return;
|
||||
}
|
||||
|
||||
base::string16 empty;
|
||||
const auto toolTip = base::UTF8ToUTF16(brightray::GetApplicationName());
|
||||
|
||||
if (libgtkui::AppIndicatorIcon::CouldOpen()) {
|
||||
++indicators_count;
|
||||
icon_.reset(new libgtkui::AppIndicatorIcon(
|
||||
base::StringPrintf(
|
||||
"%s%d", Browser::Get()->GetName().c_str(), indicators_count),
|
||||
image.AsImageSkia(),
|
||||
empty));
|
||||
toolTip));
|
||||
} else {
|
||||
icon_.reset(new libgtkui::Gtk2StatusIcon(image.AsImageSkia(), empty));
|
||||
icon_.reset(new libgtkui::Gtk2StatusIcon(image.AsImageSkia(), toolTip));
|
||||
}
|
||||
icon_->set_delegate(this);
|
||||
}
|
||||
|
||||
@@ -104,11 +104,11 @@ gfx::Size FramelessView::CalculatePreferredSize() const {
|
||||
}
|
||||
|
||||
gfx::Size FramelessView::GetMinimumSize() const {
|
||||
return window_->GetContentSizeConstraints().GetMinimumSize();
|
||||
return window_->GetContentMinimumSize();
|
||||
}
|
||||
|
||||
gfx::Size FramelessView::GetMaximumSize() const {
|
||||
return window_->GetContentSizeConstraints().GetMaximumSize();
|
||||
return window_->GetContentMaximumSize();
|
||||
}
|
||||
|
||||
const char* FramelessView::GetClassName() const {
|
||||
|
||||
@@ -209,7 +209,9 @@ void GlobalMenuBarX11::SetMenu(AtomMenuModel* menu_model) {
|
||||
DbusmenuMenuitem* root_item = menuitem_new();
|
||||
menuitem_property_set(root_item, kPropertyLabel, "Root");
|
||||
menuitem_property_set_bool(root_item, kPropertyVisible, true);
|
||||
BuildMenuFromModel(menu_model, root_item);
|
||||
if (menu_model != nullptr) {
|
||||
BuildMenuFromModel(menu_model, root_item);
|
||||
}
|
||||
|
||||
server_set_root(server_, root_item);
|
||||
g_object_unref(root_item);
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
|
||||
#include "atom/browser/ui/views/menu_bar.h"
|
||||
|
||||
#if defined(USE_X11)
|
||||
#include "gtk/gtk.h"
|
||||
#endif
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/ui/views/menu_delegate.h"
|
||||
#include "atom/browser/ui/views/submenu_button.h"
|
||||
@@ -14,54 +13,18 @@
|
||||
#include "ui/views/background.h"
|
||||
#include "ui/views/layout/box_layout.h"
|
||||
|
||||
#if defined(USE_X11)
|
||||
#include "chrome/browser/ui/libgtkui/gtk_util.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "ui/gfx/color_utils.h"
|
||||
#elif defined(USE_X11)
|
||||
#include "chrome/browser/ui/libgtkui/skia_utils_gtk.h"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(USE_X11)
|
||||
|
||||
SkColor GdkRgbaToSkColor(const GdkRGBA& rgba) {
|
||||
return SkColorSetARGB(rgba.alpha * 255, rgba.red * 255, rgba.green * 255,
|
||||
rgba.blue * 255);
|
||||
}
|
||||
|
||||
SkColor GetStyleContextFgColor(GtkStyleContext* style_context,
|
||||
GtkStateFlags state) {
|
||||
GdkRGBA rgba;
|
||||
gtk_style_context_get_color(style_context, state, &rgba);
|
||||
return GdkRgbaToSkColor(rgba);
|
||||
}
|
||||
|
||||
SkColor GetStyleContextBgColor(GtkStyleContext* style_context,
|
||||
GtkStateFlags state) {
|
||||
GdkRGBA rgba;
|
||||
gtk_style_context_get_background_color(style_context, state, &rgba);
|
||||
return GdkRgbaToSkColor(rgba);
|
||||
}
|
||||
|
||||
void GetMenuBarColor(SkColor* enabled,
|
||||
SkColor* disabled,
|
||||
SkColor* highlight,
|
||||
SkColor* hover,
|
||||
SkColor* background) {
|
||||
GtkWidget* menu_bar = gtk_menu_bar_new();
|
||||
GtkStyleContext* sc = gtk_widget_get_style_context(menu_bar);
|
||||
*enabled = GetStyleContextFgColor(sc, GTK_STATE_FLAG_NORMAL);
|
||||
*disabled = GetStyleContextFgColor(sc, GTK_STATE_FLAG_INSENSITIVE);
|
||||
*highlight = GetStyleContextFgColor(sc, GTK_STATE_FLAG_SELECTED);
|
||||
*hover = GetStyleContextFgColor(sc, GTK_STATE_FLAG_PRELIGHT);
|
||||
*background = GetStyleContextBgColor(sc, GTK_STATE_FLAG_NORMAL);
|
||||
gtk_widget_destroy(GTK_WIDGET(menu_bar));
|
||||
}
|
||||
|
||||
#endif // USE_X11
|
||||
|
||||
const char kViewClassName[] = "ElectronMenuBar";
|
||||
|
||||
// Default color of the menu bar.
|
||||
@@ -71,75 +34,70 @@ const SkColor kDefaultColor = SkColorSetARGB(255, 233, 233, 233);
|
||||
|
||||
MenuBar::MenuBar(NativeWindow* window)
|
||||
: background_color_(kDefaultColor), menu_model_(NULL), window_(window) {
|
||||
UpdateMenuBarColor();
|
||||
RefreshColorCache();
|
||||
UpdateViewColors();
|
||||
SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal));
|
||||
}
|
||||
|
||||
MenuBar::~MenuBar() {}
|
||||
|
||||
void MenuBar::AddedToWidget() {
|
||||
auto fm = GetFocusManager();
|
||||
fm->AddFocusChangeListener(this);
|
||||
// Note that we don't own fm -- this manages the _connection_
|
||||
focus_manager_.reset(fm, [this](views::FocusManager* fm) {
|
||||
fm->RemoveFocusChangeListener(this);
|
||||
});
|
||||
}
|
||||
|
||||
void MenuBar::RemovedFromWidget() {
|
||||
focus_manager_.reset();
|
||||
}
|
||||
|
||||
void MenuBar::SetMenu(AtomMenuModel* model) {
|
||||
menu_model_ = model;
|
||||
RemoveAllChildViews(true);
|
||||
|
||||
for (int i = 0; i < model->GetItemCount(); ++i) {
|
||||
SubmenuButton* button =
|
||||
new SubmenuButton(model->GetLabelAt(i), this, background_color_);
|
||||
button->set_tag(i);
|
||||
|
||||
#if defined(USE_X11)
|
||||
button->SetTextColor(views::Button::STATE_NORMAL, enabled_color_);
|
||||
button->SetTextColor(views::Button::STATE_DISABLED, disabled_color_);
|
||||
button->SetTextColor(views::Button::STATE_PRESSED, highlight_color_);
|
||||
button->SetTextColor(views::Button::STATE_HOVERED, hover_color_);
|
||||
button->SetUnderlineColor(enabled_color_);
|
||||
#elif defined(OS_WIN)
|
||||
button->SetUnderlineColor(color_utils::GetSysSkColor(COLOR_GRAYTEXT));
|
||||
#endif
|
||||
|
||||
AddChildView(button);
|
||||
}
|
||||
RebuildChildren();
|
||||
}
|
||||
|
||||
void MenuBar::SetAcceleratorVisibility(bool visible) {
|
||||
for (int i = 0; i < child_count(); ++i)
|
||||
static_cast<SubmenuButton*>(child_at(i))->SetAcceleratorVisibility(visible);
|
||||
for (auto* child : GetChildrenInZOrder())
|
||||
static_cast<SubmenuButton*>(child)->SetAcceleratorVisibility(visible);
|
||||
}
|
||||
|
||||
int MenuBar::GetAcceleratorIndex(base::char16 key) {
|
||||
for (int i = 0; i < child_count(); ++i) {
|
||||
SubmenuButton* button = static_cast<SubmenuButton*>(child_at(i));
|
||||
if (button->accelerator() == key)
|
||||
return i;
|
||||
MenuBar::View* MenuBar::FindAccelChild(base::char16 key) {
|
||||
for (auto* child : GetChildrenInZOrder()) {
|
||||
if (static_cast<SubmenuButton*>(child)->accelerator() == key)
|
||||
return child;
|
||||
}
|
||||
return -1;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool MenuBar::HasAccelerator(base::char16 key) {
|
||||
return FindAccelChild(key) != nullptr;
|
||||
}
|
||||
|
||||
void MenuBar::ActivateAccelerator(base::char16 key) {
|
||||
int i = GetAcceleratorIndex(key);
|
||||
if (i != -1)
|
||||
static_cast<SubmenuButton*>(child_at(i))->Activate(nullptr);
|
||||
auto child = FindAccelChild(key);
|
||||
if (child)
|
||||
static_cast<SubmenuButton*>(child)->Activate(nullptr);
|
||||
}
|
||||
|
||||
int MenuBar::GetItemCount() const {
|
||||
return menu_model_->GetItemCount();
|
||||
return menu_model_ ? menu_model_->GetItemCount() : 0;
|
||||
}
|
||||
|
||||
bool MenuBar::GetMenuButtonFromScreenPoint(const gfx::Point& point,
|
||||
bool MenuBar::GetMenuButtonFromScreenPoint(const gfx::Point& screenPoint,
|
||||
AtomMenuModel** menu_model,
|
||||
views::MenuButton** button) {
|
||||
gfx::Point location(point);
|
||||
views::View::ConvertPointFromScreen(this, &location);
|
||||
|
||||
if (location.x() < 0 || location.x() >= width() || location.y() < 0 ||
|
||||
location.y() >= height())
|
||||
if (!GetBoundsInScreen().Contains(screenPoint))
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < child_count(); ++i) {
|
||||
views::View* view = child_at(i);
|
||||
if (view->GetMirroredBounds().Contains(location) &&
|
||||
auto children = GetChildrenInZOrder();
|
||||
for (int i = 0, n = children.size(); i < n; ++i) {
|
||||
if (children[i]->GetBoundsInScreen().Contains(screenPoint) &&
|
||||
(menu_model_->GetTypeAt(i) == AtomMenuModel::TYPE_SUBMENU)) {
|
||||
*menu_model = menu_model_->GetSubmenuModelAt(i);
|
||||
*button = static_cast<views::MenuButton*>(view);
|
||||
*button = static_cast<views::MenuButton*>(children[i]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -175,18 +133,75 @@ void MenuBar::OnMenuButtonClicked(views::MenuButton* source,
|
||||
menu_delegate->RunMenu(menu_model_->GetSubmenuModelAt(id), source);
|
||||
}
|
||||
|
||||
void MenuBar::OnNativeThemeChanged(const ui::NativeTheme* theme) {
|
||||
UpdateMenuBarColor();
|
||||
}
|
||||
void MenuBar::RefreshColorCache(const ui::NativeTheme* theme) {
|
||||
if (!theme)
|
||||
theme = ui::NativeTheme::GetInstanceForNativeUi();
|
||||
if (theme) {
|
||||
#if defined(USE_X11)
|
||||
const std::string menubar_selector = "GtkMenuBar#menubar";
|
||||
background_color_ = libgtkui::GetBgColor(menubar_selector);
|
||||
|
||||
void MenuBar::UpdateMenuBarColor() {
|
||||
enabled_color_ = theme->GetSystemColor(
|
||||
ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor);
|
||||
disabled_color_ = theme->GetSystemColor(
|
||||
ui::NativeTheme::kColorId_DisabledMenuItemForegroundColor);
|
||||
#else
|
||||
background_color_ =
|
||||
theme->GetSystemColor(ui::NativeTheme::kColorId_MenuBackgroundColor);
|
||||
#endif
|
||||
}
|
||||
#if defined(OS_WIN)
|
||||
background_color_ = color_utils::GetSysSkColor(COLOR_MENUBAR);
|
||||
#elif defined(USE_X11)
|
||||
GetMenuBarColor(&enabled_color_, &disabled_color_, &highlight_color_,
|
||||
&hover_color_, &background_color_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MenuBar::OnNativeThemeChanged(const ui::NativeTheme* theme) {
|
||||
RefreshColorCache(theme);
|
||||
UpdateViewColors();
|
||||
}
|
||||
|
||||
void MenuBar::OnDidChangeFocus(View* focused_before, View* focused_now) {
|
||||
// if we've changed focus, update our view
|
||||
const auto had_focus = has_focus_;
|
||||
has_focus_ = focused_now != nullptr;
|
||||
if (has_focus_ != had_focus)
|
||||
UpdateViewColors();
|
||||
}
|
||||
|
||||
void MenuBar::RebuildChildren() {
|
||||
RemoveAllChildViews(true);
|
||||
for (int i = 0, n = GetItemCount(); i < n; ++i) {
|
||||
auto button =
|
||||
new SubmenuButton(menu_model_->GetLabelAt(i), this, background_color_);
|
||||
button->set_tag(i);
|
||||
AddChildView(button);
|
||||
}
|
||||
UpdateViewColors();
|
||||
}
|
||||
|
||||
void MenuBar::UpdateViewColors() {
|
||||
// set menubar background color
|
||||
SetBackground(views::CreateSolidBackground(background_color_));
|
||||
|
||||
// set child colors
|
||||
if (menu_model_ == nullptr)
|
||||
return;
|
||||
#if defined(USE_X11)
|
||||
const auto& textColor = has_focus_ ? enabled_color_ : disabled_color_;
|
||||
for (auto* child : GetChildrenInZOrder()) {
|
||||
auto button = static_cast<SubmenuButton*>(child);
|
||||
button->SetTextColor(views::Button::STATE_NORMAL, textColor);
|
||||
button->SetTextColor(views::Button::STATE_DISABLED, disabled_color_);
|
||||
button->SetTextColor(views::Button::STATE_PRESSED, enabled_color_);
|
||||
button->SetTextColor(views::Button::STATE_HOVERED, textColor);
|
||||
button->SetUnderlineColor(textColor);
|
||||
}
|
||||
#elif defined(OS_WIN)
|
||||
for (auto* child : GetChildrenInZOrder()) {
|
||||
auto button = static_cast<SubmenuButton*>(child);
|
||||
button->SetUnderlineColor(color_utils::GetSysSkColor(COLOR_MENUTEXT));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -5,9 +5,12 @@
|
||||
#ifndef ATOM_BROWSER_UI_VIEWS_MENU_BAR_H_
|
||||
#define ATOM_BROWSER_UI_VIEWS_MENU_BAR_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/ui/atom_menu_model.h"
|
||||
#include "ui/views/controls/button/menu_button_listener.h"
|
||||
#include "ui/views/focus/focus_manager.h"
|
||||
#include "ui/views/view.h"
|
||||
|
||||
namespace views {
|
||||
@@ -19,7 +22,8 @@ namespace atom {
|
||||
class MenuDelegate;
|
||||
|
||||
class MenuBar : public views::View,
|
||||
public views::MenuButtonListener {
|
||||
public views::MenuButtonListener,
|
||||
public views::FocusChangeListener {
|
||||
public:
|
||||
explicit MenuBar(NativeWindow* window);
|
||||
virtual ~MenuBar();
|
||||
@@ -30,9 +34,8 @@ class MenuBar : public views::View,
|
||||
// Shows underline under accelerators.
|
||||
void SetAcceleratorVisibility(bool visible);
|
||||
|
||||
// Returns which submenu has accelerator |key|, -1 would be returned when
|
||||
// there is no matching submenu.
|
||||
int GetAcceleratorIndex(base::char16 key);
|
||||
// Returns true if the submenu has accelerator |key|
|
||||
bool HasAccelerator(base::char16 key);
|
||||
|
||||
// Shows the submenu whose accelerator is |key|.
|
||||
void ActivateAccelerator(base::char16 key);
|
||||
@@ -47,7 +50,9 @@ class MenuBar : public views::View,
|
||||
|
||||
protected:
|
||||
// views::View:
|
||||
void AddedToWidget() override;
|
||||
const char* GetClassName() const override;
|
||||
void RemovedFromWidget() override;
|
||||
|
||||
// views::MenuButtonListener:
|
||||
void OnMenuButtonClicked(views::MenuButton* source,
|
||||
@@ -55,21 +60,29 @@ class MenuBar : public views::View,
|
||||
const ui::Event* event) override;
|
||||
void OnNativeThemeChanged(const ui::NativeTheme* theme) override;
|
||||
|
||||
// views::FocusChangeListener:
|
||||
void OnDidChangeFocus(View* focused_before, View* focused_now) override;
|
||||
void OnWillChangeFocus(View* focused_before, View* focused_now) override {}
|
||||
|
||||
private:
|
||||
void UpdateMenuBarColor();
|
||||
void RebuildChildren();
|
||||
void UpdateViewColors();
|
||||
|
||||
void RefreshColorCache(const ui::NativeTheme* theme = nullptr);
|
||||
SkColor background_color_;
|
||||
|
||||
#if defined(USE_X11)
|
||||
SkColor enabled_color_;
|
||||
SkColor disabled_color_;
|
||||
SkColor highlight_color_;
|
||||
SkColor hover_color_;
|
||||
#endif
|
||||
|
||||
NativeWindow* window_;
|
||||
AtomMenuModel* menu_model_;
|
||||
|
||||
View* FindAccelChild(base::char16 key);
|
||||
|
||||
std::shared_ptr<views::FocusManager> focus_manager_;
|
||||
bool has_focus_ = true;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MenuBar);
|
||||
};
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ void SubmenuButton::PaintButtonContents(gfx::Canvas* canvas) {
|
||||
|
||||
bool SubmenuButton::GetUnderlinePosition(const base::string16& text,
|
||||
base::char16* accelerator,
|
||||
int* start, int* end) {
|
||||
int* start, int* end) const {
|
||||
int pos, span;
|
||||
base::string16 trimmed = gfx::RemoveAcceleratorChar(text, '&', &pos, &span);
|
||||
if (pos > -1 && span != 0) {
|
||||
@@ -105,7 +105,7 @@ bool SubmenuButton::GetUnderlinePosition(const base::string16& text,
|
||||
}
|
||||
|
||||
void SubmenuButton::GetCharacterPosition(
|
||||
const base::string16& text, int index, int* pos) {
|
||||
const base::string16& text, int index, int* pos) const {
|
||||
int height = 0;
|
||||
gfx::Canvas::SizeStringInt(text.substr(0, index), gfx::FontList(), pos,
|
||||
&height, 0, 0);
|
||||
|
||||
@@ -21,9 +21,6 @@ class SubmenuButton : public views::MenuButton {
|
||||
void SetAcceleratorVisibility(bool visible);
|
||||
void SetUnderlineColor(SkColor color);
|
||||
|
||||
void SetEnabledColor(SkColor color);
|
||||
void SetBackgroundColor(SkColor color);
|
||||
|
||||
base::char16 accelerator() const { return accelerator_; }
|
||||
|
||||
// views::MenuButton:
|
||||
@@ -36,9 +33,9 @@ class SubmenuButton : public views::MenuButton {
|
||||
private:
|
||||
bool GetUnderlinePosition(const base::string16& text,
|
||||
base::char16* accelerator,
|
||||
int* start, int* end);
|
||||
int* start, int* end) const;
|
||||
void GetCharacterPosition(
|
||||
const base::string16& text, int index, int* pos);
|
||||
const base::string16& text, int index, int* pos) const;
|
||||
|
||||
base::char16 accelerator_;
|
||||
|
||||
|
||||
@@ -25,4 +25,11 @@ bool AtomDesktopWindowTreeHostWin::PreHandleMSG(
|
||||
return delegate_->PreHandleMSG(message, w_param, l_param, result);
|
||||
}
|
||||
|
||||
bool AtomDesktopWindowTreeHostWin::HasNativeFrame() const {
|
||||
// Since we never use chromium's titlebar implementation, we can just say
|
||||
// that we use a native titlebar. This will disable the repaint locking when
|
||||
// DWM composition is disabled.
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -27,6 +27,7 @@ class AtomDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin {
|
||||
protected:
|
||||
bool PreHandleMSG(
|
||||
UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) override;
|
||||
bool HasNativeFrame() const override;
|
||||
|
||||
private:
|
||||
MessageHandlerDelegate* delegate_; // weak ref
|
||||
|
||||
@@ -48,6 +48,35 @@ WebContentsPreferences::WebContentsPreferences(
|
||||
web_contents->SetUserData(UserDataKey(), base::WrapUnique(this));
|
||||
|
||||
instances_.push_back(this);
|
||||
|
||||
// Set WebPreferences defaults onto the JS object
|
||||
SetDefaultBoolIfUndefined("plugins", false);
|
||||
SetDefaultBoolIfUndefined(options::kExperimentalFeatures, false);
|
||||
SetDefaultBoolIfUndefined(options::kExperimentalCanvasFeatures, false);
|
||||
bool node = SetDefaultBoolIfUndefined(options::kNodeIntegration, true);
|
||||
SetDefaultBoolIfUndefined(options::kNodeIntegrationInWorker, false);
|
||||
SetDefaultBoolIfUndefined(options::kWebviewTag, node);
|
||||
SetDefaultBoolIfUndefined("sandbox", false);
|
||||
SetDefaultBoolIfUndefined("nativeWindowOpen", false);
|
||||
SetDefaultBoolIfUndefined(options::kContextIsolation, false);
|
||||
SetDefaultBoolIfUndefined("javascript", true);
|
||||
SetDefaultBoolIfUndefined("images", true);
|
||||
SetDefaultBoolIfUndefined("textAreasAreResizable", true);
|
||||
SetDefaultBoolIfUndefined("webgl", true);
|
||||
bool webSecurity = true;
|
||||
SetDefaultBoolIfUndefined("webSecurity", webSecurity);
|
||||
// If webSecurity was explicity set to false, let's inherit that into
|
||||
// insecureContent
|
||||
if (web_preferences.Get("webSecurity", &webSecurity) && !webSecurity) {
|
||||
SetDefaultBoolIfUndefined("allowRunningInsecureContent", true);
|
||||
} else {
|
||||
SetDefaultBoolIfUndefined("allowRunningInsecureContent", false);
|
||||
}
|
||||
#if defined(OS_MACOSX)
|
||||
SetDefaultBoolIfUndefined(options::kScrollBounce, false);
|
||||
#endif
|
||||
SetDefaultBoolIfUndefined("offscreen", false);
|
||||
last_web_preferences_.MergeDictionary(&web_preferences_);
|
||||
}
|
||||
|
||||
WebContentsPreferences::~WebContentsPreferences() {
|
||||
@@ -56,6 +85,16 @@ WebContentsPreferences::~WebContentsPreferences() {
|
||||
instances_.end());
|
||||
}
|
||||
|
||||
bool WebContentsPreferences::SetDefaultBoolIfUndefined(const std::string key,
|
||||
bool val) {
|
||||
bool existing;
|
||||
if (!web_preferences_.GetBoolean(key, &existing)) {
|
||||
web_preferences_.SetBoolean(key, val);
|
||||
return val;
|
||||
}
|
||||
return existing;
|
||||
}
|
||||
|
||||
void WebContentsPreferences::Merge(const base::DictionaryValue& extend) {
|
||||
web_preferences_.MergeDictionary(&extend);
|
||||
}
|
||||
@@ -80,6 +119,12 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
|
||||
|
||||
base::DictionaryValue& web_preferences = self->web_preferences_;
|
||||
|
||||
// We are appending args to a webContents so let's save the current state
|
||||
// of our preferences object so that during the lifetime of the WebContents
|
||||
// we can fetch the options used to initally configure the WebContents
|
||||
self->last_web_preferences_.Clear();
|
||||
self->last_web_preferences_.MergeDictionary(&web_preferences);
|
||||
|
||||
bool b;
|
||||
// Check if plugins are enabled.
|
||||
if (web_preferences.GetBoolean("plugins", &b) && b)
|
||||
@@ -156,8 +201,13 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
|
||||
|
||||
// --background-color.
|
||||
std::string color;
|
||||
if (web_preferences.GetString(options::kBackgroundColor, &color))
|
||||
if (web_preferences.GetString(options::kBackgroundColor, &color)) {
|
||||
command_line->AppendSwitchASCII(switches::kBackgroundColor, color);
|
||||
} else if (!(web_preferences.GetBoolean("offscreen", &b) && b)) {
|
||||
// For non-OSR WebContents, we expect to have white background, see
|
||||
// https://github.com/electron/electron/issues/13764 for more.
|
||||
command_line->AppendSwitchASCII(switches::kBackgroundColor, "#fff");
|
||||
}
|
||||
|
||||
// --guest-instance-id, which is used to identify guest WebContents.
|
||||
int guest_instance_id = 0;
|
||||
@@ -286,6 +336,11 @@ void WebContentsPreferences::OverrideWebkitPrefs(
|
||||
std::string encoding;
|
||||
if (self->web_preferences_.GetString("defaultEncoding", &encoding))
|
||||
prefs->default_encoding = encoding;
|
||||
|
||||
bool node_integration = false;
|
||||
self->web_preferences_.GetBoolean(options::kNodeIntegration,
|
||||
&node_integration);
|
||||
prefs->node_integration = node_integration;
|
||||
}
|
||||
|
||||
bool WebContentsPreferences::GetInteger(const std::string& attributeName,
|
||||
|
||||
@@ -53,10 +53,16 @@ class WebContentsPreferences
|
||||
|
||||
// Returns the web preferences.
|
||||
base::DictionaryValue* web_preferences() { return &web_preferences_; }
|
||||
base::DictionaryValue* last_web_preferences() {
|
||||
return &last_web_preferences_;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class content::WebContentsUserData<WebContentsPreferences>;
|
||||
|
||||
// Set preference value to given bool if user did not provide value
|
||||
bool SetDefaultBoolIfUndefined(const std::string key, bool val);
|
||||
|
||||
// Get preferences value as integer possibly coercing it from a string
|
||||
bool GetInteger(const std::string& attributeName, int* intValue);
|
||||
|
||||
@@ -64,6 +70,7 @@ class WebContentsPreferences
|
||||
|
||||
content::WebContents* web_contents_;
|
||||
base::DictionaryValue web_preferences_;
|
||||
base::DictionaryValue last_web_preferences_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContentsPreferences);
|
||||
};
|
||||
|
||||
@@ -168,10 +168,10 @@ file_dialog::Filters GetFileTypesFromAcceptType(
|
||||
|
||||
filters.push_back(file_dialog::Filter());
|
||||
|
||||
if (valid_type_count > 1 ||
|
||||
(valid_type_count == 1 && description.empty() && extensions.size() > 1))
|
||||
if (valid_type_count > 1 || (valid_type_count == 1 && description.empty()))
|
||||
description = "Custom Files";
|
||||
|
||||
DCHECK(!description.empty());
|
||||
filters[0].first = description;
|
||||
|
||||
for (const auto& extension : extensions) {
|
||||
@@ -227,6 +227,7 @@ void WebDialogHelper::RunFileChooser(
|
||||
flags |= file_dialog::FILE_DIALOG_MULTI_SELECTIONS;
|
||||
case content::FileChooserParams::Open:
|
||||
flags |= file_dialog::FILE_DIALOG_OPEN_FILE;
|
||||
flags |= file_dialog::FILE_DIALOG_TREAT_PACKAGE_APP_AS_DIRECTORY;
|
||||
break;
|
||||
case content::FileChooserParams::UploadFolder:
|
||||
flags |= file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
|
||||
|
||||
@@ -22,16 +22,16 @@ IPC_STRUCT_TRAITS_BEGIN(atom::DraggableRegion)
|
||||
IPC_STRUCT_TRAITS_MEMBER(bounds)
|
||||
IPC_STRUCT_TRAITS_END()
|
||||
|
||||
IPC_MESSAGE_ROUTED2(AtomViewHostMsg_Message,
|
||||
IPC_MESSAGE_ROUTED2(AtomFrameHostMsg_Message,
|
||||
base::string16 /* channel */,
|
||||
base::ListValue /* arguments */)
|
||||
|
||||
IPC_SYNC_MESSAGE_ROUTED2_1(AtomViewHostMsg_Message_Sync,
|
||||
IPC_SYNC_MESSAGE_ROUTED2_1(AtomFrameHostMsg_Message_Sync,
|
||||
base::string16 /* channel */,
|
||||
base::ListValue /* arguments */,
|
||||
base::string16 /* result (in JSON) */)
|
||||
|
||||
IPC_MESSAGE_ROUTED3(AtomViewMsg_Message,
|
||||
IPC_MESSAGE_ROUTED3(AtomFrameMsg_Message,
|
||||
bool /* send_to_all */,
|
||||
base::string16 /* channel */,
|
||||
base::ListValue /* arguments */)
|
||||
@@ -56,9 +56,9 @@ IPC_MESSAGE_ROUTED1(AtomFrameHostMsg_UpdateDraggableRegions,
|
||||
IPC_MESSAGE_CONTROL1(AtomMsg_UpdatePreferences, base::ListValue)
|
||||
|
||||
// Sent by renderer to set the temporary zoom level.
|
||||
IPC_SYNC_MESSAGE_ROUTED1_1(AtomViewHostMsg_SetTemporaryZoomLevel,
|
||||
double /* zoom level */,
|
||||
double /* result */)
|
||||
IPC_SYNC_MESSAGE_ROUTED1_1(AtomFrameHostMsg_SetTemporaryZoomLevel,
|
||||
double /* zoom level */,
|
||||
double /* result */)
|
||||
|
||||
// Sent by renderer to get the zoom level.
|
||||
IPC_SYNC_MESSAGE_ROUTED0_1(AtomViewHostMsg_GetZoomLevel, double /* result */)
|
||||
IPC_SYNC_MESSAGE_ROUTED0_1(AtomFrameHostMsg_GetZoomLevel, double /* result */)
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace std {
|
||||
template <typename Type1, typename Type2>
|
||||
struct hash<std::pair<Type1, Type2>> {
|
||||
std::size_t operator()(std::pair<Type1, Type2> value) const {
|
||||
return base::HashInts<Type1, Type2>(value.first, value.second);
|
||||
return base::HashInts(base::Hash(value.first), value.second);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -114,8 +114,9 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
dict.SetMethod("setRemoteCallbackFreer", &atom::RemoteCallbackFreer::BindTo);
|
||||
dict.SetMethod("setRemoteObjectFreer", &atom::RemoteObjectFreer::BindTo);
|
||||
dict.SetMethod("createIDWeakMap", &atom::api::KeyWeakMap<int32_t>::Create);
|
||||
dict.SetMethod("createDoubleIDWeakMap",
|
||||
&atom::api::KeyWeakMap<std::pair<int64_t, int32_t>>::Create);
|
||||
dict.SetMethod(
|
||||
"createDoubleIDWeakMap",
|
||||
&atom::api::KeyWeakMap<std::pair<std::string, int32_t>>::Create);
|
||||
dict.SetMethod("requestGarbageCollectionForTesting",
|
||||
&RequestGarbageCollectionForTesting);
|
||||
dict.SetMethod("isSameOrigin", &IsSameOrigin);
|
||||
|
||||
@@ -7,23 +7,28 @@
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
// static
|
||||
void RemoteCallbackFreer::BindTo(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
const std::string& context_id,
|
||||
int object_id,
|
||||
content::WebContents* web_contents) {
|
||||
new RemoteCallbackFreer(isolate, target, object_id, web_contents);
|
||||
new RemoteCallbackFreer(isolate, target, context_id, object_id, web_contents);
|
||||
}
|
||||
|
||||
RemoteCallbackFreer::RemoteCallbackFreer(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
const std::string& context_id,
|
||||
int object_id,
|
||||
content::WebContents* web_contents)
|
||||
: ObjectLifeMonitor(isolate, target),
|
||||
content::WebContentsObserver(web_contents),
|
||||
context_id_(context_id),
|
||||
object_id_(object_id) {
|
||||
}
|
||||
|
||||
@@ -34,8 +39,13 @@ void RemoteCallbackFreer::RunDestructor() {
|
||||
base::string16 channel =
|
||||
base::ASCIIToUTF16("ELECTRON_RENDERER_RELEASE_CALLBACK");
|
||||
base::ListValue args;
|
||||
args.AppendString(context_id_);
|
||||
args.AppendInteger(object_id_);
|
||||
Send(new AtomViewMsg_Message(routing_id(), false, channel, args));
|
||||
auto frame_host = web_contents()->GetMainFrame();
|
||||
if (frame_host) {
|
||||
frame_host->Send(new AtomFrameMsg_Message(frame_host->GetRoutingID(), false,
|
||||
channel, args));
|
||||
}
|
||||
|
||||
Observe(nullptr);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
|
||||
#ifndef ATOM_COMMON_API_REMOTE_CALLBACK_FREER_H_
|
||||
#define ATOM_COMMON_API_REMOTE_CALLBACK_FREER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/common/api/object_life_monitor.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
|
||||
@@ -14,12 +17,14 @@ class RemoteCallbackFreer : public ObjectLifeMonitor,
|
||||
public:
|
||||
static void BindTo(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
const std::string& context_id,
|
||||
int object_id,
|
||||
content::WebContents* web_conents);
|
||||
|
||||
protected:
|
||||
RemoteCallbackFreer(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
const std::string& context_id,
|
||||
int object_id,
|
||||
content::WebContents* web_conents);
|
||||
~RemoteCallbackFreer() override;
|
||||
@@ -30,6 +35,7 @@ class RemoteCallbackFreer : public ObjectLifeMonitor,
|
||||
void RenderViewDeleted(content::RenderViewHost*) override;
|
||||
|
||||
private:
|
||||
std::string context_id_;
|
||||
int object_id_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RemoteCallbackFreer);
|
||||
|
||||
@@ -7,45 +7,44 @@
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/renderer/render_view.h"
|
||||
#include "content/public/renderer/render_frame.h"
|
||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||
#include "third_party/WebKit/public/web/WebView.h"
|
||||
|
||||
using blink::WebLocalFrame;
|
||||
using blink::WebView;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
content::RenderView* GetCurrentRenderView() {
|
||||
content::RenderFrame* GetCurrentRenderFrame() {
|
||||
WebLocalFrame* frame = WebLocalFrame::FrameForCurrentContext();
|
||||
if (!frame)
|
||||
return nullptr;
|
||||
|
||||
WebView* view = frame->View();
|
||||
if (!view)
|
||||
return nullptr; // can happen during closing.
|
||||
|
||||
return content::RenderView::FromWebView(view);
|
||||
return content::RenderFrame::FromWebFrame(frame);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
void RemoteObjectFreer::BindTo(
|
||||
v8::Isolate* isolate, v8::Local<v8::Object> target, int object_id) {
|
||||
new RemoteObjectFreer(isolate, target, object_id);
|
||||
void RemoteObjectFreer::BindTo(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
const std::string& context_id,
|
||||
int object_id) {
|
||||
new RemoteObjectFreer(isolate, target, context_id, object_id);
|
||||
}
|
||||
|
||||
RemoteObjectFreer::RemoteObjectFreer(
|
||||
v8::Isolate* isolate, v8::Local<v8::Object> target, int object_id)
|
||||
RemoteObjectFreer::RemoteObjectFreer(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
const std::string& context_id,
|
||||
int object_id)
|
||||
: ObjectLifeMonitor(isolate, target),
|
||||
context_id_(context_id),
|
||||
object_id_(object_id),
|
||||
routing_id_(MSG_ROUTING_NONE) {
|
||||
content::RenderView* render_view = GetCurrentRenderView();
|
||||
if (render_view) {
|
||||
routing_id_ = render_view->GetRoutingID();
|
||||
content::RenderFrame* render_frame = GetCurrentRenderFrame();
|
||||
if (render_frame) {
|
||||
routing_id_ = render_frame->GetRoutingID();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,17 +52,18 @@ RemoteObjectFreer::~RemoteObjectFreer() {
|
||||
}
|
||||
|
||||
void RemoteObjectFreer::RunDestructor() {
|
||||
content::RenderView* render_view =
|
||||
content::RenderView::FromRoutingID(routing_id_);
|
||||
if (!render_view)
|
||||
content::RenderFrame* render_frame =
|
||||
content::RenderFrame::FromRoutingID(routing_id_);
|
||||
if (!render_frame)
|
||||
return;
|
||||
|
||||
base::string16 channel = base::ASCIIToUTF16("ipc-message");
|
||||
base::ListValue args;
|
||||
args.AppendString("ELECTRON_BROWSER_DEREFERENCE");
|
||||
args.AppendString(context_id_);
|
||||
args.AppendInteger(object_id_);
|
||||
render_view->Send(
|
||||
new AtomViewHostMsg_Message(render_view->GetRoutingID(), channel, args));
|
||||
render_frame->Send(new AtomFrameHostMsg_Message(render_frame->GetRoutingID(),
|
||||
channel, args));
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -5,23 +5,30 @@
|
||||
#ifndef ATOM_COMMON_API_REMOTE_OBJECT_FREER_H_
|
||||
#define ATOM_COMMON_API_REMOTE_OBJECT_FREER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/common/api/object_life_monitor.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class RemoteObjectFreer : public ObjectLifeMonitor {
|
||||
public:
|
||||
static void BindTo(
|
||||
v8::Isolate* isolate, v8::Local<v8::Object> target, int object_id);
|
||||
static void BindTo(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
const std::string& context_id,
|
||||
int object_id);
|
||||
|
||||
protected:
|
||||
RemoteObjectFreer(
|
||||
v8::Isolate* isolate, v8::Local<v8::Object> target, int object_id);
|
||||
RemoteObjectFreer(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target,
|
||||
const std::string& context_id,
|
||||
int object_id);
|
||||
~RemoteObjectFreer() override;
|
||||
|
||||
void RunDestructor() override;
|
||||
|
||||
private:
|
||||
std::string context_id_;
|
||||
int object_id_;
|
||||
int routing_id_;
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
#ifndef ATOM_COMMON_ATOM_VERSION_H_
|
||||
#define ATOM_COMMON_ATOM_VERSION_H_
|
||||
|
||||
#define ATOM_MAJOR_VERSION 1
|
||||
#define ATOM_MINOR_VERSION 8
|
||||
#define ATOM_PATCH_VERSION 2
|
||||
#define ATOM_PRE_RELEASE_VERSION -beta.2
|
||||
#define ATOM_MAJOR_VERSION 2
|
||||
#define ATOM_MINOR_VERSION 0
|
||||
#define ATOM_PATCH_VERSION 14
|
||||
// #define ATOM_PRE_RELEASE_VERSION
|
||||
|
||||
#ifndef ATOM_STRINGIFY
|
||||
#define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n)
|
||||
|
||||
@@ -209,7 +209,10 @@ void CrashReporterWin::SetUploadParameters() {
|
||||
int CrashReporterWin::CrashForException(EXCEPTION_POINTERS* info) {
|
||||
if (breakpad_) {
|
||||
breakpad_->WriteMinidumpForException(info);
|
||||
TerminateProcessWithoutDump();
|
||||
if (skip_system_crash_handler_)
|
||||
TerminateProcessWithoutDump();
|
||||
else
|
||||
RaiseFailFastException(info->ExceptionRecord, info->ContextRecord, 0);
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
@@ -229,7 +232,7 @@ bool CrashReporterWin::MinidumpCallback(const wchar_t* dump_path,
|
||||
MDRawAssertionInfo* assertion,
|
||||
bool succeeded) {
|
||||
CrashReporterWin* self = static_cast<CrashReporterWin*>(context);
|
||||
if (succeeded && !self->skip_system_crash_handler_)
|
||||
if (succeeded && self->skip_system_crash_handler_)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
@@ -13,15 +13,19 @@
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/logging.h"
|
||||
#include "brightray/common/platform_util.h"
|
||||
#include "chrome/browser/ui/libgtkui/gtk_util.h"
|
||||
|
||||
namespace {
|
||||
|
||||
GDesktopAppInfo* get_desktop_app_info() {
|
||||
std::unique_ptr<base::Environment> env(base::Environment::Create());
|
||||
const std::string desktop_id = libgtkui::GetDesktopName(env.get());
|
||||
return desktop_id.empty() ? nullptr
|
||||
: g_desktop_app_info_new(desktop_id.c_str());
|
||||
GDesktopAppInfo * ret = nullptr;
|
||||
|
||||
std::string desktop_id;
|
||||
if (brightray::platform_util::GetDesktopName(&desktop_id))
|
||||
ret = g_desktop_app_info_new(desktop_id.c_str());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -168,6 +168,7 @@ void NodeBindings::Initialize() {
|
||||
|
||||
// Init node.
|
||||
// (we assume node::Init would not modify the parameters under embedded mode).
|
||||
// NOTE: If you change this line, please ping @codebytere or @MarshallOfSound
|
||||
node::Init(nullptr, nullptr, nullptr, nullptr);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
@@ -178,6 +178,9 @@ const char kAppUserModelId[] = "app-user-model-id";
|
||||
// The application path
|
||||
const char kAppPath[] = "app-path";
|
||||
|
||||
// The context ID for this process
|
||||
const char kContextId[] = "context-id";
|
||||
|
||||
// The command line switch versions of the options.
|
||||
const char kBackgroundColor[] = "background-color";
|
||||
const char kPreloadScript[] = "preload";
|
||||
|
||||
@@ -88,6 +88,7 @@ extern const char kRegisterServiceWorkerSchemes[];
|
||||
extern const char kSecureSchemes[];
|
||||
extern const char kAppUserModelId[];
|
||||
extern const char kAppPath[];
|
||||
extern const char kContextId[];
|
||||
|
||||
extern const char kBackgroundColor[];
|
||||
extern const char kPreloadScript[];
|
||||
|
||||
@@ -7,43 +7,38 @@
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "content/public/renderer/render_view.h"
|
||||
#include "content/public/renderer/render_frame.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||
#include "third_party/WebKit/public/web/WebView.h"
|
||||
|
||||
using content::RenderView;
|
||||
using content::RenderFrame;
|
||||
using blink::WebLocalFrame;
|
||||
using blink::WebView;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
RenderView* GetCurrentRenderView() {
|
||||
RenderFrame* GetCurrentRenderFrame() {
|
||||
WebLocalFrame* frame = WebLocalFrame::FrameForCurrentContext();
|
||||
if (!frame)
|
||||
return nullptr;
|
||||
|
||||
WebView* view = frame->View();
|
||||
if (!view)
|
||||
return nullptr; // can happen during closing.
|
||||
|
||||
return RenderView::FromWebView(view);
|
||||
return RenderFrame::FromWebFrame(frame);
|
||||
}
|
||||
|
||||
void Send(mate::Arguments* args,
|
||||
const base::string16& channel,
|
||||
const base::ListValue& arguments) {
|
||||
RenderView* render_view = GetCurrentRenderView();
|
||||
if (render_view == nullptr)
|
||||
RenderFrame* render_frame = GetCurrentRenderFrame();
|
||||
if (render_frame == nullptr)
|
||||
return;
|
||||
|
||||
bool success = render_view->Send(new AtomViewHostMsg_Message(
|
||||
render_view->GetRoutingID(), channel, arguments));
|
||||
bool success = render_frame->Send(new AtomFrameHostMsg_Message(
|
||||
render_frame->GetRoutingID(), channel, arguments));
|
||||
|
||||
if (!success)
|
||||
args->ThrowError("Unable to send AtomViewHostMsg_Message");
|
||||
args->ThrowError("Unable to send AtomFrameHostMsg_Message");
|
||||
}
|
||||
|
||||
base::string16 SendSync(mate::Arguments* args,
|
||||
@@ -51,16 +46,16 @@ base::string16 SendSync(mate::Arguments* args,
|
||||
const base::ListValue& arguments) {
|
||||
base::string16 json;
|
||||
|
||||
RenderView* render_view = GetCurrentRenderView();
|
||||
if (render_view == nullptr)
|
||||
RenderFrame* render_frame = GetCurrentRenderFrame();
|
||||
if (render_frame == nullptr)
|
||||
return json;
|
||||
|
||||
IPC::SyncMessage* message = new AtomViewHostMsg_Message_Sync(
|
||||
render_view->GetRoutingID(), channel, arguments, &json);
|
||||
bool success = render_view->Send(message);
|
||||
IPC::SyncMessage* message = new AtomFrameHostMsg_Message_Sync(
|
||||
render_frame->GetRoutingID(), channel, arguments, &json);
|
||||
bool success = render_frame->Send(message);
|
||||
|
||||
if (!success)
|
||||
args->ThrowError("Unable to send AtomViewHostMsg_Message_Sync");
|
||||
args->ThrowError("Unable to send AtomFrameHostMsg_Message_Sync");
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
@@ -125,19 +125,19 @@ void WebFrame::SetName(const std::string& name) {
|
||||
|
||||
double WebFrame::SetZoomLevel(double level) {
|
||||
double result = 0.0;
|
||||
content::RenderView* render_view =
|
||||
content::RenderView::FromWebView(web_frame_->View());
|
||||
render_view->Send(new AtomViewHostMsg_SetTemporaryZoomLevel(
|
||||
render_view->GetRoutingID(), level, &result));
|
||||
content::RenderFrame* render_frame =
|
||||
content::RenderFrame::FromWebFrame(web_frame_);
|
||||
render_frame->Send(new AtomFrameHostMsg_SetTemporaryZoomLevel(
|
||||
render_frame->GetRoutingID(), level, &result));
|
||||
return result;
|
||||
}
|
||||
|
||||
double WebFrame::GetZoomLevel() const {
|
||||
double result = 0.0;
|
||||
content::RenderView* render_view =
|
||||
content::RenderView::FromWebView(web_frame_->View());
|
||||
render_view->Send(
|
||||
new AtomViewHostMsg_GetZoomLevel(render_view->GetRoutingID(), &result));
|
||||
content::RenderFrame* render_frame =
|
||||
content::RenderFrame::FromWebFrame(web_frame_);
|
||||
render_frame->Send(
|
||||
new AtomFrameHostMsg_GetZoomLevel(render_frame->GetRoutingID(), &result));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -152,6 +152,7 @@ double WebFrame::GetZoomFactor() const {
|
||||
|
||||
void WebFrame::SetVisualZoomLevelLimits(double min_level, double max_level) {
|
||||
web_frame_->View()->SetDefaultPageScaleLimits(min_level, max_level);
|
||||
web_frame_->View()->SetIgnoreViewportTagScaleLimits(true);
|
||||
}
|
||||
|
||||
void WebFrame::SetLayoutZoomLevelLimits(double min_level, double max_level) {
|
||||
|
||||
@@ -4,29 +4,90 @@
|
||||
|
||||
#include "atom/renderer/atom_render_frame_observer.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/api/event_emitter_caller.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/trace_event/trace_event.h"
|
||||
#include "content/public/renderer/render_frame.h"
|
||||
#include "content/public/renderer/render_view.h"
|
||||
#include "ipc/ipc_message_macros.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/net_module.h"
|
||||
#include "net/grit/net_resources.h"
|
||||
#include "third_party/WebKit/public/web/WebDocument.h"
|
||||
#include "third_party/WebKit/public/web/WebDraggableRegion.h"
|
||||
#include "third_party/WebKit/public/web/WebElement.h"
|
||||
#include "third_party/WebKit/public/web/WebKit.h"
|
||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||
#include "third_party/WebKit/public/web/WebScriptSource.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
bool GetIPCObject(v8::Isolate* isolate,
|
||||
v8::Local<v8::Context> context,
|
||||
v8::Local<v8::Object>* ipc) {
|
||||
v8::Local<v8::String> key = mate::StringToV8(isolate, "ipc");
|
||||
v8::Local<v8::Private> privateKey = v8::Private::ForApi(isolate, key);
|
||||
v8::Local<v8::Object> global_object = context->Global();
|
||||
v8::Local<v8::Value> value;
|
||||
if (!global_object->GetPrivate(context, privateKey).ToLocal(&value))
|
||||
return false;
|
||||
if (value.IsEmpty() || !value->IsObject())
|
||||
return false;
|
||||
*ipc = value->ToObject();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<v8::Local<v8::Value>> ListValueToVector(
|
||||
v8::Isolate* isolate,
|
||||
const base::ListValue& list) {
|
||||
v8::Local<v8::Value> array = mate::ConvertToV8(isolate, list);
|
||||
std::vector<v8::Local<v8::Value>> result;
|
||||
mate::ConvertFromV8(isolate, array, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
base::StringPiece NetResourceProvider(int key) {
|
||||
if (key == IDR_DIR_HEADER_HTML) {
|
||||
base::StringPiece html_data =
|
||||
ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
|
||||
IDR_DIR_HEADER_HTML);
|
||||
return html_data;
|
||||
}
|
||||
return base::StringPiece();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomRenderFrameObserver::AtomRenderFrameObserver(
|
||||
content::RenderFrame* frame,
|
||||
RendererClientBase* renderer_client)
|
||||
: content::RenderFrameObserver(frame),
|
||||
render_frame_(frame),
|
||||
renderer_client_(renderer_client) {}
|
||||
: content::RenderFrameObserver(frame),
|
||||
render_frame_(frame),
|
||||
renderer_client_(renderer_client),
|
||||
document_created_(false) {
|
||||
// Initialise resource for directory listing.
|
||||
net::NetModule::SetResourceProvider(NetResourceProvider);
|
||||
}
|
||||
|
||||
void AtomRenderFrameObserver::DidClearWindowObject() {
|
||||
renderer_client_->DidClearWindowObject(render_frame_);
|
||||
}
|
||||
|
||||
void AtomRenderFrameObserver::DidCreateDocumentElement() {
|
||||
document_created_ = true;
|
||||
}
|
||||
|
||||
void AtomRenderFrameObserver::DidCreateScriptContext(
|
||||
v8::Handle<v8::Context> context,
|
||||
int world_id) {
|
||||
@@ -99,4 +160,70 @@ bool AtomRenderFrameObserver::ShouldNotifyClient(int world_id) {
|
||||
return IsMainWorld(world_id);
|
||||
}
|
||||
|
||||
bool AtomRenderFrameObserver::OnMessageReceived(const IPC::Message& message) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(AtomRenderFrameObserver, message)
|
||||
IPC_MESSAGE_HANDLER(AtomFrameMsg_Message, OnBrowserMessage)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
void AtomRenderFrameObserver::OnBrowserMessage(bool send_to_all,
|
||||
const base::string16& channel,
|
||||
const base::ListValue& args) {
|
||||
// Don't handle browser messages before document element is created.
|
||||
// When we receive a message from the browser, we try to transfer it
|
||||
// to a web page, and when we do that Blink creates an empty
|
||||
// document element if it hasn't been created yet, and it makes our init
|
||||
// script to run while `window.location` is still "about:blank".
|
||||
if (!document_created_)
|
||||
return;
|
||||
|
||||
blink::WebLocalFrame* frame = render_frame_->GetWebFrame();
|
||||
if (!frame || !render_frame_->IsMainFrame())
|
||||
return;
|
||||
|
||||
EmitIPCEvent(frame, channel, args);
|
||||
|
||||
// Also send the message to all sub-frames.
|
||||
if (send_to_all) {
|
||||
for (blink::WebFrame* child = frame->FirstChild(); child;
|
||||
child = child->NextSibling())
|
||||
if (child->IsWebLocalFrame()) {
|
||||
EmitIPCEvent(child->ToWebLocalFrame(), channel, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AtomRenderFrameObserver::EmitIPCEvent(blink::WebLocalFrame* frame,
|
||||
const base::string16& channel,
|
||||
const base::ListValue& args) {
|
||||
if (!frame)
|
||||
return;
|
||||
|
||||
v8::Isolate* isolate = blink::MainThreadIsolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
v8::Local<v8::Context> context = renderer_client_->GetContext(frame, isolate);
|
||||
v8::Context::Scope context_scope(context);
|
||||
|
||||
// Only emit IPC event for context with node integration.
|
||||
node::Environment* env = node::Environment::GetCurrent(context);
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
v8::Local<v8::Object> ipc;
|
||||
if (GetIPCObject(isolate, context, &ipc)) {
|
||||
TRACE_EVENT0("devtools.timeline", "FunctionCall");
|
||||
auto args_vector = ListValueToVector(isolate, args);
|
||||
// Insert the Event object, event.sender is ipc.
|
||||
mate::Dictionary event = mate::Dictionary::CreateEmpty(isolate);
|
||||
event.Set("sender", ipc);
|
||||
args_vector.insert(args_vector.begin(), event.GetHandle());
|
||||
mate::EmitEvent(isolate, ipc, channel, args_vector);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -6,7 +6,13 @@
|
||||
#define ATOM_RENDERER_ATOM_RENDER_FRAME_OBSERVER_H_
|
||||
|
||||
#include "atom/renderer/renderer_client_base.h"
|
||||
#include "base/strings/string16.h"
|
||||
#include "content/public/renderer/render_frame_observer.h"
|
||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||
|
||||
namespace base {
|
||||
class ListValue;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -31,15 +37,26 @@ class AtomRenderFrameObserver : public content::RenderFrameObserver {
|
||||
void WillReleaseScriptContext(v8::Local<v8::Context> context,
|
||||
int world_id) override;
|
||||
void OnDestruct() override;
|
||||
bool OnMessageReceived(const IPC::Message& message) override;
|
||||
void DidCreateDocumentElement() override;
|
||||
|
||||
protected:
|
||||
virtual void EmitIPCEvent(blink::WebLocalFrame* frame,
|
||||
const base::string16& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
private:
|
||||
bool ShouldNotifyClient(int world_id);
|
||||
void CreateIsolatedWorldContext();
|
||||
bool IsMainWorld(int world_id);
|
||||
bool IsIsolatedWorld(int world_id);
|
||||
void OnBrowserMessage(bool send_to_all,
|
||||
const base::string16& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
content::RenderFrame* render_frame_;
|
||||
RendererClientBase* renderer_client_;
|
||||
bool document_created_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomRenderFrameObserver);
|
||||
};
|
||||
|
||||
@@ -4,118 +4,21 @@
|
||||
|
||||
#include "atom/renderer/atom_render_view_observer.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Put this before event_emitter_caller.h to have string16 support.
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/api/event_emitter_caller.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/renderer/atom_renderer_client.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/trace_event/trace_event.h"
|
||||
#include "content/public/renderer/render_view.h"
|
||||
#include "ipc/ipc_message_macros.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/net_module.h"
|
||||
#include "net/grit/net_resources.h"
|
||||
#include "third_party/WebKit/public/web/WebDocument.h"
|
||||
#include "third_party/WebKit/public/web/WebElement.h"
|
||||
#include "third_party/WebKit/public/web/WebFrame.h"
|
||||
#include "third_party/WebKit/public/web/WebKit.h"
|
||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||
#include "third_party/WebKit/public/web/WebView.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
AtomRenderViewObserver::AtomRenderViewObserver(content::RenderView* render_view)
|
||||
: content::RenderViewObserver(render_view) {}
|
||||
|
||||
bool GetIPCObject(v8::Isolate* isolate,
|
||||
v8::Local<v8::Context> context,
|
||||
v8::Local<v8::Object>* ipc) {
|
||||
v8::Local<v8::String> key = mate::StringToV8(isolate, "ipc");
|
||||
v8::Local<v8::Private> privateKey = v8::Private::ForApi(isolate, key);
|
||||
v8::Local<v8::Object> global_object = context->Global();
|
||||
v8::Local<v8::Value> value;
|
||||
if (!global_object->GetPrivate(context, privateKey).ToLocal(&value))
|
||||
return false;
|
||||
if (value.IsEmpty() || !value->IsObject())
|
||||
return false;
|
||||
*ipc = value->ToObject();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<v8::Local<v8::Value>> ListValueToVector(
|
||||
v8::Isolate* isolate,
|
||||
const base::ListValue& list) {
|
||||
v8::Local<v8::Value> array = mate::ConvertToV8(isolate, list);
|
||||
std::vector<v8::Local<v8::Value>> result;
|
||||
mate::ConvertFromV8(isolate, array, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
base::StringPiece NetResourceProvider(int key) {
|
||||
if (key == IDR_DIR_HEADER_HTML) {
|
||||
base::StringPiece html_data =
|
||||
ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
|
||||
IDR_DIR_HEADER_HTML);
|
||||
return html_data;
|
||||
}
|
||||
return base::StringPiece();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomRenderViewObserver::AtomRenderViewObserver(
|
||||
content::RenderView* render_view,
|
||||
AtomRendererClient* renderer_client)
|
||||
: content::RenderViewObserver(render_view),
|
||||
renderer_client_(renderer_client) {
|
||||
// Initialise resource for directory listing.
|
||||
net::NetModule::SetResourceProvider(NetResourceProvider);
|
||||
}
|
||||
|
||||
AtomRenderViewObserver::~AtomRenderViewObserver() {
|
||||
}
|
||||
|
||||
void AtomRenderViewObserver::EmitIPCEvent(blink::WebLocalFrame* frame,
|
||||
const base::string16& channel,
|
||||
const base::ListValue& args) {
|
||||
if (!frame)
|
||||
return;
|
||||
|
||||
v8::Isolate* isolate = blink::MainThreadIsolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
v8::Local<v8::Context> context = renderer_client_->GetContext(frame, isolate);
|
||||
v8::Context::Scope context_scope(context);
|
||||
|
||||
// Only emit IPC event for context with node integration.
|
||||
node::Environment* env = node::Environment::GetCurrent(context);
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
v8::Local<v8::Object> ipc;
|
||||
if (GetIPCObject(isolate, context, &ipc)) {
|
||||
TRACE_EVENT0("devtools.timeline", "FunctionCall");
|
||||
auto args_vector = ListValueToVector(isolate, args);
|
||||
// Insert the Event object, event.sender is ipc.
|
||||
mate::Dictionary event = mate::Dictionary::CreateEmpty(isolate);
|
||||
event.Set("sender", ipc);
|
||||
args_vector.insert(args_vector.begin(), event.GetHandle());
|
||||
mate::EmitEvent(isolate, ipc, channel, args_vector);
|
||||
}
|
||||
}
|
||||
AtomRenderViewObserver::~AtomRenderViewObserver() {}
|
||||
|
||||
bool AtomRenderViewObserver::OnMessageReceived(const IPC::Message& message) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(AtomRenderViewObserver, message)
|
||||
IPC_MESSAGE_HANDLER(AtomViewMsg_Message, OnBrowserMessage)
|
||||
IPC_MESSAGE_HANDLER(AtomViewMsg_Offscreen, OnOffscreen)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
@@ -127,39 +30,6 @@ void AtomRenderViewObserver::OnDestruct() {
|
||||
delete this;
|
||||
}
|
||||
|
||||
void AtomRenderViewObserver::OnBrowserMessage(bool send_to_all,
|
||||
const base::string16& channel,
|
||||
const base::ListValue& args) {
|
||||
if (!render_view()->GetWebView())
|
||||
return;
|
||||
|
||||
blink::WebFrame* frame = render_view()->GetWebView()->MainFrame();
|
||||
if (!frame || !frame->IsWebLocalFrame())
|
||||
return;
|
||||
|
||||
// Don't handle browser messages before document element is created.
|
||||
// When we receive a message from the browser, we try to transfer it
|
||||
// to a web page, and when we do that Blink creates an empty
|
||||
// document element if it hasn't been created yet, and it makes our init
|
||||
// script to run while `window.location` is still "about:blank".
|
||||
blink::WebDocument document = frame->ToWebLocalFrame()->GetDocument();
|
||||
blink::WebElement html_element = document.DocumentElement();
|
||||
if (html_element.IsNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
EmitIPCEvent(frame->ToWebLocalFrame(), channel, args);
|
||||
|
||||
// Also send the message to all sub-frames.
|
||||
if (send_to_all) {
|
||||
for (blink::WebFrame* child = frame->FirstChild(); child;
|
||||
child = child->NextSibling())
|
||||
if (child->IsWebLocalFrame()) {
|
||||
EmitIPCEvent(child->ToWebLocalFrame(), channel, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AtomRenderViewObserver::OnOffscreen() {
|
||||
blink::WebView::SetUseExternalPopupMenus(false);
|
||||
}
|
||||
|
||||
@@ -5,43 +5,24 @@
|
||||
#ifndef ATOM_RENDERER_ATOM_RENDER_VIEW_OBSERVER_H_
|
||||
#define ATOM_RENDERER_ATOM_RENDER_VIEW_OBSERVER_H_
|
||||
|
||||
#include "base/strings/string16.h"
|
||||
#include "content/public/renderer/render_view_observer.h"
|
||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||
|
||||
namespace base {
|
||||
class ListValue;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomRendererClient;
|
||||
|
||||
class AtomRenderViewObserver : public content::RenderViewObserver {
|
||||
public:
|
||||
explicit AtomRenderViewObserver(content::RenderView* render_view,
|
||||
AtomRendererClient* renderer_client);
|
||||
explicit AtomRenderViewObserver(content::RenderView* render_view);
|
||||
|
||||
protected:
|
||||
virtual ~AtomRenderViewObserver();
|
||||
|
||||
virtual void EmitIPCEvent(blink::WebLocalFrame* frame,
|
||||
const base::string16& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
private:
|
||||
// content::RenderViewObserver implementation.
|
||||
bool OnMessageReceived(const IPC::Message& message) override;
|
||||
void OnDestruct() override;
|
||||
|
||||
void OnBrowserMessage(bool send_to_all,
|
||||
const base::string16& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
void OnOffscreen();
|
||||
|
||||
AtomRendererClient* renderer_client_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomRenderViewObserver);
|
||||
};
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "atom/renderer/api/atom_api_renderer_ipc.h"
|
||||
#include "atom/renderer/atom_render_frame_observer.h"
|
||||
#include "atom/renderer/atom_render_view_observer.h"
|
||||
#include "atom/renderer/web_worker_observer.h"
|
||||
#include "base/command_line.h"
|
||||
#include "content/public/common/web_preferences.h"
|
||||
#include "content/public/renderer/render_frame.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "third_party/WebKit/public/web/WebDocument.h"
|
||||
@@ -53,11 +53,11 @@ void AtomRendererClient::RenderThreadStarted() {
|
||||
|
||||
void AtomRendererClient::RenderFrameCreated(
|
||||
content::RenderFrame* render_frame) {
|
||||
new AtomRenderFrameObserver(render_frame, this);
|
||||
RendererClientBase::RenderFrameCreated(render_frame);
|
||||
}
|
||||
|
||||
void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) {
|
||||
new AtomRenderViewObserver(render_view, this);
|
||||
RendererClientBase::RenderViewCreated(render_view);
|
||||
}
|
||||
|
||||
@@ -83,11 +83,22 @@ void AtomRendererClient::RunScriptsAtDocumentEnd(
|
||||
|
||||
void AtomRendererClient::DidCreateScriptContext(
|
||||
v8::Handle<v8::Context> context, content::RenderFrame* render_frame) {
|
||||
RendererClientBase::DidCreateScriptContext(context, render_frame);
|
||||
|
||||
// Only allow node integration for the main frame, unless it is a devtools
|
||||
// extension page.
|
||||
if (!render_frame->IsMainFrame() && !IsDevToolsExtension(render_frame))
|
||||
return;
|
||||
|
||||
// Don't allow node integration if this is a child window and it does not have
|
||||
// node integration enabled. Otherwise we would have memory leak in the child
|
||||
// window since we don't clean up node environments.
|
||||
//
|
||||
// TODO(zcbenz): We shouldn't allow node integration even for the top frame.
|
||||
if (!render_frame->GetWebkitPreferences().node_integration &&
|
||||
render_frame->GetWebFrame()->Opener())
|
||||
return;
|
||||
|
||||
// Prepare the node bindings.
|
||||
if (!node_integration_initialized_) {
|
||||
node_integration_initialized_ = true;
|
||||
|
||||
@@ -13,20 +13,14 @@
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "atom/renderer/api/atom_api_renderer_ipc.h"
|
||||
#include "atom/renderer/atom_render_view_observer.h"
|
||||
#include "atom/renderer/atom_render_frame_observer.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "chrome/renderer/printing/print_web_view_helper.h"
|
||||
#include "content/public/renderer/render_frame.h"
|
||||
#include "content/public/renderer/render_view.h"
|
||||
#include "content/public/renderer/render_view_observer.h"
|
||||
#include "ipc/ipc_message_macros.h"
|
||||
#include "native_mate/converter.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "third_party/WebKit/public/web/WebFrame.h"
|
||||
#include "third_party/WebKit/public/web/WebDocument.h"
|
||||
#include "third_party/WebKit/public/web/WebKit.h"
|
||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||
#include "third_party/WebKit/public/web/WebScriptSource.h"
|
||||
#include "third_party/WebKit/public/web/WebView.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom_natives.h" // NOLINT: This file is generated with js2c
|
||||
@@ -38,6 +32,11 @@ namespace {
|
||||
const std::string kIpcKey = "ipcNative";
|
||||
const std::string kModuleCacheKey = "native-module-cache";
|
||||
|
||||
bool IsDevTools(content::RenderFrame* render_frame) {
|
||||
return render_frame->GetWebFrame()->GetDocument().Url()
|
||||
.ProtocolIs("chrome-devtools");
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> GetModuleCache(v8::Isolate* isolate) {
|
||||
mate::Dictionary global(isolate, isolate->GetCurrentContext()->Global());
|
||||
v8::Local<v8::Value> cache;
|
||||
@@ -95,20 +94,20 @@ void InitializeBindings(v8::Local<v8::Object> binding,
|
||||
b.SetMethod("getSystemMemoryInfo", &AtomBindings::GetSystemMemoryInfo);
|
||||
}
|
||||
|
||||
class AtomSandboxedRenderViewObserver : public AtomRenderViewObserver {
|
||||
class AtomSandboxedRenderFrameObserver : public AtomRenderFrameObserver {
|
||||
public:
|
||||
AtomSandboxedRenderViewObserver(content::RenderView* render_view,
|
||||
AtomSandboxedRendererClient* renderer_client)
|
||||
: AtomRenderViewObserver(render_view, nullptr),
|
||||
v8_converter_(new atom::V8ValueConverter),
|
||||
renderer_client_(renderer_client) {
|
||||
v8_converter_->SetDisableNode(true);
|
||||
}
|
||||
AtomSandboxedRenderFrameObserver(content::RenderFrame* render_frame,
|
||||
AtomSandboxedRendererClient* renderer_client)
|
||||
: AtomRenderFrameObserver(render_frame, renderer_client),
|
||||
v8_converter_(new atom::V8ValueConverter),
|
||||
renderer_client_(renderer_client) {
|
||||
v8_converter_->SetDisableNode(true);
|
||||
}
|
||||
|
||||
protected:
|
||||
void EmitIPCEvent(blink::WebLocalFrame* frame,
|
||||
const base::string16& channel,
|
||||
const base::ListValue& args) override {
|
||||
const base::ListValue& args) {
|
||||
if (!frame)
|
||||
return;
|
||||
|
||||
@@ -129,7 +128,7 @@ class AtomSandboxedRenderViewObserver : public AtomRenderViewObserver {
|
||||
private:
|
||||
std::unique_ptr<atom::V8ValueConverter> v8_converter_;
|
||||
AtomSandboxedRendererClient* renderer_client_;
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomSandboxedRenderViewObserver);
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomSandboxedRenderFrameObserver);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -143,27 +142,27 @@ AtomSandboxedRendererClient::~AtomSandboxedRendererClient() {
|
||||
|
||||
void AtomSandboxedRendererClient::RenderFrameCreated(
|
||||
content::RenderFrame* render_frame) {
|
||||
new AtomSandboxedRenderFrameObserver(render_frame, this);
|
||||
RendererClientBase::RenderFrameCreated(render_frame);
|
||||
}
|
||||
|
||||
void AtomSandboxedRendererClient::RenderViewCreated(
|
||||
content::RenderView* render_view) {
|
||||
new AtomSandboxedRenderViewObserver(render_view, this);
|
||||
RendererClientBase::RenderViewCreated(render_view);
|
||||
}
|
||||
|
||||
void AtomSandboxedRendererClient::DidCreateScriptContext(
|
||||
v8::Handle<v8::Context> context, content::RenderFrame* render_frame) {
|
||||
RendererClientBase::DidCreateScriptContext(context, render_frame);
|
||||
|
||||
// Only allow preload for the main frame
|
||||
if (!render_frame->IsMainFrame())
|
||||
// Only allow preload for the main frame or
|
||||
// For devtools we still want to run the preload_bundle script
|
||||
if (!render_frame->IsMainFrame() && !IsDevTools(render_frame))
|
||||
return;
|
||||
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
std::string preload_script = command_line->GetSwitchValueASCII(
|
||||
base::FilePath preload_script_path = command_line->GetSwitchValuePath(
|
||||
switches::kPreloadScript);
|
||||
if (preload_script.empty())
|
||||
return;
|
||||
|
||||
auto isolate = context->GetIsolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
@@ -188,7 +187,7 @@ void AtomSandboxedRendererClient::DidCreateScriptContext(
|
||||
AddRenderBindings(isolate, binding);
|
||||
v8::Local<v8::Value> args[] = {
|
||||
binding,
|
||||
mate::ConvertToV8(isolate, preload_script)
|
||||
mate::ConvertToV8(isolate, preload_script_path.value())
|
||||
};
|
||||
// Execute the function with proper arguments
|
||||
ignore_result(func->Call(context, v8::Null(isolate), 2, args));
|
||||
|
||||
@@ -13,12 +13,15 @@
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "atom/renderer/atom_autofill_agent.h"
|
||||
#include "atom/renderer/atom_render_frame_observer.h"
|
||||
#include "atom/renderer/atom_render_view_observer.h"
|
||||
#include "atom/renderer/content_settings_observer.h"
|
||||
#include "atom/renderer/guest_view_container.h"
|
||||
#include "atom/renderer/preferences_manager.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/process/process_handle.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "chrome/renderer/media/chrome_key_systems.h"
|
||||
#include "chrome/renderer/pepper/pepper_helper.h"
|
||||
#include "chrome/renderer/printing/print_web_view_helper.h"
|
||||
@@ -26,13 +29,13 @@
|
||||
#include "content/public/common/content_constants.h"
|
||||
#include "content/public/renderer/render_view.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "third_party/WebKit/public/web/WebCustomElement.h"
|
||||
#include "third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h"
|
||||
#include "third_party/WebKit/public/web/WebCustomElement.h" // NOLINT(build/include_alpha)
|
||||
#include "third_party/WebKit/public/web/WebFrameWidget.h"
|
||||
#include "third_party/WebKit/public/web/WebKit.h"
|
||||
#include "third_party/WebKit/public/web/WebPluginParams.h"
|
||||
#include "third_party/WebKit/public/web/WebScriptSource.h"
|
||||
#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
|
||||
#include "third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "base/mac/mac_util.h"
|
||||
@@ -43,6 +46,14 @@
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
// This is defined in later versions of Chromium, remove this if you see
|
||||
// compiler complaining duplicate defines.
|
||||
#if defined(OS_WIN) || defined(OS_FUCHSIA)
|
||||
#define CrPRIdPid "ld"
|
||||
#else
|
||||
#define CrPRIdPid "d"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
@@ -77,6 +88,19 @@ RendererClientBase::RendererClientBase() {
|
||||
RendererClientBase::~RendererClientBase() {
|
||||
}
|
||||
|
||||
void RendererClientBase::DidCreateScriptContext(
|
||||
v8::Handle<v8::Context> context,
|
||||
content::RenderFrame* render_frame) {
|
||||
// global.setHidden("contextId", `${processId}-${++nextContextId}`)
|
||||
std::string context_id = base::StringPrintf(
|
||||
"%" CrPRIdPid "-%d", base::GetCurrentProcId(), ++next_context_id_);
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
v8::Local<v8::String> key = mate::StringToSymbol(isolate, "contextId");
|
||||
v8::Local<v8::Private> private_key = v8::Private::ForApi(isolate, key);
|
||||
v8::Local<v8::Value> value = mate::ConvertToV8(isolate, context_id);
|
||||
context->Global()->SetPrivate(context, private_key, value);
|
||||
}
|
||||
|
||||
void RendererClientBase::AddRenderBindings(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> binding_object) {
|
||||
@@ -144,7 +168,6 @@ void RendererClientBase::RenderThreadStarted() {
|
||||
|
||||
void RendererClientBase::RenderFrameCreated(
|
||||
content::RenderFrame* render_frame) {
|
||||
new AtomRenderFrameObserver(render_frame, this);
|
||||
new AutofillAgent(render_frame);
|
||||
new PepperHelper(render_frame);
|
||||
new ContentSettingsObserver(render_frame);
|
||||
@@ -159,6 +182,7 @@ void RendererClientBase::RenderFrameCreated(
|
||||
}
|
||||
|
||||
void RendererClientBase::RenderViewCreated(content::RenderView* render_view) {
|
||||
new AtomRenderViewObserver(render_view);
|
||||
blink::WebFrameWidget* web_frame_widget = render_view->GetWebFrameWidget();
|
||||
if (!web_frame_widget)
|
||||
return;
|
||||
|
||||
@@ -21,7 +21,7 @@ class RendererClientBase : public content::ContentRendererClient {
|
||||
virtual ~RendererClientBase();
|
||||
|
||||
virtual void DidCreateScriptContext(
|
||||
v8::Handle<v8::Context> context, content::RenderFrame* render_frame) = 0;
|
||||
v8::Handle<v8::Context> context, content::RenderFrame* render_frame);
|
||||
virtual void WillReleaseScriptContext(
|
||||
v8::Handle<v8::Context> context, content::RenderFrame* render_frame) = 0;
|
||||
virtual void DidClearWindowObject(content::RenderFrame* render_frame);
|
||||
@@ -57,6 +57,9 @@ class RendererClientBase : public content::ContentRendererClient {
|
||||
private:
|
||||
std::unique_ptr<PreferencesManager> preferences_manager_;
|
||||
bool isolated_world_;
|
||||
|
||||
// An increasing ID used for indentifying an V8 context in this process.
|
||||
int next_context_id_ = 0;
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -4,6 +4,13 @@
|
||||
|
||||
#include "atom/utility/atom_content_utility_client.h"
|
||||
|
||||
#include "content/public/common/service_manager_connection.h"
|
||||
#include "content/public/common/simple_connection_filter.h"
|
||||
#include "content/public/utility/utility_thread.h"
|
||||
#include "mojo/public/cpp/bindings/strong_binding.h"
|
||||
#include "net/proxy/mojo_proxy_resolver_factory_impl.h"
|
||||
#include "services/service_manager/public/cpp/binder_registry.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "chrome/utility/printing_handler_win.h"
|
||||
@@ -11,6 +18,16 @@
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
void CreateProxyResolverFactory(
|
||||
net::interfaces::ProxyResolverFactoryRequest request) {
|
||||
mojo::MakeStrongBinding(base::MakeUnique<net::MojoProxyResolverFactoryImpl>(),
|
||||
std::move(request));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomContentUtilityClient::AtomContentUtilityClient() {
|
||||
#if defined(OS_WIN)
|
||||
handlers_.push_back(base::MakeUnique<printing::PrintingHandlerWin>());
|
||||
@@ -20,6 +37,23 @@ AtomContentUtilityClient::AtomContentUtilityClient() {
|
||||
AtomContentUtilityClient::~AtomContentUtilityClient() {
|
||||
}
|
||||
|
||||
void AtomContentUtilityClient::UtilityThreadStarted() {
|
||||
content::ServiceManagerConnection* connection =
|
||||
content::ChildThread::Get()->GetServiceManagerConnection();
|
||||
|
||||
// NOTE: Some utility process instances are not connected to the Service
|
||||
// Manager. Nothing left to do in that case.
|
||||
if (!connection)
|
||||
return;
|
||||
|
||||
auto registry = base::MakeUnique<service_manager::BinderRegistry>();
|
||||
registry->AddInterface<net::interfaces::ProxyResolverFactory>(
|
||||
base::Bind(CreateProxyResolverFactory),
|
||||
base::ThreadTaskRunnerHandle::Get());
|
||||
connection->AddConnectionFilter(
|
||||
base::MakeUnique<content::SimpleConnectionFilter>(std::move(registry)));
|
||||
}
|
||||
|
||||
bool AtomContentUtilityClient::OnMessageReceived(
|
||||
const IPC::Message& message) {
|
||||
#if defined(OS_WIN)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user