mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
87 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9dcbbb08db | ||
|
|
bab968ca77 | ||
|
|
7fa3eba951 | ||
|
|
c0efff45fa | ||
|
|
5eac44126f | ||
|
|
b2cec7b602 | ||
|
|
f6328a515d | ||
|
|
47fe11e281 | ||
|
|
0be8732f03 | ||
|
|
9c466846ed | ||
|
|
67b75fe204 | ||
|
|
ef6e045241 | ||
|
|
95f0eeeb37 | ||
|
|
dfa394ba29 | ||
|
|
5f6997caee | ||
|
|
fed76dcfaa | ||
|
|
42d284607e | ||
|
|
3e2fff287a | ||
|
|
11ce66b79a | ||
|
|
1a48ee2827 | ||
|
|
413519b081 | ||
|
|
d701526a55 | ||
|
|
924e372def | ||
|
|
a27b7d1f10 | ||
|
|
d3d8c1626a | ||
|
|
8b6aa225ae | ||
|
|
e02440e0d8 | ||
|
|
cd5bdc88c3 | ||
|
|
9021989cfd | ||
|
|
4a61a8dd34 | ||
|
|
04efcac8cc | ||
|
|
6f27d5dd51 | ||
|
|
7fb00bfca7 | ||
|
|
b22734ccc1 | ||
|
|
a69a5de12f | ||
|
|
d2a9ea4684 | ||
|
|
e7074c5cdb | ||
|
|
97349eb30a | ||
|
|
f6c915bbb5 | ||
|
|
378666668f | ||
|
|
9623329cbd | ||
|
|
34b75e5e73 | ||
|
|
c339e576a8 | ||
|
|
c12d88fc30 | ||
|
|
8f2064d9b7 | ||
|
|
75ff5d2a45 | ||
|
|
87565e25eb | ||
|
|
d0c9c4028e | ||
|
|
37f23f6d4e | ||
|
|
4b8f3276b5 | ||
|
|
b15c418c54 | ||
|
|
d964560990 | ||
|
|
66e0e8fdcd | ||
|
|
c16498c274 | ||
|
|
62bd339b0d | ||
|
|
0368460d74 | ||
|
|
9386de415a | ||
|
|
4d3d7aa5fd | ||
|
|
1d0dfd590b | ||
|
|
5b679cb1eb | ||
|
|
8c28e3b6f1 | ||
|
|
f786199d2c | ||
|
|
acfc24e45e | ||
|
|
01ca2252cd | ||
|
|
53db3862c0 | ||
|
|
6099ab222e | ||
|
|
830cc7ecd1 | ||
|
|
eef8ff09e2 | ||
|
|
b15392e1c1 | ||
|
|
fd1bb3f95d | ||
|
|
53eb4d68c5 | ||
|
|
331a1759d2 | ||
|
|
b69d76258a | ||
|
|
680bf0076b | ||
|
|
d42d856b9a | ||
|
|
e6f6862ae8 | ||
|
|
44b4cc374b | ||
|
|
9824c88d2d | ||
|
|
96bc46c255 | ||
|
|
873a8902af | ||
|
|
7dac300305 | ||
|
|
2a536d2aa2 | ||
|
|
ccd03c6675 | ||
|
|
5515092944 | ||
|
|
fb7661d2d2 | ||
|
|
75b31f0bb6 | ||
|
|
cfee5ba8c8 |
@@ -3,10 +3,10 @@ version: 2
|
||||
jobs:
|
||||
electron-linux-arm:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.3
|
||||
- image: electronbuilds/electron:0.0.7
|
||||
environment:
|
||||
TARGET_ARCH: arm
|
||||
resource_class: xlarge
|
||||
resource_class: 2xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
@@ -58,71 +58,30 @@ jobs:
|
||||
else
|
||||
echo 'Skipping upload distribution because build is not for release'
|
||||
fi
|
||||
electron-linux-arm64:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.3
|
||||
environment:
|
||||
TARGET_ARCH: arm64
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Check for release
|
||||
name: Zip out directory
|
||||
command: |
|
||||
if [ -n "${RUN_RELEASE_BUILD}" ]; then
|
||||
echo 'release build triggered from api'
|
||||
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
|
||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||
zip -r electron.zip out/D
|
||||
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
|
||||
- persist_to_workspace:
|
||||
root: /home/builduser
|
||||
paths:
|
||||
- project/out
|
||||
- store_artifacts:
|
||||
path: electron.zip
|
||||
electron-linux-ia32:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.3
|
||||
- image: electronbuilds/electron:0.0.7
|
||||
environment:
|
||||
TARGET_ARCH: ia32
|
||||
DISPLAY: ':99.0'
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Setup for headless testing
|
||||
command: sh -e /etc/init.d/xvfb start
|
||||
- run:
|
||||
name: Check for release
|
||||
command: |
|
||||
@@ -172,9 +131,36 @@ jobs:
|
||||
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'
|
||||
out/D/electron --version
|
||||
mkdir junit
|
||||
script/test.py --ci
|
||||
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
|
||||
- store_test_results:
|
||||
path: junit
|
||||
- store_artifacts:
|
||||
path: junit
|
||||
electron-linux-mips64el:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.3
|
||||
- image: electronbuilds/electron:0.0.7
|
||||
environment:
|
||||
TARGET_ARCH: mips64el
|
||||
resource_class: xlarge
|
||||
@@ -232,7 +218,7 @@ jobs:
|
||||
|
||||
electron-linux-x64:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.3
|
||||
- image: electronbuilds/electron:0.0.7
|
||||
environment:
|
||||
TARGET_ARCH: x64
|
||||
DISPLAY: ':99.0'
|
||||
@@ -300,7 +286,7 @@ jobs:
|
||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||
echo 'Testing Electron debug build'
|
||||
mkdir junit
|
||||
script/test.py --ci --rebuild_native_modules
|
||||
script/test.py --ci
|
||||
else
|
||||
echo 'Skipping testing on release build'
|
||||
fi
|
||||
@@ -325,20 +311,214 @@ jobs:
|
||||
- store_artifacts:
|
||||
path: out/electron-api.json
|
||||
|
||||
electron-osx-x64:
|
||||
environment:
|
||||
TARGET_ARCH: x64
|
||||
macos:
|
||||
xcode: "8.3.3"
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Install node
|
||||
command: |
|
||||
brew update
|
||||
brew install node@8
|
||||
brew link node@8 --force
|
||||
- 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
|
||||
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: "8.3.3"
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Install node
|
||||
command: |
|
||||
brew update
|
||||
brew install node@8
|
||||
brew link node@8 --force
|
||||
- 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
|
||||
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
|
||||
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build-arm:
|
||||
jobs:
|
||||
- electron-linux-arm
|
||||
build-arm64:
|
||||
jobs:
|
||||
- electron-linux-arm64
|
||||
build-ia32:
|
||||
jobs:
|
||||
- electron-linux-ia32
|
||||
build-x64:
|
||||
jobs:
|
||||
- electron-linux-x64
|
||||
build-mips64el:
|
||||
build-osx-x64:
|
||||
jobs:
|
||||
- electron-linux-mips64el
|
||||
- electron-osx-x64
|
||||
build-mas-x64:
|
||||
jobs:
|
||||
- electron-mas-x64
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
*
|
||||
!tools/xvfb-init.sh
|
||||
21
.github/CODEOWNERS
vendored
21
.github/CODEOWNERS
vendored
@@ -1,21 +0,0 @@
|
||||
# Order is important. The LAST matching pattern has the MOST precedence.
|
||||
# gitignore style patterns are used, not globs.
|
||||
# https://help.github.com/articles/about-codeowners
|
||||
# https://git-scm.com/docs/gitignore
|
||||
|
||||
# Everything that falls through the cracks:
|
||||
* @electron/reviewers
|
||||
|
||||
# filename patterns
|
||||
*browser_view* @electron/browserview
|
||||
*notification* @electron/notifications
|
||||
*pdf* @electron/printing
|
||||
*printing* @electron/printing
|
||||
*updater* @electron/updater
|
||||
|
||||
# directories
|
||||
/.github/ @electron/hubbers
|
||||
/default_app/ @electron/docs
|
||||
/docs/ @electron/docs
|
||||
/docs-translations/ @electron/i18n
|
||||
/npm/ @electron/hubbers
|
||||
29
.github/config.yml
vendored
29
.github/config.yml
vendored
@@ -1,29 +0,0 @@
|
||||
# Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome
|
||||
|
||||
# Comment to be posted to on first time issues
|
||||
newIssueWelcomeComment: |
|
||||
👋 Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.
|
||||
|
||||
To help make it easier for us to investigate your issue, please follow the [contributing guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md#submitting-issues).
|
||||
|
||||
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
|
||||
|
||||
# Comment to be posted to on PRs from first time contributors in your repository
|
||||
newPRWelcomeComment: |
|
||||
💖 Thanks for opening this pull request! 💖
|
||||
|
||||
Here is a list of things that will help get it across the finish line:
|
||||
- Follow the JavaScript, C++, and Python [coding style](https://github.com/electron/electron/blob/master/docs/development/coding-style.md).
|
||||
- Run `npm run lint` locally to catch formatting errors earlier.
|
||||
- Document any user-facing changes you've made following the [documentation styleguide](https://github.com/electron/electron/blob/master/docs/styleguide.md).
|
||||
- Include tests when adding/changing behavior.
|
||||
- Include screenshots and animated GIFs whenever possible.
|
||||
We get a lot of pull requests on this repo, so please be patient and we will get back to you as soon as we can.
|
||||
|
||||
# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
|
||||
|
||||
# Comment to be posted to on pull requests merged by a first time user
|
||||
firstPRMergeComment: >
|
||||
Congrats on merging your first pull request! 🎉🎉🎉
|
||||
|
||||
# It is recommend to include as many gifs and emojis as possiblec
|
||||
25
.github/stale.yml
vendored
25
.github/stale.yml
vendored
@@ -1,25 +0,0 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 45
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- fixme/bug
|
||||
- fixme/crash
|
||||
- fixme/regression
|
||||
- fixme/security
|
||||
- blocked
|
||||
- blocking-stable
|
||||
- needs-review
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity and is not currently prioritized. It will be closed
|
||||
in a week if no further activity occurs :)
|
||||
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
If you still think this issue is relevant, please ping a maintainer or
|
||||
leave a comment!
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,6 +1,5 @@
|
||||
.DS_Store
|
||||
.env
|
||||
.gclient_done
|
||||
.npmrc
|
||||
.tags*
|
||||
.vs/
|
||||
@@ -15,6 +14,7 @@
|
||||
*.vcxproj.filters
|
||||
*.vcxproj.user
|
||||
*.xcodeproj
|
||||
node_modules/
|
||||
/.idea/
|
||||
/brightray/brightray.opensdf
|
||||
/brightray/brightray.sdf
|
||||
@@ -28,12 +28,10 @@
|
||||
/external_binaries/
|
||||
/out/
|
||||
/vendor/.gclient
|
||||
/vendor/cross-gcc-4.9.3-n64-loongson-rc5.4
|
||||
/vendor/debian_jessie_amd64-sysroot/
|
||||
/vendor/debian_jessie_arm-sysroot/
|
||||
/vendor/debian_jessie_arm64-sysroot/
|
||||
/vendor/debian_jessie_i386-sysroot/
|
||||
/vendor/debian_jessie_mips64-sysroot/
|
||||
/vendor/debian_wheezy_amd64-sysroot/
|
||||
/vendor/debian_wheezy_arm-sysroot/
|
||||
/vendor/debian_wheezy_i386-sysroot/
|
||||
@@ -43,5 +41,3 @@
|
||||
/vendor/node/deps/node-inspect/.npmrc
|
||||
/vendor/npm/
|
||||
/vendor/python_26/
|
||||
node_modules/
|
||||
SHASUMS256.txt
|
||||
|
||||
@@ -1 +1 @@
|
||||
v8.2.1
|
||||
v7.9.0
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"plugins": [
|
||||
["remark-lint-code-block-style", "fenced"],
|
||||
["remark-lint-fenced-code-flag"]
|
||||
]
|
||||
}
|
||||
@@ -5,7 +5,7 @@ notifications:
|
||||
|
||||
before_install:
|
||||
- export BOTO_CONFIG=/dev/null
|
||||
|
||||
|
||||
language: node_js
|
||||
node_js:
|
||||
- "4"
|
||||
@@ -22,8 +22,6 @@ matrix:
|
||||
env: TARGET_ARCH=arm
|
||||
- os: linux
|
||||
env: TARGET_ARCH=ia32
|
||||
- os: linux
|
||||
env: TARGET_ARCH=arm64
|
||||
allow_failures:
|
||||
- os: osx
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Contributor Covenant Code of Conduct:
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
@@ -40,7 +40,7 @@ Project maintainers who do not follow or enforce the Code of Conduct in good fai
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor-Covenant][homepage], version 1.4, available at [https://contributor-covenant.org/version/1/4][version]
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: https://contributor-covenant.org
|
||||
[version]: https://contributor-covenant.org/version/1/4/
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Contributing to Electron
|
||||
|
||||
:memo: Available Translations: [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/CONTRIBUTING.md) | [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/CONTRIBUTING.md) | [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR/project/CONTRIBUTING.md) | [Dutch](https://github.com/electron/electron/tree/master/docs-translations/nl/project/CONTRIBUTING.md)
|
||||
|
||||
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
|
||||
|
||||
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md).
|
||||
@@ -12,7 +14,6 @@ propose changes to this document in a pull request.
|
||||
|
||||
## Submitting Issues
|
||||
|
||||
### Creating Issues
|
||||
* You can create an issue [here](https://github.com/electron/electron/issues/new),
|
||||
but before doing that please read the notes below and include as many details as
|
||||
possible with your report. If you can, please include:
|
||||
@@ -26,15 +27,6 @@ possible with your report. If you can, please include:
|
||||
* Perform a [cursory search](https://github.com/electron/electron/issues?utf8=✓&q=is%3Aissue+)
|
||||
to see if a similar issue has already been submitted
|
||||
|
||||
### Issue Maintenance and Closure
|
||||
* If an issue is inactive for 45 days (no activity of any kind), it will be
|
||||
marked for closure with `stale`.
|
||||
* If after this label is applied, no further activity occurs in the next 7 days,
|
||||
the issue will be closed.
|
||||
* If an issue has been closed and you still feel it's relevant, feel free to
|
||||
ping a maintainer or add a comment!
|
||||
|
||||
|
||||
## Submitting Pull Requests
|
||||
|
||||
* Include screenshots and animated GIFs in your pull request whenever possible.
|
||||
|
||||
18
Dockerfile
18
Dockerfile
@@ -1,18 +0,0 @@
|
||||
FROM electronbuilds/libchromiumcontent:0.0.4
|
||||
|
||||
USER root
|
||||
|
||||
# Set up HOME directory
|
||||
ENV HOME=/home
|
||||
RUN chmod a+rwx /home
|
||||
|
||||
# Install node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
|
||||
RUN apt-get update && apt-get install -y --force-yes nodejs
|
||||
|
||||
# Install wget used by crash reporter
|
||||
RUN apt-get install -y --force-yes wget
|
||||
|
||||
# Add xvfb init script
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
@@ -1,17 +0,0 @@
|
||||
FROM electronbuilds/libchromiumcontent:0.0.4
|
||||
|
||||
USER root
|
||||
|
||||
# Install node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
|
||||
RUN apt-get update && apt-get install -y --force-yes nodejs
|
||||
|
||||
# Install wget used by crash reporter
|
||||
RUN apt-get install -y --force-yes wget
|
||||
|
||||
# Add xvfb init script
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
|
||||
USER builduser
|
||||
WORKDIR /home/builduser
|
||||
50
README.md
50
README.md
@@ -1,22 +1,21 @@
|
||||
[](https://electronjs.org)
|
||||
[](https://electron.atom.io/)
|
||||
|
||||
[](https://travis-ci.org/electron/electron)
|
||||
[](https://ci.appveyor.com/project/electron-bot/electron/branch/master)
|
||||
[](https://david-dm.org/electron/electron?type=dev)
|
||||
[](https://atom-slack.herokuapp.com/)
|
||||
[](http://atom-slack.herokuapp.com/)
|
||||
|
||||
:memo: Available Translations: 🇨🇳 🇹🇼 🇧🇷 🇪🇸 🇰🇷 🇯🇵 🇷🇺 🇫🇷 🇹🇭 🇳🇱 🇹🇷 🇮🇩 🇺🇦 🇨🇿 🇮🇹.
|
||||
View these docs in other languages at [electron/electron-i18n](https://github.com/electron/electron-i18n/tree/master/content/).
|
||||
:memo: Available Translations: [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/README.md) | [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/README.md) | [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR/project/README.md) | [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW/project/README.md) | [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es/project/README.md) | [Turkish](https://github.com/electron/electron/tree/master/docs-translations/tr-TR/project/README.md) | [German](https://github.com/electron/electron/tree/master/docs-translations/de-DE/project/README.md)
|
||||
|
||||
The Electron framework lets you write cross-platform desktop applications
|
||||
using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) and
|
||||
[Chromium](https://www.chromium.org) and is used by the [Atom
|
||||
editor](https://github.com/atom/atom) and many other [apps](https://electronjs.org/apps).
|
||||
[Chromium](http://www.chromium.org) and is used by the [Atom
|
||||
editor](https://github.com/atom/atom) and many other [apps](https://electron.atom.io/apps).
|
||||
|
||||
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
|
||||
announcements.
|
||||
|
||||
This project adheres to the Contributor Covenant
|
||||
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).
|
||||
@@ -33,29 +32,29 @@ npm install electron --save-dev --save-exact
|
||||
|
||||
The `--save-exact` flag is recommended as Electron does not follow semantic
|
||||
versioning. For info on how to manage Electron versions in your apps, see
|
||||
[Electron versioning](https://electronjs.org/docs/tutorial/electron-versioning).
|
||||
[Electron versioning](https://electron.atom.io/docs/tutorial/electron-versioning/).
|
||||
|
||||
For more installation options and troubleshooting tips, see
|
||||
[installation](https://electronjs.org/docs/tutorial/installation).
|
||||
[installation](https://electron.atom.io/docs/tutorial/installation/).
|
||||
|
||||
## Quick start
|
||||
## Quick Start
|
||||
|
||||
Clone and run the
|
||||
Clone and run the
|
||||
[electron/electron-quick-start](https://github.com/electron/electron-quick-start)
|
||||
repository to see a minimal Electron app in action:
|
||||
|
||||
```sh
|
||||
```
|
||||
git clone https://github.com/electron/electron-quick-start
|
||||
cd electron-quick-start
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
## Resources for learning Electron
|
||||
## Resources for Learning Electron
|
||||
|
||||
- [electronjs.org/docs](https://electronjs.org/docs) - all of Electron's documentation
|
||||
- [electron.atom.io/docs](http://electron.atom.io/docs) - all of Electron's documentation
|
||||
- [electron/electron-quick-start](https://github.com/electron/electron-quick-start) - a very basic starter Electron app
|
||||
- [electronjs.org/community#boilerplates](https://electronjs.org/community#boilerplates) - sample starter apps created by the community
|
||||
- [electron.atom.io/community/#boilerplates](http://electron.atom.io/community/#boilerplates) - sample starter apps created by the community
|
||||
- [electron/simple-samples](https://github.com/electron/simple-samples) - small applications with ideas for taking them further
|
||||
- [electron/electron-api-demos](https://github.com/electron/electron-api-demos) - an Electron app that teaches you how to use Electron
|
||||
- [hokein/electron-sample-apps](https://github.com/hokein/electron-sample-apps) - small demo apps for the various Electron APIs
|
||||
@@ -83,21 +82,32 @@ const child = proc.spawn(electron)
|
||||
|
||||
## Documentation Translations
|
||||
|
||||
Find documentation translations in [electron/electron-i18n](https://github.com/electron/electron-i18n).
|
||||
- [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR)
|
||||
- [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR)
|
||||
- [Japanese](https://github.com/electron/electron/tree/master/docs-translations/jp)
|
||||
- [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es)
|
||||
- [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN)
|
||||
- [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW)
|
||||
- [Turkish](https://github.com/electron/electron/tree/master/docs-translations/tr-TR)
|
||||
- [Thai](https://github.com/electron/electron/tree/master/docs-translations/th-TH)
|
||||
- [Ukrainian](https://github.com/electron/electron/tree/master/docs-translations/uk-UA)
|
||||
- [Russian](https://github.com/electron/electron/tree/master/docs-translations/ru-RU)
|
||||
- [French](https://github.com/electron/electron/tree/master/docs-translations/fr-FR)
|
||||
- [Indonesian](https://github.com/electron/electron/tree/master/docs-translations/id)
|
||||
|
||||
## 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
|
||||
- [`electron`](http://discuss.atom.io/c/electron) category on the Atom
|
||||
forums
|
||||
- `#atom-shell` channel on Freenode
|
||||
- [`Atom`](https://atom-slack.herokuapp.com) channel on Slack
|
||||
- [`Atom`](http://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-kr`](http://www.meetup.com/electron-kr/) *(Korean)*
|
||||
- [`electron-jp`](https://electron-jp.slack.com) *(Japanese)*
|
||||
- [`electron-tr`](https://electron-tr.herokuapp.com) *(Turkish)*
|
||||
- [`electron-tr`](http://electron-tr.herokuapp.com) *(Turkish)*
|
||||
- [`electron-id`](https://electron-id.slack.com) *(Indonesia)*
|
||||
|
||||
Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron)
|
||||
|
||||
83
appveyor.yml
83
appveyor.yml
@@ -1,25 +1,58 @@
|
||||
# appveyor file
|
||||
# http://www.appveyor.com/docs/appveyor-yml
|
||||
version: "{build}"
|
||||
|
||||
os: Visual Studio 2015
|
||||
|
||||
init:
|
||||
- git config --global core.autocrlf input
|
||||
|
||||
platform:
|
||||
- x86
|
||||
- x64
|
||||
|
||||
install:
|
||||
- cmd: SET PATH=C:\Program Files (x86)\MSBuild\14.0\bin\;%PATH%
|
||||
- cmd: SET PATH=C:\python27;%PATH%
|
||||
- cmd: python script/cibuild
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
# disable build and test phases
|
||||
build: off
|
||||
test: off
|
||||
build_cloud: electron-16
|
||||
image: electron-16-vs2015
|
||||
build_script:
|
||||
- ps: >-
|
||||
if(($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) {\n if (Test-Path Env:\\RUN_RELEASE_BUILD) {\n Write-Output \"Uploading Electron release distribution to s3\"\n & python script\\upload.py --upload_to_s3\n } else {\n Write-Output \"Uploading Electron release distribution to github releases\"\n & python script\\upload.py\n }\n} else {\n Write-Output \"Skipping upload distribution because build is not for release\"\n}"
|
||||
@@ -10,7 +10,6 @@
|
||||
#if defined(OS_WIN)
|
||||
#include <windows.h> // windows.h must be included first
|
||||
|
||||
#include <atlbase.h> // ensures that ATL statics like `_AtlWinModule` are initialized (it's an issue in static debug build)
|
||||
#include <shellapi.h>
|
||||
#include <shellscalingapi.h>
|
||||
#include <tchar.h>
|
||||
@@ -38,7 +37,7 @@
|
||||
|
||||
namespace {
|
||||
|
||||
const auto kRunAsNode = "ELECTRON_RUN_AS_NODE";
|
||||
const char* kRunAsNode = "ELECTRON_RUN_AS_NODE";
|
||||
|
||||
bool IsEnvSet(const char* name) {
|
||||
#if defined(OS_WIN)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "atom/app/uv_task_runner.h"
|
||||
|
||||
#include "base/stl_util.h"
|
||||
@@ -21,13 +19,13 @@ UvTaskRunner::~UvTaskRunner() {
|
||||
}
|
||||
|
||||
bool UvTaskRunner::PostDelayedTask(const tracked_objects::Location& from_here,
|
||||
base::OnceClosure task,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) {
|
||||
auto* timer = new uv_timer_t;
|
||||
timer->data = this;
|
||||
uv_timer_init(loop_, timer);
|
||||
uv_timer_start(timer, UvTaskRunner::OnTimeout, delay.InMilliseconds(), 0);
|
||||
tasks_[timer] = std::move(task);
|
||||
tasks_[timer] = task;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -37,9 +35,9 @@ bool UvTaskRunner::RunsTasksOnCurrentThread() const {
|
||||
|
||||
bool UvTaskRunner::PostNonNestableDelayedTask(
|
||||
const tracked_objects::Location& from_here,
|
||||
base::OnceClosure task,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) {
|
||||
return PostDelayedTask(from_here, std::move(task), delay);
|
||||
return PostDelayedTask(from_here, task, delay);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -48,7 +46,7 @@ void UvTaskRunner::OnTimeout(uv_timer_t* timer) {
|
||||
if (!ContainsKey(self->tasks_, timer))
|
||||
return;
|
||||
|
||||
std::move(self->tasks_[timer]).Run();
|
||||
self->tasks_[timer].Run();
|
||||
self->tasks_.erase(timer);
|
||||
uv_timer_stop(timer);
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(timer), UvTaskRunner::OnClose);
|
||||
|
||||
@@ -21,12 +21,12 @@ class UvTaskRunner : public base::SingleThreadTaskRunner {
|
||||
|
||||
// base::SingleThreadTaskRunner:
|
||||
bool PostDelayedTask(const tracked_objects::Location& from_here,
|
||||
base::OnceClosure task,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) override;
|
||||
bool RunsTasksOnCurrentThread() const override;
|
||||
bool PostNonNestableDelayedTask(
|
||||
const tracked_objects::Location& from_here,
|
||||
base::OnceClosure task,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) override;
|
||||
|
||||
private:
|
||||
@@ -35,7 +35,7 @@ class UvTaskRunner : public base::SingleThreadTaskRunner {
|
||||
|
||||
uv_loop_t* loop_;
|
||||
|
||||
std::map<uv_timer_t*, base::OnceClosure> tasks_;
|
||||
std::map<uv_timer_t*, base::Closure> tasks_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(UvTaskRunner);
|
||||
};
|
||||
|
||||
@@ -54,10 +54,6 @@
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "atom/browser/ui/cocoa/atom_bundle_mover.h"
|
||||
#endif
|
||||
|
||||
using atom::Browser;
|
||||
|
||||
namespace mate {
|
||||
@@ -375,8 +371,6 @@ int GetPathConstant(const std::string& name) {
|
||||
return brightray::DIR_CACHE;
|
||||
else if (name == "userCache")
|
||||
return brightray::DIR_USER_CACHE;
|
||||
else if (name == "logs")
|
||||
return brightray::DIR_APP_LOGS;
|
||||
else if (name == "home")
|
||||
return base::DIR_HOME;
|
||||
else if (name == "temp")
|
||||
@@ -592,18 +586,6 @@ void App::OnAccessibilitySupportChanged() {
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void App::OnWillContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type) {
|
||||
*prevent_default = Emit("will-continue-activity", type);
|
||||
}
|
||||
|
||||
void App::OnDidFailToContinueUserActivity(
|
||||
const std::string& type,
|
||||
const std::string& error) {
|
||||
Emit("continue-activity-error", type, error);
|
||||
}
|
||||
|
||||
void App::OnContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
@@ -611,39 +593,22 @@ void App::OnContinueUserActivity(
|
||||
*prevent_default = Emit("continue-activity", type, user_info);
|
||||
}
|
||||
|
||||
void App::OnUserActivityWasContinued(
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
Emit("activity-was-continued", type, user_info);
|
||||
}
|
||||
|
||||
void App::OnUpdateUserActivityState(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
*prevent_default = Emit("update-activity-state", type, user_info);
|
||||
}
|
||||
|
||||
void App::OnNewWindowForTab() {
|
||||
Emit("new-window-for-tab");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void App::OnLogin(LoginHandler* login_handler,
|
||||
const base::DictionaryValue& request_details) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
bool prevent_default = false;
|
||||
content::WebContents* web_contents = login_handler->GetWebContents();
|
||||
if (web_contents) {
|
||||
prevent_default =
|
||||
Emit("login",
|
||||
WebContents::CreateFrom(isolate(), web_contents),
|
||||
request_details,
|
||||
login_handler->auth_info(),
|
||||
base::Bind(&PassLoginInformation,
|
||||
make_scoped_refptr(login_handler)));
|
||||
}
|
||||
bool prevent_default = Emit(
|
||||
"login",
|
||||
WebContents::CreateFrom(isolate(), login_handler->GetWebContents()),
|
||||
request_details,
|
||||
login_handler->auth_info(),
|
||||
base::Bind(&PassLoginInformation, make_scoped_refptr(login_handler)));
|
||||
|
||||
// Default behavior is to always cancel the auth.
|
||||
if (!prevent_default)
|
||||
@@ -906,16 +871,6 @@ bool App::IsAccessibilitySupportEnabled() {
|
||||
return ax_state->IsAccessibleBrowser();
|
||||
}
|
||||
|
||||
void App::SetAccessibilitySupportEnabled(bool enabled) {
|
||||
auto ax_state = content::BrowserAccessibilityState::GetInstance();
|
||||
if (enabled) {
|
||||
ax_state->OnScreenReaderDetected();
|
||||
} else {
|
||||
ax_state->DisableAccessibility();
|
||||
}
|
||||
Browser::Get()->OnAccessibilitySupportChanged();
|
||||
}
|
||||
|
||||
Browser::LoginItemSettings App::GetLoginItemSettings(mate::Arguments* args) {
|
||||
Browser::LoginItemSettings options;
|
||||
args->GetNext(&options);
|
||||
@@ -1074,17 +1029,8 @@ std::vector<mate::Dictionary> App::GetAppMetrics(v8::Isolate* isolate) {
|
||||
cpu_dict.Set("percentCPUUsage",
|
||||
process_metric.second->metrics->GetPlatformIndependentCPUUsage()
|
||||
/ processor_count);
|
||||
|
||||
#if !defined(OS_WIN)
|
||||
cpu_dict.Set("idleWakeupsPerSecond",
|
||||
process_metric.second->metrics->GetIdleWakeupsPerSecond());
|
||||
#else
|
||||
// Chrome's underlying process_metrics.cc will throw a non-fatal warning
|
||||
// that this method isn't implemented on Windows, so set it to 0 instead
|
||||
// of calling it
|
||||
cpu_dict.Set("idleWakeupsPerSecond", 0);
|
||||
#endif
|
||||
|
||||
pid_dict.Set("cpu", cpu_dict);
|
||||
pid_dict.Set("pid", process_metric.second->pid);
|
||||
pid_dict.Set("type",
|
||||
@@ -1128,16 +1074,6 @@ void App::EnableMixedSandbox(mate::Arguments* args) {
|
||||
command_line->AppendSwitch(switches::kEnableMixedSandbox);
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool App::MoveToApplicationsFolder(mate::Arguments* args) {
|
||||
return ui::cocoa::AtomBundleMover::Move(args);
|
||||
}
|
||||
|
||||
bool App::IsInApplicationsFolder() {
|
||||
return ui::cocoa::AtomBundleMover::IsCurrentAppInApplicationsFolder();
|
||||
}
|
||||
#endif
|
||||
|
||||
// static
|
||||
mate::Handle<App> App::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new App(isolate));
|
||||
@@ -1181,10 +1117,6 @@ void App::BuildPrototype(
|
||||
base::Bind(&Browser::SetUserActivity, browser))
|
||||
.SetMethod("getCurrentActivityType",
|
||||
base::Bind(&Browser::GetCurrentActivityType, browser))
|
||||
.SetMethod("invalidateCurrentActivity",
|
||||
base::Bind(&Browser::InvalidateCurrentActivity, browser))
|
||||
.SetMethod("updateCurrentActivity",
|
||||
base::Bind(&Browser::UpdateCurrentActivity, browser))
|
||||
.SetMethod("setAboutPanelOptions",
|
||||
base::Bind(&Browser::SetAboutPanelOptions, browser))
|
||||
#endif
|
||||
@@ -1211,8 +1143,6 @@ void App::BuildPrototype(
|
||||
.SetMethod("relaunch", &App::Relaunch)
|
||||
.SetMethod("isAccessibilitySupportEnabled",
|
||||
&App::IsAccessibilitySupportEnabled)
|
||||
.SetMethod("setAccessibilitySupportEnabled",
|
||||
&App::SetAccessibilitySupportEnabled)
|
||||
.SetMethod("disableHardwareAcceleration",
|
||||
&App::DisableHardwareAcceleration)
|
||||
.SetMethod("disableDomainBlockingFor3DAPIs",
|
||||
@@ -1222,10 +1152,6 @@ void App::BuildPrototype(
|
||||
.SetMethod("getGPUFeatureStatus", &App::GetGPUFeatureStatus)
|
||||
.SetMethod("enableMixedSandbox", &App::EnableMixedSandbox)
|
||||
// TODO(juturu): Remove in 2.0, deprecate before then with warnings
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("moveToApplicationsFolder", &App::MoveToApplicationsFolder)
|
||||
.SetMethod("isInApplicationsFolder", &App::IsInApplicationsFolder)
|
||||
#endif
|
||||
.SetMethod("getAppMemoryInfo", &App::GetAppMetrics);
|
||||
}
|
||||
|
||||
|
||||
@@ -115,23 +115,11 @@ class App : public AtomBrowserClient::Delegate,
|
||||
void OnAccessibilitySupportChanged() override;
|
||||
void OnPreMainMessageLoopRun() override;
|
||||
#if defined(OS_MACOSX)
|
||||
void OnWillContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type) override;
|
||||
void OnDidFailToContinueUserActivity(
|
||||
const std::string& type,
|
||||
const std::string& error) override;
|
||||
void OnContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) override;
|
||||
void OnUserActivityWasContinued(
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) override;
|
||||
void OnUpdateUserActivityState(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) override;
|
||||
|
||||
void OnNewWindowForTab() override;
|
||||
#endif
|
||||
|
||||
@@ -185,7 +173,6 @@ class App : public AtomBrowserClient::Delegate,
|
||||
void DisableHardwareAcceleration(mate::Arguments* args);
|
||||
void DisableDomainBlockingFor3DAPIs(mate::Arguments* args);
|
||||
bool IsAccessibilitySupportEnabled();
|
||||
void SetAccessibilitySupportEnabled(bool enabled);
|
||||
Browser::LoginItemSettings GetLoginItemSettings(mate::Arguments* args);
|
||||
#if defined(USE_NSS_CERTS)
|
||||
void ImportCertificate(const base::DictionaryValue& options,
|
||||
@@ -198,11 +185,6 @@ class App : public AtomBrowserClient::Delegate,
|
||||
v8::Local<v8::Value> GetGPUFeatureStatus(v8::Isolate* isolate);
|
||||
void EnableMixedSandbox(mate::Arguments* args);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool MoveToApplicationsFolder(mate::Arguments* args);
|
||||
bool IsInApplicationsFolder();
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Get the current Jump List settings.
|
||||
v8::Local<v8::Value> GetJumpListSettings();
|
||||
|
||||
@@ -114,7 +114,7 @@ void BrowserView::SetBackgroundColor(const std::string& color_name) {
|
||||
view_->SetBackgroundColor(ParseHexColor(color_name));
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> BrowserView::GetWebContents() {
|
||||
v8::Local<v8::Value> BrowserView::WebContents() {
|
||||
if (web_contents_.IsEmpty()) {
|
||||
return v8::Null(isolate());
|
||||
}
|
||||
@@ -131,7 +131,7 @@ void BrowserView::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setAutoResize", &BrowserView::SetAutoResize)
|
||||
.SetMethod("setBounds", &BrowserView::SetBounds)
|
||||
.SetMethod("setBackgroundColor", &BrowserView::SetBackgroundColor)
|
||||
.SetProperty("webContents", &BrowserView::GetWebContents)
|
||||
.SetProperty("webContents", &BrowserView::WebContents)
|
||||
.SetProperty("id", &BrowserView::ID);
|
||||
}
|
||||
|
||||
@@ -154,8 +154,6 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
isolate, BrowserView::GetConstructor(isolate)->GetFunction());
|
||||
browser_view.SetMethod("fromId",
|
||||
&mate::TrackableObject<BrowserView>::FromWeakMapID);
|
||||
browser_view.SetMethod("getAllViews",
|
||||
&mate::TrackableObject<BrowserView>::GetAll);
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("BrowserView", browser_view);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class BrowserView : public mate::TrackableObject<BrowserView> {
|
||||
void SetBounds(const gfx::Rect& bounds);
|
||||
void SetBackgroundColor(const std::string& color_name);
|
||||
|
||||
v8::Local<v8::Value> GetWebContents();
|
||||
v8::Local<v8::Value> WebContents();
|
||||
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
class WebContents* api_web_contents_;
|
||||
|
||||
@@ -169,22 +169,14 @@ void Notification::NotificationDisplayed() {
|
||||
}
|
||||
|
||||
void Notification::NotificationDestroyed() {
|
||||
}
|
||||
|
||||
void Notification::NotificationClosed() {
|
||||
Emit("close");
|
||||
}
|
||||
|
||||
void Notification::Close() {
|
||||
if (notification_) {
|
||||
notification_->Dismiss();
|
||||
notification_.reset();
|
||||
}
|
||||
void Notification::NotificationClosed() {
|
||||
}
|
||||
|
||||
// Showing notifications
|
||||
void Notification::Show() {
|
||||
Close();
|
||||
if (presenter_) {
|
||||
notification_ = presenter_->CreateNotification(this);
|
||||
if (notification_) {
|
||||
@@ -215,7 +207,6 @@ void Notification::BuildPrototype(v8::Isolate* isolate,
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
.SetMethod("show", &Notification::Show)
|
||||
.SetMethod("close", &Notification::Close)
|
||||
.SetProperty("title", &Notification::GetTitle, &Notification::SetTitle)
|
||||
.SetProperty("subtitle", &Notification::GetSubtitle,
|
||||
&Notification::SetSubtitle)
|
||||
|
||||
@@ -45,7 +45,6 @@ class Notification : public mate::TrackableObject<Notification>,
|
||||
~Notification() override;
|
||||
|
||||
void Show();
|
||||
void Close();
|
||||
|
||||
// Prop Getters
|
||||
base::string16 GetTitle() const;
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "atom/browser/net/url_request_async_asar_job.h"
|
||||
#include "atom/browser/net/url_request_buffer_job.h"
|
||||
#include "atom/browser/net/url_request_fetch_job.h"
|
||||
#include "atom/browser/net/url_request_stream_job.h"
|
||||
#include "atom/browser/net/url_request_string_job.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
@@ -209,8 +208,6 @@ void Protocol::BuildPrototype(
|
||||
&Protocol::RegisterProtocol<URLRequestAsyncAsarJob>)
|
||||
.SetMethod("registerHttpProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestFetchJob>)
|
||||
.SetMethod("registerStreamProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestStreamJob>)
|
||||
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
|
||||
.SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled)
|
||||
.SetMethod("interceptStringProtocol",
|
||||
@@ -221,8 +218,6 @@ void Protocol::BuildPrototype(
|
||||
&Protocol::InterceptProtocol<URLRequestAsyncAsarJob>)
|
||||
.SetMethod("interceptHttpProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestFetchJob>)
|
||||
.SetMethod("interceptStreamProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestStreamJob>)
|
||||
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
|
||||
}
|
||||
|
||||
|
||||
@@ -78,10 +78,6 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
||||
net::URLRequestJob* MaybeCreateJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const override {
|
||||
if (!request->initiator().has_value()) {
|
||||
// Don't intercept this request as it was created by `net.request`.
|
||||
return nullptr;
|
||||
}
|
||||
RequestJob* request_job = new RequestJob(request, network_delegate);
|
||||
request_job->SetHandlerInfo(isolate_, request_context_.get(), handler_);
|
||||
return request_job;
|
||||
|
||||
@@ -212,7 +212,6 @@ struct Converter<atom::VerifyRequestParams> {
|
||||
dict.Set("hostname", val.hostname);
|
||||
dict.Set("certificate", val.certificate);
|
||||
dict.Set("verificationResult", val.default_result);
|
||||
dict.Set("errorCode", val.error_code);
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
@@ -434,7 +433,6 @@ void DownloadIdCallback(content::DownloadManager* download_manager,
|
||||
content::DownloadItem::INTERRUPTED,
|
||||
content::DownloadDangerType::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
content::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT, false,
|
||||
base::Time(), false,
|
||||
std::vector<content::DownloadItem::ReceivedSlice>());
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,6 @@ void SystemPreferences::BuildPrototype(
|
||||
&SystemPreferences::UnsubscribeLocalNotification)
|
||||
.SetMethod("getUserDefault", &SystemPreferences::GetUserDefault)
|
||||
.SetMethod("setUserDefault", &SystemPreferences::SetUserDefault)
|
||||
.SetMethod("removeUserDefault", &SystemPreferences::RemoveUserDefault)
|
||||
.SetMethod("isSwipeTrackingFromScrollEventsEnabled",
|
||||
&SystemPreferences::IsSwipeTrackingFromScrollEventsEnabled)
|
||||
#endif
|
||||
|
||||
@@ -76,7 +76,6 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
||||
void SetUserDefault(const std::string& name,
|
||||
const std::string& type,
|
||||
mate::Arguments* args);
|
||||
void RemoveUserDefault(const std::string& name);
|
||||
bool IsSwipeTrackingFromScrollEventsEnabled();
|
||||
#endif
|
||||
bool IsDarkMode();
|
||||
|
||||
@@ -229,11 +229,6 @@ void SystemPreferences::SetUserDefault(const std::string& name,
|
||||
}
|
||||
}
|
||||
|
||||
void SystemPreferences::RemoveUserDefault(const std::string& name) {
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
[defaults removeObjectForKey:base::SysUTF8ToNSString(name)];
|
||||
}
|
||||
|
||||
bool SystemPreferences::IsDarkMode() {
|
||||
NSString* mode = [[NSUserDefaults standardUserDefaults]
|
||||
stringForKey:@"AppleInterfaceStyle"];
|
||||
|
||||
@@ -86,10 +86,8 @@ mate::WrappableBase* Tray::New(mate::Handle<NativeImage> image,
|
||||
return new Tray(args->isolate(), args->GetThis(), image);
|
||||
}
|
||||
|
||||
void Tray::OnClicked(const gfx::Rect& bounds,
|
||||
const gfx::Point& location,
|
||||
int modifiers) {
|
||||
EmitWithFlags("click", modifiers, bounds, location);
|
||||
void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
EmitWithFlags("click", modifiers, bounds);
|
||||
}
|
||||
|
||||
void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
@@ -132,10 +130,6 @@ void Tray::OnMouseExited(const gfx::Point& location, int modifiers) {
|
||||
EmitWithFlags("mouse-leave", modifiers, location);
|
||||
}
|
||||
|
||||
void Tray::OnMouseMoved(const gfx::Point& location, int modifiers) {
|
||||
EmitWithFlags("mouse-move", modifiers, location);
|
||||
}
|
||||
|
||||
void Tray::OnDragEntered() {
|
||||
Emit("drag-enter");
|
||||
}
|
||||
|
||||
@@ -47,9 +47,7 @@ class Tray : public mate::TrackableObject<Tray>,
|
||||
~Tray() override;
|
||||
|
||||
// TrayIconObserver:
|
||||
void OnClicked(const gfx::Rect& bounds,
|
||||
const gfx::Point& location,
|
||||
int modifiers) override;
|
||||
void OnClicked(const gfx::Rect& bounds, int modifiers) override;
|
||||
void OnDoubleClicked(const gfx::Rect& bounds, int modifiers) override;
|
||||
void OnRightClicked(const gfx::Rect& bounds, int modifiers) override;
|
||||
void OnBalloonShow() override;
|
||||
@@ -63,7 +61,6 @@ class Tray : public mate::TrackableObject<Tray>,
|
||||
void OnDragEnded() override;
|
||||
void OnMouseEntered(const gfx::Point& location, int modifiers) override;
|
||||
void OnMouseExited(const gfx::Point& location, int modifiers) override;
|
||||
void OnMouseMoved(const gfx::Point& location, int modifiers) override;
|
||||
|
||||
void SetImage(v8::Isolate* isolate, mate::Handle<NativeImage> image);
|
||||
void SetPressedImage(v8::Isolate* isolate, mate::Handle<NativeImage> image);
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
#include "content/browser/renderer_host/render_widget_host_view_base.h"
|
||||
#include "content/browser/web_contents/web_contents_impl.h"
|
||||
#include "content/common/view_messages.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "content/public/browser/favicon_status.h"
|
||||
#include "content/public/browser/native_web_keyboard_event.h"
|
||||
#include "content/public/browser/navigation_details.h"
|
||||
@@ -82,7 +81,6 @@
|
||||
#include "third_party/WebKit/public/web/WebFindOptions.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/events/base_event_utils.h"
|
||||
#include "ui/latency/latency_info.h"
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
#include "ui/aura/window.h"
|
||||
@@ -286,13 +284,12 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
request_id_(0),
|
||||
background_throttling_(true),
|
||||
enable_devtools_(true) {
|
||||
const mate::Dictionary options = mate::Dictionary::CreateEmpty(isolate);
|
||||
if (type == REMOTE) {
|
||||
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
|
||||
Init(isolate);
|
||||
AttachAsUserData(web_contents);
|
||||
InitZoomController(web_contents, options);
|
||||
} else {
|
||||
const mate::Dictionary options = mate::Dictionary::CreateEmpty(isolate);
|
||||
auto session = Session::CreateFrom(isolate, GetBrowserContext());
|
||||
session_.Reset(isolate, session.ToV8());
|
||||
InitWithSessionAndOptions(isolate, web_contents, session, options);
|
||||
@@ -306,10 +303,6 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
|
||||
request_id_(0),
|
||||
background_throttling_(true),
|
||||
enable_devtools_(true) {
|
||||
// WebContents may need to emit events when it is garbage collected, so it
|
||||
// has to be deleted in the first gc callback.
|
||||
MarkHighMemoryUsage();
|
||||
|
||||
// Read options.
|
||||
options.Get("backgroundThrottling", &background_throttling_);
|
||||
|
||||
@@ -377,8 +370,8 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
|
||||
options.Get("transparent", &transparent);
|
||||
|
||||
content::WebContents::CreateParams params(session->browser_context());
|
||||
auto* view = new OffScreenWebContentsView(
|
||||
transparent, base::Bind(&WebContents::OnPaint, base::Unretained(this)));
|
||||
auto* view = new OffScreenWebContentsView(transparent,
|
||||
base::Bind(&WebContents::OnPaint, base::Unretained(this)));
|
||||
params.view = view;
|
||||
params.delegate_view = view;
|
||||
|
||||
@@ -393,15 +386,6 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
|
||||
InitWithSessionAndOptions(isolate, web_contents, session, options);
|
||||
}
|
||||
|
||||
void WebContents::InitZoomController(content::WebContents* web_contents,
|
||||
const mate::Dictionary& options) {
|
||||
WebContentsZoomController::CreateForWebContents(web_contents);
|
||||
zoom_controller_ = WebContentsZoomController::FromWebContents(web_contents);
|
||||
double zoom_factor;
|
||||
if (options.Get(options::kZoomFactor, &zoom_factor))
|
||||
zoom_controller_->SetDefaultZoomFactor(zoom_factor);
|
||||
}
|
||||
|
||||
void WebContents::InitWithSessionAndOptions(v8::Isolate* isolate,
|
||||
content::WebContents *web_contents,
|
||||
mate::Handle<api::Session> session,
|
||||
@@ -419,7 +403,11 @@ void WebContents::InitWithSessionAndOptions(v8::Isolate* isolate,
|
||||
// Initialize security state client.
|
||||
SecurityStateTabHelper::CreateForWebContents(web_contents);
|
||||
// Initialize zoom controller.
|
||||
InitZoomController(web_contents, options);
|
||||
WebContentsZoomController::CreateForWebContents(web_contents);
|
||||
zoom_controller_ = WebContentsZoomController::FromWebContents(web_contents);
|
||||
double zoom_factor;
|
||||
if (options.Get(options::kZoomFactor, &zoom_factor))
|
||||
zoom_controller_->SetDefaultZoomFactor(zoom_factor);
|
||||
|
||||
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
|
||||
|
||||
@@ -480,7 +468,7 @@ bool WebContents::DidAddMessageToConsole(content::WebContents* source,
|
||||
const base::string16& message,
|
||||
int32_t line_no,
|
||||
const base::string16& source_id) {
|
||||
if (type_ == OFF_SCREEN) {
|
||||
if (type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) {
|
||||
return false;
|
||||
} else {
|
||||
Emit("console-message", level, message, line_no, source_id);
|
||||
@@ -598,18 +586,16 @@ void WebContents::HandleKeyboardEvent(
|
||||
}
|
||||
}
|
||||
|
||||
content::KeyboardEventProcessingResult WebContents::PreHandleKeyboardEvent(
|
||||
bool WebContents::PreHandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
if (event.GetType() == blink::WebInputEvent::Type::kRawKeyDown ||
|
||||
event.GetType() == blink::WebInputEvent::Type::kKeyUp) {
|
||||
bool prevent_default = Emit("before-input-event", event);
|
||||
if (prevent_default) {
|
||||
return content::KeyboardEventProcessingResult::HANDLED;
|
||||
}
|
||||
const content::NativeWebKeyboardEvent& event,
|
||||
bool* is_keyboard_shortcut) {
|
||||
if (event.type() == blink::WebInputEvent::Type::RawKeyDown ||
|
||||
event.type() == blink::WebInputEvent::Type::KeyUp) {
|
||||
return Emit("before-input-event", event);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return content::KeyboardEventProcessingResult::NOT_HANDLED;
|
||||
}
|
||||
|
||||
void WebContents::EnterFullscreenModeForTab(content::WebContents* source,
|
||||
@@ -767,11 +753,7 @@ void WebContents::MediaStoppedPlaying(const MediaPlayerInfo& video_type,
|
||||
}
|
||||
|
||||
void WebContents::DidChangeThemeColor(SkColor theme_color) {
|
||||
if (theme_color != SK_ColorTRANSPARENT) {
|
||||
Emit("did-change-theme-color", atom::ToRGBHex(theme_color));
|
||||
} else {
|
||||
Emit("did-change-theme-color", nullptr);
|
||||
}
|
||||
Emit("did-change-theme-color", atom::ToRGBHex(theme_color));
|
||||
}
|
||||
|
||||
void WebContents::DocumentLoadedInFrame(
|
||||
@@ -836,7 +818,7 @@ void WebContents::DidFinishNavigation(
|
||||
bool is_main_frame = navigation_handle->IsInMainFrame();
|
||||
if (navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()) {
|
||||
auto url = navigation_handle->GetURL();
|
||||
bool is_in_page = navigation_handle->IsSameDocument();
|
||||
bool is_in_page = navigation_handle->IsSamePage();
|
||||
if (is_main_frame && !is_in_page) {
|
||||
Emit("did-navigate", url);
|
||||
} else if (is_in_page) {
|
||||
@@ -909,17 +891,6 @@ void WebContents::DevToolsClosed() {
|
||||
Emit("devtools-closed");
|
||||
}
|
||||
|
||||
void WebContents::ShowAutofillPopup(content::RenderFrameHost* frame_host,
|
||||
const gfx::RectF& bounds,
|
||||
const std::vector<base::string16>& values,
|
||||
const std::vector<base::string16>& labels) {
|
||||
auto relay = NativeWindowRelay::FromWebContents(web_contents());
|
||||
if (relay) {
|
||||
relay->window->ShowAutofillPopup(
|
||||
frame_host, web_contents(), bounds, values, labels);
|
||||
}
|
||||
}
|
||||
|
||||
bool WebContents::OnMessageReceived(const IPC::Message& message) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(WebContents, message)
|
||||
@@ -944,10 +915,9 @@ bool WebContents::OnMessageReceived(const IPC::Message& message,
|
||||
auto relay = NativeWindowRelay::FromWebContents(web_contents());
|
||||
if (!relay)
|
||||
return false;
|
||||
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(WebContents, message, frame_host)
|
||||
IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_ShowPopup, ShowAutofillPopup)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(NativeWindow, message, frame_host)
|
||||
IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_ShowPopup,
|
||||
relay->window.get(), NativeWindow::ShowAutofillPopup)
|
||||
IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_HidePopup,
|
||||
relay->window.get(), NativeWindow::HideAutofillPopup)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
@@ -1032,7 +1002,7 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
|
||||
GURL http_referrer;
|
||||
if (options.Get("httpReferrer", &http_referrer))
|
||||
params.referrer = content::Referrer(http_referrer.GetAsReferrer(),
|
||||
blink::kWebReferrerPolicyDefault);
|
||||
blink::WebReferrerPolicyDefault);
|
||||
|
||||
std::string user_agent;
|
||||
if (options.Get("userAgent", &user_agent))
|
||||
@@ -1270,22 +1240,9 @@ void WebContents::HasServiceWorker(
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
struct WrappedCallback {
|
||||
base::Callback<void(bool)> callback_;
|
||||
explicit WrappedCallback(const base::Callback<void(bool)>& callback)
|
||||
: callback_(callback) {}
|
||||
void Run(content::ServiceWorkerCapability capability) {
|
||||
callback_.Run(capability !=
|
||||
content::ServiceWorkerCapability::NO_SERVICE_WORKER);
|
||||
delete this;
|
||||
}
|
||||
};
|
||||
|
||||
auto wrapped_callback = new WrappedCallback(callback);
|
||||
|
||||
context->CheckHasServiceWorker(
|
||||
web_contents()->GetLastCommittedURL(), GURL::EmptyGURL(),
|
||||
base::Bind(&WrappedCallback::Run, base::Unretained(wrapped_callback)));
|
||||
context->CheckHasServiceWorker(web_contents()->GetLastCommittedURL(),
|
||||
GURL::EmptyGURL(),
|
||||
callback);
|
||||
}
|
||||
|
||||
void WebContents::UnregisterServiceWorker(
|
||||
@@ -1312,21 +1269,13 @@ bool WebContents::IsAudioMuted() {
|
||||
|
||||
void WebContents::Print(mate::Arguments* args) {
|
||||
PrintSettings settings = { false, false, base::string16() };
|
||||
if (args->Length() >= 1 && !args->GetNext(&settings)) {
|
||||
if (args->Length() == 1 && !args->GetNext(&settings)) {
|
||||
args->ThrowError();
|
||||
return;
|
||||
}
|
||||
auto print_view_manager_basic_ptr =
|
||||
printing::PrintViewManagerBasic::FromWebContents(web_contents());
|
||||
if (args->Length() == 2) {
|
||||
base::Callback<void(bool)> callback;
|
||||
if (!args->GetNext(&callback)) {
|
||||
args->ThrowError();
|
||||
return;
|
||||
}
|
||||
print_view_manager_basic_ptr->SetCallback(callback);
|
||||
}
|
||||
print_view_manager_basic_ptr->PrintNow(web_contents()->GetMainFrame(),
|
||||
|
||||
printing::PrintViewManagerBasic::FromWebContents(web_contents())->
|
||||
PrintNow(web_contents()->GetMainFrame(),
|
||||
settings.silent,
|
||||
settings.print_background,
|
||||
settings.device_name);
|
||||
@@ -1477,22 +1426,22 @@ void WebContents::SendInputEvent(v8::Isolate* isolate,
|
||||
return;
|
||||
|
||||
int type = mate::GetWebInputEventType(isolate, input_event);
|
||||
if (blink::WebInputEvent::IsMouseEventType(type)) {
|
||||
if (blink::WebInputEvent::isMouseEventType(type)) {
|
||||
blink::WebMouseEvent mouse_event;
|
||||
if (mate::ConvertFromV8(isolate, input_event, &mouse_event)) {
|
||||
view->ProcessMouseEvent(mouse_event, ui::LatencyInfo());
|
||||
return;
|
||||
}
|
||||
} else if (blink::WebInputEvent::IsKeyboardEventType(type)) {
|
||||
} else if (blink::WebInputEvent::isKeyboardEventType(type)) {
|
||||
content::NativeWebKeyboardEvent keyboard_event(
|
||||
blink::WebKeyboardEvent::kRawKeyDown,
|
||||
blink::WebInputEvent::kNoModifiers,
|
||||
blink::WebKeyboardEvent::RawKeyDown,
|
||||
blink::WebInputEvent::NoModifiers,
|
||||
ui::EventTimeForNow());
|
||||
if (mate::ConvertFromV8(isolate, input_event, &keyboard_event)) {
|
||||
view->ProcessKeyboardEvent(keyboard_event);
|
||||
return;
|
||||
}
|
||||
} else if (type == blink::WebInputEvent::kMouseWheel) {
|
||||
} else if (type == blink::WebInputEvent::MouseWheel) {
|
||||
blink::WebMouseWheelEvent mouse_wheel_event;
|
||||
if (mate::ConvertFromV8(isolate, input_event, &mouse_wheel_event)) {
|
||||
view->ProcessMouseWheelEvent(mouse_wheel_event, ui::LatencyInfo());
|
||||
@@ -1592,7 +1541,7 @@ void WebContents::CapturePage(mate::Arguments* args) {
|
||||
gfx::Size bitmap_size = view_size;
|
||||
const gfx::NativeView native_view = view->GetNativeView();
|
||||
const float scale =
|
||||
display::Screen::GetScreen()->GetDisplayNearestView(native_view)
|
||||
display::Screen::GetScreen()->GetDisplayNearestWindow(native_view)
|
||||
.device_scale_factor();
|
||||
if (scale > 1.0f)
|
||||
bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
|
||||
@@ -1604,7 +1553,7 @@ void WebContents::CapturePage(mate::Arguments* args) {
|
||||
}
|
||||
|
||||
void WebContents::OnCursorChange(const content::WebCursor& cursor) {
|
||||
content::CursorInfo info;
|
||||
content::WebCursor::CursorInfo info;
|
||||
cursor.GetCursorInfo(&info);
|
||||
|
||||
if (cursor.IsCustom()) {
|
||||
@@ -1635,6 +1584,10 @@ bool WebContents::IsOffScreen() const {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool WebContents::IsOffScreenOrEmbedderOffscreen() const {
|
||||
return IsOffScreen() || (embedder_ && embedder_->IsOffScreen());
|
||||
}
|
||||
|
||||
void WebContents::OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap) {
|
||||
Emit("paint", dirty_rect, gfx::Image::CreateFrom1xBitmap(bitmap));
|
||||
}
|
||||
@@ -1644,10 +1597,10 @@ void WebContents::StartPainting() {
|
||||
return;
|
||||
|
||||
#if defined(ENABLE_OSR)
|
||||
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
||||
web_contents()->GetRenderWidgetHostView());
|
||||
if (osr_rwhv)
|
||||
osr_rwhv->SetPainting(true);
|
||||
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
|
||||
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
|
||||
if (osr_wcv)
|
||||
osr_wcv->SetPainting(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1656,10 +1609,10 @@ void WebContents::StopPainting() {
|
||||
return;
|
||||
|
||||
#if defined(ENABLE_OSR)
|
||||
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
||||
web_contents()->GetRenderWidgetHostView());
|
||||
if (osr_rwhv)
|
||||
osr_rwhv->SetPainting(false);
|
||||
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
|
||||
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
|
||||
if (osr_wcv)
|
||||
osr_wcv->SetPainting(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1668,9 +1621,10 @@ bool WebContents::IsPainting() const {
|
||||
return false;
|
||||
|
||||
#if defined(ENABLE_OSR)
|
||||
const auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
||||
web_contents()->GetRenderWidgetHostView());
|
||||
return osr_rwhv && osr_rwhv->IsPainting();
|
||||
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
|
||||
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
|
||||
|
||||
return osr_wcv && osr_wcv->IsPainting();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
@@ -1681,10 +1635,11 @@ void WebContents::SetFrameRate(int frame_rate) {
|
||||
return;
|
||||
|
||||
#if defined(ENABLE_OSR)
|
||||
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
||||
web_contents()->GetRenderWidgetHostView());
|
||||
if (osr_rwhv)
|
||||
osr_rwhv->SetFrameRate(frame_rate);
|
||||
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
|
||||
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
|
||||
|
||||
if (osr_wcv)
|
||||
osr_wcv->SetFrameRate(frame_rate);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1693,9 +1648,10 @@ int WebContents::GetFrameRate() const {
|
||||
return 0;
|
||||
|
||||
#if defined(ENABLE_OSR)
|
||||
const auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
||||
web_contents()->GetRenderWidgetHostView());
|
||||
return osr_rwhv ? osr_rwhv->GetFrameRate() : 0;
|
||||
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
|
||||
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
|
||||
|
||||
return osr_wcv ? osr_wcv->GetFrameRate() : 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
@@ -1765,6 +1721,14 @@ v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* 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());
|
||||
@@ -1805,16 +1769,6 @@ void WebContents::SetEmbedder(const WebContents* embedder) {
|
||||
}
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebContents::GetNativeView() const {
|
||||
gfx::NativeView ptr = web_contents()->GetNativeView();
|
||||
auto buffer = node::Buffer::Copy(
|
||||
isolate(), reinterpret_cast<char*>(&ptr), sizeof(gfx::NativeView));
|
||||
if (buffer.IsEmpty())
|
||||
return v8::Null(isolate());
|
||||
else
|
||||
return buffer.ToLocalChecked();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebContents::DevToolsWebContents(v8::Isolate* isolate) {
|
||||
if (devtools_web_contents_.IsEmpty())
|
||||
return v8::Null(isolate);
|
||||
@@ -1830,12 +1784,6 @@ v8::Local<v8::Value> WebContents::Debugger(v8::Isolate* isolate) {
|
||||
return v8::Local<v8::Value>::New(isolate, debugger_);
|
||||
}
|
||||
|
||||
void WebContents::GrantOriginAccess(const GURL& url) {
|
||||
content::ChildProcessSecurityPolicy::GetInstance()->GrantOrigin(
|
||||
web_contents()->GetMainFrame()->GetProcess()->GetID(),
|
||||
url::Origin(url));
|
||||
}
|
||||
|
||||
// static
|
||||
void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
@@ -1911,6 +1859,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",
|
||||
@@ -1926,12 +1875,10 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("copyImageAt", &WebContents::CopyImageAt)
|
||||
.SetMethod("capturePage", &WebContents::CapturePage)
|
||||
.SetMethod("setEmbedder", &WebContents::SetEmbedder)
|
||||
.SetMethod("getNativeView", &WebContents::GetNativeView)
|
||||
.SetMethod("setWebRTCIPHandlingPolicy",
|
||||
&WebContents::SetWebRTCIPHandlingPolicy)
|
||||
.SetMethod("getWebRTCIPHandlingPolicy",
|
||||
&WebContents::GetWebRTCIPHandlingPolicy)
|
||||
.SetMethod("_grantOriginAccess", &WebContents::GrantOriginAccess)
|
||||
.SetProperty("id", &WebContents::ID)
|
||||
.SetProperty("session", &WebContents::Session)
|
||||
.SetProperty("hostWebContents", &WebContents::HostWebContents)
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "atom/browser/common_web_contents_delegate.h"
|
||||
#include "atom/browser/ui/autofill_popup.h"
|
||||
#include "content/common/cursors/webcursor.h"
|
||||
#include "content/public/browser/keyboard_event_processing_result.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "content/public/common/favicon_url.h"
|
||||
#include "native_mate/handle.h"
|
||||
@@ -116,8 +115,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void DisableDeviceEmulation();
|
||||
void InspectElement(int x, int y);
|
||||
void InspectServiceWorker();
|
||||
void HasServiceWorker(
|
||||
const base::Callback<void(bool)>&);
|
||||
void HasServiceWorker(const base::Callback<void(bool)>&);
|
||||
void UnregisterServiceWorker(const base::Callback<void(bool)>&);
|
||||
void SetIgnoreMenuShortcuts(bool ignore);
|
||||
void SetAudioMuted(bool muted);
|
||||
@@ -125,7 +123,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void Print(mate::Arguments* args);
|
||||
std::vector<printing::PrinterBasicInfo> GetPrinterList();
|
||||
void SetEmbedder(const WebContents* embedder);
|
||||
v8::Local<v8::Value> GetNativeView() const;
|
||||
|
||||
// Print current page as PDF.
|
||||
void PrintToPDF(const base::DictionaryValue& setting,
|
||||
@@ -182,6 +179,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
|
||||
// Methods for offscreen rendering
|
||||
bool IsOffScreen() const;
|
||||
bool IsOffScreenOrEmbedderOffscreen() const;
|
||||
void OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap);
|
||||
void StartPainting();
|
||||
void StopPainting();
|
||||
@@ -212,14 +210,11 @@ 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();
|
||||
|
||||
// Grants the child process the capability to access URLs with the origin of
|
||||
// the specified URL.
|
||||
void GrantOriginAccess(const GURL& url);
|
||||
|
||||
// Properties.
|
||||
int32_t ID() const;
|
||||
v8::Local<v8::Value> Session(v8::Isolate* isolate);
|
||||
@@ -274,9 +269,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
content::KeyboardEventProcessingResult PreHandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
bool PreHandleKeyboardEvent(content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event,
|
||||
bool* is_keyboard_shortcut) override;
|
||||
void EnterFullscreenModeForTab(content::WebContents* source,
|
||||
const GURL& origin) override;
|
||||
void ExitFullscreenModeForTab(content::WebContents* source) override;
|
||||
@@ -357,11 +352,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void DevToolsOpened() override;
|
||||
void DevToolsClosed() override;
|
||||
|
||||
void ShowAutofillPopup(content::RenderFrameHost* frame_host,
|
||||
const gfx::RectF& bounds,
|
||||
const std::vector<base::string16>& values,
|
||||
const std::vector<base::string16>& labels);
|
||||
|
||||
private:
|
||||
AtomBrowserContext* GetBrowserContext() const;
|
||||
|
||||
@@ -389,9 +379,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
// get the zoom level.
|
||||
void OnGetZoomLevel(IPC::Message* reply_msg);
|
||||
|
||||
void InitZoomController(content::WebContents* web_contents,
|
||||
const mate::Dictionary& options);
|
||||
|
||||
v8::Global<v8::Value> session_;
|
||||
v8::Global<v8::Value> devtools_web_contents_;
|
||||
v8::Global<v8::Value> debugger_;
|
||||
|
||||
@@ -144,7 +144,6 @@ void Window::Init(v8::Isolate* isolate,
|
||||
options,
|
||||
parent.IsEmpty() ? nullptr : parent->window_.get()));
|
||||
web_contents->SetOwnerWindow(window_.get());
|
||||
window_->set_is_offscreen_dummy(api_web_contents_->IsOffScreen());
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
// Sets the window icon.
|
||||
@@ -604,14 +603,6 @@ void Window::SetSkipTaskbar(bool skip) {
|
||||
window_->SetSkipTaskbar(skip);
|
||||
}
|
||||
|
||||
void Window::SetSimpleFullScreen(bool simple_fullscreen) {
|
||||
window_->SetSimpleFullScreen(simple_fullscreen);
|
||||
}
|
||||
|
||||
bool Window::IsSimpleFullScreen() {
|
||||
return window_->IsSimpleFullScreen();
|
||||
}
|
||||
|
||||
void Window::SetKiosk(bool kiosk) {
|
||||
window_->SetKiosk(kiosk);
|
||||
}
|
||||
@@ -632,14 +623,6 @@ bool Window::HasShadow() {
|
||||
return window_->HasShadow();
|
||||
}
|
||||
|
||||
void Window::SetOpacity(const double opacity) {
|
||||
window_->SetOpacity(opacity);
|
||||
}
|
||||
|
||||
double Window::GetOpacity() {
|
||||
return window_->GetOpacity();
|
||||
}
|
||||
|
||||
void Window::FocusOnWebView() {
|
||||
window_->FocusOnWebView();
|
||||
}
|
||||
@@ -668,11 +651,8 @@ bool Window::IsDocumentEdited() {
|
||||
return window_->IsDocumentEdited();
|
||||
}
|
||||
|
||||
void Window::SetIgnoreMouseEvents(bool ignore, mate::Arguments* args) {
|
||||
mate::Dictionary options;
|
||||
bool forward = false;
|
||||
args->GetNext(&options) && options.Get("forward", &forward);
|
||||
return window_->SetIgnoreMouseEvents(ignore, forward);
|
||||
void Window::SetIgnoreMouseEvents(bool ignore) {
|
||||
return window_->SetIgnoreMouseEvents(ignore);
|
||||
}
|
||||
|
||||
void Window::SetContentProtection(bool enable) {
|
||||
@@ -927,30 +907,6 @@ void Window::SetAutoHideCursor(bool auto_hide) {
|
||||
window_->SetAutoHideCursor(auto_hide);
|
||||
}
|
||||
|
||||
void Window::SelectPreviousTab() {
|
||||
window_->SelectPreviousTab();
|
||||
}
|
||||
|
||||
void Window::SelectNextTab() {
|
||||
window_->SelectNextTab();
|
||||
}
|
||||
|
||||
void Window::MergeAllWindows() {
|
||||
window_->MergeAllWindows();
|
||||
}
|
||||
|
||||
void Window::MoveTabToNewWindow() {
|
||||
window_->MoveTabToNewWindow();
|
||||
}
|
||||
|
||||
void Window::ToggleTabBar() {
|
||||
window_->ToggleTabBar();
|
||||
}
|
||||
|
||||
void Window::AddTabbedWindow(NativeWindow* window) {
|
||||
window_->AddTabbedWindow(window);
|
||||
}
|
||||
|
||||
void Window::SetVibrancy(mate::Arguments* args) {
|
||||
std::string type;
|
||||
|
||||
@@ -1062,15 +1018,11 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("getTitle", &Window::GetTitle)
|
||||
.SetMethod("flashFrame", &Window::FlashFrame)
|
||||
.SetMethod("setSkipTaskbar", &Window::SetSkipTaskbar)
|
||||
.SetMethod("setSimpleFullScreen", &Window::SetSimpleFullScreen)
|
||||
.SetMethod("isSimpleFullScreen", &Window::IsSimpleFullScreen)
|
||||
.SetMethod("setKiosk", &Window::SetKiosk)
|
||||
.SetMethod("isKiosk", &Window::IsKiosk)
|
||||
.SetMethod("setBackgroundColor", &Window::SetBackgroundColor)
|
||||
.SetMethod("setHasShadow", &Window::SetHasShadow)
|
||||
.SetMethod("hasShadow", &Window::HasShadow)
|
||||
.SetMethod("setOpacity", &Window::SetOpacity)
|
||||
.SetMethod("getOpacity", &Window::GetOpacity)
|
||||
.SetMethod("setRepresentedFilename", &Window::SetRepresentedFilename)
|
||||
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
|
||||
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
|
||||
@@ -1095,12 +1047,6 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
&Window::IsVisibleOnAllWorkspaces)
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("setAutoHideCursor", &Window::SetAutoHideCursor)
|
||||
.SetMethod("mergeAllWindows", &Window::MergeAllWindows)
|
||||
.SetMethod("selectPreviousTab", &Window::SelectPreviousTab)
|
||||
.SetMethod("selectNextTab", &Window::SelectNextTab)
|
||||
.SetMethod("moveTabToNewWindow", &Window::MoveTabToNewWindow)
|
||||
.SetMethod("toggleTabBar", &Window::ToggleTabBar)
|
||||
.SetMethod("addTabbedWindow", &Window::AddTabbedWindow)
|
||||
#endif
|
||||
.SetMethod("setVibrancy", &Window::SetVibrancy)
|
||||
.SetMethod("_setTouchBarItems", &Window::SetTouchBar)
|
||||
|
||||
@@ -154,15 +154,11 @@ class Window : public mate::TrackableObject<Window>,
|
||||
std::string GetTitle();
|
||||
void FlashFrame(bool flash);
|
||||
void SetSkipTaskbar(bool skip);
|
||||
void SetSimpleFullScreen(bool simple_fullscreen);
|
||||
bool IsSimpleFullScreen();
|
||||
void SetKiosk(bool kiosk);
|
||||
bool IsKiosk();
|
||||
void SetBackgroundColor(const std::string& color_name);
|
||||
void SetHasShadow(bool has_shadow);
|
||||
bool HasShadow();
|
||||
void SetOpacity(const double opacity);
|
||||
double GetOpacity();
|
||||
void FocusOnWebView();
|
||||
void BlurWebView();
|
||||
bool IsWebViewFocused();
|
||||
@@ -170,7 +166,7 @@ class Window : public mate::TrackableObject<Window>,
|
||||
std::string GetRepresentedFilename();
|
||||
void SetDocumentEdited(bool edited);
|
||||
bool IsDocumentEdited();
|
||||
void SetIgnoreMouseEvents(bool ignore, mate::Arguments* args);
|
||||
void SetIgnoreMouseEvents(bool ignore);
|
||||
void SetContentProtection(bool enable);
|
||||
void SetFocusable(bool focusable);
|
||||
void SetProgressBar(double progress, mate::Arguments* args);
|
||||
@@ -216,13 +212,6 @@ class Window : public mate::TrackableObject<Window>,
|
||||
|
||||
void SetAutoHideCursor(bool auto_hide);
|
||||
|
||||
void SelectPreviousTab();
|
||||
void SelectNextTab();
|
||||
void MergeAllWindows();
|
||||
void MoveTabToNewWindow();
|
||||
void ToggleTabBar();
|
||||
void AddTabbedWindow(NativeWindow* window);
|
||||
|
||||
void SetVibrancy(mate::Arguments* args);
|
||||
void SetTouchBar(const std::vector<mate::PersistentDictionary>& items);
|
||||
void RefreshTouchBarItem(const std::string& item_id);
|
||||
|
||||
@@ -79,12 +79,8 @@ class EventEmitter : public Wrappable<T> {
|
||||
const Args&... args) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
v8::Local<v8::Object> wrapper = GetWrapper();
|
||||
if (wrapper.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
v8::Local<v8::Object> event = internal::CreateJSEvent(
|
||||
isolate(), wrapper, sender, message);
|
||||
isolate(), GetWrapper(), sender, message);
|
||||
return EmitWithEvent(name, event, args...);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/event_subscriber.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// A FunctionTemplate lifetime is bound to the v8 context, so it can be safely
|
||||
// stored as a global here since there's only one for the main process.
|
||||
v8::Global<v8::FunctionTemplate> g_cached_template;
|
||||
|
||||
struct JSHandlerData {
|
||||
JSHandlerData(v8::Isolate* isolate,
|
||||
mate::internal::EventSubscriberBase* subscriber)
|
||||
: handle_(isolate, v8::External::New(isolate, this)),
|
||||
subscriber_(subscriber) {
|
||||
handle_.SetWeak(this, GC, v8::WeakCallbackType::kFinalizer);
|
||||
}
|
||||
|
||||
static void GC(const v8::WeakCallbackInfo<JSHandlerData>& data) {
|
||||
delete data.GetParameter();
|
||||
}
|
||||
|
||||
v8::Global<v8::External> handle_;
|
||||
mate::internal::EventSubscriberBase* subscriber_;
|
||||
};
|
||||
|
||||
void InvokeCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
|
||||
v8::Locker locker(info.GetIsolate());
|
||||
v8::HandleScope handle_scope(info.GetIsolate());
|
||||
v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
|
||||
v8::Context::Scope context_scope(context);
|
||||
mate::Arguments args(info);
|
||||
v8::Local<v8::Value> handler, event;
|
||||
args.GetNext(&handler);
|
||||
args.GetNext(&event);
|
||||
DCHECK(handler->IsExternal());
|
||||
DCHECK(event->IsString());
|
||||
JSHandlerData* handler_data = static_cast<JSHandlerData*>(
|
||||
v8::Local<v8::External>::Cast(handler)->Value());
|
||||
handler_data->subscriber_->EventEmitted(mate::V8ToString(event), &args);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace internal {
|
||||
|
||||
EventSubscriberBase::EventSubscriberBase(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> emitter)
|
||||
: isolate_(isolate), emitter_(isolate, emitter) {
|
||||
if (g_cached_template.IsEmpty()) {
|
||||
g_cached_template = v8::Global<v8::FunctionTemplate>(
|
||||
isolate_, v8::FunctionTemplate::New(isolate_, InvokeCallback));
|
||||
}
|
||||
}
|
||||
|
||||
EventSubscriberBase::~EventSubscriberBase() {
|
||||
if (!isolate_) {
|
||||
return;
|
||||
}
|
||||
RemoveAllListeners();
|
||||
emitter_.Reset();
|
||||
DCHECK_EQ(js_handlers_.size(), 0);
|
||||
}
|
||||
|
||||
void EventSubscriberBase::On(const std::string& event_name) {
|
||||
DCHECK(js_handlers_.find(event_name) == js_handlers_.end());
|
||||
v8::Locker locker(isolate_);
|
||||
v8::Isolate::Scope isolate_scope(isolate_);
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
auto fn_template = g_cached_template.Get(isolate_);
|
||||
auto event = mate::StringToV8(isolate_, event_name);
|
||||
auto js_handler_data = new JSHandlerData(isolate_, this);
|
||||
v8::Local<v8::Value> fn = internal::BindFunctionWith(
|
||||
isolate_, isolate_->GetCurrentContext(), fn_template->GetFunction(),
|
||||
js_handler_data->handle_.Get(isolate_), event);
|
||||
js_handlers_.insert(
|
||||
std::make_pair(event_name, v8::Global<v8::Value>(isolate_, fn)));
|
||||
internal::ValueVector converted_args = {event, fn};
|
||||
internal::CallMethodWithArgs(isolate_, emitter_.Get(isolate_), "on",
|
||||
&converted_args);
|
||||
}
|
||||
|
||||
void EventSubscriberBase::Off(const std::string& event_name) {
|
||||
v8::Locker locker(isolate_);
|
||||
v8::Isolate::Scope isolate_scope(isolate_);
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
auto js_handler = js_handlers_.find(event_name);
|
||||
DCHECK(js_handler != js_handlers_.end());
|
||||
RemoveListener(js_handler);
|
||||
}
|
||||
|
||||
void EventSubscriberBase::RemoveAllListeners() {
|
||||
v8::Locker locker(isolate_);
|
||||
v8::Isolate::Scope isolate_scope(isolate_);
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
while (!js_handlers_.empty()) {
|
||||
RemoveListener(js_handlers_.begin());
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, v8::Global<v8::Value>>::iterator
|
||||
EventSubscriberBase::RemoveListener(
|
||||
std::map<std::string, v8::Global<v8::Value>>::iterator it) {
|
||||
internal::ValueVector args = {StringToV8(isolate_, it->first),
|
||||
it->second.Get(isolate_)};
|
||||
internal::CallMethodWithArgs(
|
||||
isolate_, v8::Local<v8::Object>::Cast(emitter_.Get(isolate_)),
|
||||
"removeListener", &args);
|
||||
it->second.Reset();
|
||||
return js_handlers_.erase(it);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace mate
|
||||
@@ -1,132 +0,0 @@
|
||||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_EVENT_SUBSCRIBER_H_
|
||||
#define ATOM_BROWSER_API_EVENT_SUBSCRIBER_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "atom/common/api/event_emitter_caller.h"
|
||||
#include "base/synchronization/lock.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/native_mate/arguments.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace internal {
|
||||
|
||||
class EventSubscriberBase {
|
||||
public:
|
||||
EventSubscriberBase(v8::Isolate* isolate, v8::Local<v8::Object> emitter);
|
||||
virtual ~EventSubscriberBase();
|
||||
virtual void EventEmitted(const std::string& event_name,
|
||||
mate::Arguments* args) = 0;
|
||||
|
||||
protected:
|
||||
void On(const std::string& event_name);
|
||||
void Off(const std::string& event_name);
|
||||
void RemoveAllListeners();
|
||||
|
||||
private:
|
||||
std::map<std::string, v8::Global<v8::Value>>::iterator RemoveListener(
|
||||
std::map<std::string, v8::Global<v8::Value>>::iterator it);
|
||||
|
||||
v8::Isolate* isolate_;
|
||||
v8::Global<v8::Object> emitter_;
|
||||
std::map<std::string, v8::Global<v8::Value>> js_handlers_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(EventSubscriberBase);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename HandlerType>
|
||||
class EventSubscriber : internal::EventSubscriberBase {
|
||||
public:
|
||||
using EventCallback = void (HandlerType::*)(mate::Arguments* args);
|
||||
// Alias to unique_ptr with deleter.
|
||||
using unique_ptr = std::unique_ptr<EventSubscriber<HandlerType>,
|
||||
void (*)(EventSubscriber<HandlerType>*)>;
|
||||
// EventSubscriber should only be created/deleted in the main thread since it
|
||||
// communicates with the V8 engine. This smart pointer makes it simpler to
|
||||
// bind the lifetime of EventSubscriber with a class whose lifetime is managed
|
||||
// by a non-UI thread.
|
||||
class SafePtr : public unique_ptr {
|
||||
public:
|
||||
SafePtr() : SafePtr(nullptr) {}
|
||||
explicit SafePtr(EventSubscriber<HandlerType>* ptr)
|
||||
: unique_ptr(ptr, Deleter) {}
|
||||
|
||||
private:
|
||||
// Custom deleter that schedules destructor invocation to the main thread.
|
||||
static void Deleter(EventSubscriber<HandlerType>* ptr) {
|
||||
DCHECK(
|
||||
!::content::BrowserThread::CurrentlyOn(::content::BrowserThread::UI));
|
||||
DCHECK(ptr);
|
||||
// Acquire handler lock and reset handler_ to ensure that any new events
|
||||
// emitted will be ignored after this function returns
|
||||
base::AutoLock auto_lock(ptr->handler_lock_);
|
||||
ptr->handler_ = nullptr;
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(
|
||||
[](EventSubscriber<HandlerType>* subscriber) {
|
||||
delete subscriber;
|
||||
},
|
||||
ptr));
|
||||
}
|
||||
};
|
||||
|
||||
EventSubscriber(HandlerType* handler,
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> emitter)
|
||||
: EventSubscriberBase(isolate, emitter), handler_(handler) {
|
||||
DCHECK_CURRENTLY_ON(::content::BrowserThread::UI);
|
||||
}
|
||||
|
||||
void On(const std::string& event, EventCallback callback) {
|
||||
DCHECK_CURRENTLY_ON(::content::BrowserThread::UI);
|
||||
EventSubscriberBase::On(event);
|
||||
callbacks_.insert(std::make_pair(event, callback));
|
||||
}
|
||||
|
||||
void Off(const std::string& event) {
|
||||
DCHECK_CURRENTLY_ON(::content::BrowserThread::UI);
|
||||
EventSubscriberBase::Off(event);
|
||||
DCHECK(callbacks_.find(event) != callbacks_.end());
|
||||
callbacks_.erase(callbacks_.find(event));
|
||||
}
|
||||
|
||||
void RemoveAllListeners() {
|
||||
DCHECK_CURRENTLY_ON(::content::BrowserThread::UI);
|
||||
EventSubscriberBase::RemoveAllListeners();
|
||||
callbacks_.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
void EventEmitted(const std::string& event_name,
|
||||
mate::Arguments* args) override {
|
||||
DCHECK_CURRENTLY_ON(::content::BrowserThread::UI);
|
||||
base::AutoLock auto_lock(handler_lock_);
|
||||
if (!handler_) {
|
||||
// handler_ was probably destroyed by another thread and we should not
|
||||
// access it.
|
||||
return;
|
||||
}
|
||||
auto it = callbacks_.find(event_name);
|
||||
if (it != callbacks_.end()) {
|
||||
auto method = it->second;
|
||||
(handler_->*method)(args);
|
||||
}
|
||||
}
|
||||
|
||||
HandlerType* handler_;
|
||||
base::Lock handler_lock_;
|
||||
std::map<std::string, EventCallback> callbacks_;
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_BROWSER_API_EVENT_SUBSCRIBER_H_
|
||||
@@ -45,9 +45,9 @@ bool FrameSubscriber::ShouldCaptureFrame(
|
||||
|
||||
gfx::Size view_size = rect.size();
|
||||
gfx::Size bitmap_size = view_size;
|
||||
gfx::NativeView native_view = view_->GetNativeView();
|
||||
const gfx::NativeView native_view = view_->GetNativeView();
|
||||
const float scale =
|
||||
display::Screen::GetScreen()->GetDisplayNearestView(native_view)
|
||||
display::Screen::GetScreen()->GetDisplayNearestWindow(native_view)
|
||||
.device_scale_factor();
|
||||
if (scale > 1.0f)
|
||||
bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
|
||||
@@ -78,32 +78,20 @@ void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback,
|
||||
v8::Locker locker(isolate_);
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
|
||||
size_t rgb_row_size = bitmap.width() * bitmap.bytesPerPixel();
|
||||
|
||||
v8::MaybeLocal<v8::Object> buffer =
|
||||
node::Buffer::New(isolate_, rgb_row_size * bitmap.height());
|
||||
|
||||
size_t rgb_arr_size = bitmap.width() * bitmap.height() *
|
||||
bitmap.bytesPerPixel();
|
||||
v8::MaybeLocal<v8::Object> buffer = node::Buffer::New(isolate_, rgb_arr_size);
|
||||
if (buffer.IsEmpty())
|
||||
return;
|
||||
|
||||
auto local_buffer = buffer.ToLocalChecked();
|
||||
|
||||
{
|
||||
SkAutoLockPixels lock(bitmap);
|
||||
auto source = static_cast<const unsigned char*>(bitmap.getPixels());
|
||||
auto target = node::Buffer::Data(local_buffer);
|
||||
|
||||
for (int y = 0; y < bitmap.height(); ++y) {
|
||||
memcpy(target, source, rgb_row_size);
|
||||
source += bitmap.rowBytes();
|
||||
target += rgb_row_size;
|
||||
}
|
||||
}
|
||||
bitmap.copyPixelsTo(
|
||||
reinterpret_cast<uint8_t*>(node::Buffer::Data(buffer.ToLocalChecked())),
|
||||
rgb_arr_size);
|
||||
|
||||
v8::Local<v8::Value> damage =
|
||||
mate::Converter<gfx::Rect>::ToV8(isolate_, damage_rect);
|
||||
|
||||
callback_.Run(local_buffer, damage);
|
||||
callback_.Run(buffer.ToLocalChecked(), damage);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/supports_user_data.h"
|
||||
|
||||
namespace mate {
|
||||
@@ -47,19 +46,16 @@ void TrackableObjectBase::Destroy() {
|
||||
}
|
||||
|
||||
void TrackableObjectBase::AttachAsUserData(base::SupportsUserData* wrapped) {
|
||||
wrapped->SetUserData(kTrackedObjectKey,
|
||||
base::MakeUnique<IDUserData>(weak_map_id_));
|
||||
wrapped->SetUserData(kTrackedObjectKey, new IDUserData(weak_map_id_));
|
||||
}
|
||||
|
||||
// static
|
||||
int32_t TrackableObjectBase::GetIDFromWrappedClass(
|
||||
base::SupportsUserData* wrapped) {
|
||||
if (wrapped) {
|
||||
auto id = static_cast<IDUserData*>(wrapped->GetUserData(kTrackedObjectKey));
|
||||
if (id)
|
||||
return *id;
|
||||
}
|
||||
return 0;
|
||||
int32_t TrackableObjectBase::GetIDFromWrappedClass(base::SupportsUserData* w) {
|
||||
auto id = static_cast<IDUserData*>(w->GetUserData(kTrackedObjectKey));
|
||||
if (id)
|
||||
return *id;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -30,15 +30,15 @@ class TrackableObjectBase {
|
||||
// Wrap TrackableObject into a class that SupportsUserData.
|
||||
void AttachAsUserData(base::SupportsUserData* wrapped);
|
||||
|
||||
// Get the weak_map_id from SupportsUserData.
|
||||
static int32_t GetIDFromWrappedClass(base::SupportsUserData* wrapped);
|
||||
|
||||
protected:
|
||||
virtual ~TrackableObjectBase();
|
||||
|
||||
// Returns a closure that can destroy the native class.
|
||||
base::Closure GetDestroyClosure();
|
||||
|
||||
// Get the weak_map_id from SupportsUserData.
|
||||
static int32_t GetIDFromWrappedClass(base::SupportsUserData* wrapped);
|
||||
|
||||
// Register a callback that should be destroyed before JavaScript environment
|
||||
// gets destroyed.
|
||||
static base::Closure RegisterDestructionCallback(const base::Closure& c);
|
||||
@@ -62,10 +62,7 @@ class TrackableObject : public TrackableObjectBase,
|
||||
public:
|
||||
// Mark the JS object as destroyed.
|
||||
void MarkDestroyed() {
|
||||
v8::Local<v8::Object> wrapper = Wrappable<T>::GetWrapper();
|
||||
if (!wrapper.IsEmpty()) {
|
||||
wrapper->SetAlignedPointerInInternalField(0, nullptr);
|
||||
}
|
||||
Wrappable<T>::GetWrapper()->SetAlignedPointerInInternalField(0, nullptr);
|
||||
}
|
||||
|
||||
bool IsDestroyed() {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "atom/browser/net/about_protocol_handler.h"
|
||||
#include "atom/browser/net/asar/asar_protocol_handler.h"
|
||||
#include "atom/browser/net/atom_cert_verifier.h"
|
||||
#include "atom/browser/net/atom_ct_delegate.h"
|
||||
#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"
|
||||
@@ -71,6 +72,7 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
||||
bool in_memory,
|
||||
const base::DictionaryValue& options)
|
||||
: brightray::BrowserContext(partition, in_memory),
|
||||
ct_delegate_(new AtomCTDelegate),
|
||||
network_delegate_(new AtomNetworkDelegate),
|
||||
cookie_delegate_(new AtomCookieDelegate) {
|
||||
// Construct user agent string.
|
||||
@@ -190,9 +192,8 @@ content::PermissionManager* AtomBrowserContext::GetPermissionManager() {
|
||||
return permission_manager_.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<net::CertVerifier> AtomBrowserContext::CreateCertVerifier(
|
||||
brightray::RequireCTDelegate* ct_delegate) {
|
||||
return base::WrapUnique(new AtomCertVerifier(ct_delegate));
|
||||
std::unique_ptr<net::CertVerifier> AtomBrowserContext::CreateCertVerifier() {
|
||||
return base::WrapUnique(new AtomCertVerifier(ct_delegate_.get()));
|
||||
}
|
||||
|
||||
std::vector<std::string> AtomBrowserContext::GetCookieableSchemes() {
|
||||
@@ -203,6 +204,11 @@ std::vector<std::string> AtomBrowserContext::GetCookieableSchemes() {
|
||||
return default_schemes;
|
||||
}
|
||||
|
||||
net::TransportSecurityState::RequireCTDelegate*
|
||||
AtomBrowserContext::GetRequireCTDelegate() {
|
||||
return ct_delegate_.get();
|
||||
}
|
||||
|
||||
void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
|
||||
pref_registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory,
|
||||
base::FilePath());
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
namespace atom {
|
||||
|
||||
class AtomBlobReader;
|
||||
class AtomCTDelegate;
|
||||
class AtomDownloadManagerDelegate;
|
||||
class AtomNetworkDelegate;
|
||||
class AtomPermissionManager;
|
||||
@@ -39,9 +40,10 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
content::ProtocolHandlerMap* protocol_handlers) override;
|
||||
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
|
||||
const base::FilePath& base_path) override;
|
||||
std::unique_ptr<net::CertVerifier> CreateCertVerifier(
|
||||
brightray::RequireCTDelegate* ct_delegate) override;
|
||||
std::unique_ptr<net::CertVerifier> CreateCertVerifier() override;
|
||||
std::vector<std::string> GetCookieableSchemes() override;
|
||||
net::TransportSecurityState::RequireCTDelegate* GetRequireCTDelegate()
|
||||
override;
|
||||
|
||||
// content::BrowserContext:
|
||||
content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
|
||||
@@ -67,6 +69,7 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
std::unique_ptr<WebViewManager> guest_manager_;
|
||||
std::unique_ptr<AtomPermissionManager> permission_manager_;
|
||||
std::unique_ptr<AtomBlobReader> blob_reader_;
|
||||
std::unique_ptr<AtomCTDelegate> ct_delegate_;
|
||||
std::string user_agent_;
|
||||
bool use_cache_;
|
||||
|
||||
|
||||
@@ -92,7 +92,6 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
|
||||
// Show save dialog if save path was not set already on item
|
||||
file_dialog::DialogSettings settings;
|
||||
settings.parent_window = window;
|
||||
settings.force_detached = window->is_offscreen_dummy();
|
||||
settings.title = item->GetURL().spec();
|
||||
settings.default_path = default_path;
|
||||
if (path.empty() && file_dialog::ShowSaveDialog(settings, &path)) {
|
||||
@@ -116,10 +115,7 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
|
||||
// If user cancels the file save dialog, run the callback with empty FilePath.
|
||||
callback.Run(path,
|
||||
content::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
||||
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path,
|
||||
path.empty() ?
|
||||
content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED :
|
||||
content::DOWNLOAD_INTERRUPT_REASON_NONE);
|
||||
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path);
|
||||
}
|
||||
|
||||
void AtomDownloadManagerDelegate::Shutdown() {
|
||||
@@ -136,8 +132,7 @@ bool AtomDownloadManagerDelegate::DetermineDownloadTarget(
|
||||
callback.Run(download->GetForcedFilePath(),
|
||||
content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
||||
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
download->GetForcedFilePath(),
|
||||
content::DOWNLOAD_INTERRUPT_REASON_NONE);
|
||||
download->GetForcedFilePath());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -148,7 +143,7 @@ bool AtomDownloadManagerDelegate::DetermineDownloadTarget(
|
||||
callback.Run(save_path,
|
||||
content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
||||
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
save_path, content::DOWNLOAD_INTERRUPT_REASON_NONE);
|
||||
save_path);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/download_manager.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/stream_info.h"
|
||||
#include "net/base/escape.h"
|
||||
#include "net/ssl/client_cert_store.h"
|
||||
@@ -35,7 +34,8 @@ namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
void OnOpenExternal(const GURL& escaped_url, bool allowed) {
|
||||
void OnOpenExternal(const GURL& escaped_url,
|
||||
bool allowed) {
|
||||
if (allowed)
|
||||
platform_util::OpenExternal(
|
||||
#if defined(OS_WIN)
|
||||
@@ -66,8 +66,6 @@ void HandleExternalProtocolInUI(
|
||||
|
||||
void OnPdfResourceIntercepted(
|
||||
const GURL& original_url,
|
||||
int render_process_host_id,
|
||||
int render_frame_id,
|
||||
const content::ResourceRequestInfo::WebContentsGetter&
|
||||
web_contents_getter) {
|
||||
content::WebContents* web_contents = web_contents_getter.Run();
|
||||
@@ -77,7 +75,7 @@ void OnPdfResourceIntercepted(
|
||||
if (!WebContentsPreferences::IsPluginsEnabled(web_contents)) {
|
||||
auto browser_context = web_contents->GetBrowserContext();
|
||||
auto download_manager =
|
||||
content::BrowserContext::GetDownloadManager(browser_context);
|
||||
content::BrowserContext::GetDownloadManager(browser_context);
|
||||
|
||||
download_manager->DownloadUrl(
|
||||
content::DownloadUrlParameters::CreateForWebContentsMainFrame(
|
||||
@@ -88,29 +86,26 @@ void OnPdfResourceIntercepted(
|
||||
// The URL passes the original pdf resource url, that will be requested
|
||||
// by the webui page.
|
||||
// chrome://pdf-viewer/index.html?src=https://somepage/123.pdf
|
||||
content::NavigationController::LoadURLParams params(GURL(base::StringPrintf(
|
||||
"%sindex.html?%s=%s", kPdfViewerUIOrigin, kPdfPluginSrc,
|
||||
net::EscapeUrlEncodedData(original_url.spec(), false).c_str())));
|
||||
|
||||
content::RenderFrameHost* frame_host =
|
||||
content::RenderFrameHost::FromID(render_process_host_id, render_frame_id);
|
||||
if (!frame_host) {
|
||||
return;
|
||||
}
|
||||
|
||||
params.frame_tree_node_id = frame_host->GetFrameTreeNodeId();
|
||||
content::NavigationController::LoadURLParams params(
|
||||
GURL(base::StringPrintf(
|
||||
"%sindex.html?%s=%s",
|
||||
kPdfViewerUIOrigin,
|
||||
kPdfPluginSrc,
|
||||
net::EscapeUrlEncodedData(original_url.spec(), false).c_str())));
|
||||
web_contents->GetController().LoadURLWithParams(params);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomResourceDispatcherHostDelegate::AtomResourceDispatcherHostDelegate() {}
|
||||
AtomResourceDispatcherHostDelegate::AtomResourceDispatcherHostDelegate() {
|
||||
}
|
||||
|
||||
bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol(
|
||||
const GURL& url,
|
||||
content::ResourceRequestInfo* info) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&HandleExternalProtocolInUI, url,
|
||||
base::Bind(&HandleExternalProtocolInUI,
|
||||
url,
|
||||
info->GetWebContentsGetterForRequest(),
|
||||
info->HasUserGesture()));
|
||||
return true;
|
||||
@@ -126,16 +121,16 @@ AtomResourceDispatcherHostDelegate::CreateLoginDelegate(
|
||||
std::unique_ptr<net::ClientCertStore>
|
||||
AtomResourceDispatcherHostDelegate::CreateClientCertStore(
|
||||
content::ResourceContext* resource_context) {
|
||||
#if defined(USE_NSS_CERTS)
|
||||
return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreNSS(
|
||||
net::ClientCertStoreNSS::PasswordDelegateFactory()));
|
||||
#elif defined(OS_WIN)
|
||||
return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreWin());
|
||||
#elif defined(OS_MACOSX)
|
||||
return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreMac());
|
||||
#elif defined(USE_OPENSSL)
|
||||
return std::unique_ptr<net::ClientCertStore>();
|
||||
#endif
|
||||
#if defined(USE_NSS_CERTS)
|
||||
return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreNSS(
|
||||
net::ClientCertStoreNSS::PasswordDelegateFactory()));
|
||||
#elif defined(OS_WIN)
|
||||
return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreWin());
|
||||
#elif defined(OS_MACOSX)
|
||||
return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreMac());
|
||||
#elif defined(USE_OPENSSL)
|
||||
return std::unique_ptr<net::ClientCertStore>();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool AtomResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream(
|
||||
@@ -146,20 +141,11 @@ bool AtomResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream(
|
||||
std::string* payload) {
|
||||
const content::ResourceRequestInfo* info =
|
||||
content::ResourceRequestInfo::ForRequest(request);
|
||||
|
||||
int render_process_host_id;
|
||||
int render_frame_id;
|
||||
if (!info->GetAssociatedRenderFrame(&render_process_host_id,
|
||||
&render_frame_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mime_type == "application/pdf") {
|
||||
if (mime_type == "application/pdf" && info->IsMainFrame()) {
|
||||
*origin = GURL(kPdfViewerUIOrigin);
|
||||
content::BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&OnPdfResourceIntercepted, request->url(),
|
||||
render_process_host_id, render_frame_id,
|
||||
info->GetWebContentsGetterForRequest()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -11,28 +11,27 @@ namespace atom {
|
||||
void BridgeTaskRunner::MessageLoopIsReady() {
|
||||
auto message_loop = base::MessageLoop::current();
|
||||
CHECK(message_loop);
|
||||
for (TaskPair& task : tasks_) {
|
||||
for (const TaskPair& task : tasks_) {
|
||||
message_loop->task_runner()->PostDelayedTask(
|
||||
std::get<0>(task), std::move(std::get<1>(task)), std::get<2>(task));
|
||||
base::get<0>(task), base::get<1>(task), base::get<2>(task));
|
||||
}
|
||||
for (TaskPair& task : non_nestable_tasks_) {
|
||||
for (const TaskPair& task : non_nestable_tasks_) {
|
||||
message_loop->task_runner()->PostNonNestableDelayedTask(
|
||||
std::get<0>(task), std::move(std::get<1>(task)), std::get<2>(task));
|
||||
base::get<0>(task), base::get<1>(task), base::get<2>(task));
|
||||
}
|
||||
}
|
||||
|
||||
bool BridgeTaskRunner::PostDelayedTask(
|
||||
const tracked_objects::Location& from_here,
|
||||
base::OnceClosure task,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) {
|
||||
auto message_loop = base::MessageLoop::current();
|
||||
if (!message_loop) {
|
||||
tasks_.push_back(std::make_tuple(from_here, std::move(task), delay));
|
||||
tasks_.push_back(std::make_tuple(from_here, task, delay));
|
||||
return true;
|
||||
}
|
||||
|
||||
return message_loop->task_runner()->PostDelayedTask(
|
||||
from_here, std::move(task), delay);
|
||||
return message_loop->task_runner()->PostDelayedTask(from_here, task, delay);
|
||||
}
|
||||
|
||||
bool BridgeTaskRunner::RunsTasksOnCurrentThread() const {
|
||||
@@ -45,17 +44,16 @@ bool BridgeTaskRunner::RunsTasksOnCurrentThread() const {
|
||||
|
||||
bool BridgeTaskRunner::PostNonNestableDelayedTask(
|
||||
const tracked_objects::Location& from_here,
|
||||
base::OnceClosure task,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) {
|
||||
auto message_loop = base::MessageLoop::current();
|
||||
if (!message_loop) {
|
||||
non_nestable_tasks_.push_back(std::make_tuple(
|
||||
from_here, std::move(task), delay));
|
||||
non_nestable_tasks_.push_back(std::make_tuple(from_here, task, delay));
|
||||
return true;
|
||||
}
|
||||
|
||||
return message_loop->task_runner()->PostNonNestableDelayedTask(
|
||||
from_here, std::move(task), delay);
|
||||
from_here, task, delay);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -25,17 +25,17 @@ class BridgeTaskRunner : public base::SingleThreadTaskRunner {
|
||||
|
||||
// base::SingleThreadTaskRunner:
|
||||
bool PostDelayedTask(const tracked_objects::Location& from_here,
|
||||
base::OnceClosure task,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) override;
|
||||
bool RunsTasksOnCurrentThread() const override;
|
||||
bool PostNonNestableDelayedTask(
|
||||
const tracked_objects::Location& from_here,
|
||||
base::OnceClosure task,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) override;
|
||||
|
||||
private:
|
||||
using TaskPair = std::tuple<
|
||||
tracked_objects::Location, base::OnceClosure, base::TimeDelta>;
|
||||
tracked_objects::Location, base::Closure, base::TimeDelta>;
|
||||
std::vector<TaskPair> tasks_;
|
||||
std::vector<TaskPair> non_nestable_tasks_;
|
||||
|
||||
|
||||
@@ -119,32 +119,10 @@ class Browser : public WindowListObserver {
|
||||
// Returns the type name of the current user activity.
|
||||
std::string GetCurrentActivityType();
|
||||
|
||||
// Invalidates the current user activity.
|
||||
void InvalidateCurrentActivity();
|
||||
|
||||
// Updates the current user activity
|
||||
void UpdateCurrentActivity(const std::string& type,
|
||||
const base::DictionaryValue& user_info);
|
||||
|
||||
// Indicates that an user activity is about to be resumed.
|
||||
bool WillContinueUserActivity(const std::string& type);
|
||||
|
||||
// Indicates a failure to resume a Handoff activity.
|
||||
void DidFailToContinueUserActivity(const std::string& type,
|
||||
const std::string& error);
|
||||
|
||||
// Resumes an activity via hand-off.
|
||||
bool ContinueUserActivity(const std::string& type,
|
||||
const base::DictionaryValue& user_info);
|
||||
|
||||
// Indicates that an activity was continued on another device.
|
||||
void UserActivityWasContinued(const std::string& type,
|
||||
const base::DictionaryValue& user_info);
|
||||
|
||||
// Gives an oportunity to update the Handoff payload.
|
||||
bool UpdateUserActivityState(const std::string& type,
|
||||
const base::DictionaryValue& user_info);
|
||||
|
||||
// Bounce the dock icon.
|
||||
enum BounceType {
|
||||
BOUNCE_CRITICAL = 0,
|
||||
|
||||
@@ -4,62 +4,16 @@
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/process/launch.h"
|
||||
#include "brightray/common/application_info.h"
|
||||
|
||||
#if defined(USE_X11)
|
||||
#include "chrome/browser/ui/libgtkui/gtk_util.h"
|
||||
#include "chrome/browser/ui/libgtkui/unity_service.h"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
const char kXdgSettings[] = "xdg-settings";
|
||||
const char kXdgSettingsDefaultSchemeHandler[] = "default-url-scheme-handler";
|
||||
|
||||
bool LaunchXdgUtility(const std::vector<std::string>& argv, int* exit_code) {
|
||||
*exit_code = EXIT_FAILURE;
|
||||
int devnull = open("/dev/null", O_RDONLY);
|
||||
if (devnull < 0) return false;
|
||||
|
||||
base::LaunchOptions options;
|
||||
|
||||
base::FileHandleMappingVector remap;
|
||||
remap.push_back(std::make_pair(devnull, STDIN_FILENO));
|
||||
options.fds_to_remap = &remap;
|
||||
|
||||
base::Process process = base::LaunchProcess(argv, options);
|
||||
close(devnull);
|
||||
|
||||
if (!process.IsValid()) return false;
|
||||
return process.WaitForExit(exit_code);
|
||||
}
|
||||
|
||||
bool SetDefaultWebClient(const std::string& protocol) {
|
||||
std::unique_ptr<base::Environment> env(base::Environment::Create());
|
||||
|
||||
std::vector<std::string> argv;
|
||||
argv.push_back(kXdgSettings);
|
||||
argv.push_back("set");
|
||||
if (!protocol.empty()) {
|
||||
argv.push_back(kXdgSettingsDefaultSchemeHandler);
|
||||
argv.push_back(protocol);
|
||||
}
|
||||
argv.push_back(libgtkui::GetDesktopName(env.get()));
|
||||
|
||||
int exit_code;
|
||||
bool ran_ok = LaunchXdgUtility(argv, &exit_code);
|
||||
return ran_ok && exit_code == EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
void Browser::Focus() {
|
||||
// Focus on the first visible window.
|
||||
for (const auto& window : WindowList::GetWindows()) {
|
||||
@@ -79,40 +33,18 @@ void Browser::ClearRecentDocuments() {
|
||||
void Browser::SetAppUserModelID(const base::string16& name) {
|
||||
}
|
||||
|
||||
bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol,
|
||||
mate::Arguments* args) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Browser::SetAsDefaultProtocolClient(const std::string& protocol,
|
||||
mate::Arguments* args) {
|
||||
return SetDefaultWebClient(protocol);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Browser::IsDefaultProtocolClient(const std::string& protocol,
|
||||
mate::Arguments* args) {
|
||||
std::unique_ptr<base::Environment> env(base::Environment::Create());
|
||||
|
||||
if (protocol.empty()) return false;
|
||||
|
||||
std::vector<std::string> argv;
|
||||
argv.push_back(kXdgSettings);
|
||||
argv.push_back("check");
|
||||
argv.push_back(kXdgSettingsDefaultSchemeHandler);
|
||||
argv.push_back(protocol);
|
||||
argv.push_back(libgtkui::GetDesktopName(env.get()));
|
||||
|
||||
std::string reply;
|
||||
int success_code;
|
||||
bool ran_ok = base::GetAppOutputWithExitCode(base::CommandLine(argv),
|
||||
&reply, &success_code);
|
||||
|
||||
if (!ran_ok || success_code != EXIT_SUCCESS) return false;
|
||||
|
||||
// Allow any reply that starts with "yes".
|
||||
return base::StartsWith(reply, "yes", base::CompareCase::SENSITIVE)
|
||||
? true
|
||||
: false;
|
||||
}
|
||||
|
||||
// Todo implement
|
||||
bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol,
|
||||
mate::Arguments* args) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -144,30 +144,6 @@ std::string Browser::GetCurrentActivityType() {
|
||||
return base::SysNSStringToUTF8(userActivity.activityType);
|
||||
}
|
||||
|
||||
void Browser::InvalidateCurrentActivity() {
|
||||
[[AtomApplication sharedApplication] invalidateCurrentActivity];
|
||||
}
|
||||
|
||||
void Browser::UpdateCurrentActivity(const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
[[AtomApplication sharedApplication]
|
||||
updateCurrentActivity:base::SysUTF8ToNSString(type)
|
||||
withUserInfo:DictionaryValueToNSDictionary(user_info)];
|
||||
}
|
||||
|
||||
bool Browser::WillContinueUserActivity(const std::string& type) {
|
||||
bool prevent_default = false;
|
||||
for (BrowserObserver& observer : observers_)
|
||||
observer.OnWillContinueUserActivity(&prevent_default, type);
|
||||
return prevent_default;
|
||||
}
|
||||
|
||||
void Browser::DidFailToContinueUserActivity(const std::string& type,
|
||||
const std::string& error) {
|
||||
for (BrowserObserver& observer : observers_)
|
||||
observer.OnDidFailToContinueUserActivity(type, error);
|
||||
}
|
||||
|
||||
bool Browser::ContinueUserActivity(const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
bool prevent_default = false;
|
||||
@@ -176,20 +152,6 @@ bool Browser::ContinueUserActivity(const std::string& type,
|
||||
return prevent_default;
|
||||
}
|
||||
|
||||
void Browser::UserActivityWasContinued(const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
for (BrowserObserver& observer : observers_)
|
||||
observer.OnUserActivityWasContinued(type, user_info);
|
||||
}
|
||||
|
||||
bool Browser::UpdateUserActivityState(const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
bool prevent_default = false;
|
||||
for (BrowserObserver& observer : observers_)
|
||||
observer.OnUpdateUserActivityState(&prevent_default, type, user_info);
|
||||
return prevent_default;
|
||||
}
|
||||
|
||||
Browser::LoginItemSettings Browser::GetLoginItemSettings(
|
||||
const LoginItemSettings& options) {
|
||||
LoginItemSettings settings;
|
||||
|
||||
@@ -59,28 +59,12 @@ class BrowserObserver {
|
||||
virtual void OnPreMainMessageLoopRun() {}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// The browser wants to report that an user activity will resume. (macOS only)
|
||||
virtual void OnWillContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type) {}
|
||||
// The browser wants to report an user activity resuming error. (macOS only)
|
||||
virtual void OnDidFailToContinueUserActivity(
|
||||
const std::string& type,
|
||||
const std::string& error) {}
|
||||
// The browser wants to resume a user activity via handoff. (macOS only)
|
||||
virtual void OnContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {}
|
||||
// The browser wants to notify that an user activity was resumed. (macOS only)
|
||||
virtual void OnUserActivityWasContinued(
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {}
|
||||
// The browser wants to update an user activity payload. (macOS only)
|
||||
virtual void OnUpdateUserActivityState(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {}
|
||||
|
||||
// User clicked the native macOS new tab button. (macOS only)
|
||||
virtual void OnNewWindowForTab() {}
|
||||
#endif
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "atom/browser/web_dialog_helper.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "chrome/browser/printing/print_preview_message_handler.h"
|
||||
#include "chrome/browser/printing/print_view_manager_basic.h"
|
||||
#include "chrome/browser/ssl/security_state_tab_helper.h"
|
||||
@@ -242,8 +241,7 @@ void CommonWebContentsDelegate::RunFileChooser(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const content::FileChooserParams& params) {
|
||||
if (!web_dialog_helper_)
|
||||
web_dialog_helper_.reset(new WebDialogHelper(
|
||||
owner_window(), owner_window()->is_offscreen_dummy()));
|
||||
web_dialog_helper_.reset(new WebDialogHelper(owner_window()));
|
||||
web_dialog_helper_->RunFileChooser(render_frame_host, params);
|
||||
}
|
||||
|
||||
@@ -251,8 +249,7 @@ void CommonWebContentsDelegate::EnumerateDirectory(content::WebContents* guest,
|
||||
int request_id,
|
||||
const base::FilePath& path) {
|
||||
if (!web_dialog_helper_)
|
||||
web_dialog_helper_.reset(new WebDialogHelper(
|
||||
owner_window(), owner_window()->is_offscreen_dummy()));
|
||||
web_dialog_helper_.reset(new WebDialogHelper(owner_window()));
|
||||
web_dialog_helper_->EnumerateDirectory(guest, request_id, path);
|
||||
}
|
||||
|
||||
@@ -300,11 +297,10 @@ void CommonWebContentsDelegate::DevToolsSaveToFile(
|
||||
} else {
|
||||
file_dialog::DialogSettings settings;
|
||||
settings.parent_window = owner_window();
|
||||
settings.force_detached = owner_window()->is_offscreen_dummy();
|
||||
settings.title = url;
|
||||
settings.default_path = base::FilePath::FromUTF8Unsafe(url);
|
||||
if (!file_dialog::ShowSaveDialog(settings, &path)) {
|
||||
base::Value url_value(url);
|
||||
base::StringValue url_value(url);
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.canceledSaveURL", &url_value, nullptr, nullptr);
|
||||
return;
|
||||
@@ -367,7 +363,6 @@ void CommonWebContentsDelegate::DevToolsAddFileSystem(
|
||||
std::vector<base::FilePath> paths;
|
||||
file_dialog::DialogSettings settings;
|
||||
settings.parent_window = owner_window();
|
||||
settings.force_detached = owner_window()->is_offscreen_dummy();
|
||||
settings.properties = file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
|
||||
if (!file_dialog::ShowOpenDialog(settings, &paths))
|
||||
return;
|
||||
@@ -389,7 +384,7 @@ void CommonWebContentsDelegate::DevToolsAddFileSystem(
|
||||
auto pref_service = GetPrefService(GetDevToolsWebContents());
|
||||
DictionaryPrefUpdate update(pref_service, prefs::kDevToolsFileSystemPaths);
|
||||
update.Get()->SetWithoutPathExpansion(
|
||||
path.AsUTF8Unsafe(), base::MakeUnique<base::Value>());
|
||||
path.AsUTF8Unsafe(), base::Value::CreateNullValue());
|
||||
|
||||
web_contents_->CallClientFunction("DevToolsAPI.fileSystemAdded",
|
||||
file_system_value.get(),
|
||||
@@ -409,7 +404,7 @@ void CommonWebContentsDelegate::DevToolsRemoveFileSystem(
|
||||
DictionaryPrefUpdate update(pref_service, prefs::kDevToolsFileSystemPaths);
|
||||
update.Get()->RemoveWithoutPathExpansion(path, nullptr);
|
||||
|
||||
base::Value file_system_path_value(path);
|
||||
base::StringValue file_system_path_value(path);
|
||||
web_contents_->CallClientFunction("DevToolsAPI.fileSystemRemoved",
|
||||
&file_system_path_value,
|
||||
nullptr, nullptr);
|
||||
@@ -473,7 +468,7 @@ void CommonWebContentsDelegate::DevToolsSearchInPath(
|
||||
void CommonWebContentsDelegate::OnDevToolsSaveToFile(
|
||||
const std::string& url) {
|
||||
// Notify DevTools.
|
||||
base::Value url_value(url);
|
||||
base::StringValue url_value(url);
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.savedURL", &url_value, nullptr, nullptr);
|
||||
}
|
||||
@@ -481,7 +476,7 @@ void CommonWebContentsDelegate::OnDevToolsSaveToFile(
|
||||
void CommonWebContentsDelegate::OnDevToolsAppendToFile(
|
||||
const std::string& url) {
|
||||
// Notify DevTools.
|
||||
base::Value url_value(url);
|
||||
base::StringValue url_value(url);
|
||||
web_contents_->CallClientFunction(
|
||||
"DevToolsAPI.appendedToURL", &url_value, nullptr, nullptr);
|
||||
}
|
||||
@@ -491,7 +486,7 @@ void CommonWebContentsDelegate::OnDevToolsIndexingWorkCalculated(
|
||||
const std::string& file_system_path,
|
||||
int total_work) {
|
||||
base::Value request_id_value(request_id);
|
||||
base::Value file_system_path_value(file_system_path);
|
||||
base::StringValue file_system_path_value(file_system_path);
|
||||
base::Value total_work_value(total_work);
|
||||
web_contents_->CallClientFunction("DevToolsAPI.indexingTotalWorkCalculated",
|
||||
&request_id_value,
|
||||
@@ -504,7 +499,7 @@ void CommonWebContentsDelegate::OnDevToolsIndexingWorked(
|
||||
const std::string& file_system_path,
|
||||
int worked) {
|
||||
base::Value request_id_value(request_id);
|
||||
base::Value file_system_path_value(file_system_path);
|
||||
base::StringValue file_system_path_value(file_system_path);
|
||||
base::Value worked_value(worked);
|
||||
web_contents_->CallClientFunction("DevToolsAPI.indexingWorked",
|
||||
&request_id_value,
|
||||
@@ -517,7 +512,7 @@ void CommonWebContentsDelegate::OnDevToolsIndexingDone(
|
||||
const std::string& file_system_path) {
|
||||
devtools_indexing_jobs_.erase(request_id);
|
||||
base::Value request_id_value(request_id);
|
||||
base::Value file_system_path_value(file_system_path);
|
||||
base::StringValue file_system_path_value(file_system_path);
|
||||
web_contents_->CallClientFunction("DevToolsAPI.indexingDone",
|
||||
&request_id_value,
|
||||
&file_system_path_value,
|
||||
@@ -533,7 +528,7 @@ void CommonWebContentsDelegate::OnDevToolsSearchCompleted(
|
||||
file_paths_value.AppendString(file_path);
|
||||
}
|
||||
base::Value request_id_value(request_id);
|
||||
base::Value file_system_path_value(file_system_path);
|
||||
base::StringValue file_system_path_value(file_system_path);
|
||||
web_contents_->CallClientFunction("DevToolsAPI.searchCompleted",
|
||||
&request_id_value,
|
||||
&file_system_path_value,
|
||||
|
||||
@@ -20,11 +20,11 @@ void CommonWebContentsDelegate::HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
if (event.skip_in_browser ||
|
||||
event.GetType() == content::NativeWebKeyboardEvent::kChar)
|
||||
event.type() == content::NativeWebKeyboardEvent::Char)
|
||||
return;
|
||||
|
||||
// Escape exits tabbed fullscreen mode.
|
||||
if (event.windows_key_code == ui::VKEY_ESCAPE && is_html_fullscreen())
|
||||
if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen())
|
||||
ExitFullscreenModeForTab(source);
|
||||
|
||||
if (!ignore_menu_shortcuts_) {
|
||||
|
||||
@@ -19,7 +19,7 @@ void CommonWebContentsDelegate::HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
// Escape exits tabbed fullscreen mode.
|
||||
if (event.windows_key_code == ui::VKEY_ESCAPE && is_html_fullscreen())
|
||||
if (event.windowsKeyCode == ui::VKEY_ESCAPE && is_html_fullscreen())
|
||||
ExitFullscreenModeForTab(source);
|
||||
|
||||
// Let the NativeWindow handle other parts.
|
||||
|
||||
@@ -33,7 +33,7 @@ class BluetoothChooser : public content::BluetoothChooser {
|
||||
bool is_gatt_connected,
|
||||
bool is_paired,
|
||||
int signal_strength_level) override;
|
||||
void RemoveDevice(const std::string& device_id);
|
||||
void RemoveDevice(const std::string& device_id) override;
|
||||
|
||||
private:
|
||||
std::vector<DeviceInfo> device_list_;
|
||||
|
||||
@@ -6,13 +6,10 @@
|
||||
#import "base/mac/scoped_nsobject.h"
|
||||
|
||||
@interface AtomApplication : NSApplication<CrAppProtocol,
|
||||
CrAppControlProtocol,
|
||||
NSUserActivityDelegate> {
|
||||
CrAppControlProtocol> {
|
||||
@private
|
||||
BOOL handlingSendEvent_;
|
||||
base::scoped_nsobject<NSUserActivity> currentActivity_;
|
||||
NSCondition* handoffLock_;
|
||||
BOOL updateReceived_;
|
||||
}
|
||||
|
||||
+ (AtomApplication*)sharedApplication;
|
||||
@@ -27,8 +24,5 @@
|
||||
- (void)setCurrentActivity:(NSString*)type
|
||||
withUserInfo:(NSDictionary*)userInfo
|
||||
withWebpageURL:(NSURL*)webpageURL;
|
||||
- (void)invalidateCurrentActivity;
|
||||
- (void)updateCurrentActivity:(NSString*)type
|
||||
withUserInfo:(NSDictionary*)userInfo;
|
||||
|
||||
@end
|
||||
|
||||
@@ -4,23 +4,11 @@
|
||||
|
||||
#import "atom/browser/mac/atom_application.h"
|
||||
|
||||
#include "atom/browser/mac/dict_util.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "base/auto_reset.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "content/public/browser/browser_accessibility_state.h"
|
||||
|
||||
namespace {
|
||||
|
||||
inline void dispatch_sync_main(dispatch_block_t block) {
|
||||
if ([NSThread isMainThread])
|
||||
block();
|
||||
else
|
||||
dispatch_sync(dispatch_get_main_queue(), block);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@implementation AtomApplication
|
||||
|
||||
+ (AtomApplication*)sharedApplication {
|
||||
@@ -47,78 +35,19 @@ inline void dispatch_sync_main(dispatch_block_t block) {
|
||||
[[NSUserActivity alloc] initWithActivityType:type]);
|
||||
[currentActivity_ setUserInfo:userInfo];
|
||||
[currentActivity_ setWebpageURL:webpageURL];
|
||||
[currentActivity_ setDelegate:self];
|
||||
[currentActivity_ becomeCurrent];
|
||||
[currentActivity_ setNeedsSave:YES];
|
||||
}
|
||||
|
||||
- (NSUserActivity*)getCurrentActivity {
|
||||
return currentActivity_.get();
|
||||
}
|
||||
|
||||
- (void)invalidateCurrentActivity {
|
||||
if (currentActivity_) {
|
||||
[currentActivity_ invalidate];
|
||||
currentActivity_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateCurrentActivity:(NSString*)type
|
||||
withUserInfo:(NSDictionary*)userInfo {
|
||||
if (currentActivity_) {
|
||||
[currentActivity_ addUserInfoEntriesFromDictionary:userInfo];
|
||||
}
|
||||
|
||||
[handoffLock_ lock];
|
||||
updateReceived_ = YES;
|
||||
[handoffLock_ signal];
|
||||
[handoffLock_ unlock];
|
||||
}
|
||||
|
||||
- (void)userActivityWillSave:(NSUserActivity *)userActivity {
|
||||
__block BOOL shouldWait = NO;
|
||||
dispatch_sync_main(^{
|
||||
std::string activity_type(base::SysNSStringToUTF8(userActivity.activityType));
|
||||
std::unique_ptr<base::DictionaryValue> user_info =
|
||||
atom::NSDictionaryToDictionaryValue(userActivity.userInfo);
|
||||
|
||||
atom::Browser* browser = atom::Browser::Get();
|
||||
shouldWait = browser->UpdateUserActivityState(activity_type, *user_info) ? YES : NO;
|
||||
});
|
||||
|
||||
if (shouldWait) {
|
||||
[handoffLock_ lock];
|
||||
updateReceived_ = NO;
|
||||
while (!updateReceived_) {
|
||||
BOOL isSignaled = [handoffLock_ waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
|
||||
if (!isSignaled) break;
|
||||
}
|
||||
[handoffLock_ unlock];
|
||||
}
|
||||
|
||||
[userActivity setNeedsSave:YES];
|
||||
}
|
||||
|
||||
- (void)userActivityWasContinued:(NSUserActivity *)userActivity {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
std::string activity_type(base::SysNSStringToUTF8(userActivity.activityType));
|
||||
std::unique_ptr<base::DictionaryValue> user_info =
|
||||
atom::NSDictionaryToDictionaryValue(userActivity.userInfo);
|
||||
|
||||
atom::Browser* browser = atom::Browser::Get();
|
||||
browser->UserActivityWasContinued(activity_type, *user_info);
|
||||
});
|
||||
[userActivity setNeedsSave:YES];
|
||||
}
|
||||
|
||||
- (void)awakeFromNib {
|
||||
[[NSAppleEventManager sharedAppleEventManager]
|
||||
setEventHandler:self
|
||||
andSelector:@selector(handleURLEvent:withReplyEvent:)
|
||||
forEventClass:kInternetEventClass
|
||||
andEventID:kAEGetURL];
|
||||
|
||||
handoffLock_ = [NSCondition new];
|
||||
}
|
||||
|
||||
- (void)handleURLEvent:(NSAppleEventDescriptor*)event
|
||||
@@ -143,9 +72,6 @@ inline void dispatch_sync_main(dispatch_block_t block) {
|
||||
bool enableAccessibility = ([self voiceOverEnabled] && [value boolValue]);
|
||||
[self updateAccessibilityEnabled:enableAccessibility];
|
||||
}
|
||||
else if ([attribute isEqualToString:@"AXManualAccessibility"]) {
|
||||
[self updateAccessibilityEnabled:[value boolValue]];
|
||||
}
|
||||
return [super accessibilitySetValue:value forAttribute:attribute];
|
||||
}
|
||||
|
||||
|
||||
@@ -118,21 +118,6 @@ continueUserActivity:(NSUserActivity*)userActivity
|
||||
return browser->ContinueUserActivity(activity_type, *user_info) ? YES : NO;
|
||||
}
|
||||
|
||||
- (BOOL)application:(NSApplication*)application willContinueUserActivityWithType:(NSString*)userActivityType {
|
||||
std::string activity_type(base::SysNSStringToUTF8(userActivityType));
|
||||
|
||||
atom::Browser* browser = atom::Browser::Get();
|
||||
return browser->WillContinueUserActivity(activity_type) ? YES : NO;
|
||||
}
|
||||
|
||||
- (void)application:(NSApplication*)application didFailToContinueUserActivityWithType:(NSString*)userActivityType error:(NSError*)error {
|
||||
std::string activity_type(base::SysNSStringToUTF8(userActivityType));
|
||||
std::string error_message(base::SysNSStringToUTF8([error localizedDescription]));
|
||||
|
||||
atom::Browser* browser = atom::Browser::Get();
|
||||
browser->DidFailToContinueUserActivity(activity_type, error_message);
|
||||
}
|
||||
|
||||
- (IBAction)newWindowForTab:(id)sender {
|
||||
atom::Browser::Get()->NewWindowForTab();
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "atom/browser/mac/dict_util.h"
|
||||
|
||||
#include "base/json/json_writer.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/values.h"
|
||||
|
||||
@@ -46,14 +45,14 @@ std::unique_ptr<base::ListValue> NSArrayToListValue(NSArray* arr) {
|
||||
if (sub_arr)
|
||||
result->Append(std::move(sub_arr));
|
||||
else
|
||||
result->Append(base::MakeUnique<base::Value>());
|
||||
result->Append(base::Value::CreateNullValue());
|
||||
} else if ([value isKindOfClass:[NSDictionary class]]) {
|
||||
std::unique_ptr<base::DictionaryValue> sub_dict =
|
||||
NSDictionaryToDictionaryValue(value);
|
||||
if (sub_dict)
|
||||
result->Append(std::move(sub_dict));
|
||||
else
|
||||
result->Append(base::MakeUnique<base::Value>());
|
||||
result->Append(base::Value::CreateNullValue());
|
||||
} else {
|
||||
result->AppendString(base::SysNSStringToUTF8([value description]));
|
||||
}
|
||||
@@ -105,7 +104,7 @@ std::unique_ptr<base::DictionaryValue> NSDictionaryToDictionaryValue(
|
||||
result->SetWithoutPathExpansion(str_key, std::move(sub_arr));
|
||||
else
|
||||
result->SetWithoutPathExpansion(str_key,
|
||||
base::MakeUnique<base::Value>());
|
||||
base::Value::CreateNullValue());
|
||||
} else if ([value isKindOfClass:[NSDictionary class]]) {
|
||||
std::unique_ptr<base::DictionaryValue> sub_dict =
|
||||
NSDictionaryToDictionaryValue(value);
|
||||
@@ -113,7 +112,7 @@ std::unique_ptr<base::DictionaryValue> NSDictionaryToDictionaryValue(
|
||||
result->SetWithoutPathExpansion(str_key, std::move(sub_dict));
|
||||
else
|
||||
result->SetWithoutPathExpansion(str_key,
|
||||
base::MakeUnique<base::Value>());
|
||||
base::Value::CreateNullValue());
|
||||
} else {
|
||||
result->SetStringWithoutPathExpansion(
|
||||
str_key,
|
||||
|
||||
@@ -43,20 +43,10 @@ const NSAutoresizingMaskOptions kDefaultAutoResizingMask =
|
||||
- (void)mouseDown:(NSEvent *)event
|
||||
{
|
||||
if ([self.window respondsToSelector:@selector(performWindowDragWithEvent)]) {
|
||||
// According to Google, using performWindowDragWithEvent:
|
||||
// does not generate a NSWindowWillMoveNotification. Hence post one.
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
postNotificationName:NSWindowWillMoveNotification
|
||||
object:self];
|
||||
|
||||
[self.window performWindowDragWithEvent:event];
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.window.styleMask & NSFullScreenWindowMask) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.initialLocation = [event locationInWindow];
|
||||
}
|
||||
|
||||
@@ -66,53 +56,17 @@ const NSAutoresizingMaskOptions kDefaultAutoResizingMask =
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.window.styleMask & NSFullScreenWindowMask) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSPoint currentLocation = [NSEvent mouseLocation];
|
||||
NSPoint newOrigin;
|
||||
|
||||
NSRect screenFrame = [[NSScreen mainScreen] frame];
|
||||
NSSize screenSize = screenFrame.size;
|
||||
NSRect windowFrame = [self.window frame];
|
||||
NSSize windowSize = windowFrame.size;
|
||||
|
||||
newOrigin.x = currentLocation.x - self.initialLocation.x;
|
||||
newOrigin.y = currentLocation.y - self.initialLocation.y;
|
||||
|
||||
BOOL inMenuBar = (newOrigin.y + windowSize.height) > (screenFrame.origin.y + screenSize.height);
|
||||
BOOL screenAboveMainScreen = false;
|
||||
|
||||
if (inMenuBar) {
|
||||
for (NSScreen *screen in [NSScreen screens]) {
|
||||
NSRect currentScreenFrame = [screen frame];
|
||||
BOOL isHigher = currentScreenFrame.origin.y > screenFrame.origin.y;
|
||||
|
||||
// If there's another screen that is generally above the current screen,
|
||||
// we'll draw a new rectangle that is just above the current screen. If the
|
||||
// "higher" screen intersects with this rectangle, we'll allow drawing above
|
||||
// the menubar.
|
||||
if (isHigher) {
|
||||
NSRect aboveScreenRect = NSMakeRect(
|
||||
screenFrame.origin.x,
|
||||
screenFrame.origin.y + screenFrame.size.height - 10,
|
||||
screenFrame.size.width,
|
||||
200
|
||||
);
|
||||
|
||||
BOOL screenAboveIntersects = NSIntersectsRect(currentScreenFrame, aboveScreenRect);
|
||||
|
||||
if (screenAboveIntersects) {
|
||||
screenAboveMainScreen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Don't let window get dragged up under the menu bar
|
||||
if (inMenuBar && !screenAboveMainScreen) {
|
||||
if ((newOrigin.y + windowFrame.size.height) > (screenFrame.origin.y + screenFrame.size.height)) {
|
||||
newOrigin.y = screenFrame.origin.y + (screenFrame.size.height - windowFrame.size.height);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,6 @@ NativeWindow::NativeWindow(
|
||||
aspect_ratio_(0.0),
|
||||
parent_(parent),
|
||||
is_modal_(false),
|
||||
is_osr_dummy_(false),
|
||||
inspectable_web_contents_(inspectable_web_contents),
|
||||
weak_factory_(this) {
|
||||
options.Get(options::kFrame, &has_frame_);
|
||||
@@ -118,14 +117,6 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
|
||||
bool center;
|
||||
if (options.Get(options::kX, &x) && options.Get(options::kY, &y)) {
|
||||
SetPosition(gfx::Point(x, y));
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// FIXME(felixrieseberg): Dirty, dirty workaround for
|
||||
// https://github.com/electron/electron/issues/10862
|
||||
// Somehow, we need to call `SetBounds` twice to get
|
||||
// usable results. The root cause is still unknown.
|
||||
SetPosition(gfx::Point(x, y));
|
||||
#endif
|
||||
} else if (options.Get(options::kCenter, ¢er) && center) {
|
||||
Center();
|
||||
}
|
||||
@@ -168,10 +159,6 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
|
||||
if (options.Get(options::kHasShadow, &has_shadow)) {
|
||||
SetHasShadow(has_shadow);
|
||||
}
|
||||
double opacity;
|
||||
if (options.Get(options::kOpacity, &opacity)) {
|
||||
SetOpacity(opacity);
|
||||
}
|
||||
bool top;
|
||||
if (options.Get(options::kAlwaysOnTop, &top) && top) {
|
||||
SetAlwaysOnTop(true);
|
||||
@@ -349,24 +336,6 @@ void NativeWindow::SetParentWindow(NativeWindow* parent) {
|
||||
void NativeWindow::SetAutoHideCursor(bool auto_hide) {
|
||||
}
|
||||
|
||||
void NativeWindow::SelectPreviousTab() {
|
||||
}
|
||||
|
||||
void NativeWindow::SelectNextTab() {
|
||||
}
|
||||
|
||||
void NativeWindow::MergeAllWindows() {
|
||||
}
|
||||
|
||||
void NativeWindow::MoveTabToNewWindow() {
|
||||
}
|
||||
|
||||
void NativeWindow::ToggleTabBar() {
|
||||
}
|
||||
|
||||
void NativeWindow::AddTabbedWindow(NativeWindow* window) {
|
||||
}
|
||||
|
||||
void NativeWindow::SetVibrancy(const std::string& filename) {
|
||||
}
|
||||
|
||||
|
||||
@@ -134,20 +134,16 @@ class NativeWindow : public base::SupportsUserData,
|
||||
virtual std::string GetTitle() = 0;
|
||||
virtual void FlashFrame(bool flash) = 0;
|
||||
virtual void SetSkipTaskbar(bool skip) = 0;
|
||||
virtual void SetSimpleFullScreen(bool simple_fullscreen) = 0;
|
||||
virtual bool IsSimpleFullScreen() = 0;
|
||||
virtual void SetKiosk(bool kiosk) = 0;
|
||||
virtual bool IsKiosk() = 0;
|
||||
virtual void SetBackgroundColor(const std::string& color_name) = 0;
|
||||
virtual void SetHasShadow(bool has_shadow) = 0;
|
||||
virtual bool HasShadow() = 0;
|
||||
virtual void SetOpacity(const double opacity) = 0;
|
||||
virtual double GetOpacity() = 0;
|
||||
virtual void SetRepresentedFilename(const std::string& filename);
|
||||
virtual std::string GetRepresentedFilename();
|
||||
virtual void SetDocumentEdited(bool edited);
|
||||
virtual bool IsDocumentEdited();
|
||||
virtual void SetIgnoreMouseEvents(bool ignore, bool forward) = 0;
|
||||
virtual void SetIgnoreMouseEvents(bool ignore) = 0;
|
||||
virtual void SetContentProtection(bool enable) = 0;
|
||||
virtual void SetFocusable(bool focusable);
|
||||
virtual void SetMenu(AtomMenuModel* menu);
|
||||
@@ -186,14 +182,6 @@ class NativeWindow : public base::SupportsUserData,
|
||||
virtual void RefreshTouchBarItem(const std::string& item_id);
|
||||
virtual void SetEscapeTouchBarItem(const mate::PersistentDictionary& item);
|
||||
|
||||
// Native Tab API
|
||||
virtual void SelectPreviousTab();
|
||||
virtual void SelectNextTab();
|
||||
virtual void MergeAllWindows();
|
||||
virtual void MoveTabToNewWindow();
|
||||
virtual void ToggleTabBar();
|
||||
virtual void AddTabbedWindow(NativeWindow* window);
|
||||
|
||||
// Webview APIs.
|
||||
virtual void FocusOnWebView();
|
||||
virtual void BlurWebView();
|
||||
@@ -231,7 +219,6 @@ class NativeWindow : public base::SupportsUserData,
|
||||
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) {}
|
||||
@@ -289,9 +276,6 @@ class NativeWindow : public base::SupportsUserData,
|
||||
SkRegion* draggable_region() const { return draggable_region_.get(); }
|
||||
bool enable_larger_than_screen() const { return enable_larger_than_screen_; }
|
||||
|
||||
void set_is_offscreen_dummy(bool is_dummy) { is_osr_dummy_ = is_dummy; }
|
||||
bool is_offscreen_dummy() const { return is_osr_dummy_; }
|
||||
|
||||
NativeWindow* parent() const { return parent_; }
|
||||
bool is_modal() const { return is_modal_; }
|
||||
|
||||
@@ -370,9 +354,6 @@ class NativeWindow : public base::SupportsUserData,
|
||||
// Is this a modal window.
|
||||
bool is_modal_;
|
||||
|
||||
// Is this a dummy window for an offscreen WebContents.
|
||||
bool is_osr_dummy_;
|
||||
|
||||
// The page this window is viewing.
|
||||
brightray::InspectableWebContents* inspectable_web_contents_;
|
||||
|
||||
|
||||
@@ -76,20 +76,16 @@ class NativeWindowMac : public NativeWindow,
|
||||
std::string GetTitle() override;
|
||||
void FlashFrame(bool flash) override;
|
||||
void SetSkipTaskbar(bool skip) override;
|
||||
void SetSimpleFullScreen(bool simple_fullscreen) override;
|
||||
bool IsSimpleFullScreen() override;
|
||||
void SetKiosk(bool kiosk) override;
|
||||
bool IsKiosk() override;
|
||||
void SetBackgroundColor(const std::string& color_name) override;
|
||||
void SetHasShadow(bool has_shadow) override;
|
||||
bool HasShadow() override;
|
||||
void SetOpacity(const double opacity) override;
|
||||
double GetOpacity() override;
|
||||
void SetRepresentedFilename(const std::string& filename) override;
|
||||
std::string GetRepresentedFilename() override;
|
||||
void SetDocumentEdited(bool edited) override;
|
||||
bool IsDocumentEdited() override;
|
||||
void SetIgnoreMouseEvents(bool ignore, bool) override;
|
||||
void SetIgnoreMouseEvents(bool ignore) override;
|
||||
void SetContentProtection(bool enable) override;
|
||||
void SetBrowserView(NativeBrowserView* browser_view) override;
|
||||
void SetParentWindow(NativeWindow* parent) override;
|
||||
@@ -105,13 +101,6 @@ class NativeWindowMac : public NativeWindow,
|
||||
|
||||
void SetAutoHideCursor(bool auto_hide) override;
|
||||
|
||||
void SelectPreviousTab() override;
|
||||
void SelectNextTab() override;
|
||||
void MergeAllWindows() override;
|
||||
void MoveTabToNewWindow() override;
|
||||
void ToggleTabBar() override;
|
||||
void AddTabbedWindow(NativeWindow* window) override;
|
||||
|
||||
void SetVibrancy(const std::string& type) override;
|
||||
void SetTouchBar(
|
||||
const std::vector<mate::PersistentDictionary>& items) override;
|
||||
@@ -146,8 +135,6 @@ class NativeWindowMac : public NativeWindow,
|
||||
|
||||
bool fullscreen_window_title() const { return fullscreen_window_title_; }
|
||||
|
||||
bool simple_fullscreen() const { return always_simple_fullscreen_; }
|
||||
|
||||
protected:
|
||||
// Return a vector of non-draggable regions that fill a window of size
|
||||
// |width| by |height|, but leave gaps where the window should be draggable.
|
||||
@@ -161,7 +148,6 @@ class NativeWindowMac : public NativeWindow,
|
||||
void UpdateDraggableRegions(
|
||||
const std::vector<DraggableRegion>& regions) override;
|
||||
|
||||
void InternalSetParentWindow(NativeWindow* parent, bool attach);
|
||||
void ShowWindowButton(NSWindowButton button);
|
||||
|
||||
void InstallView();
|
||||
@@ -203,17 +189,6 @@ class NativeWindowMac : public NativeWindow,
|
||||
// The "titleBarStyle" option.
|
||||
TitleBarStyle title_bar_style_;
|
||||
|
||||
// Simple (pre-Lion) Fullscreen Settings
|
||||
bool always_simple_fullscreen_;
|
||||
bool is_simple_fullscreen_;
|
||||
bool was_maximizable_;
|
||||
bool was_movable_;
|
||||
NSRect original_frame_;
|
||||
NSUInteger simple_fullscreen_mask_;
|
||||
|
||||
// The presentation options before entering simple fullscreen mode.
|
||||
NSApplicationPresentationOptions simple_fullscreen_options_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NativeWindowMac);
|
||||
};
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include "atom/browser/native_window_mac.h"
|
||||
|
||||
#include <AvailabilityMacros.h>
|
||||
#include <Quartz/Quartz.h>
|
||||
#include <string>
|
||||
|
||||
@@ -174,7 +173,6 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
atom::NativeWindowMac* shell_;
|
||||
bool is_zooming_;
|
||||
int level_;
|
||||
bool is_resizable_;
|
||||
}
|
||||
- (id)initWithShell:(atom::NativeWindowMac*)shell;
|
||||
@end
|
||||
@@ -337,9 +335,6 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
}
|
||||
|
||||
- (void)windowWillEnterFullScreen:(NSNotification*)notification {
|
||||
// Setting resizable to true before entering fullscreen
|
||||
is_resizable_ = shell_->IsResizable();
|
||||
shell_->SetResizable(true);
|
||||
// Hide the native toolbar before entering fullscreen, so there is no visual
|
||||
// artifacts.
|
||||
if (base::mac::IsAtLeastOS10_10() &&
|
||||
@@ -399,7 +394,6 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
}
|
||||
|
||||
- (void)windowDidExitFullScreen:(NSNotification*)notification {
|
||||
shell_->SetResizable(is_resizable_);
|
||||
shell_->NotifyWindowLeaveFullScreen();
|
||||
}
|
||||
|
||||
@@ -466,7 +460,7 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||
|
||||
@end
|
||||
|
||||
#if !defined(AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER)
|
||||
#if !defined(MAC_OS_X_VERSION_10_12)
|
||||
|
||||
enum {
|
||||
NSWindowTabbingModeDisallowed = 2
|
||||
@@ -475,15 +469,9 @@ enum {
|
||||
@interface NSWindow (SierraSDK)
|
||||
- (void)setTabbingMode:(NSInteger)mode;
|
||||
- (void)setTabbingIdentifier:(NSString*)identifier;
|
||||
- (void)addTabbedWindow:(NSWindow*)window ordered:(NSWindowOrderingMode)ordered;
|
||||
- (IBAction)selectPreviousTab:(id)sender;
|
||||
- (IBAction)selectNextTab:(id)sender;
|
||||
- (IBAction)mergeAllWindows:(id)sender;
|
||||
- (IBAction)moveTabToNewWindow:(id)sender;
|
||||
- (IBAction)toggleTabBar:(id)sender;
|
||||
@end
|
||||
|
||||
#endif
|
||||
#endif // MAC_OS_X_VERSION_10_12
|
||||
|
||||
@interface AtomNSWindow : EventDispatchingWindow<QLPreviewPanelDataSource, QLPreviewPanelDelegate, NSTouchBarDelegate> {
|
||||
@private
|
||||
@@ -732,13 +720,6 @@ enum {
|
||||
[super performClose:sender];
|
||||
}
|
||||
|
||||
- (void)toggleFullScreen:(id)sender {
|
||||
if (shell_->simple_fullscreen())
|
||||
shell_->SetSimpleFullScreen(!shell_->IsSimpleFullScreen());
|
||||
else
|
||||
[super toggleFullScreen:sender];
|
||||
}
|
||||
|
||||
- (void)performMiniaturize:(id)sender {
|
||||
if (shell_->title_bar_style() == atom::NativeWindowMac::CUSTOM_BUTTONS_ON_HOVER)
|
||||
[self miniaturize:self];
|
||||
@@ -838,9 +819,7 @@ NativeWindowMac::NativeWindowMac(
|
||||
zoom_to_page_width_(false),
|
||||
fullscreen_window_title_(false),
|
||||
attention_request_id_(0),
|
||||
title_bar_style_(NORMAL),
|
||||
always_simple_fullscreen_(false),
|
||||
is_simple_fullscreen_(false) {
|
||||
title_bar_style_(NORMAL) {
|
||||
int width = 800, height = 600;
|
||||
options.Get(options::kWidth, &width);
|
||||
options.Get(options::kHeight, &height);
|
||||
@@ -962,16 +941,10 @@ NativeWindowMac::NativeWindowMac(
|
||||
// We will manage window's lifetime ourselves.
|
||||
[window_ setReleasedWhenClosed:NO];
|
||||
|
||||
// Hide the title bar background
|
||||
if (title_bar_style_ != NORMAL) {
|
||||
if (base::mac::IsAtLeastOS10_10()) {
|
||||
[window_ setTitlebarAppearsTransparent:YES];
|
||||
}
|
||||
}
|
||||
|
||||
// Hide the title bar.
|
||||
if (title_bar_style_ == HIDDEN_INSET) {
|
||||
if (base::mac::IsAtLeastOS10_10()) {
|
||||
[window_ setTitlebarAppearsTransparent:YES];
|
||||
base::scoped_nsobject<NSToolbar> toolbar(
|
||||
[[NSToolbar alloc] initWithIdentifier:@"titlebarStylingToolbar"]);
|
||||
[toolbar setShowsBaselineSeparator:NO];
|
||||
@@ -992,8 +965,6 @@ NativeWindowMac::NativeWindowMac(
|
||||
|
||||
options.Get(options::kFullscreenWindowTitle, &fullscreen_window_title_);
|
||||
|
||||
options.Get(options::kSimpleFullScreen, &always_simple_fullscreen_);
|
||||
|
||||
// Enable the NSView to accept first mouse event.
|
||||
bool acceptsFirstMouse = false;
|
||||
options.Get(options::kAcceptFirstMouse, &acceptsFirstMouse);
|
||||
@@ -1094,10 +1065,6 @@ void NativeWindowMac::Show() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reattach the window to the parent to actually show it.
|
||||
if (parent())
|
||||
InternalSetParentWindow(parent(), true);
|
||||
|
||||
// This method is supposed to put focus on window, however if the app does not
|
||||
// have focus then "makeKeyAndOrderFront" will only show the window.
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
@@ -1106,10 +1073,6 @@ void NativeWindowMac::Show() {
|
||||
}
|
||||
|
||||
void NativeWindowMac::ShowInactive() {
|
||||
// Reattach the window to the parent to actually show it.
|
||||
if (parent())
|
||||
InternalSetParentWindow(parent(), true);
|
||||
|
||||
[window_ orderFrontRegardless];
|
||||
}
|
||||
|
||||
@@ -1120,10 +1083,6 @@ void NativeWindowMac::Hide() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Deattach the window from the parent before.
|
||||
if (parent())
|
||||
InternalSetParentWindow(parent(), false);
|
||||
|
||||
[window_ orderOut:nil];
|
||||
}
|
||||
|
||||
@@ -1392,80 +1351,6 @@ void NativeWindowMac::FlashFrame(bool flash) {
|
||||
void NativeWindowMac::SetSkipTaskbar(bool skip) {
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetSimpleFullScreen(bool simple_fullscreen) {
|
||||
NSWindow* window = GetNativeWindow();
|
||||
|
||||
if (simple_fullscreen && !is_simple_fullscreen_) {
|
||||
is_simple_fullscreen_ = true;
|
||||
|
||||
// Take note of the current window size
|
||||
original_frame_ = [window frame];
|
||||
|
||||
simple_fullscreen_options_ = [NSApp currentSystemPresentationOptions];
|
||||
simple_fullscreen_mask_ = [window styleMask];
|
||||
|
||||
// We can simulate the pre-Lion fullscreen by auto-hiding the dock and menu bar
|
||||
NSApplicationPresentationOptions options =
|
||||
NSApplicationPresentationAutoHideDock +
|
||||
NSApplicationPresentationAutoHideMenuBar;
|
||||
[NSApp setPresentationOptions:options];
|
||||
|
||||
was_maximizable_ = IsMaximizable();
|
||||
was_movable_ = IsMovable();
|
||||
|
||||
NSRect fullscreenFrame = [window.screen frame];
|
||||
|
||||
if ( !fullscreen_window_title() ) {
|
||||
// Hide the titlebar
|
||||
SetStyleMask(false, NSTitledWindowMask);
|
||||
|
||||
// Resize the window to accomodate the _entire_ screen size
|
||||
fullscreenFrame.size.height -= [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
|
||||
} else {
|
||||
// No need to hide the title, but we should still hide the window buttons
|
||||
[[window standardWindowButton:NSWindowZoomButton] setHidden:YES];
|
||||
[[window standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
|
||||
[[window standardWindowButton:NSWindowCloseButton] setHidden:YES];
|
||||
}
|
||||
|
||||
[window setFrame:fullscreenFrame display: YES animate: YES];
|
||||
|
||||
// Fullscreen windows can't be resized, minimized, maximized, or moved
|
||||
SetMinimizable(false);
|
||||
SetResizable(false);
|
||||
SetMaximizable(false);
|
||||
SetMovable(false);
|
||||
} else if (!simple_fullscreen && is_simple_fullscreen_) {
|
||||
is_simple_fullscreen_ = false;
|
||||
|
||||
if ( !fullscreen_window_title() ) {
|
||||
// Restore the titlebar
|
||||
SetStyleMask(true, NSTitledWindowMask);
|
||||
} else {
|
||||
// Show the window buttons
|
||||
[[window standardWindowButton:NSWindowZoomButton] setHidden:NO];
|
||||
[[window standardWindowButton:NSWindowMiniaturizeButton] setHidden:NO];
|
||||
[[window standardWindowButton:NSWindowCloseButton] setHidden:NO];
|
||||
}
|
||||
|
||||
[window setFrame:original_frame_ display: YES animate: YES];
|
||||
|
||||
[NSApp setPresentationOptions:simple_fullscreen_options_];
|
||||
|
||||
// Restore original style mask
|
||||
ScopedDisableResize disable_resize;
|
||||
[window_ setStyleMask:simple_fullscreen_mask_];
|
||||
|
||||
// Restore window manipulation abilities
|
||||
SetMaximizable(was_maximizable_);
|
||||
SetMovable(was_movable_);
|
||||
}
|
||||
}
|
||||
|
||||
bool NativeWindowMac::IsSimpleFullScreen() {
|
||||
return is_simple_fullscreen_;
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetKiosk(bool kiosk) {
|
||||
if (kiosk && !is_kiosk_) {
|
||||
kiosk_options_ = [NSApp currentSystemPresentationOptions];
|
||||
@@ -1511,14 +1396,6 @@ bool NativeWindowMac::HasShadow() {
|
||||
return [window_ hasShadow];
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetOpacity(const double opacity) {
|
||||
[window_ setAlphaValue:opacity];
|
||||
}
|
||||
|
||||
double NativeWindowMac::GetOpacity() {
|
||||
return [window_ alphaValue];
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetRepresentedFilename(const std::string& filename) {
|
||||
[window_ setRepresentedFilename:base::SysUTF8ToNSString(filename)];
|
||||
}
|
||||
@@ -1535,7 +1412,7 @@ bool NativeWindowMac::IsDocumentEdited() {
|
||||
return [window_ isDocumentEdited];
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetIgnoreMouseEvents(bool ignore, bool) {
|
||||
void NativeWindowMac::SetIgnoreMouseEvents(bool ignore) {
|
||||
[window_ setIgnoresMouseEvents:ignore];
|
||||
}
|
||||
|
||||
@@ -1565,7 +1442,18 @@ void NativeWindowMac::SetBrowserView(NativeBrowserView* browser_view) {
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetParentWindow(NativeWindow* parent) {
|
||||
InternalSetParentWindow(parent, IsVisible());
|
||||
if (is_modal())
|
||||
return;
|
||||
|
||||
NativeWindow::SetParentWindow(parent);
|
||||
|
||||
// Remove current parent window.
|
||||
if ([window_ parentWindow])
|
||||
[[window_ parentWindow] removeChildWindow:window_];
|
||||
|
||||
// Set new current window.
|
||||
if (parent)
|
||||
[parent->GetNativeWindow() addChildWindow:window_ ordered:NSWindowAbove];
|
||||
}
|
||||
|
||||
gfx::NativeView NativeWindowMac::GetNativeView() const {
|
||||
@@ -1635,42 +1523,6 @@ void NativeWindowMac::SetAutoHideCursor(bool auto_hide) {
|
||||
[window_ setDisableAutoHideCursor:!auto_hide];
|
||||
}
|
||||
|
||||
void NativeWindowMac::SelectPreviousTab() {
|
||||
if ([window_ respondsToSelector:@selector(selectPreviousTab:)]) {
|
||||
[window_ selectPreviousTab:nil];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::SelectNextTab() {
|
||||
if ([window_ respondsToSelector:@selector(selectNextTab:)]) {
|
||||
[window_ selectNextTab:nil];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::MergeAllWindows() {
|
||||
if ([window_ respondsToSelector:@selector(mergeAllWindows:)]) {
|
||||
[window_ mergeAllWindows:nil];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::MoveTabToNewWindow() {
|
||||
if ([window_ respondsToSelector:@selector(moveTabToNewWindow:)]) {
|
||||
[window_ moveTabToNewWindow:nil];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::ToggleTabBar() {
|
||||
if ([window_ respondsToSelector:@selector(toggleTabBar:)]) {
|
||||
[window_ toggleTabBar:nil];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::AddTabbedWindow(NativeWindow* window) {
|
||||
if ([window_ respondsToSelector:@selector(addTabbedWindow:ordered:)]) {
|
||||
[window_ addTabbedWindow:window->GetNativeWindow() ordered:NSWindowAbove];
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetVibrancy(const std::string& type) {
|
||||
if (!base::mac::IsAtLeastOS10_10()) return;
|
||||
|
||||
@@ -1752,10 +1604,10 @@ void NativeWindowMac::SetEscapeTouchBarItem(const mate::PersistentDictionary& it
|
||||
}
|
||||
|
||||
void NativeWindowMac::OnInputEvent(const blink::WebInputEvent& event) {
|
||||
switch (event.GetType()) {
|
||||
case blink::WebInputEvent::kGestureScrollBegin:
|
||||
case blink::WebInputEvent::kGestureScrollUpdate:
|
||||
case blink::WebInputEvent::kGestureScrollEnd:
|
||||
switch (event.type()) {
|
||||
case blink::WebInputEvent::GestureScrollBegin:
|
||||
case blink::WebInputEvent::GestureScrollUpdate:
|
||||
case blink::WebInputEvent::GestureScrollEnd:
|
||||
this->NotifyWindowScrollTouchEdge();
|
||||
break;
|
||||
default:
|
||||
@@ -1820,26 +1672,6 @@ void NativeWindowMac::UpdateDraggableRegions(
|
||||
UpdateDraggableRegionViews(regions);
|
||||
}
|
||||
|
||||
void NativeWindowMac::InternalSetParentWindow(NativeWindow* parent, bool attach) {
|
||||
if (is_modal())
|
||||
return;
|
||||
|
||||
NativeWindow::SetParentWindow(parent);
|
||||
|
||||
// Do not remove/add if we are already properly attached.
|
||||
if (attach && parent && [window_ parentWindow] == parent->GetNativeWindow())
|
||||
return;
|
||||
|
||||
// Remove current parent window.
|
||||
if ([window_ parentWindow])
|
||||
[[window_ parentWindow] removeChildWindow:window_];
|
||||
|
||||
// Set new parent window.
|
||||
// Note that this method will force the window to become visible.
|
||||
if (parent && attach)
|
||||
[parent->GetNativeWindow() addChildWindow:window_ ordered:NSWindowAbove];
|
||||
}
|
||||
|
||||
void NativeWindowMac::ShowWindowButton(NSWindowButton button) {
|
||||
auto view = [window_ standardWindowButton:button];
|
||||
[view.superview addSubview:view positioned:NSWindowAbove relativeTo:nil];
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/native_browser_view_views.h"
|
||||
#include "atom/browser/ui/views/menu_bar.h"
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/color_util.h"
|
||||
#include "atom/common/draggable_region.h"
|
||||
@@ -84,17 +82,17 @@ void FlipWindowStyle(HWND handle, bool on, DWORD flag) {
|
||||
#endif
|
||||
|
||||
bool IsAltKey(const content::NativeWebKeyboardEvent& event) {
|
||||
return event.windows_key_code == ui::VKEY_MENU;
|
||||
return event.windowsKeyCode == ui::VKEY_MENU;
|
||||
}
|
||||
|
||||
bool IsAltModifier(const content::NativeWebKeyboardEvent& event) {
|
||||
typedef content::NativeWebKeyboardEvent::Modifiers Modifiers;
|
||||
int modifiers = event.GetModifiers();
|
||||
modifiers &= ~Modifiers::kNumLockOn;
|
||||
modifiers &= ~Modifiers::kCapsLockOn;
|
||||
return (modifiers == Modifiers::kAltKey) ||
|
||||
(modifiers == (Modifiers::kAltKey | Modifiers::kIsLeft)) ||
|
||||
(modifiers == (Modifiers::kAltKey | Modifiers::kIsRight));
|
||||
int modifiers = event.modifiers();
|
||||
modifiers &= ~Modifiers::NumLockOn;
|
||||
modifiers &= ~Modifiers::CapsLockOn;
|
||||
return (modifiers == Modifiers::AltKey) ||
|
||||
(modifiers == (Modifiers::AltKey | Modifiers::IsLeft)) ||
|
||||
(modifiers == (Modifiers::AltKey | Modifiers::IsRight));
|
||||
}
|
||||
|
||||
#if defined(USE_X11)
|
||||
@@ -298,21 +296,19 @@ NativeWindowViews::NativeWindowViews(
|
||||
}
|
||||
|
||||
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
|
||||
// Window without thick frame has to have WS_EX_COMPOSITED style.
|
||||
if (!thick_frame_)
|
||||
ex_style |= WS_EX_COMPOSITED;
|
||||
if (window_type == "toolbar")
|
||||
ex_style |= WS_EX_TOOLWINDOW;
|
||||
::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style);
|
||||
#endif
|
||||
|
||||
// TODO(zcbenz): This was used to force using native frame on Windows 2003, we
|
||||
// should check whether setting it in InitParams can work.
|
||||
if (has_frame()) {
|
||||
// TODO(zcbenz): This was used to force using native frame on Windows 2003,
|
||||
// we should check whether setting it in InitParams can work.
|
||||
window_->set_frame_type(views::Widget::FrameType::FRAME_TYPE_FORCE_NATIVE);
|
||||
window_->FrameTypeChanged();
|
||||
#if defined(OS_WIN)
|
||||
// thickFrame also works for normal window.
|
||||
if (!thick_frame_)
|
||||
FlipWindowStyle(GetAcceleratedWidget(), false, WS_THICKFRAME);
|
||||
#endif
|
||||
}
|
||||
|
||||
gfx::Size size = bounds.size();
|
||||
@@ -338,11 +334,6 @@ NativeWindowViews::NativeWindowViews(
|
||||
|
||||
NativeWindowViews::~NativeWindowViews() {
|
||||
window_->RemoveObserver(this);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Disable mouse forwarding to relinquish resources, should any be held.
|
||||
SetForwardMouseMessages(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void NativeWindowViews::Close() {
|
||||
@@ -581,12 +572,6 @@ gfx::Size NativeWindowViews::GetContentSize() {
|
||||
void NativeWindowViews::SetContentSizeConstraints(
|
||||
const extensions::SizeConstraints& size_constraints) {
|
||||
NativeWindow::SetContentSizeConstraints(size_constraints);
|
||||
#if defined(OS_WIN)
|
||||
// Changing size constraints would force adding the WS_THICKFRAME style, so
|
||||
// do nothing if thickFrame is false.
|
||||
if (!thick_frame_)
|
||||
return;
|
||||
#endif
|
||||
// widget_delegate() is only available after Init() is called, we make use of
|
||||
// this to determine whether native widget has initialized.
|
||||
if (window_ && window_->widget_delegate())
|
||||
@@ -599,7 +584,7 @@ void NativeWindowViews::SetContentSizeConstraints(
|
||||
|
||||
void NativeWindowViews::SetResizable(bool resizable) {
|
||||
#if defined(OS_WIN)
|
||||
if (has_frame() && thick_frame_)
|
||||
if (has_frame())
|
||||
FlipWindowStyle(GetAcceleratedWidget(), resizable, WS_THICKFRAME);
|
||||
#elif defined(USE_X11)
|
||||
if (resizable != resizable_) {
|
||||
@@ -769,14 +754,6 @@ void NativeWindowViews::SetSkipTaskbar(bool skip) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetSimpleFullScreen(bool simple_fullscreen) {
|
||||
SetFullScreen(simple_fullscreen);
|
||||
}
|
||||
|
||||
bool NativeWindowViews::IsSimpleFullScreen() {
|
||||
return IsFullscreen();
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetKiosk(bool kiosk) {
|
||||
SetFullScreen(kiosk);
|
||||
}
|
||||
@@ -813,41 +790,14 @@ bool NativeWindowViews::HasShadow() {
|
||||
!= wm::ShadowElevation::NONE;
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetOpacity(const double opacity) {
|
||||
#if defined(OS_WIN)
|
||||
HWND hwnd = GetAcceleratedWidget();
|
||||
if (!layered_) {
|
||||
LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||
ex_style |= WS_EX_LAYERED;
|
||||
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
|
||||
layered_ = true;
|
||||
}
|
||||
::SetLayeredWindowAttributes(hwnd, 0, opacity * 255, LWA_ALPHA);
|
||||
#endif
|
||||
opacity_ = opacity;
|
||||
}
|
||||
|
||||
double NativeWindowViews::GetOpacity() {
|
||||
return opacity_;
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetIgnoreMouseEvents(bool ignore, bool forward) {
|
||||
void NativeWindowViews::SetIgnoreMouseEvents(bool ignore) {
|
||||
#if defined(OS_WIN)
|
||||
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
|
||||
if (ignore)
|
||||
ex_style |= (WS_EX_TRANSPARENT | WS_EX_LAYERED);
|
||||
else
|
||||
ex_style &= ~(WS_EX_TRANSPARENT | WS_EX_LAYERED);
|
||||
if (layered_)
|
||||
ex_style |= WS_EX_LAYERED;
|
||||
::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style);
|
||||
|
||||
// Forwarding is always disabled when not ignoring mouse messages.
|
||||
if (!ignore) {
|
||||
SetForwardMouseMessages(false);
|
||||
} else {
|
||||
SetForwardMouseMessages(forward);
|
||||
}
|
||||
#elif defined(USE_X11)
|
||||
if (ignore) {
|
||||
XRectangle r = {0, 0, 1, 1};
|
||||
@@ -1140,31 +1090,9 @@ void NativeWindowViews::OnWidgetBoundsChanged(
|
||||
if (widget != window_.get())
|
||||
return;
|
||||
|
||||
// Note: We intentionally use `GetBounds()` instead of `bounds` to properly
|
||||
// handle minimized windows on Windows.
|
||||
const auto new_bounds = GetBounds();
|
||||
if (widget_size_ != new_bounds.size()) {
|
||||
if (browser_view_) {
|
||||
const auto flags = static_cast<NativeBrowserViewViews*>(browser_view_)
|
||||
->GetAutoResizeFlags();
|
||||
int width_delta = 0;
|
||||
int height_delta = 0;
|
||||
if (flags & kAutoResizeWidth) {
|
||||
width_delta = new_bounds.width() - widget_size_.width();
|
||||
}
|
||||
if (flags & kAutoResizeHeight) {
|
||||
height_delta = new_bounds.height() - widget_size_.height();
|
||||
}
|
||||
|
||||
auto* view = browser_view_->GetInspectableWebContentsView()->GetView();
|
||||
auto new_view_size = view->size();
|
||||
new_view_size.set_width(new_view_size.width() + width_delta);
|
||||
new_view_size.set_height(new_view_size.height() + height_delta);
|
||||
view->SetSize(new_view_size);
|
||||
}
|
||||
|
||||
if (widget_size_ != bounds.size()) {
|
||||
NotifyWindowResize();
|
||||
widget_size_ = new_bounds.size();
|
||||
widget_size_ = bounds.size();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1324,15 +1252,15 @@ void NativeWindowViews::HandleKeyboardEvent(
|
||||
// Show accelerator when "Alt" is pressed.
|
||||
if (menu_bar_visible_ && IsAltKey(event))
|
||||
menu_bar_->SetAcceleratorVisibility(
|
||||
event.GetType() == blink::WebInputEvent::kRawKeyDown);
|
||||
event.type() == blink::WebInputEvent::RawKeyDown);
|
||||
|
||||
// Show the submenu when "Alt+Key" is pressed.
|
||||
if (event.GetType() == blink::WebInputEvent::kRawKeyDown &&
|
||||
!IsAltKey(event) && IsAltModifier(event)) {
|
||||
if (event.type() == blink::WebInputEvent::RawKeyDown && !IsAltKey(event) &&
|
||||
IsAltModifier(event)) {
|
||||
if (!menu_bar_visible_ &&
|
||||
(menu_bar_->GetAcceleratorIndex(event.windows_key_code) != -1))
|
||||
(menu_bar_->GetAcceleratorIndex(event.windowsKeyCode) != -1))
|
||||
SetMenuBarVisibility(true);
|
||||
menu_bar_->ActivateAccelerator(event.windows_key_code);
|
||||
menu_bar_->ActivateAccelerator(event.windowsKeyCode);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1340,11 +1268,11 @@ void NativeWindowViews::HandleKeyboardEvent(
|
||||
return;
|
||||
|
||||
// Toggle the menu bar only when a single Alt is released.
|
||||
if (event.GetType() == blink::WebInputEvent::kRawKeyDown && IsAltKey(event)) {
|
||||
if (event.type() == blink::WebInputEvent::RawKeyDown && IsAltKey(event)) {
|
||||
// When a single Alt is pressed:
|
||||
menu_bar_alt_pressed_ = true;
|
||||
} else if (event.GetType() == blink::WebInputEvent::kKeyUp &&
|
||||
IsAltKey(event) && menu_bar_alt_pressed_) {
|
||||
} else if (event.type() == blink::WebInputEvent::KeyUp && IsAltKey(event) &&
|
||||
menu_bar_alt_pressed_) {
|
||||
// When a single Alt is released right after a Alt is pressed:
|
||||
menu_bar_alt_pressed_ = false;
|
||||
SetMenuBarVisibility(!menu_bar_visible_);
|
||||
@@ -1356,41 +1284,17 @@ void NativeWindowViews::HandleKeyboardEvent(
|
||||
|
||||
void NativeWindowViews::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) {
|
||||
bool is_offsceen = false;
|
||||
bool is_embedder_offscreen = false;
|
||||
|
||||
auto* web_contents_preferences =
|
||||
WebContentsPreferences::FromWebContents(web_contents);
|
||||
if (web_contents_preferences) {
|
||||
const auto* web_preferences = web_contents_preferences->web_preferences();
|
||||
|
||||
web_preferences->GetBoolean("offscreen", &is_offsceen);
|
||||
int guest_instance_id = 0;
|
||||
web_preferences->GetInteger(options::kGuestInstanceID, &guest_instance_id);
|
||||
|
||||
if (guest_instance_id) {
|
||||
auto manager = WebViewManager::GetWebViewManager(web_contents);
|
||||
if (manager) {
|
||||
auto embedder = manager->GetEmbedder(guest_instance_id);
|
||||
if (embedder) {
|
||||
is_embedder_offscreen = WebContentsPreferences::IsPreferenceEnabled(
|
||||
"offscreen", embedder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto wc = atom::api::WebContents::FromWrappedClass(
|
||||
v8::Isolate::GetCurrent(), web_contents());
|
||||
autofill_popup_->CreateView(
|
||||
frame_host,
|
||||
is_offsceen || is_embedder_offscreen,
|
||||
widget(),
|
||||
bounds);
|
||||
frame_host,
|
||||
wc->IsOffScreenOrEmbedderOffscreen(),
|
||||
widget(),
|
||||
bounds);
|
||||
autofill_popup_->SetItems(values, labels);
|
||||
autofill_popup_->UpdatePopupBounds(menu_bar_visible_ ? 0 : kMenuBarHeight);
|
||||
}
|
||||
|
||||
void NativeWindowViews::HideAutofillPopup(
|
||||
@@ -1407,14 +1311,32 @@ void NativeWindowViews::Layout() {
|
||||
menu_bar_->SetBoundsRect(menu_bar_bounds);
|
||||
}
|
||||
|
||||
const auto old_web_view_size = web_view_ ? web_view_->size() : gfx::Size();
|
||||
if (web_view_) {
|
||||
web_view_->SetBoundsRect(
|
||||
gfx::Rect(0, menu_bar_bounds.height(), size.width(),
|
||||
size.height() - menu_bar_bounds.height()));
|
||||
}
|
||||
const auto new_web_view_size = web_view_ ? web_view_->size() : gfx::Size();
|
||||
|
||||
if (autofill_popup_.get())
|
||||
autofill_popup_->UpdatePopupBounds(menu_bar_visible_ ? 0 : kMenuBarHeight);
|
||||
if (browser_view_) {
|
||||
const auto flags = static_cast<NativeBrowserViewViews*>(browser_view_)
|
||||
->GetAutoResizeFlags();
|
||||
int width_delta = 0;
|
||||
int height_delta = 0;
|
||||
if (flags & kAutoResizeWidth) {
|
||||
width_delta = new_web_view_size.width() - old_web_view_size.width();
|
||||
}
|
||||
if (flags & kAutoResizeHeight) {
|
||||
height_delta = new_web_view_size.height() - old_web_view_size.height();
|
||||
}
|
||||
|
||||
auto* view = browser_view_->GetInspectableWebContentsView()->GetView();
|
||||
auto new_view_size = view->size();
|
||||
new_view_size.set_width(new_view_size.width() + width_delta);
|
||||
new_view_size.set_height(new_view_size.height() + height_delta);
|
||||
view->SetSize(new_view_size);
|
||||
}
|
||||
}
|
||||
|
||||
gfx::Size NativeWindowViews::GetMinimumSize() const {
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -97,16 +96,12 @@ class NativeWindowViews : public NativeWindow,
|
||||
std::string GetTitle() override;
|
||||
void FlashFrame(bool flash) override;
|
||||
void SetSkipTaskbar(bool skip) override;
|
||||
void SetSimpleFullScreen(bool simple_fullscreen) override;
|
||||
bool IsSimpleFullScreen() override;
|
||||
void SetKiosk(bool kiosk) override;
|
||||
bool IsKiosk() override;
|
||||
void SetBackgroundColor(const std::string& color_name) override;
|
||||
void SetHasShadow(bool has_shadow) override;
|
||||
bool HasShadow() override;
|
||||
void SetOpacity(const double opacity) override;
|
||||
double GetOpacity() override;
|
||||
void SetIgnoreMouseEvents(bool ignore, bool forward) override;
|
||||
void SetIgnoreMouseEvents(bool ignore) override;
|
||||
void SetContentProtection(bool enable) override;
|
||||
void SetFocusable(bool focusable) override;
|
||||
void SetMenu(AtomMenuModel* menu_model) override;
|
||||
@@ -174,12 +169,6 @@ class NativeWindowViews : public NativeWindow,
|
||||
bool PreHandleMSG(
|
||||
UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) override;
|
||||
void HandleSizeEvent(WPARAM w_param, LPARAM l_param);
|
||||
void SetForwardMouseMessages(bool forward);
|
||||
static LRESULT CALLBACK SubclassProc(
|
||||
HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param, UINT_PTR subclass_id,
|
||||
DWORD_PTR ref_data);
|
||||
static LRESULT CALLBACK MouseHookProc(
|
||||
int n_code, WPARAM w_param, LPARAM l_param);
|
||||
#endif
|
||||
|
||||
// NativeWindow:
|
||||
@@ -190,7 +179,6 @@ class NativeWindowViews : public NativeWindow,
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
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) override;
|
||||
@@ -271,13 +259,6 @@ class NativeWindowViews : public NativeWindow,
|
||||
// The icons of window and taskbar.
|
||||
base::win::ScopedHICON window_icon_;
|
||||
base::win::ScopedHICON app_icon_;
|
||||
|
||||
// The set of windows currently forwarding mouse messages.
|
||||
static std::set<NativeWindowViews*> forwarding_windows_;
|
||||
static HHOOK mouse_hook_;
|
||||
bool forwarding_mouse_messages_ = false;
|
||||
HWND legacy_window_ = NULL;
|
||||
bool layered_ = false;
|
||||
#endif
|
||||
|
||||
// Handles unhandled keyboard messages coming back from the renderer process.
|
||||
@@ -297,7 +278,6 @@ class NativeWindowViews : public NativeWindow,
|
||||
bool fullscreenable_;
|
||||
std::string title_;
|
||||
gfx::Size widget_size_;
|
||||
double opacity_ = 1.0;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NativeWindowViews);
|
||||
};
|
||||
|
||||
@@ -80,9 +80,6 @@ bool IsScreenReaderActive() {
|
||||
|
||||
} // namespace
|
||||
|
||||
std::set<NativeWindowViews*> NativeWindowViews::forwarding_windows_;
|
||||
HHOOK NativeWindowViews::mouse_hook_ = NULL;
|
||||
|
||||
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
|
||||
std::string command = AppCommandToString(command_id);
|
||||
NotifyWindowExecuteWindowsCommand(command);
|
||||
@@ -154,16 +151,6 @@ bool NativeWindowViews::PreHandleMSG(
|
||||
if (w_param) {
|
||||
NotifyWindowEndSession();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case WM_PARENTNOTIFY: {
|
||||
if (LOWORD(w_param) == WM_CREATE) {
|
||||
// Because of reasons regarding legacy drivers and stuff, a window that
|
||||
// matches the client area is created and used internally by Chromium.
|
||||
// This is used when forwarding mouse messages.
|
||||
legacy_window_ = reinterpret_cast<HWND>(l_param);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
@@ -220,86 +207,4 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetForwardMouseMessages(bool forward) {
|
||||
if (forward && !forwarding_mouse_messages_) {
|
||||
forwarding_mouse_messages_ = true;
|
||||
forwarding_windows_.insert(this);
|
||||
|
||||
// Subclassing is used to fix some issues when forwarding mouse messages;
|
||||
// see comments in |SubclassProc|.
|
||||
SetWindowSubclass(
|
||||
legacy_window_, SubclassProc, 1, reinterpret_cast<DWORD_PTR>(this));
|
||||
|
||||
if (!mouse_hook_) {
|
||||
mouse_hook_ = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, NULL, 0);
|
||||
}
|
||||
} else if (!forward && forwarding_mouse_messages_) {
|
||||
forwarding_mouse_messages_ = false;
|
||||
forwarding_windows_.erase(this);
|
||||
|
||||
RemoveWindowSubclass(legacy_window_, SubclassProc, 1);
|
||||
|
||||
if (forwarding_windows_.size() == 0) {
|
||||
UnhookWindowsHookEx(mouse_hook_);
|
||||
mouse_hook_ = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK NativeWindowViews::SubclassProc(
|
||||
HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param, UINT_PTR subclass_id,
|
||||
DWORD_PTR ref_data) {
|
||||
NativeWindowViews* window = reinterpret_cast<NativeWindowViews*>(ref_data);
|
||||
switch (msg) {
|
||||
case WM_MOUSELEAVE: {
|
||||
// When input is forwarded to underlying windows, this message is posted.
|
||||
// If not handled, it interferes with Chromium logic, causing for example
|
||||
// mouseleave events to fire. If those events are used to exit forward
|
||||
// mode, excessive flickering on for example hover items in underlying
|
||||
// windows can occur due to rapidly entering and leaving forwarding mode.
|
||||
// By consuming and ignoring the message, we're essentially telling
|
||||
// Chromium that we have not left the window despite somebody else getting
|
||||
// the messages. As to why this is catched for the legacy window and not
|
||||
// the actual browser window is simply that the legacy window somehow
|
||||
// makes use of these events; posting to the main window didn't work.
|
||||
if (window->forwarding_mouse_messages_) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefSubclassProc(hwnd, msg, w_param, l_param);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK NativeWindowViews::MouseHookProc(
|
||||
int n_code, WPARAM w_param, LPARAM l_param) {
|
||||
if (n_code < 0) {
|
||||
return CallNextHookEx(NULL, n_code, w_param, l_param);
|
||||
}
|
||||
|
||||
// Post a WM_MOUSEMOVE message for those windows whose client area contains
|
||||
// the cursor since they are in a state where they would otherwise ignore all
|
||||
// mouse input.
|
||||
if (w_param == WM_MOUSEMOVE) {
|
||||
for (auto window : forwarding_windows_) {
|
||||
// At first I considered enumerating windows to check whether the cursor
|
||||
// was directly above the window, but since nothing bad seems to happen
|
||||
// if we post the message even if some other window occludes it I have
|
||||
// just left it as is.
|
||||
RECT client_rect;
|
||||
GetClientRect(window->legacy_window_, &client_rect);
|
||||
POINT p = reinterpret_cast<MSLLHOOKSTRUCT*>(l_param)->pt;
|
||||
ScreenToClient(window->legacy_window_, &p);
|
||||
if (PtInRect(&client_rect, p)) {
|
||||
WPARAM w = 0; // No virtual keys pressed for our purposes
|
||||
LPARAM l = MAKELPARAM(p.x, p.y);
|
||||
PostMessage(window->legacy_window_, WM_MOUSEMOVE, w, l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CallNextHookEx(NULL, n_code, w_param, l_param);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -245,10 +245,21 @@ void URLRequestAsarJob::FetchMetaInfo(const base::FilePath& file_path,
|
||||
meta_info->file_size = file_info.size;
|
||||
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) {
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
#include "atom/browser/net/atom_cert_verifier.h"
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/net/atom_ct_delegate.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "base/containers/linked_list.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "brightray/browser/net/require_ct_delegate.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/cert/cert_verify_result.h"
|
||||
@@ -92,7 +92,6 @@ class CertVerifierRequest : public AtomCertVerifier::Request {
|
||||
std::unique_ptr<VerifyRequestParams> request(new VerifyRequestParams());
|
||||
request->hostname = params_.hostname();
|
||||
request->default_result = net::ErrorToString(error);
|
||||
request->error_code = error;
|
||||
request->certificate = params_.certificate();
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
@@ -147,7 +146,7 @@ class CertVerifierRequest : public AtomCertVerifier::Request {
|
||||
base::WeakPtrFactory<CertVerifierRequest> weak_ptr_factory_;
|
||||
};
|
||||
|
||||
AtomCertVerifier::AtomCertVerifier(brightray::RequireCTDelegate* ct_delegate)
|
||||
AtomCertVerifier::AtomCertVerifier(AtomCTDelegate* ct_delegate)
|
||||
: default_cert_verifier_(net::CertVerifier::CreateDefault()),
|
||||
ct_delegate_(ct_delegate) {}
|
||||
|
||||
|
||||
@@ -11,26 +11,20 @@
|
||||
|
||||
#include "net/cert/cert_verifier.h"
|
||||
|
||||
namespace brightray {
|
||||
|
||||
class RequireCTDelegate;
|
||||
|
||||
} // namespace brightray
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomCTDelegate;
|
||||
class CertVerifierRequest;
|
||||
|
||||
struct VerifyRequestParams {
|
||||
std::string hostname;
|
||||
std::string default_result;
|
||||
int error_code;
|
||||
scoped_refptr<net::X509Certificate> certificate;
|
||||
};
|
||||
|
||||
class AtomCertVerifier : public net::CertVerifier {
|
||||
public:
|
||||
explicit AtomCertVerifier(brightray::RequireCTDelegate* ct_delegate);
|
||||
explicit AtomCertVerifier(AtomCTDelegate* ct_delegate);
|
||||
virtual ~AtomCertVerifier();
|
||||
|
||||
using VerifyProc = base::Callback<void(const VerifyRequestParams& request,
|
||||
@@ -39,7 +33,7 @@ class AtomCertVerifier : public net::CertVerifier {
|
||||
void SetVerifyProc(const VerifyProc& proc);
|
||||
|
||||
const VerifyProc verify_proc() const { return verify_proc_; }
|
||||
brightray::RequireCTDelegate* ct_delegate() const { return ct_delegate_; }
|
||||
AtomCTDelegate* ct_delegate() const { return ct_delegate_; }
|
||||
net::CertVerifier* default_verifier() const {
|
||||
return default_cert_verifier_.get();
|
||||
}
|
||||
@@ -63,7 +57,7 @@ class AtomCertVerifier : public net::CertVerifier {
|
||||
std::map<RequestParams, CertVerifierRequest*> inflight_requests_;
|
||||
VerifyProc verify_proc_;
|
||||
std::unique_ptr<net::CertVerifier> default_cert_verifier_;
|
||||
brightray::RequireCTDelegate* ct_delegate_;
|
||||
AtomCTDelegate* ct_delegate_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomCertVerifier);
|
||||
};
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "brightray/browser/net/require_ct_delegate.h"
|
||||
#include "atom/browser/net/atom_ct_delegate.h"
|
||||
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
|
||||
namespace brightray {
|
||||
namespace atom {
|
||||
|
||||
RequireCTDelegate::RequireCTDelegate() {}
|
||||
AtomCTDelegate::AtomCTDelegate() {}
|
||||
|
||||
RequireCTDelegate::~RequireCTDelegate() {}
|
||||
AtomCTDelegate::~AtomCTDelegate() {}
|
||||
|
||||
void RequireCTDelegate::AddCTExcludedHost(const std::string& host) {
|
||||
void AtomCTDelegate::AddCTExcludedHost(const std::string& host) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
ct_excluded_hosts_.insert(host);
|
||||
}
|
||||
|
||||
void RequireCTDelegate::ClearCTExcludedHostsList() {
|
||||
void AtomCTDelegate::ClearCTExcludedHostsList() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
ct_excluded_hosts_.clear();
|
||||
}
|
||||
|
||||
RequireCTDelegate::CTRequirementLevel RequireCTDelegate::IsCTRequiredForHost(
|
||||
AtomCTDelegate::CTRequirementLevel AtomCTDelegate::IsCTRequiredForHost(
|
||||
const std::string& host) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
if (!ct_excluded_hosts_.empty() &&
|
||||
@@ -31,4 +31,4 @@ RequireCTDelegate::CTRequirementLevel RequireCTDelegate::IsCTRequiredForHost(
|
||||
return CTRequirementLevel::DEFAULT;
|
||||
}
|
||||
|
||||
} // namespace brightray
|
||||
} // namespace atom
|
||||
@@ -1,22 +1,21 @@
|
||||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef BRIGHTRAY_BROWSER_NET_REQUIRE_CT_DELEGATE_H_
|
||||
#define BRIGHTRAY_BROWSER_NET_REQUIRE_CT_DELEGATE_H_
|
||||
#ifndef ATOM_BROWSER_NET_ATOM_CT_DELEGATE_H_
|
||||
#define ATOM_BROWSER_NET_ATOM_CT_DELEGATE_H_
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "net/http/transport_security_state.h"
|
||||
|
||||
namespace brightray {
|
||||
namespace atom {
|
||||
|
||||
class RequireCTDelegate
|
||||
: public net::TransportSecurityState::RequireCTDelegate {
|
||||
class AtomCTDelegate : public net::TransportSecurityState::RequireCTDelegate {
|
||||
public:
|
||||
RequireCTDelegate();
|
||||
~RequireCTDelegate() override;
|
||||
AtomCTDelegate();
|
||||
~AtomCTDelegate() override;
|
||||
|
||||
void AddCTExcludedHost(const std::string& host);
|
||||
void ClearCTExcludedHostsList();
|
||||
@@ -26,9 +25,9 @@ class RequireCTDelegate
|
||||
|
||||
private:
|
||||
std::set<std::string> ct_excluded_hosts_;
|
||||
DISALLOW_COPY_AND_ASSIGN(RequireCTDelegate);
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomCTDelegate);
|
||||
};
|
||||
|
||||
} // namespace brightray
|
||||
} // namespace atom
|
||||
|
||||
#endif // BRIGHTRAY_BROWSER_NET_REQUIRE_CT_DELEGATE_H_
|
||||
#endif // ATOM_BROWSER_NET_ATOM_CT_DELEGATE_H_
|
||||
@@ -6,13 +6,11 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "brightray/browser/net/devtools_network_transaction.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "net/url_request/url_request.h"
|
||||
|
||||
using brightray::DevToolsNetworkTransaction;
|
||||
@@ -76,23 +74,10 @@ void ToDictionary(base::DictionaryValue* details, net::URLRequest* request) {
|
||||
FillRequestDetails(details, request);
|
||||
details->SetInteger("id", request->identifier());
|
||||
details->SetDouble("timestamp", base::Time::Now().ToDoubleT() * 1000);
|
||||
const auto* info = content::ResourceRequestInfo::ForRequest(request);
|
||||
if (info) {
|
||||
int process_id = info->GetChildID();
|
||||
int frame_id = info->GetRenderFrameID();
|
||||
auto* webContents = content::WebContents::FromRenderFrameHost(
|
||||
content::RenderFrameHost::FromID(process_id, frame_id));
|
||||
int webContentsId = atom::api::WebContents::GetIDFromWrappedClass(
|
||||
webContents);
|
||||
|
||||
// webContentsId must be greater than zero
|
||||
if (webContentsId)
|
||||
details->SetInteger("webContentsId", webContentsId);
|
||||
details->SetString("resourceType",
|
||||
ResourceTypeToString(info->GetResourceType()));
|
||||
} else {
|
||||
details->SetString("resourceType", "other");
|
||||
}
|
||||
auto info = content::ResourceRequestInfo::ForRequest(request);
|
||||
details->SetString("resourceType",
|
||||
info ? ResourceTypeToString(info->GetResourceType())
|
||||
: "other");
|
||||
}
|
||||
|
||||
void ToDictionary(base::DictionaryValue* details,
|
||||
|
||||
@@ -117,13 +117,17 @@ bool AtomURLRequestJobFactory::IsHandledProtocol(
|
||||
net::URLRequest::IsHandledProtocol(scheme);
|
||||
}
|
||||
|
||||
bool AtomURLRequestJobFactory::IsSafeRedirectTarget(
|
||||
const GURL& location) const {
|
||||
if (!location.is_valid()) {
|
||||
bool AtomURLRequestJobFactory::IsHandledURL(const GURL& url) const {
|
||||
if (!url.is_valid()) {
|
||||
// We handle error cases.
|
||||
return true;
|
||||
}
|
||||
return IsHandledProtocol(location.scheme());
|
||||
return IsHandledProtocol(url.scheme());
|
||||
}
|
||||
|
||||
bool AtomURLRequestJobFactory::IsSafeRedirectTarget(
|
||||
const GURL& location) const {
|
||||
return IsHandledURL(location);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -55,6 +55,7 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const override;
|
||||
bool IsHandledProtocol(const std::string& scheme) const override;
|
||||
bool IsHandledURL(const GURL& url) const override;
|
||||
bool IsSafeRedirectTarget(const GURL& location) const override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -71,7 +71,6 @@ class JsAsker : public RequestJob {
|
||||
void Start() override {
|
||||
std::unique_ptr<base::DictionaryValue> request_details(
|
||||
new base::DictionaryValue);
|
||||
request_start_time_ = base::TimeTicks::Now();
|
||||
FillRequestDetails(request_details.get(), RequestJob::request());
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::UI, FROM_HERE,
|
||||
@@ -87,15 +86,6 @@ class JsAsker : public RequestJob {
|
||||
|
||||
int GetResponseCode() const override { return net::HTTP_OK; }
|
||||
|
||||
// NOTE: We have to implement this method or risk a crash in blink for
|
||||
// redirects!
|
||||
void GetLoadTimingInfo(net::LoadTimingInfo* load_timing_info) const override {
|
||||
load_timing_info->send_start = request_start_time_;
|
||||
load_timing_info->send_end = request_start_time_;
|
||||
load_timing_info->request_start = request_start_time_;
|
||||
load_timing_info->receive_headers_end = response_start_time_;
|
||||
}
|
||||
|
||||
void GetResponseInfo(net::HttpResponseInfo* info) override {
|
||||
info->headers = new net::HttpResponseHeaders("");
|
||||
}
|
||||
@@ -103,7 +93,6 @@ class JsAsker : public RequestJob {
|
||||
// Called when the JS handler has sent the response, we need to decide whether
|
||||
// to start, or fail the job.
|
||||
void OnResponse(bool success, std::unique_ptr<base::Value> value) {
|
||||
response_start_time_ = base::TimeTicks::Now();
|
||||
int error = net::ERR_NOT_IMPLEMENTED;
|
||||
if (success && value && !internal::IsErrorOptions(value.get(), &error)) {
|
||||
StartAsync(std::move(value));
|
||||
@@ -116,8 +105,6 @@ class JsAsker : public RequestJob {
|
||||
v8::Isolate* isolate_;
|
||||
net::URLRequestContextGetter* request_context_getter_;
|
||||
JavaScriptHandler handler_;
|
||||
base::TimeTicks request_start_time_;
|
||||
base::TimeTicks response_start_time_;
|
||||
|
||||
base::WeakPtrFactory<JsAsker> weak_factory_;
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ URLRequestBufferJob::URLRequestBufferJob(
|
||||
}
|
||||
|
||||
void URLRequestBufferJob::StartAsync(std::unique_ptr<base::Value> options) {
|
||||
const base::Value* binary = nullptr;
|
||||
const base::BinaryValue* binary = nullptr;
|
||||
if (options->IsType(base::Value::Type::DICTIONARY)) {
|
||||
base::DictionaryValue* dict =
|
||||
static_cast<base::DictionaryValue*>(options.get());
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <algorithm>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/net/url_request_stream_job.h"
|
||||
#include "atom/common/api/event_emitter_caller.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/time/time.h"
|
||||
#include "net/filter/gzip_source_stream.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
URLRequestStreamJob::URLRequestStreamJob(net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate)
|
||||
: JsAsker<net::URLRequestJob>(request, network_delegate),
|
||||
ended_(false),
|
||||
errored_(false),
|
||||
pending_io_buf_(nullptr),
|
||||
pending_io_buf_size_(0),
|
||||
response_headers_(nullptr),
|
||||
weak_factory_(this) {}
|
||||
|
||||
void URLRequestStreamJob::BeforeStartInUI(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> value) {
|
||||
if (value->IsNull() || value->IsUndefined() || !value->IsObject()) {
|
||||
// Invalid opts.
|
||||
ended_ = true;
|
||||
errored_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
mate::Dictionary opts(isolate, v8::Local<v8::Object>::Cast(value));
|
||||
int status_code;
|
||||
if (!opts.Get("statusCode", &status_code)) {
|
||||
// assume HTTP OK if statusCode is not passed.
|
||||
status_code = 200;
|
||||
}
|
||||
std::string status("HTTP/1.1 ");
|
||||
status.append(base::IntToString(status_code));
|
||||
status.append(" ");
|
||||
status.append(
|
||||
net::GetHttpReasonPhrase(static_cast<net::HttpStatusCode>(status_code)));
|
||||
status.append("\0\0", 2);
|
||||
response_headers_ = new net::HttpResponseHeaders(status);
|
||||
|
||||
if (opts.Get("headers", &value)) {
|
||||
mate::Converter<net::HttpResponseHeaders*>::FromV8(isolate, value,
|
||||
response_headers_.get());
|
||||
}
|
||||
|
||||
if (!opts.Get("data", &value)) {
|
||||
// Assume the opts is already a stream
|
||||
value = opts.GetHandle();
|
||||
} else if (value->IsNullOrUndefined()) {
|
||||
// "data" was explicitly passed as null or undefined, assume the user wants
|
||||
// to send an empty body.
|
||||
ended_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
mate::Dictionary data(isolate, v8::Local<v8::Object>::Cast(value));
|
||||
if (!data.Get("on", &value) || !value->IsFunction() ||
|
||||
!data.Get("removeListener", &value) || !value->IsFunction()) {
|
||||
// If data is passed but it is not a stream, signal an error.
|
||||
ended_ = true;
|
||||
errored_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
subscriber_.reset(new mate::EventSubscriber<URLRequestStreamJob>(
|
||||
this, isolate, data.GetHandle()));
|
||||
subscriber_->On("data", &URLRequestStreamJob::OnData);
|
||||
subscriber_->On("end", &URLRequestStreamJob::OnEnd);
|
||||
subscriber_->On("error", &URLRequestStreamJob::OnError);
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::StartAsync(std::unique_ptr<base::Value> options) {
|
||||
NotifyHeadersComplete();
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::OnData(mate::Arguments* args) {
|
||||
v8::Local<v8::Value> node_data;
|
||||
args->GetNext(&node_data);
|
||||
if (node_data->IsUint8Array()) {
|
||||
const char* data = node::Buffer::Data(node_data);
|
||||
size_t data_size = node::Buffer::Length(node_data);
|
||||
std::copy(data, data + data_size, std::back_inserter(buffer_));
|
||||
} else {
|
||||
NOTREACHED();
|
||||
}
|
||||
if (pending_io_buf_) {
|
||||
CopyMoreData(pending_io_buf_, pending_io_buf_size_);
|
||||
}
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::OnEnd(mate::Arguments* args) {
|
||||
ended_ = true;
|
||||
if (pending_io_buf_) {
|
||||
CopyMoreData(pending_io_buf_, pending_io_buf_size_);
|
||||
}
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::OnError(mate::Arguments* args) {
|
||||
errored_ = true;
|
||||
if (pending_io_buf_) {
|
||||
CopyMoreData(pending_io_buf_, pending_io_buf_size_);
|
||||
}
|
||||
}
|
||||
|
||||
int URLRequestStreamJob::ReadRawData(net::IOBuffer* dest, int dest_size) {
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&URLRequestStreamJob::CopyMoreData, weak_factory_.GetWeakPtr(),
|
||||
make_scoped_refptr(dest), dest_size));
|
||||
return net::ERR_IO_PENDING;
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::DoneReading() {
|
||||
subscriber_.reset();
|
||||
buffer_.clear();
|
||||
ended_ = true;
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::DoneReadingRedirectResponse() {
|
||||
DoneReading();
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::CopyMoreDataDone(scoped_refptr<net::IOBuffer> io_buf,
|
||||
int status) {
|
||||
if (status <= 0) {
|
||||
subscriber_.reset();
|
||||
}
|
||||
ReadRawDataComplete(status);
|
||||
io_buf = nullptr;
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::CopyMoreData(scoped_refptr<net::IOBuffer> io_buf,
|
||||
int io_buf_size) {
|
||||
// reset any instance references to io_buf
|
||||
pending_io_buf_ = nullptr;
|
||||
pending_io_buf_size_ = 0;
|
||||
|
||||
int read_count = 0;
|
||||
if (buffer_.size()) {
|
||||
size_t count = std::min((size_t)io_buf_size, buffer_.size());
|
||||
std::copy(buffer_.begin(), buffer_.begin() + count, io_buf->data());
|
||||
buffer_.erase(buffer_.begin(), buffer_.begin() + count);
|
||||
read_count = count;
|
||||
} else if (!ended_ && !errored_) {
|
||||
// No data available yet, save references to the IOBuffer, which will be
|
||||
// passed back to this function when OnData/OnEnd/OnError are called
|
||||
pending_io_buf_ = io_buf;
|
||||
pending_io_buf_size_ = io_buf_size;
|
||||
}
|
||||
|
||||
if (!pending_io_buf_) {
|
||||
// Only call CopyMoreDataDone if we have read something.
|
||||
int status = (errored_ && !read_count) ? net::ERR_FAILED : read_count;
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&URLRequestStreamJob::CopyMoreDataDone,
|
||||
weak_factory_.GetWeakPtr(), io_buf, status));
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<net::SourceStream> URLRequestStreamJob::SetUpSourceStream() {
|
||||
std::unique_ptr<net::SourceStream> source =
|
||||
net::URLRequestJob::SetUpSourceStream();
|
||||
size_t i = 0;
|
||||
std::string type;
|
||||
while (response_headers_->EnumerateHeader(&i, "Content-Encoding", &type)) {
|
||||
if (base::LowerCaseEqualsASCII(type, "gzip") ||
|
||||
base::LowerCaseEqualsASCII(type, "x-gzip")) {
|
||||
return net::GzipSourceStream::Create(std::move(source),
|
||||
net::SourceStream::TYPE_GZIP);
|
||||
} else if (base::LowerCaseEqualsASCII(type, "deflate")) {
|
||||
return net::GzipSourceStream::Create(std::move(source),
|
||||
net::SourceStream::TYPE_DEFLATE);
|
||||
}
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
bool URLRequestStreamJob::GetMimeType(std::string* mime_type) const {
|
||||
return response_headers_->GetMimeType(mime_type);
|
||||
}
|
||||
|
||||
int URLRequestStreamJob::GetResponseCode() const {
|
||||
return response_headers_->response_code();
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::GetResponseInfo(net::HttpResponseInfo* info) {
|
||||
info->headers = response_headers_;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
@@ -1,66 +0,0 @@
|
||||
// Copyright (c) 2017 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_URL_REQUEST_STREAM_JOB_H_
|
||||
#define ATOM_BROWSER_NET_URL_REQUEST_STREAM_JOB_H_
|
||||
|
||||
#include <deque>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/event_subscriber.h"
|
||||
#include "atom/browser/net/js_asker.h"
|
||||
#include "base/memory/ref_counted_memory.h"
|
||||
#include "native_mate/persistent_dictionary.h"
|
||||
#include "net/base/io_buffer.h"
|
||||
#include "net/http/http_status_code.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class URLRequestStreamJob : public JsAsker<net::URLRequestJob> {
|
||||
public:
|
||||
URLRequestStreamJob(net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate);
|
||||
|
||||
void OnData(mate::Arguments* args);
|
||||
void OnEnd(mate::Arguments* args);
|
||||
void OnError(mate::Arguments* args);
|
||||
|
||||
// URLRequestJob
|
||||
void GetResponseInfo(net::HttpResponseInfo* info) override;
|
||||
|
||||
protected:
|
||||
// URLRequestJob
|
||||
int ReadRawData(net::IOBuffer* buf, int buf_size) override;
|
||||
void DoneReading() override;
|
||||
void DoneReadingRedirectResponse() override;
|
||||
std::unique_ptr<net::SourceStream> SetUpSourceStream() override;
|
||||
bool GetMimeType(std::string* mime_type) const override;
|
||||
int GetResponseCode() const override;
|
||||
|
||||
private:
|
||||
// JSAsker
|
||||
void BeforeStartInUI(v8::Isolate*, v8::Local<v8::Value>) override;
|
||||
void StartAsync(std::unique_ptr<base::Value> options) override;
|
||||
void OnResponse(bool success, std::unique_ptr<base::Value> value);
|
||||
|
||||
// Callback after data is asynchronously read from the file into |buf|.
|
||||
void CopyMoreData(scoped_refptr<net::IOBuffer> io_buf, int io_buf_size);
|
||||
void CopyMoreDataDone(scoped_refptr<net::IOBuffer> io_buf, int read_count);
|
||||
|
||||
std::deque<char> buffer_;
|
||||
bool ended_;
|
||||
bool errored_;
|
||||
scoped_refptr<net::IOBuffer> pending_io_buf_;
|
||||
int pending_io_buf_size_;
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers_;
|
||||
mate::EventSubscriber<URLRequestStreamJob>::SafePtr subscriber_;
|
||||
base::WeakPtrFactory<URLRequestStreamJob> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(URLRequestStreamJob);
|
||||
};
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_NET_URL_REQUEST_STREAM_JOB_H_
|
||||
@@ -27,9 +27,9 @@ void NodeDebugger::Start() {
|
||||
node::DebugOptions options;
|
||||
for (auto& arg : base::CommandLine::ForCurrentProcess()->argv()) {
|
||||
#if defined(OS_WIN)
|
||||
options.ParseOption("Electron", base::UTF16ToUTF8(arg));
|
||||
options.ParseOption(base::UTF16ToUTF8(arg));
|
||||
#else
|
||||
options.ParseOption("Electron", arg);
|
||||
options.ParseOption(arg);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ void NodeDebugger::Start() {
|
||||
// the debugger on the first line
|
||||
if (options.wait_for_connect()) {
|
||||
mate::Dictionary process(env_->isolate(), env_->process_object());
|
||||
process.Set("_breakFirstLine", true);
|
||||
process.Set("_debugWaitConnect", true);
|
||||
}
|
||||
|
||||
inspector->Start(platform_.get(), nullptr, options);
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/callback_helpers.h"
|
||||
@@ -17,10 +15,10 @@
|
||||
#include "cc/output/copy_output_request.h"
|
||||
#include "cc/scheduler/delay_based_time_source.h"
|
||||
#include "components/display_compositor/gl_helper.h"
|
||||
#include "content/browser/renderer_host/compositor_resize_lock.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_delegate.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_view_frame_subscriber.h"
|
||||
#include "content/browser/renderer_host/resize_lock.h"
|
||||
#include "content/common/view_messages.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/context_factory.h"
|
||||
@@ -31,10 +29,10 @@
|
||||
#include "ui/compositor/layer_type.h"
|
||||
#include "ui/events/base_event_utils.h"
|
||||
#include "ui/events/event_constants.h"
|
||||
#include "ui/events/latency_info.h"
|
||||
#include "ui/gfx/geometry/dip_util.h"
|
||||
#include "ui/gfx/native_widget_types.h"
|
||||
#include "ui/gfx/skbitmap_operations.h"
|
||||
#include "ui/latency/latency_info.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -45,23 +43,23 @@ const int kFrameRetryLimit = 2;
|
||||
|
||||
ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
|
||||
ui::EventType type = ui::EventType::ET_UNKNOWN;
|
||||
switch (event.GetType()) {
|
||||
case blink::WebInputEvent::kMouseDown:
|
||||
switch (event.type()) {
|
||||
case blink::WebInputEvent::MouseDown:
|
||||
type = ui::EventType::ET_MOUSE_PRESSED;
|
||||
break;
|
||||
case blink::WebInputEvent::kMouseUp:
|
||||
case blink::WebInputEvent::MouseUp:
|
||||
type = ui::EventType::ET_MOUSE_RELEASED;
|
||||
break;
|
||||
case blink::WebInputEvent::kMouseMove:
|
||||
case blink::WebInputEvent::MouseMove:
|
||||
type = ui::EventType::ET_MOUSE_MOVED;
|
||||
break;
|
||||
case blink::WebInputEvent::kMouseEnter:
|
||||
case blink::WebInputEvent::MouseEnter:
|
||||
type = ui::EventType::ET_MOUSE_ENTERED;
|
||||
break;
|
||||
case blink::WebInputEvent::kMouseLeave:
|
||||
case blink::WebInputEvent::MouseLeave:
|
||||
type = ui::EventType::ET_MOUSE_EXITED;
|
||||
break;
|
||||
case blink::WebInputEvent::kMouseWheel:
|
||||
case blink::WebInputEvent::MouseWheel:
|
||||
type = ui::EventType::ET_MOUSEWHEEL;
|
||||
break;
|
||||
default:
|
||||
@@ -71,19 +69,19 @@ ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
|
||||
|
||||
int button_flags = 0;
|
||||
switch (event.button) {
|
||||
case blink::WebMouseEvent::Button::kBack:
|
||||
case blink::WebMouseEvent::Button::X1:
|
||||
button_flags |= ui::EventFlags::EF_BACK_MOUSE_BUTTON;
|
||||
break;
|
||||
case blink::WebMouseEvent::Button::kForward:
|
||||
case blink::WebMouseEvent::Button::X2:
|
||||
button_flags |= ui::EventFlags::EF_FORWARD_MOUSE_BUTTON;
|
||||
break;
|
||||
case blink::WebMouseEvent::Button::kLeft:
|
||||
case blink::WebMouseEvent::Button::Left:
|
||||
button_flags |= ui::EventFlags::EF_LEFT_MOUSE_BUTTON;
|
||||
break;
|
||||
case blink::WebMouseEvent::Button::kMiddle:
|
||||
case blink::WebMouseEvent::Button::Middle:
|
||||
button_flags |= ui::EventFlags::EF_MIDDLE_MOUSE_BUTTON;
|
||||
break;
|
||||
case blink::WebMouseEvent::Button::kRight:
|
||||
case blink::WebMouseEvent::Button::Right:
|
||||
button_flags |= ui::EventFlags::EF_RIGHT_MOUSE_BUTTON;
|
||||
break;
|
||||
default:
|
||||
@@ -92,12 +90,11 @@ ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
|
||||
}
|
||||
|
||||
ui::MouseEvent ui_event(type,
|
||||
gfx::Point(std::floor(event.PositionInWidget().x),
|
||||
std::floor(event.PositionInWidget().y)),
|
||||
gfx::Point(std::floor(event.PositionInWidget().x),
|
||||
std::floor(event.PositionInWidget().y)),
|
||||
ui::EventTimeForNow(), button_flags, button_flags);
|
||||
ui_event.SetClickCount(event.click_count);
|
||||
gfx::Point(std::floor(event.x), std::floor(event.y)),
|
||||
gfx::Point(std::floor(event.x), std::floor(event.y)),
|
||||
ui::EventTimeForNow(),
|
||||
button_flags, button_flags);
|
||||
ui_event.SetClickCount(event.clickCount);
|
||||
|
||||
return ui_event;
|
||||
}
|
||||
@@ -105,9 +102,69 @@ ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
|
||||
ui::MouseWheelEvent UiMouseWheelEventFromWebMouseEvent(
|
||||
blink::WebMouseWheelEvent event) {
|
||||
return ui::MouseWheelEvent(UiMouseEventFromWebMouseEvent(event),
|
||||
std::floor(event.delta_x), std::floor(event.delta_y));
|
||||
std::floor(event.deltaX), std::floor(event.deltaY));
|
||||
}
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
|
||||
const int kResizeLockTimeoutMs = 67;
|
||||
|
||||
class AtomResizeLock : public content::ResizeLock {
|
||||
public:
|
||||
AtomResizeLock(OffScreenRenderWidgetHostView* host,
|
||||
const gfx::Size new_size,
|
||||
bool defer_compositor_lock)
|
||||
: ResizeLock(new_size, defer_compositor_lock),
|
||||
host_(host),
|
||||
cancelled_(false),
|
||||
weak_ptr_factory_(this) {
|
||||
DCHECK(host_);
|
||||
host_->HoldResize();
|
||||
|
||||
content::BrowserThread::PostDelayedTask(content::BrowserThread::UI,
|
||||
FROM_HERE, base::Bind(&AtomResizeLock::CancelLock,
|
||||
weak_ptr_factory_.GetWeakPtr()),
|
||||
base::TimeDelta::FromMilliseconds(kResizeLockTimeoutMs));
|
||||
}
|
||||
|
||||
~AtomResizeLock() override {
|
||||
CancelLock();
|
||||
}
|
||||
|
||||
bool GrabDeferredLock() override {
|
||||
return ResizeLock::GrabDeferredLock();
|
||||
}
|
||||
|
||||
void UnlockCompositor() override {
|
||||
ResizeLock::UnlockCompositor();
|
||||
compositor_lock_ = NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
void LockCompositor() override {
|
||||
ResizeLock::LockCompositor();
|
||||
compositor_lock_ = host_->GetCompositor()->GetCompositorLock();
|
||||
}
|
||||
|
||||
void CancelLock() {
|
||||
if (cancelled_)
|
||||
return;
|
||||
cancelled_ = true;
|
||||
UnlockCompositor();
|
||||
host_->ReleaseResize();
|
||||
}
|
||||
|
||||
private:
|
||||
OffScreenRenderWidgetHostView* host_;
|
||||
scoped_refptr<ui::CompositorLock> compositor_lock_;
|
||||
bool cancelled_;
|
||||
base::WeakPtrFactory<AtomResizeLock> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomResizeLock);
|
||||
};
|
||||
|
||||
#endif // !defined(OS_MACOSX)
|
||||
|
||||
} // namespace
|
||||
|
||||
class AtomCopyFrameGenerator {
|
||||
@@ -124,7 +181,7 @@ class AtomCopyFrameGenerator {
|
||||
}
|
||||
|
||||
void GenerateCopyFrame(const gfx::Rect& damage_rect) {
|
||||
if (!view_->render_widget_host())
|
||||
if (!view_->render_widget_host() || !view_->IsPainting())
|
||||
return;
|
||||
|
||||
std::unique_ptr<cc::CopyOutputRequest> request =
|
||||
@@ -255,6 +312,8 @@ class AtomBeginFrameTimer : public cc::DelayBasedTimeSourceClient {
|
||||
|
||||
OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
bool transparent,
|
||||
bool painting,
|
||||
int frame_rate,
|
||||
const OnPaintCallback& callback,
|
||||
content::RenderWidgetHost* host,
|
||||
OffScreenRenderWidgetHostView* parent_host_view,
|
||||
@@ -268,19 +327,18 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
transparent_(transparent),
|
||||
callback_(callback),
|
||||
parent_callback_(nullptr),
|
||||
frame_rate_(60),
|
||||
frame_rate_(frame_rate),
|
||||
frame_rate_threshold_us_(0),
|
||||
last_time_(base::Time::Now()),
|
||||
scale_factor_(kDefaultScaleFactor),
|
||||
size_(native_window->GetSize()),
|
||||
painting_(true),
|
||||
painting_(painting),
|
||||
is_showing_(!render_widget_host_->is_hidden()),
|
||||
is_destroyed_(false),
|
||||
popup_position_(gfx::Rect()),
|
||||
hold_resize_(false),
|
||||
pending_resize_(false),
|
||||
renderer_compositor_frame_sink_(nullptr),
|
||||
background_color_(SkColor()),
|
||||
paint_callback_running_(false),
|
||||
weak_ptr_factory_(this) {
|
||||
DCHECK(render_widget_host_);
|
||||
bool is_guest_view_hack = parent_host_view_ != nullptr;
|
||||
@@ -303,7 +361,7 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
new ui::Compositor(context_factory_private->AllocateFrameSinkId(),
|
||||
content::GetContextFactory(), context_factory_private,
|
||||
base::ThreadTaskRunnerHandle::Get()));
|
||||
compositor_->SetAcceleratedWidget(native_window_->GetAcceleratedWidget());
|
||||
compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
|
||||
compositor_->SetRootLayer(root_layer_.get());
|
||||
#endif
|
||||
GetCompositor()->SetDelegate(this);
|
||||
@@ -499,18 +557,14 @@ gfx::Rect OffScreenRenderWidgetHostView::GetViewBounds() const {
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetBackgroundColor(SkColor color) {
|
||||
// The renderer will feed its color back to us with the first CompositorFrame.
|
||||
// We short-cut here to show a sensible color before that happens.
|
||||
UpdateBackgroundColorFromRenderer(color);
|
||||
if (transparent_)
|
||||
color = SkColorSetARGB(SK_AlphaTRANSPARENT, 0, 0, 0);
|
||||
|
||||
if (render_widget_host_) {
|
||||
render_widget_host_->SetBackgroundOpaque(SkColorGetA(color) ==
|
||||
SK_AlphaOPAQUE);
|
||||
}
|
||||
}
|
||||
content::RenderWidgetHostViewBase::SetBackgroundColor(color);
|
||||
|
||||
SkColor OffScreenRenderWidgetHostView::background_color() const {
|
||||
return background_color_;
|
||||
const bool opaque = !transparent_ && GetBackgroundOpaque();
|
||||
if (render_widget_host_)
|
||||
render_widget_host_->SetBackgroundOpaque(opaque);
|
||||
}
|
||||
|
||||
gfx::Size OffScreenRenderWidgetHostView::GetVisibleViewportSize() const {
|
||||
@@ -527,20 +581,11 @@ bool OffScreenRenderWidgetHostView::LockMouse() {
|
||||
void OffScreenRenderWidgetHostView::UnlockMouse() {
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::DidCreateNewRendererCompositorFrameSink(
|
||||
cc::mojom::MojoCompositorFrameSinkClient* renderer_compositor_frame_sink) {
|
||||
renderer_compositor_frame_sink_ = renderer_compositor_frame_sink;
|
||||
if (GetDelegatedFrameHost()) {
|
||||
GetDelegatedFrameHost()->DidCreateNewRendererCompositorFrameSink(
|
||||
renderer_compositor_frame_sink_);
|
||||
}
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SubmitCompositorFrame(
|
||||
const cc::LocalSurfaceId& local_surface_id,
|
||||
cc::CompositorFrame frame) {
|
||||
void OffScreenRenderWidgetHostView::OnSwapCompositorFrame(
|
||||
uint32_t output_surface_id,
|
||||
cc::CompositorFrame frame) {
|
||||
TRACE_EVENT0("electron",
|
||||
"OffScreenRenderWidgetHostView::SubmitCompositorFrame");
|
||||
"OffScreenRenderWidgetHostView::OnSwapCompositorFrame");
|
||||
|
||||
if (frame.metadata.root_scroll_offset != last_scroll_offset_) {
|
||||
last_scroll_offset_ = frame.metadata.root_scroll_offset;
|
||||
@@ -554,11 +599,11 @@ void OffScreenRenderWidgetHostView::SubmitCompositorFrame(
|
||||
|
||||
// The compositor will draw directly to the SoftwareOutputDevice which
|
||||
// then calls OnPaint.
|
||||
// We would normally call BrowserCompositorMac::SubmitCompositorFrame on
|
||||
// We would normally call BrowserCompositorMac::SwapCompositorFrame on
|
||||
// macOS, however it contains compositor resize logic that we don't want.
|
||||
// Consequently we instead call the SubmitCompositorFrame method directly.
|
||||
GetDelegatedFrameHost()->SubmitCompositorFrame(local_surface_id,
|
||||
std::move(frame));
|
||||
// Consequently we instead call the SwapDelegatedFrame method directly.
|
||||
GetDelegatedFrameHost()->SwapDelegatedFrame(output_surface_id,
|
||||
std::move(frame));
|
||||
} else {
|
||||
if (!copy_frame_generator_.get()) {
|
||||
copy_frame_generator_.reset(
|
||||
@@ -573,11 +618,11 @@ void OffScreenRenderWidgetHostView::SubmitCompositorFrame(
|
||||
gfx::ToEnclosingRect(gfx::RectF(root_pass->damage_rect));
|
||||
damage_rect.Intersect(gfx::Rect(frame_size));
|
||||
|
||||
// We would normally call BrowserCompositorMac::SubmitCompositorFrame on
|
||||
// We would normally call BrowserCompositorMac::SwapCompositorFrame on
|
||||
// macOS, however it contains compositor resize logic that we don't want.
|
||||
// Consequently we instead call the SubmitCompositorFrame method directly.
|
||||
GetDelegatedFrameHost()->SubmitCompositorFrame(local_surface_id,
|
||||
std::move(frame));
|
||||
// Consequently we instead call the SwapDelegatedFrame method directly.
|
||||
GetDelegatedFrameHost()->SwapDelegatedFrame(output_surface_id,
|
||||
std::move(frame));
|
||||
|
||||
// Request a copy of the last compositor frame which will eventually call
|
||||
// OnPaint asynchronously.
|
||||
@@ -643,14 +688,8 @@ void OffScreenRenderWidgetHostView::Destroy() {
|
||||
popup_bitmap_.reset();
|
||||
if (child_host_view_)
|
||||
child_host_view_->CancelWidget();
|
||||
if (!guest_host_views_.empty()) {
|
||||
// Guest RWHVs will be destroyed when the associated RWHVGuest is
|
||||
// destroyed. This parent RWHV may be destroyed first, so disassociate
|
||||
// the guest RWHVs here without destroying them.
|
||||
for (auto guest_host_view : guest_host_views_)
|
||||
guest_host_view->parent_host_view_ = nullptr;
|
||||
guest_host_views_.clear();
|
||||
}
|
||||
for (auto guest_host_view : guest_host_views_)
|
||||
guest_host_view->CancelWidget();
|
||||
for (auto proxy_view : proxy_views_)
|
||||
proxy_view->RemoveObserver();
|
||||
Hide();
|
||||
@@ -738,6 +777,8 @@ content::RenderWidgetHostViewBase*
|
||||
|
||||
return new OffScreenRenderWidgetHostView(
|
||||
transparent_,
|
||||
true,
|
||||
embedder_host_view->GetFrameRate(),
|
||||
callback_,
|
||||
render_widget_host,
|
||||
embedder_host_view,
|
||||
@@ -771,25 +812,31 @@ bool OffScreenRenderWidgetHostView::DelegatedFrameCanCreateResizeLock() const {
|
||||
return !render_widget_host_->auto_resize_enabled();
|
||||
}
|
||||
|
||||
std::unique_ptr<content::CompositorResizeLock>
|
||||
OffScreenRenderWidgetHostView::DelegatedFrameHostCreateResizeLock() {
|
||||
HoldResize();
|
||||
const gfx::Size& desired_size = GetRootLayer()->bounds().size();
|
||||
return base::MakeUnique<content::CompositorResizeLock>(this, desired_size);
|
||||
std::unique_ptr<content::ResizeLock>
|
||||
OffScreenRenderWidgetHostView::DelegatedFrameHostCreateResizeLock(
|
||||
bool defer_compositor_lock) {
|
||||
return std::unique_ptr<content::ResizeLock>(new AtomResizeLock(
|
||||
this,
|
||||
DelegatedFrameHostDesiredSizeInDIP(),
|
||||
defer_compositor_lock));
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::DelegatedFrameHostResizeLockWasReleased() {
|
||||
return render_widget_host_->WasResized();
|
||||
}
|
||||
|
||||
void
|
||||
OffScreenRenderWidgetHostView::OnBeginFrame(const cc::BeginFrameArgs& args) {
|
||||
OffScreenRenderWidgetHostView::DelegatedFrameHostSendReclaimCompositorResources(
|
||||
int output_surface_id,
|
||||
bool is_swap_ack,
|
||||
const cc::ReturnedResourceArray& resources) {
|
||||
render_widget_host_->Send(new ViewMsg_ReclaimCompositorResources(
|
||||
render_widget_host_->GetRoutingID(), output_surface_id, is_swap_ack,
|
||||
resources));
|
||||
}
|
||||
|
||||
std::unique_ptr<ui::CompositorLock>
|
||||
OffScreenRenderWidgetHostView::GetCompositorLock(
|
||||
ui::CompositorLockClient* client) {
|
||||
return GetCompositor()->GetCompositorLock(client);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::CompositorResizeLockEnded() {
|
||||
ReleaseResize();
|
||||
void OffScreenRenderWidgetHostView::SetBeginFrameSource(
|
||||
cc::BeginFrameSource* source) {
|
||||
}
|
||||
|
||||
#endif // !defined(OS_MACOSX)
|
||||
@@ -930,7 +977,7 @@ bool OffScreenRenderWidgetHostView::IsAutoResizeEnabled() const {
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetNeedsBeginFrames(
|
||||
bool needs_begin_frames) {
|
||||
SetupFrameRate(false);
|
||||
SetupFrameRate(true);
|
||||
|
||||
begin_frame_timer_->SetActive(needs_begin_frames);
|
||||
|
||||
@@ -1004,7 +1051,9 @@ void OffScreenRenderWidgetHostView::OnPaint(
|
||||
}
|
||||
|
||||
damage.Intersect(GetViewBounds());
|
||||
paint_callback_running_ = true;
|
||||
callback_.Run(damage, bitmap);
|
||||
paint_callback_running_ = false;
|
||||
|
||||
for (size_t i = 0; i < damages.size(); i++) {
|
||||
CopyBitmapTo(bitmap, originals[i], damages[i]);
|
||||
@@ -1069,12 +1118,12 @@ void OffScreenRenderWidgetHostView::ProcessMouseEvent(
|
||||
const ui::LatencyInfo& latency) {
|
||||
for (auto proxy_view : proxy_views_) {
|
||||
gfx::Rect bounds = proxy_view->GetBounds();
|
||||
if (bounds.Contains(event.PositionInWidget().x,
|
||||
event.PositionInWidget().y)) {
|
||||
if (bounds.Contains(event.x, event.y)) {
|
||||
blink::WebMouseEvent proxy_event(event);
|
||||
proxy_event.SetPositionInWidget(
|
||||
proxy_event.PositionInWidget().x - bounds.x(),
|
||||
proxy_event.PositionInWidget().y - bounds.y());
|
||||
proxy_event.x -= bounds.x();
|
||||
proxy_event.y -= bounds.y();
|
||||
proxy_event.windowX = proxy_event.x;
|
||||
proxy_event.windowY = proxy_event.y;
|
||||
|
||||
ui::MouseEvent ui_event = UiMouseEventFromWebMouseEvent(proxy_event);
|
||||
proxy_view->OnEvent(&ui_event);
|
||||
@@ -1083,14 +1132,13 @@ void OffScreenRenderWidgetHostView::ProcessMouseEvent(
|
||||
}
|
||||
|
||||
if (!IsPopupWidget()) {
|
||||
if (popup_host_view_ && popup_host_view_->popup_position_.Contains(
|
||||
event.PositionInWidget().x, event.PositionInWidget().y)) {
|
||||
if (popup_host_view_ &&
|
||||
popup_host_view_->popup_position_.Contains(event.x, event.y)) {
|
||||
blink::WebMouseEvent popup_event(event);
|
||||
popup_event.SetPositionInWidget(
|
||||
popup_event.PositionInWidget().x -
|
||||
popup_host_view_->popup_position_.x(),
|
||||
popup_event.PositionInWidget().y -
|
||||
popup_host_view_->popup_position_.y());
|
||||
popup_event.x -= popup_host_view_->popup_position_.x();
|
||||
popup_event.y -= popup_host_view_->popup_position_.y();
|
||||
popup_event.windowX = popup_event.x;
|
||||
popup_event.windowY = popup_event.y;
|
||||
|
||||
popup_host_view_->ProcessMouseEvent(popup_event, latency);
|
||||
return;
|
||||
@@ -1107,12 +1155,12 @@ void OffScreenRenderWidgetHostView::ProcessMouseWheelEvent(
|
||||
const ui::LatencyInfo& latency) {
|
||||
for (auto proxy_view : proxy_views_) {
|
||||
gfx::Rect bounds = proxy_view->GetBounds();
|
||||
if (bounds.Contains(event.PositionInWidget().x,
|
||||
event.PositionInWidget().y)) {
|
||||
if (bounds.Contains(event.x, event.y)) {
|
||||
blink::WebMouseWheelEvent proxy_event(event);
|
||||
proxy_event.SetPositionInWidget(
|
||||
proxy_event.PositionInWidget().x - bounds.x(),
|
||||
proxy_event.PositionInWidget().y - bounds.y());
|
||||
proxy_event.x -= bounds.x();
|
||||
proxy_event.y -= bounds.y();
|
||||
proxy_event.windowX = proxy_event.x;
|
||||
proxy_event.windowY = proxy_event.y;
|
||||
|
||||
ui::MouseWheelEvent ui_event =
|
||||
UiMouseWheelEventFromWebMouseEvent(proxy_event);
|
||||
@@ -1122,14 +1170,12 @@ void OffScreenRenderWidgetHostView::ProcessMouseWheelEvent(
|
||||
}
|
||||
if (!IsPopupWidget()) {
|
||||
if (popup_host_view_) {
|
||||
if (popup_host_view_->popup_position_.Contains(
|
||||
event.PositionInWidget().x, event.PositionInWidget().y)) {
|
||||
if (popup_host_view_->popup_position_.Contains(event.x, event.y)) {
|
||||
blink::WebMouseWheelEvent popup_event(event);
|
||||
popup_event.SetPositionInWidget(
|
||||
popup_event.PositionInWidget().x -
|
||||
popup_host_view_->popup_position_.x(),
|
||||
popup_event.PositionInWidget().y -
|
||||
popup_host_view_->popup_position_.y());
|
||||
popup_event.x -= popup_host_view_->popup_position_.x();
|
||||
popup_event.y -= popup_host_view_->popup_position_.y();
|
||||
popup_event.windowX = popup_event.x;
|
||||
popup_event.windowY = popup_event.y;
|
||||
popup_host_view_->ProcessMouseWheelEvent(popup_event, latency);
|
||||
return;
|
||||
} else {
|
||||
@@ -1151,7 +1197,7 @@ void OffScreenRenderWidgetHostView::SetPainting(bool painting) {
|
||||
painting_ = painting;
|
||||
|
||||
if (software_output_device_) {
|
||||
software_output_device_->SetActive(painting_, true);
|
||||
software_output_device_->SetActive(painting_, !paint_callback_running_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1168,16 +1214,16 @@ void OffScreenRenderWidgetHostView::SetFrameRate(int frame_rate) {
|
||||
} else {
|
||||
if (frame_rate <= 0)
|
||||
frame_rate = 1;
|
||||
if (frame_rate > 60)
|
||||
frame_rate = 60;
|
||||
if (frame_rate > 240)
|
||||
frame_rate = 240;
|
||||
|
||||
frame_rate_ = frame_rate;
|
||||
}
|
||||
|
||||
SetupFrameRate(true);
|
||||
|
||||
for (auto guest_host_view : guest_host_views_)
|
||||
guest_host_view->SetFrameRate(frame_rate);
|
||||
|
||||
SetupFrameRate(true);
|
||||
}
|
||||
|
||||
int OffScreenRenderWidgetHostView::GetFrameRate() const {
|
||||
@@ -1205,7 +1251,7 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
|
||||
|
||||
frame_rate_threshold_us_ = 1000000 / frame_rate_;
|
||||
|
||||
GetCompositor()->vsync_manager()->SetAuthoritativeVSyncInterval(
|
||||
GetCompositor()->SetAuthoritativeVSyncInterval(
|
||||
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_));
|
||||
|
||||
if (copy_frame_generator_.get()) {
|
||||
@@ -1273,15 +1319,4 @@ cc::FrameSinkId OffScreenRenderWidgetHostView::AllocateFrameSinkId(
|
||||
render_widget_host_->GetRoutingID()));
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::UpdateBackgroundColorFromRenderer(
|
||||
SkColor color) {
|
||||
if (color == background_color())
|
||||
return;
|
||||
background_color_ = color;
|
||||
|
||||
bool opaque = SkColorGetA(color) == SK_AlphaOPAQUE;
|
||||
GetRootLayer()->SetFillsBoundsOpaquely(opaque);
|
||||
GetRootLayer()->SetColor(color);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
#include "cc/output/compositor_frame.h"
|
||||
#include "cc/scheduler/begin_frame_source.h"
|
||||
#include "content/browser/frame_host/render_widget_host_view_guest.h"
|
||||
#include "content/browser/renderer_host/compositor_resize_lock.h"
|
||||
#include "content/browser/renderer_host/delegated_frame_host.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_view_base.h"
|
||||
#include "content/browser/renderer_host/resize_lock.h"
|
||||
#include "content/browser/web_contents/web_contents_view.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "third_party/WebKit/public/platform/WebVector.h"
|
||||
@@ -68,12 +68,13 @@ class OffScreenRenderWidgetHostView
|
||||
public ui::CompositorDelegate,
|
||||
#if !defined(OS_MACOSX)
|
||||
public content::DelegatedFrameHostClient,
|
||||
public content::CompositorResizeLockClient,
|
||||
#endif
|
||||
public NativeWindowObserver,
|
||||
public OffscreenViewProxyObserver {
|
||||
public:
|
||||
OffScreenRenderWidgetHostView(bool transparent,
|
||||
bool painting,
|
||||
int frame_rate,
|
||||
const OnPaintCallback& callback,
|
||||
content::RenderWidgetHost* render_widget_host,
|
||||
OffScreenRenderWidgetHostView* parent_host_view,
|
||||
@@ -100,7 +101,6 @@ class OffScreenRenderWidgetHostView
|
||||
gfx::Size GetVisibleViewportSize() const override;
|
||||
void SetInsets(const gfx::Insets&) override;
|
||||
void SetBackgroundColor(SkColor color) override;
|
||||
SkColor background_color() const override;
|
||||
bool LockMouse(void) override;
|
||||
void UnlockMouse(void) override;
|
||||
void SetNeedsBeginFrames(bool needs_begin_frames) override;
|
||||
@@ -115,12 +115,8 @@ class OffScreenRenderWidgetHostView
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
// content::RenderWidgetHostViewBase:
|
||||
void DidCreateNewRendererCompositorFrameSink(
|
||||
cc::mojom::MojoCompositorFrameSinkClient* renderer_compositor_frame_sink)
|
||||
override;
|
||||
void SubmitCompositorFrame(const cc::LocalSurfaceId& local_surface_id,
|
||||
cc::CompositorFrame frame) override;
|
||||
|
||||
void OnSwapCompositorFrame(uint32_t, cc::CompositorFrame)
|
||||
override;
|
||||
void ClearCompositorFrame(void) override;
|
||||
void InitAsPopup(content::RenderWidgetHostView *rwhv, const gfx::Rect& rect)
|
||||
override;
|
||||
@@ -173,14 +169,15 @@ class OffScreenRenderWidgetHostView
|
||||
bool DelegatedFrameHostIsVisible(void) const override;
|
||||
SkColor DelegatedFrameHostGetGutterColor(SkColor) const override;
|
||||
gfx::Size DelegatedFrameHostDesiredSizeInDIP(void) const override;
|
||||
bool DelegatedFrameCanCreateResizeLock() const override;
|
||||
std::unique_ptr<content::CompositorResizeLock>
|
||||
DelegatedFrameHostCreateResizeLock() override;
|
||||
void OnBeginFrame(const cc::BeginFrameArgs& args) override;
|
||||
// CompositorResizeLockClient implementation.
|
||||
std::unique_ptr<ui::CompositorLock> GetCompositorLock(
|
||||
ui::CompositorLockClient* client) override;
|
||||
void CompositorResizeLockEnded() override;
|
||||
bool DelegatedFrameCanCreateResizeLock(void) const override;
|
||||
std::unique_ptr<content::ResizeLock> DelegatedFrameHostCreateResizeLock(
|
||||
bool defer_compositor_lock) override;
|
||||
void DelegatedFrameHostResizeLockWasReleased(void) override;
|
||||
void DelegatedFrameHostSendReclaimCompositorResources(
|
||||
int output_surface_id,
|
||||
bool is_swap_ack,
|
||||
const cc::ReturnedResourceArray& resources) override;
|
||||
void SetBeginFrameSource(cc::BeginFrameSource* source) override;
|
||||
#endif // !defined(OS_MACOSX)
|
||||
|
||||
bool TransformPointToLocalCoordSpace(
|
||||
@@ -229,7 +226,7 @@ class OffScreenRenderWidgetHostView
|
||||
void OnProxyViewPaint(const gfx::Rect& damage_rect);
|
||||
|
||||
bool IsPopupWidget() const {
|
||||
return popup_type_ != blink::kWebPopupTypeNone;
|
||||
return popup_type_ != blink::WebPopupTypeNone;
|
||||
}
|
||||
|
||||
void HoldResize();
|
||||
@@ -276,10 +273,6 @@ class OffScreenRenderWidgetHostView
|
||||
|
||||
cc::FrameSinkId AllocateFrameSinkId(bool is_guest_view_hack);
|
||||
|
||||
// Applies background color without notifying the RenderWidget about
|
||||
// opaqueness changes.
|
||||
void UpdateBackgroundColorFromRenderer(SkColor color);
|
||||
|
||||
// Weak ptrs.
|
||||
content::RenderWidgetHostImpl* render_widget_host_;
|
||||
|
||||
@@ -314,6 +307,8 @@ class OffScreenRenderWidgetHostView
|
||||
bool hold_resize_;
|
||||
bool pending_resize_;
|
||||
|
||||
bool paint_callback_running_;
|
||||
|
||||
std::unique_ptr<ui::Layer> root_layer_;
|
||||
std::unique_ptr<ui::Compositor> compositor_;
|
||||
std::unique_ptr<content::DelegatedFrameHost> delegated_frame_host_;
|
||||
@@ -337,10 +332,6 @@ class OffScreenRenderWidgetHostView
|
||||
std::string selected_text_;
|
||||
#endif
|
||||
|
||||
cc::mojom::MojoCompositorFrameSinkClient* renderer_compositor_frame_sink_;
|
||||
|
||||
SkColor background_color_;
|
||||
|
||||
base::WeakPtrFactory<OffScreenRenderWidgetHostView> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(OffScreenRenderWidgetHostView);
|
||||
|
||||
@@ -38,6 +38,15 @@ class MacHelper :
|
||||
return color;
|
||||
}
|
||||
|
||||
void BrowserCompositorMacSendReclaimCompositorResources(
|
||||
int output_surface_id,
|
||||
bool is_swap_ack,
|
||||
const cc::ReturnedResourceArray& resources) override {
|
||||
view_->render_widget_host()->Send(new ViewMsg_ReclaimCompositorResources(
|
||||
view_->render_widget_host()->GetRoutingID(), output_surface_id,
|
||||
is_swap_ack, resources));
|
||||
}
|
||||
|
||||
void BrowserCompositorMacSendBeginFrame(
|
||||
const cc::BeginFrameArgs& args) override {
|
||||
view_->render_widget_host()->Send(
|
||||
|
||||
@@ -15,6 +15,8 @@ namespace atom {
|
||||
OffScreenWebContentsView::OffScreenWebContentsView(
|
||||
bool transparent, const OnPaintCallback& callback)
|
||||
: transparent_(transparent),
|
||||
painting_(true),
|
||||
frame_rate_(60),
|
||||
callback_(callback),
|
||||
web_contents_(nullptr) {
|
||||
#if defined(OS_MACOSX)
|
||||
@@ -103,6 +105,8 @@ content::RenderWidgetHostViewBase*
|
||||
auto relay = NativeWindowRelay::FromWebContents(web_contents_);
|
||||
return new OffScreenRenderWidgetHostView(
|
||||
transparent_,
|
||||
painting_,
|
||||
GetFrameRate(),
|
||||
callback_,
|
||||
render_widget_host,
|
||||
nullptr,
|
||||
@@ -125,6 +129,8 @@ content::RenderWidgetHostViewBase*
|
||||
|
||||
return new OffScreenRenderWidgetHostView(
|
||||
transparent_,
|
||||
true,
|
||||
view->GetFrameRate(),
|
||||
callback_,
|
||||
render_widget_host,
|
||||
view,
|
||||
@@ -202,6 +208,42 @@ void OffScreenWebContentsView::UpdateDragCursor(
|
||||
blink::WebDragOperation operation) {
|
||||
}
|
||||
|
||||
void OffScreenWebContentsView::SetPainting(bool painting) {
|
||||
auto* view = GetView();
|
||||
if (view != nullptr) {
|
||||
view->SetPainting(painting);
|
||||
} else {
|
||||
painting_ = painting;
|
||||
}
|
||||
}
|
||||
|
||||
bool OffScreenWebContentsView::IsPainting() const {
|
||||
auto* view = GetView();
|
||||
if (view != nullptr) {
|
||||
return view->IsPainting();
|
||||
} else {
|
||||
return painting_;
|
||||
}
|
||||
}
|
||||
|
||||
void OffScreenWebContentsView::SetFrameRate(int frame_rate) {
|
||||
auto* view = GetView();
|
||||
if (view != nullptr) {
|
||||
view->SetFrameRate(frame_rate);
|
||||
} else {
|
||||
frame_rate_ = frame_rate;
|
||||
}
|
||||
}
|
||||
|
||||
int OffScreenWebContentsView::GetFrameRate() const {
|
||||
auto* view = GetView();
|
||||
if (view != nullptr) {
|
||||
return view->GetFrameRate();
|
||||
} else {
|
||||
return frame_rate_;
|
||||
}
|
||||
}
|
||||
|
||||
OffScreenRenderWidgetHostView* OffScreenWebContentsView::GetView() const {
|
||||
if (web_contents_) {
|
||||
return static_cast<OffScreenRenderWidgetHostView*>(
|
||||
|
||||
@@ -69,6 +69,11 @@ class OffScreenWebContentsView : public content::WebContentsView,
|
||||
content::RenderWidgetHostImpl* source_rwh) override;
|
||||
void UpdateDragCursor(blink::WebDragOperation operation) override;
|
||||
|
||||
void SetPainting(bool painting);
|
||||
bool IsPainting() const;
|
||||
void SetFrameRate(int frame_rate);
|
||||
int GetFrameRate() const;
|
||||
|
||||
private:
|
||||
#if defined(OS_MACOSX)
|
||||
void PlatformCreate();
|
||||
@@ -78,6 +83,8 @@ class OffScreenWebContentsView : public content::WebContentsView,
|
||||
OffScreenRenderWidgetHostView* GetView() const;
|
||||
|
||||
const bool transparent_;
|
||||
bool painting_;
|
||||
int frame_rate_;
|
||||
OnPaintCallback callback_;
|
||||
|
||||
// Weak refs.
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>electron.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.8.2</string>
|
||||
<string>1.7.16</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.8.2</string>
|
||||
<string>1.7.16</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,0
|
||||
PRODUCTVERSION 1,8,2,0
|
||||
FILEVERSION 1,7,16,0
|
||||
PRODUCTVERSION 1,7,16,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", "1.7.16"
|
||||
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", "1.7.16"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -155,6 +155,7 @@ void AutofillPopup::SetItems(const std::vector<base::string16>& values,
|
||||
const std::vector<base::string16>& labels) {
|
||||
values_ = values;
|
||||
labels_ = labels;
|
||||
UpdatePopupBounds();
|
||||
if (view_) {
|
||||
view_->OnSuggestionsChanged();
|
||||
}
|
||||
@@ -165,23 +166,21 @@ void AutofillPopup::AcceptSuggestion(int index) {
|
||||
frame_host_->GetRoutingID(), GetValueAt(index)));
|
||||
}
|
||||
|
||||
void AutofillPopup::UpdatePopupBounds(int height_compensation) {
|
||||
void AutofillPopup::UpdatePopupBounds() {
|
||||
int desired_width = GetDesiredPopupWidth();
|
||||
int desired_height = GetDesiredPopupHeight();
|
||||
bool is_rtl = false;
|
||||
|
||||
gfx::Point origin(element_bounds_.origin().x(),
|
||||
element_bounds_.origin().y() - height_compensation);
|
||||
gfx::Rect bounds(origin, element_bounds_.size());
|
||||
|
||||
gfx::Point top_left_corner_of_popup =
|
||||
origin + gfx::Vector2d(bounds.width() - desired_width, -desired_height);
|
||||
element_bounds_.origin() +
|
||||
gfx::Vector2d(element_bounds_.width() - desired_width, -desired_height);
|
||||
|
||||
// This is the bottom right point of the popup if the popup is below the
|
||||
// element and grows to the right (since the is the lowest and furthest right
|
||||
// the popup could go).
|
||||
gfx::Point bottom_right_corner_of_popup =
|
||||
origin + gfx::Vector2d(desired_width, bounds.height() + desired_height);
|
||||
element_bounds_.origin() +
|
||||
gfx::Vector2d(desired_width, element_bounds_.height() + desired_height);
|
||||
|
||||
display::Display top_left_display =
|
||||
GetDisplayNearestPoint(top_left_corner_of_popup, container_view_);
|
||||
@@ -190,19 +189,14 @@ void AutofillPopup::UpdatePopupBounds(int height_compensation) {
|
||||
|
||||
std::pair<int, int> popup_x_and_width =
|
||||
CalculatePopupXAndWidth(top_left_display, bottom_right_display,
|
||||
desired_width, bounds, is_rtl);
|
||||
std::pair<int, int> popup_y_and_height =
|
||||
CalculatePopupYAndHeight(top_left_display, bottom_right_display,
|
||||
desired_height, bounds);
|
||||
desired_width, element_bounds_, is_rtl);
|
||||
std::pair<int, int> popup_y_and_height = CalculatePopupYAndHeight(
|
||||
top_left_display, bottom_right_display, desired_height, element_bounds_);
|
||||
|
||||
popup_bounds_ = gfx::Rect(
|
||||
popup_x_and_width.first, popup_y_and_height.first,
|
||||
popup_bounds_ = gfx::Rect(popup_x_and_width.first, popup_y_and_height.first,
|
||||
popup_x_and_width.second, popup_y_and_height.second);
|
||||
popup_bounds_in_view_ = gfx::Rect(
|
||||
popup_bounds_in_view_.origin(),
|
||||
popup_bounds_in_view_ = gfx::Rect(popup_bounds_in_view_.origin(),
|
||||
gfx::Size(popup_x_and_width.second, popup_y_and_height.second));
|
||||
if (view_)
|
||||
view_->DoUpdateBoundsAndRedrawPopup();
|
||||
}
|
||||
|
||||
int AutofillPopup::GetDesiredPopupHeight() {
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "ui/gfx/font_list.h"
|
||||
#include "ui/native_theme/native_theme.h"
|
||||
#include "ui/views/view.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
|
||||
namespace atom {
|
||||
@@ -29,13 +28,13 @@ class AutofillPopup {
|
||||
|
||||
void SetItems(const std::vector<base::string16>& values,
|
||||
const std::vector<base::string16>& labels);
|
||||
void UpdatePopupBounds(int height_compensation);
|
||||
|
||||
private:
|
||||
friend class AutofillPopupView;
|
||||
|
||||
void AcceptSuggestion(int index);
|
||||
|
||||
void UpdatePopupBounds();
|
||||
int GetDesiredPopupHeight();
|
||||
int GetDesiredPopupWidth();
|
||||
gfx::Rect GetRowBounds(int i);
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "net/cert/cert_database.h"
|
||||
#include "net/cert/x509_util_mac.h"
|
||||
|
||||
@interface TrustDelegate : NSObject {
|
||||
@private
|
||||
@@ -86,8 +85,7 @@ void ShowCertificateTrust(atom::NativeWindow* parent_window,
|
||||
const std::string& message,
|
||||
const ShowTrustCallback& callback) {
|
||||
auto sec_policy = SecPolicyCreateBasicX509();
|
||||
auto cert_chain =
|
||||
net::x509_util::CreateSecCertificateArrayForX509Certificate(cert.get());
|
||||
auto cert_chain = cert->CreateOSCertChainForCert();
|
||||
SecTrustRef trust = nullptr;
|
||||
SecTrustCreateWithCertificates(cert_chain, sec_policy, &trust);
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_COCOA_ATOM_BUNDLE_MOVER_H_
|
||||
#define ATOM_BROWSER_UI_COCOA_ATOM_BUNDLE_MOVER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "native_mate/persistent_dictionary.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace ui {
|
||||
|
||||
namespace cocoa {
|
||||
|
||||
class AtomBundleMover {
|
||||
public:
|
||||
static bool Move(mate::Arguments* args);
|
||||
static bool IsCurrentAppInApplicationsFolder();
|
||||
|
||||
private:
|
||||
static bool IsInApplicationsFolder(NSString* bundlePath);
|
||||
static NSString* ContainingDiskImageDevice(NSString* bundlePath);
|
||||
static void Relaunch(NSString* destinationPath);
|
||||
static NSString* ShellQuotedString(NSString* string);
|
||||
static bool CopyBundle(NSString* srcPath, NSString* dstPath);
|
||||
static bool AuthorizedInstall(NSString* srcPath, NSString* dstPath,
|
||||
bool* canceled);
|
||||
static bool IsApplicationAtPathRunning(NSString* bundlePath);
|
||||
static bool DeleteOrTrash(NSString* path);
|
||||
static bool Trash(NSString* path);
|
||||
};
|
||||
|
||||
} // namespace cocoa
|
||||
|
||||
} // namespace ui
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_UI_COCOA_ATOM_BUNDLE_MOVER_H_
|
||||
@@ -1,345 +0,0 @@
|
||||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "atom/browser/ui/cocoa/atom_bundle_mover.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Security/Security.h>
|
||||
#import <dlfcn.h>
|
||||
#import <sys/param.h>
|
||||
#import <sys/mount.h>
|
||||
|
||||
#import "atom/browser/browser.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace ui {
|
||||
|
||||
namespace cocoa {
|
||||
|
||||
bool AtomBundleMover::Move(mate::Arguments* args) {
|
||||
// Path of the current bundle
|
||||
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
|
||||
|
||||
// Skip if the application is already in the Applications folder
|
||||
if (IsInApplicationsFolder(bundlePath)) return true;
|
||||
|
||||
NSFileManager* fileManager = [NSFileManager defaultManager];
|
||||
|
||||
NSString* diskImageDevice = ContainingDiskImageDevice(bundlePath);
|
||||
|
||||
NSString *applicationsDirectory = [[NSSearchPathForDirectoriesInDomains(NSApplicationDirectory, NSLocalDomainMask, true) lastObject] stringByResolvingSymlinksInPath];
|
||||
NSString *bundleName = [bundlePath lastPathComponent];
|
||||
NSString *destinationPath = [applicationsDirectory stringByAppendingPathComponent:bundleName];
|
||||
|
||||
// Check if we can write to the applications directory
|
||||
// and then make sure that if the app already exists we can overwrite it
|
||||
bool needAuthorization = ![fileManager isWritableFileAtPath:applicationsDirectory]
|
||||
| ([fileManager fileExistsAtPath:destinationPath] && ![fileManager isWritableFileAtPath:destinationPath]);
|
||||
|
||||
// Activate app -- work-around for focus issues related to "scary file from internet" OS dialog.
|
||||
if (![NSApp isActive]) {
|
||||
[NSApp activateIgnoringOtherApps:true];
|
||||
}
|
||||
|
||||
// Move to applications folder
|
||||
if (needAuthorization) {
|
||||
bool authorizationCanceled;
|
||||
|
||||
if (!AuthorizedInstall(bundlePath, destinationPath, &authorizationCanceled)) {
|
||||
if (authorizationCanceled) {
|
||||
// User rejected the authorization request
|
||||
args->ThrowError("User rejected the authorization request");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
args->ThrowError("Failed to copy to applications directory even with authorization");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If a copy already exists in the Applications folder, put it in the Trash
|
||||
if ([fileManager fileExistsAtPath:destinationPath]) {
|
||||
// But first, make sure that it's not running
|
||||
if (IsApplicationAtPathRunning(destinationPath)) {
|
||||
// Give the running app focus and terminate myself
|
||||
[[NSTask launchedTaskWithLaunchPath:@"/usr/bin/open" arguments:[NSArray arrayWithObject:destinationPath]] waitUntilExit];
|
||||
atom::Browser::Get()->Quit();
|
||||
return true;
|
||||
} else {
|
||||
if (!Trash([applicationsDirectory stringByAppendingPathComponent:bundleName])) {
|
||||
args->ThrowError("Failed to delete existing application");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!CopyBundle(bundlePath, destinationPath)) {
|
||||
args->ThrowError("Failed to copy current bundle to the applications folder");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Trash the original app. It's okay if this fails.
|
||||
// NOTE: This final delete does not work if the source bundle is in a network mounted volume.
|
||||
// Calling rm or file manager's delete method doesn't work either. It's unlikely to happen
|
||||
// but it'd be great if someone could fix this.
|
||||
if (diskImageDevice == nil && !DeleteOrTrash(bundlePath)) {
|
||||
// Could not delete original but we just don't care
|
||||
}
|
||||
|
||||
// Relaunch.
|
||||
Relaunch(destinationPath);
|
||||
|
||||
// Launched from within a disk image? -- unmount (if no files are open after 5 seconds,
|
||||
// otherwise leave it mounted).
|
||||
if (diskImageDevice) {
|
||||
NSString *script = [NSString stringWithFormat:@"(/bin/sleep 5 && /usr/bin/hdiutil detach %@) &", ShellQuotedString(diskImageDevice)];
|
||||
[NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:[NSArray arrayWithObjects:@"-c", script, nil]];
|
||||
}
|
||||
|
||||
atom::Browser::Get()->Quit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtomBundleMover::IsCurrentAppInApplicationsFolder() {
|
||||
return IsInApplicationsFolder([[NSBundle mainBundle] bundlePath]);
|
||||
}
|
||||
|
||||
bool AtomBundleMover::IsInApplicationsFolder(NSString* bundlePath) {
|
||||
// Check all the normal Application directories
|
||||
NSArray* applicationDirs = NSSearchPathForDirectoriesInDomains(NSApplicationDirectory, NSAllDomainsMask, true);
|
||||
for (NSString* appDir in applicationDirs) {
|
||||
if ([bundlePath hasPrefix:appDir]) return true;
|
||||
}
|
||||
|
||||
// Also, handle the case that the user has some other Application directory (perhaps on a separate data partition).
|
||||
if ([[bundlePath pathComponents] containsObject:@"Applications"]) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
NSString* AtomBundleMover::ContainingDiskImageDevice(NSString* bundlePath) {
|
||||
NSString* containingPath = [bundlePath stringByDeletingLastPathComponent];
|
||||
|
||||
struct statfs fs;
|
||||
if (statfs([containingPath fileSystemRepresentation], &fs) || (fs.f_flags & MNT_ROOTFS))
|
||||
return nil;
|
||||
|
||||
NSString *device = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:fs.f_mntfromname length:strlen(fs.f_mntfromname)];
|
||||
|
||||
NSTask *hdiutil = [[[NSTask alloc] init] autorelease];
|
||||
[hdiutil setLaunchPath:@"/usr/bin/hdiutil"];
|
||||
[hdiutil setArguments:[NSArray arrayWithObjects:@"info", @"-plist", nil]];
|
||||
[hdiutil setStandardOutput:[NSPipe pipe]];
|
||||
[hdiutil launch];
|
||||
[hdiutil waitUntilExit];
|
||||
|
||||
NSData *data = [[[hdiutil standardOutput] fileHandleForReading] readDataToEndOfFile];
|
||||
|
||||
NSDictionary *info = nil;
|
||||
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5) {
|
||||
info = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListImmutable format:NULL error:NULL];
|
||||
} else {
|
||||
info = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:NSPropertyListImmutable format:NULL errorDescription:NULL];
|
||||
}
|
||||
|
||||
if (![info isKindOfClass:[NSDictionary class]]) return nil;
|
||||
|
||||
NSArray *images = (NSArray *)[info objectForKey:@"images"];
|
||||
if (![images isKindOfClass:[NSArray class]]) return nil;
|
||||
|
||||
for (NSDictionary *image in images) {
|
||||
if (![image isKindOfClass:[NSDictionary class]]) return nil;
|
||||
|
||||
id systemEntities = [image objectForKey:@"system-entities"];
|
||||
if (![systemEntities isKindOfClass:[NSArray class]]) return nil;
|
||||
|
||||
for (NSDictionary *systemEntity in systemEntities) {
|
||||
if (![systemEntity isKindOfClass:[NSDictionary class]]) return nil;
|
||||
|
||||
NSString *devEntry = [systemEntity objectForKey:@"dev-entry"];
|
||||
if (![devEntry isKindOfClass:[NSString class]]) return nil;
|
||||
|
||||
if ([devEntry isEqualToString:device])
|
||||
return device;
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
bool AtomBundleMover::AuthorizedInstall(NSString* srcPath, NSString* dstPath, bool* canceled) {
|
||||
if (canceled) *canceled = false;
|
||||
|
||||
// Make sure that the destination path is an app bundle. We're essentially running 'sudo rm -rf'
|
||||
// so we really don't want to screw this up.
|
||||
if (![[dstPath pathExtension] isEqualToString:@"app"]) return false;
|
||||
|
||||
// Do some more checks
|
||||
if ([[dstPath stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0) return false;
|
||||
if ([[srcPath stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0) return false;
|
||||
|
||||
int pid, status;
|
||||
AuthorizationRef myAuthorizationRef;
|
||||
|
||||
// Get the authorization
|
||||
OSStatus err = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &myAuthorizationRef);
|
||||
if (err != errAuthorizationSuccess) return false;
|
||||
|
||||
AuthorizationItem myItems = {kAuthorizationRightExecute, 0, NULL, 0};
|
||||
AuthorizationRights myRights = {1, &myItems};
|
||||
AuthorizationFlags myFlags = (AuthorizationFlags)(kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights | kAuthorizationFlagPreAuthorize);
|
||||
|
||||
err = AuthorizationCopyRights(myAuthorizationRef, &myRights, NULL, myFlags, NULL);
|
||||
if (err != errAuthorizationSuccess) {
|
||||
if (err == errAuthorizationCanceled && canceled)
|
||||
*canceled = true;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
static OSStatus (*security_AuthorizationExecuteWithPrivileges)(AuthorizationRef authorization, const char *pathToTool,
|
||||
AuthorizationFlags options, char * const *arguments,
|
||||
FILE **communicationsPipe) = NULL;
|
||||
if (!security_AuthorizationExecuteWithPrivileges) {
|
||||
// On 10.7, AuthorizationExecuteWithPrivileges is deprecated. We want to still use it since there's no
|
||||
// good alternative (without requiring code signing). We'll look up the function through dyld and fail
|
||||
// if it is no longer accessible. If Apple removes the function entirely this will fail gracefully. If
|
||||
// they keep the function and throw some sort of exception, this won't fail gracefully, but that's a
|
||||
// risk we'll have to take for now.
|
||||
security_AuthorizationExecuteWithPrivileges = (OSStatus (*)(AuthorizationRef, const char*,
|
||||
AuthorizationFlags, char* const*,
|
||||
FILE **)) dlsym(RTLD_DEFAULT, "AuthorizationExecuteWithPrivileges");
|
||||
}
|
||||
if (!security_AuthorizationExecuteWithPrivileges) goto fail;
|
||||
|
||||
// Delete the destination
|
||||
{
|
||||
char rf[] = "-rf";
|
||||
char *args[] = {rf, (char *)[dstPath fileSystemRepresentation], NULL};
|
||||
err = security_AuthorizationExecuteWithPrivileges(myAuthorizationRef, "/bin/rm", kAuthorizationFlagDefaults, args, NULL);
|
||||
if (err != errAuthorizationSuccess) goto fail;
|
||||
|
||||
// Wait until it's done
|
||||
pid = wait(&status);
|
||||
if (pid == -1 || !WIFEXITED(status)) goto fail; // We don't care about exit status as the destination most likely does not exist
|
||||
}
|
||||
|
||||
// Copy
|
||||
{
|
||||
char pR[] = "-pR";
|
||||
char *args[] = {pR, (char *)[srcPath fileSystemRepresentation], (char *)[dstPath fileSystemRepresentation], NULL};
|
||||
err = security_AuthorizationExecuteWithPrivileges(myAuthorizationRef, "/bin/cp", kAuthorizationFlagDefaults, args, NULL);
|
||||
if (err != errAuthorizationSuccess) goto fail;
|
||||
|
||||
// Wait until it's done
|
||||
pid = wait(&status);
|
||||
if (pid == -1 || !WIFEXITED(status) || WEXITSTATUS(status)) goto fail;
|
||||
}
|
||||
|
||||
AuthorizationFree(myAuthorizationRef, kAuthorizationFlagDefaults);
|
||||
return true;
|
||||
|
||||
fail:
|
||||
AuthorizationFree(myAuthorizationRef, kAuthorizationFlagDefaults);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomBundleMover::CopyBundle(NSString* srcPath, NSString* dstPath) {
|
||||
NSFileManager* fileManager = [NSFileManager defaultManager];
|
||||
NSError* error = nil;
|
||||
|
||||
if ([fileManager copyItemAtPath:srcPath toPath:dstPath error:&error]) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
NSString* AtomBundleMover::ShellQuotedString(NSString* string) {
|
||||
return [NSString stringWithFormat:@"'%@'", [string stringByReplacingOccurrencesOfString:@"'" withString:@"'\\''"]];
|
||||
}
|
||||
|
||||
void AtomBundleMover::Relaunch(NSString* destinationPath) {
|
||||
// The shell script waits until the original app process terminates.
|
||||
// This is done so that the relaunched app opens as the front-most app.
|
||||
int pid = [[NSProcessInfo processInfo] processIdentifier];
|
||||
|
||||
// Command run just before running open /final/path
|
||||
NSString* preOpenCmd = @"";
|
||||
|
||||
NSString* quotedDestinationPath = ShellQuotedString(destinationPath);
|
||||
|
||||
// Before we launch the new app, clear xattr:com.apple.quarantine to avoid
|
||||
// duplicate "scary file from the internet" dialog.
|
||||
preOpenCmd = [NSString stringWithFormat:@"/usr/bin/xattr -d -r com.apple.quarantine %@", quotedDestinationPath];
|
||||
|
||||
NSString* script = [NSString stringWithFormat:@"(while /bin/kill -0 %d >&/dev/null; do /bin/sleep 0.1; done; %@; /usr/bin/open %@) &", pid, preOpenCmd, quotedDestinationPath];
|
||||
|
||||
[NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:[NSArray arrayWithObjects:@"-c", script, nil]];
|
||||
}
|
||||
|
||||
bool AtomBundleMover::IsApplicationAtPathRunning(NSString* bundlePath) {
|
||||
bundlePath = [bundlePath stringByStandardizingPath];
|
||||
|
||||
for (NSRunningApplication *runningApplication in [[NSWorkspace sharedWorkspace] runningApplications]) {
|
||||
NSString* runningAppBundlePath = [[[runningApplication bundleURL] path] stringByStandardizingPath];
|
||||
if ([runningAppBundlePath isEqualToString:bundlePath]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomBundleMover::Trash(NSString* path) {
|
||||
bool result = false;
|
||||
|
||||
if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_8) {
|
||||
result = [[NSFileManager defaultManager] trashItemAtURL:[NSURL fileURLWithPath:path] resultingItemURL:NULL error:NULL];
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
result = [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation
|
||||
source:[path stringByDeletingLastPathComponent]
|
||||
destination:@""
|
||||
files:[NSArray arrayWithObject:[path lastPathComponent]]
|
||||
tag:NULL];
|
||||
}
|
||||
|
||||
// As a last resort try trashing with AppleScript.
|
||||
// This allows us to trash the app in macOS Sierra even when the app is running inside
|
||||
// an app translocation image.
|
||||
if (!result) {
|
||||
NSAppleScript* appleScript = [[[NSAppleScript alloc] initWithSource:
|
||||
[NSString stringWithFormat:@"\
|
||||
set theFile to POSIX file \"%@\" \n\
|
||||
tell application \"Finder\" \n\
|
||||
move theFile to trash \n\
|
||||
end tell", path]] autorelease];
|
||||
NSDictionary* errorDict = nil;
|
||||
NSAppleEventDescriptor* scriptResult = [appleScript executeAndReturnError:&errorDict];
|
||||
result = (scriptResult != nil);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool AtomBundleMover::DeleteOrTrash(NSString* path) {
|
||||
NSError* error;
|
||||
|
||||
if ([[NSFileManager defaultManager] removeItemAtPath:path error:&error]) {
|
||||
return true;
|
||||
} else {
|
||||
return Trash(path);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cocoa
|
||||
|
||||
} // namespace ui
|
||||
|
||||
} // namespace atom
|
||||
@@ -45,11 +45,6 @@ Role kRolesMap[] = {
|
||||
{ @selector(performZoom:), "zoom" },
|
||||
{ @selector(terminate:), "quit" },
|
||||
{ @selector(toggleFullScreen:), "togglefullscreen" },
|
||||
{ @selector(toggleTabBar:), "toggletabbar" },
|
||||
{ @selector(selectNextTab:), "selectnexttab" },
|
||||
{ @selector(selectPreviousTab:), "selectprevioustab" },
|
||||
{ @selector(mergeAllWindows:), "mergeallwindows" },
|
||||
{ @selector(moveTabToNewWindow:), "movetabtonewwindow" },
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -143,7 +143,6 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
|
||||
}
|
||||
|
||||
- (void)setEscapeTouchBarItem:(const mate::PersistentDictionary&)item forTouchBar:(NSTouchBar*)touchBar {
|
||||
if (![touchBar respondsToSelector:@selector(escapeKeyReplacementItemIdentifier)]) return;
|
||||
std::string type;
|
||||
std::string item_id;
|
||||
NSTouchBarItemIdentifier identifier = nil;
|
||||
|
||||
@@ -7,13 +7,12 @@
|
||||
#include "ui/aura/client/drag_drop_client.h"
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/base/dragdrop/drag_drop_types.h"
|
||||
#include "ui/base/dragdrop/drag_utils.h"
|
||||
#include "ui/base/dragdrop/file_info.h"
|
||||
#include "ui/base/dragdrop/os_exchange_data.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
#include "ui/views/button_drag_utils.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -23,9 +22,7 @@ void DragFileItems(const std::vector<base::FilePath>& files,
|
||||
// Set up our OLE machinery
|
||||
ui::OSExchangeData data;
|
||||
|
||||
button_drag_utils::SetDragImage(GURL(), files[0].LossyDisplayName(),
|
||||
icon.AsImageSkia(), nullptr,
|
||||
*views::Widget::GetTopLevelWidgetForNativeView(view), &data);
|
||||
drag_utils::CreateDragImageForFile(files[0], icon.AsImageSkia(), &data);
|
||||
|
||||
std::vector<ui::FileInfo> file_infos;
|
||||
for (const base::FilePath& file : files) {
|
||||
|
||||
@@ -49,7 +49,6 @@ struct DialogSettings {
|
||||
Filters filters;
|
||||
int properties = 0;
|
||||
bool shows_tag_field = true;
|
||||
bool force_detached = false;
|
||||
};
|
||||
|
||||
bool ShowOpenDialog(const DialogSettings& settings,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user