Compare commits

..

87 Commits

Author SHA1 Message Date
John Kleinschmidt
9dcbbb08db v1.7.16 2018-08-22 16:36:54 -04:00
Samuel Attard
bab968ca77 fix: inheritance of webPreferences sub properties 2018-08-22 12:36:02 -05:00
Samuel Attard
7fa3eba951 chore: stop auto releasing from windows CI 2018-08-19 15:43:00 -07:00
John Kleinschmidt
c0efff45fa Merge pull request #14087 from electron/update-libcc-1-7-x
fix: Update to latest libcc for 1-7-x
2018-08-14 14:38:30 -07:00
John Kleinschmidt
5eac44126f Update to latest libcc
Fixes issue with bad libcc archive files in 1-7-x
2018-08-14 10:01:04 -07:00
John Kleinschmidt
b2cec7b602 Merge pull request #14083 from electron/appveyor-rename-1-7-x
ci: rename appveyor-override to appveyor
2018-08-14 09:54:26 -07:00
John Kleinschmidt
f6328a515d Rename appveyor-override to appveyor 2018-08-14 09:42:20 -07:00
Jeremy Apthorp
47fe11e281 chore: roll libcc (#13991) 2018-08-08 20:48:31 -05:00
trop[bot]
0be8732f03 Use Visual Studio 2015 for 2-0-x (#13609) 2018-07-10 10:30:38 -05:00
John Kleinschmidt
9c466846ed v1.7.15 2018-05-16 14:08:31 -04:00
John Kleinschmidt
67b75fe204 Merge pull request #12947 from electron/update-ci-1-7-x
Update CI for 1-7-x
2018-05-16 12:51:34 -04:00
John Kleinschmidt
ef6e045241 Update CI for 1-7-x
Remove custom appveyor config
Add mac builds to CircleCI
2018-05-16 11:39:52 -04:00
John Kleinschmidt
95f0eeeb37 Merge pull request #12928 from electron/disable-exec-stack_1-7-x
Disable executable stack in `electron` binary
2018-05-15 10:40:14 -04:00
Ales Pergl
dfa394ba29 Disable executable stack in electron binary 2018-05-14 20:48:35 -05:00
Charles Kerr
5f6997caee update command-line backlist switches (1.7.x) (#12808)
Do a better job of finding edge cases, e.g. network_switch_list.h

**NB: This can't be tropped** because the list is dependent on the libcc version
2018-05-14 17:16:03 -05:00
John Kleinschmidt
fed76dcfaa v1.7.14 2018-04-26 20:47:01 -04:00
trop[bot]
42d284607e net: change mime type deduction in Change URLRequestAsarJob (#12383) 2018-04-06 11:16:25 -05:00
Shelley Vohr
3e2fff287a Update CI to use Node 8 (#12357) 2018-04-06 08:52:57 -05:00
John Kleinschmidt
11ce66b79a v1.7.13 2018-03-15 10:28:46 -04:00
Samuel Attard
1a48ee2827 Backport (1-7-x) - Set appropriate defaults for webview options (#12294)
* Fix NIB.

* Fix up tests
2018-03-15 15:34:56 +09:00
Alexey Kuzmin
413519b081 Update to the latest libcc from electron-1-7-x (#12203)
* Update to the latest libcc from electron-1-7-x

* Use electron-typescript-definitions 1.2.x
2018-03-12 09:28:16 +09:00
Samuel Attard
d701526a55 Merge pull request #11730 from brenca/osr-gpu-update-1-7-x
Improve OSR API (1-7-x)
2018-02-13 05:36:31 +11:00
John Kleinschmidt
924e372def v1.7.12 2018-01-31 14:46:48 -07:00
John Kleinschmidt
a27b7d1f10 Merge pull request #11785 from electron/case-insensitive-comparison-1-7-x
Do case insensitive comparisons
2018-01-31 12:58:06 -05:00
John Kleinschmidt
d3d8c1626a Merge pull request #11775 from electron/parallel-releases-1-7-x
Parallel releases for 1-7-x
2018-01-31 12:39:14 -05:00
Samuel Attard
8b6aa225ae Do case insensitive comparisons 2018-01-31 10:38:21 -07:00
John Kleinschmidt
e02440e0d8 Allow multiple releases to run at once
Find draft release by draft flag and tag name
2018-01-30 17:52:58 -07:00
Heilig Benedek
cd5bdc88c3 Remove web_contents_impl() helper to clarify code and remove unnecessary guard 2018-01-26 10:32:20 +01:00
Heilig Benedek
9021989cfd Move OSR api to OsrWCV to allow api calls to take effect sooner 2018-01-25 15:31:57 +01:00
Heilig Benedek
4a61a8dd34 Call SetAuthoritativeVsyncInterval on the Compositor directly 2018-01-25 15:31:27 +01:00
Heilig Benedek
04efcac8cc Raise maximum OSR framerate to 240 2018-01-25 15:31:18 +01:00
Heilig Benedek
6f27d5dd51 Don't generate a frame with GPU OSR if IsPainting is false 2018-01-25 15:31:04 +01:00
Heilig Benedek
7fb00bfca7 Don't generate a paint when StartPainting is called inside paint cb 2018-01-25 15:29:17 +01:00
Heilig Benedek
b22734ccc1 Use null accelerated widget to avoid showing GPU accelerated OSR surface 2018-01-25 15:24:20 +01:00
John Kleinschmidt
a69a5de12f v1.7.11 2018-01-22 17:24:59 -05:00
Charles Kerr
d2a9ea4684 fix 'npm lint' errors 2018-01-22 15:21:39 -06:00
Aleš Pergl
e7074c5cdb Disallow launching unknown apps via browser client.
CVE-2018-1000006
2018-01-22 14:53:17 -06:00
Cheng Zhao
97349eb30a Merge pull request #11576 from dengyaolong/bugfix/1-7-x/ime-crash
fix mac ime crack
2018-01-18 16:05:23 +09:00
allenliu
f6c915bbb5 fix mac ime crack 2018-01-05 22:06:00 +08:00
John Kleinschmidt
378666668f v1.7.10 2017-12-18 15:23:57 -05:00
John Kleinschmidt
9623329cbd Merge pull request #11427 from electron/prepare-for-release
Preparation for 1.7.10 release
2017-12-18 13:20:31 -05:00
John Kleinschmidt
34b75e5e73 Update to use new release scripts 2017-12-13 11:54:23 -05:00
John Kleinschmidt
c339e576a8 Update libcc 2017-12-13 10:44:20 -05:00
Charles Kerr
c12d88fc30 Merge pull request #11327 from electron/cherry/1-7-x/10540
Cherry #10540
2017-12-04 10:43:49 -06:00
Benjamin Pasero
8f2064d9b7 set iconPosition as optional 2017-12-04 10:04:29 -06:00
Charles Kerr
75ff5d2a45 Merge pull request #11141 from electron/backport-scrubber-width-fix
Backport scrubber width fix to 1-7-x
2017-11-17 14:31:54 -06:00
John Kleinschmidt
87565e25eb Add Jenkinsfile for macOS CI 2017-11-17 10:58:26 -05:00
Samuel Attard
d0c9c4028e Forward declare the scrubber layout 2017-11-17 06:21:36 +11:00
Armagan Amcalar
37f23f6d4e Make ScrubberItem width dynamic
Depending on whether a ScrubberItem has text or an icon, this changeset
calculates the actual width and sizes the TouchBar items accordingly.
Previously, all ScrubberItems, regardless of their content, had a static
width of 50px.

This commit also fixes #10539.
2017-11-17 06:19:19 +11:00
Charles Kerr
4b8f3276b5 Merge pull request #11020 from pfrazee/fix-protocol-crash-error-17x
Fix crash in custom protocols caused by bad callback exec
2017-11-16 09:36:38 -06:00
Charles Kerr
b15c418c54 Merge pull request #10898 from electron/nvidia-high-sierra-17x-fix
Fix rendering issues with Nvidia GPU on High Sierra for 1.7.x
2017-11-13 17:49:30 -06:00
Paul Frazee
d964560990 Fix crash in custom protocols caused by bad callback exec 2017-11-05 12:20:46 -06:00
John Kleinschmidt
66e0e8fdcd Fix rendering issues with Nvidia GPU on High Sierra 2017-10-24 13:48:39 -04:00
John Kleinschmidt
c16498c274 Bump v1.7.9 2017-10-10 15:33:41 -04:00
John Kleinschmidt
62bd339b0d Merge pull request #10743 from electron/crankshaft-fix
Crankshaft RCE fix
2017-10-10 15:04:29 -04:00
John Kleinschmidt
0368460d74 Crankshaft RCE fix 2017-10-10 13:23:31 -04:00
John Kleinschmidt
9386de415a Merge pull request #10687 from electron/circleci-report-testing-results
CircleCI report testing results
2017-10-04 10:41:10 -04:00
John Kleinschmidt
4d3d7aa5fd Improve CircleCI test results 2017-10-04 10:01:09 -04:00
John Kleinschmidt
1d0dfd590b Release process updates for 1-7-x (#10643)
* Add prerelease script

* Update CircleCI for releases

* Rerun builds
2017-09-28 10:48:02 -04:00
Birunthan Mohanathas
5b679cb1eb Merge pull request #10630 from electron/squirrel-avoid-double-update-1-7
Use Squirrel.Windows --checkForUpdate (1.7.x)
2017-09-27 21:20:22 +03:00
J.M
8c28e3b6f1 Use Squirrel.Windows --checkForUpdate
This cherry-picks #10483 to fix #5057.
2017-09-27 20:32:58 +03:00
Birunthan Mohanathas
f786199d2c Merge pull request #10628 from electron/squirrel-mac-bump
Bump external binaries to 1.2.2
2017-09-27 16:06:03 +03:00
Josh Abernathy
acfc24e45e Bump external binaries to 1.2.2 2017-09-27 16:04:05 +03:00
John Kleinschmidt
01ca2252cd Bump v1.7.8 2017-09-24 10:34:18 +09:00
John Kleinschmidt
53db3862c0 Merge pull request #10591 from electron/disable-app-importcertificate-tests
disable flaky app.importCertificate and select-client-certificate tests
2017-09-24 10:25:57 +09:00
John Kleinschmidt
6099ab222e Change GitHub upload to use JS GitHub lib 2017-09-24 10:17:15 +09:00
Zeke Sikelianos
830cc7ecd1 disable select-client-certificate spec 2017-09-24 10:00:34 +09:00
Zeke Sikelianos
eef8ff09e2 disable flaky app.importCertificate tests 2017-09-24 09:49:48 +09:00
Samuel Attard
b15392e1c1 Backporting changes for 1.7.8 (#10586)
* Fix app.makeSingleInstance hanging on posix systems

Wait for the IO thread to be a thing before attempting to listen on the socket

Fixes #9880

* Move OnBrowserReady call to PreMainMessageLoopRun to account for timing issues on macOS

* Woops, how did that happen ;)

* Refactor as per @zcbenz comments

Also fix issue where we run the single instance callback *not* on the UI thread,
this apparently results in a hung process.

* Appease the linting gods

* Create watcher when message loop is ready

* spec: Add test case for app.makeSingleInstance

* Fix missing extension when saving a file without filters

Previously, when triggering the save dialog through e.g. `<a download>`
links (e.g. http://jsfiddle.net/koldev/cW7W5/), the extension was only
saved if Finder was set to show all extensions by default. We now always
display the extension to make sure that it is saved.

If we want to keep the extension hidden, we could also populate the
allowed file types array with the extension from the default filename,
but that would have interfered with how we set the filters.

* Try to make test less flaky

* Try simpler test

* Fix stdout detection

* Try longer timeout on test
2017-09-24 07:27:08 +09:00
John Kleinschmidt
fd1bb3f95d Merge pull request #10585 from electron/turbofan-fix
Apply turbofan-fix
2017-09-23 16:06:34 +09:00
John Kleinschmidt
53eb4d68c5 Apply turbofan-fix 2017-09-23 15:05:15 +09:00
John Kleinschmidt
331a1759d2 Fix CircleCI test step 2017-09-13 11:22:33 -04:00
John Kleinschmidt
b69d76258a Remove arm64 build
Arm64 builds are not built for 1.7.x
2017-09-13 10:50:53 -04:00
John Kleinschmidt
680bf0076b Bump v1.7.7 2017-08-30 13:06:59 -04:00
John Kleinschmidt
d42d856b9a Rerun builds 2017-08-30 09:42:23 -04:00
John Kleinschmidt
e6f6862ae8 Merge pull request #10390 from electron/render_widget_compositor_patch
Backport fix for flickering web contents on large monitors
2017-08-29 21:52:35 -04:00
John Kleinschmidt
44b4cc374b Update to latest build 2017-08-29 21:27:59 -04:00
John Kleinschmidt
9824c88d2d Backport fix for flickering web contents on large monitors 2017-08-29 13:43:02 -04:00
John Kleinschmidt
96bc46c255 Merge pull request #10365 from electron/fix_exit_crash
Fixed crash on process exit on Windows
2017-08-29 11:55:12 -04:00
John Kleinschmidt
873a8902af Merge pull request #10375 from electron/backport-notification-sounds
Backport #10293 (notification-sounds)
2017-08-29 10:52:26 -04:00
John Kleinschmidt
7dac300305 Merge pull request #10377 from electron/backfort-libuv-1419
Backport libuv/libuv#1419
2017-08-29 10:50:32 -04:00
John Kleinschmidt
2a536d2aa2 Merge pull request #10374 from electron/backport-drag-browser-view
Backport #10232 (drag-browser-view)
2017-08-29 09:34:58 -04:00
Cheng Zhao
ccd03c6675 Backport https://github.com/libuv/libuv/pull/1419
win, fs: support unusual reparse points

Allow for running uv_fs_stat and uv_fs_lstat on all reparse points. One
of such points is new OneDrive drive with "files on demand" feature
enabled.
2017-08-29 10:25:45 +09:00
Charlie Hess
5515092944 Merge pull request #10293 from electron/notification-sounds
Add support for soundName in main process notifications
2017-08-28 13:23:27 -07:00
Samuel Attard
fb7661d2d2 Merge pull request #10232 from electron/drag-browser-view
Add -webkit-app-region support to BrowserView
2017-08-28 13:19:09 -07:00
John Kleinschmidt
75b31f0bb6 Add CircleCI 2017-08-28 11:35:30 -04:00
Ales Pergl
cfee5ba8c8 Fixed crash on process exit on Windows 2017-08-28 16:28:07 +02:00
758 changed files with 60301 additions and 13595 deletions

View File

@@ -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

View File

@@ -1,2 +0,0 @@
*
!tools/xvfb-init.sh

21
.github/CODEOWNERS vendored
View File

@@ -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
View File

@@ -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
View File

@@ -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
View File

@@ -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

View File

@@ -1 +1 @@
v8.2.1
v7.9.0

View File

@@ -1,6 +0,0 @@
{
"plugins": [
["remark-lint-code-block-style", "fenced"],
["remark-lint-fenced-code-flag"]
]
}

View File

@@ -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

View File

@@ -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/

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -1,22 +1,21 @@
[![Electron Logo](https://electronjs.org/images/electron-logo.svg)](https://electronjs.org)
[![Electron Logo](https://electron.atom.io/images/electron-logo.svg)](https://electron.atom.io/)
[![Travis Build Status](https://travis-ci.org/electron/electron.svg?branch=master)](https://travis-ci.org/electron/electron)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/bc56v83355fi3369/branch/master?svg=true)](https://ci.appveyor.com/project/electron-bot/electron/branch/master)
[![devDependency Status](https://david-dm.org/electron/electron/dev-status.svg)](https://david-dm.org/electron/electron?type=dev)
[![Join the Electron Community on Slack](https://atom-slack.herokuapp.com/badge.svg)](https://atom-slack.herokuapp.com/)
[![Join the Electron Community on Slack](http://atom-slack.herokuapp.com/badge.svg)](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)

View File

@@ -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}"

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
};

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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_;

View File

@@ -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)

View File

@@ -45,7 +45,6 @@ class Notification : public mate::TrackableObject<Notification>,
~Notification() override;
void Show();
void Close();
// Prop Getters
base::string16 GetTitle() const;

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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>());
}

View File

@@ -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

View File

@@ -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();

View File

@@ -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"];

View File

@@ -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");
}

View File

@@ -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);

View File

@@ -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)

View File

@@ -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_;

View File

@@ -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)

View File

@@ -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);

View File

@@ -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...);
}

View File

@@ -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

View File

@@ -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_

View File

@@ -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

View File

@@ -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

View File

@@ -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() {

View File

@@ -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"

View File

@@ -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());

View File

@@ -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_;

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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_;

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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,

View File

@@ -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_) {

View File

@@ -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.

View File

@@ -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_;

View File

@@ -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

View File

@@ -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];
}

View File

@@ -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();
}

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -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, &center) && 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) {
}

View File

@@ -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_;

View File

@@ -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);
};

View File

@@ -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];

View File

@@ -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 {

View File

@@ -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);
};

View File

@@ -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

View File

@@ -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) {

View File

@@ -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) {}

View File

@@ -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);
};

View File

@@ -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

View File

@@ -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_

View File

@@ -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,

View File

@@ -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

View File

@@ -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:

View File

@@ -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_;

View File

@@ -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());

View File

@@ -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

View File

@@ -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_

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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(

View File

@@ -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*>(

View File

@@ -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.

View File

@@ -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>

View File

@@ -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

View File

@@ -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() {

View File

@@ -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);

View File

@@ -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);

View File

@@ -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_

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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