Compare commits

...

294 Commits

Author SHA1 Message Date
Cheng Zhao
b3770bc407 Bump v0.16.3. 2014-09-20 23:12:05 +08:00
Cheng Zhao
8f44046f9a Fix chromedriver's version in archive. 2014-09-20 23:09:49 +08:00
Cheng Zhao
a717235212 Only include chromedriver in vX.X.0 releases. 2014-09-20 22:39:52 +08:00
Cheng Zhao
805215be78 Merge pull request #655 from hokein/master
SetProgressBar API Implementation, fixes #635
2014-09-20 11:19:34 +08:00
Haojian Wu
e7fbe84644 Use app name as desktop name by default. 2014-09-18 22:58:17 +08:00
Cheng Zhao
9653f20995 win: Add "direct-write" option for BrowserWindow.
For atom/atom#3540.
2014-09-18 21:49:04 +08:00
Haojian Wu
e959a40b49 docs: setProgressBar API. 2014-09-18 19:32:58 +08:00
Haojian Wu
d9ce3f0ca3 linux: Implement SetProgressBar API. 2014-09-18 19:26:52 +08:00
Haojian Wu
d8f57a0ecc Correct code style. 2014-09-18 16:48:00 +08:00
Haojian Wu
c5e0b65cc7 mac: Implement SetProgressBar API. 2014-09-18 10:20:55 +08:00
Haojian Wu
b5e82dac6f win: Implement SetProgressBar API. 2014-09-17 09:42:47 +08:00
Cheng Zhao
1381d16f9c Merge pull request #652 from atom/chromedriver
Ship chromedriver and add docs on how to use it
2014-09-16 17:45:39 +08:00
Cheng Zhao
268508764f docs: use => using 2014-09-13 00:16:32 +08:00
Cheng Zhao
34109fa741 docs: Document how to use chromedriver. 2014-09-13 00:07:21 +08:00
Cheng Zhao
925ff2da5b Pretend to be Chrome by default.
This is used to cheat client web drivers.
2014-09-12 23:28:14 +08:00
Cheng Zhao
b8a6658ba9 Make our user agent string follow standard. 2014-09-12 23:08:13 +08:00
Cheng Zhao
4a4814b41c default_app: Don't quit when started as web driver. 2014-09-12 22:54:00 +08:00
Cheng Zhao
f952dae0d0 Create dist for chromedriver and upload it. 2014-09-12 22:10:06 +08:00
Cheng Zhao
cba155bcfb Add action to copy chromedriver. 2014-09-12 21:48:45 +08:00
Cheng Zhao
0f714c81cd Merge pull request #644 from lusbuab/patch-1
Correct parameter type of setHightlightMode()
2014-09-10 10:30:42 +09:00
Cheng Zhao
92b5dab3f9 Merge pull request #642 from hokein/master
Add Volume keys support in global-shortcut API, fix #630.
2014-09-10 10:30:26 +09:00
Florian
6ca238852a Correct parameter type of setHightlightMode() 2014-09-09 15:04:00 +02:00
Haojian Wu
d2368d2d3b Add Volume keys support in global-shortcut API, fix #630. 2014-09-09 20:56:47 +08:00
Cheng Zhao
88269a613a Bump v0.16.2. 2014-09-09 20:07:08 +08:00
Cheng Zhao
5696fe8ec8 No need to set "--harmony" in renderer process.
After Chrome 37 renderer process can work correctly without it.
2014-09-09 20:05:43 +08:00
Cheng Zhao
ba439b6824 Merge pull request #643 from atom/mac-tray
Add some OS X only Tray APIs
2014-09-09 21:00:27 +09:00
Cheng Zhao
c8a8576970 docs: Document the new Tray APIs. 2014-09-09 19:50:50 +08:00
Cheng Zhao
67cbecaba0 mac: Add "double-clicked" event for Tray. 2014-09-09 19:45:21 +08:00
Cheng Zhao
ec1db0c7bb mac: Add Tray.setHighlightMode API, fixes #425. 2014-09-09 19:39:39 +08:00
Cheng Zhao
4330d67e0d mac: Add Tray.setTitle API, fixes #560. 2014-09-09 19:36:15 +08:00
Cheng Zhao
db8de9e60d Make default_app focus the main window on startup. 2014-09-09 18:33:36 +08:00
Cheng Zhao
9c9a306095 Upgrade brightray. 2014-09-09 18:33:22 +08:00
Cheng Zhao
bda317b000 views: Set devtools window's icon, fixes #429. 2014-09-09 15:30:33 +08:00
Cheng Zhao
700510d63a mac: Don't activate window when showing. 2014-09-09 14:47:04 +08:00
Cheng Zhao
ab2714fda9 Merge pull request #641 from atom/web-runtime-flags
Add options for web runtime features
2014-09-09 14:43:08 +08:00
Cheng Zhao
33b94edcf0 Use PersistentDictionary to store web perferences. 2014-09-09 14:13:21 +08:00
Cheng Zhao
44d3e58ddb Make code more tidy. 2014-09-09 13:21:15 +08:00
Cheng Zhao
f08c3f9134 docs: Add options for web runtime features. 2014-09-09 11:14:44 +08:00
Cheng Zhao
8de90db429 Pass web runtime features by command line. 2014-09-09 11:08:30 +08:00
Cheng Zhao
81241b38eb Add switches of web runtime flags. 2014-09-09 10:33:31 +08:00
Cheng Zhao
1c07b9c85b Bump v0.16.1. 2014-09-08 16:00:32 +08:00
Cheng Zhao
1199224086 BrowserWindow.show() should not focus window, fixes #609. 2014-09-08 15:28:34 +08:00
Cheng Zhao
add4e3c6f5 docs: Now atom-shell's version should be used when building modules. 2014-09-08 15:07:33 +08:00
Cheng Zhao
eb55f1cf47 Merge pull request #636 from kitematic/master
Fixing dialog api parameter parsing
2014-09-08 11:26:03 +08:00
Jeffrey Morgan
8367071dc6 Fixing dialog api parameter parsing 2014-09-07 15:14:43 -07:00
Cheng Zhao
68ac6b0cbb Bump v0.16.0. 2014-09-06 20:58:34 +08:00
Cheng Zhao
7fb1cb5b3d Merge pull request #612 from nuivall/master
win: Don't overwrite Chrome high DPI setting.
2014-09-06 20:55:58 +08:00
Cheng Zhao
19b25c0d83 Make dialog API's parameters more flexible. 2014-09-06 18:56:28 +08:00
Cheng Zhao
fd806f81ce linux: Don't set PR_SET_NO_NEW_PRIVS when creating process, fixes #623. 2014-09-05 21:04:27 +08:00
Cheng Zhao
d515404abd Merge pull request #626 from atom/v8-debugger
Implement V8 debugger agent
2014-09-05 13:40:37 +08:00
Cheng Zhao
4509056d5e docs: Add notes on OS X application menu. 2014-09-05 13:39:29 +08:00
Cheng Zhao
f604525b98 mac: Enable setting "Services" menu.
Regarding https://github.com/atom/atom/issues/3204.
2014-09-05 13:07:05 +08:00
Cheng Zhao
3afbb66b92 Send message to client in debugger thread. 2014-09-05 11:51:45 +08:00
Cheng Zhao
fadfd74923 win: Fix compilation error. 2014-09-05 11:44:30 +08:00
Cheng Zhao
222f8e1028 Make --debug-brk work. 2014-09-05 10:59:29 +08:00
Cheng Zhao
e3b6ea62d6 Send connect message if client is connected. 2014-09-05 10:52:47 +08:00
Cheng Zhao
3795cc58b0 Pass debugger messages between V8 debugger. 2014-09-05 10:44:07 +08:00
Cheng Zhao
ed7d430f2b Pass header sent from client. 2014-09-05 09:39:28 +08:00
Cheng Zhao
20f21b707b Start a TCP server in the debugger thread. 2014-09-04 23:02:18 +08:00
Cheng Zhao
a584ca3678 Start a new debugger thread to listen for commands. 2014-09-04 21:06:31 +08:00
Cheng Zhao
ca881c5aaf win: Fix compilation with Chrome 37. 2014-09-03 23:17:00 +08:00
Cheng Zhao
2832708618 Merge pull request #622 from atom/chrome37
Upgrade to Chrome37
2014-09-02 17:03:07 +08:00
Cheng Zhao
b00e56f587 Upgrade to apm@0.93.0 2014-09-02 10:58:42 +08:00
Cheng Zhao
d64f43da65 Merge pull request #624 from Rahazan/patch-1
Small typo fix in fatal JS error message
2014-09-02 09:55:07 +08:00
Guido Zuidhof
3e6d8ddbbd Small typo fix in fatal JS error message
An javascript error -> A javascript error
2014-09-01 21:02:03 +02:00
Cheng Zhao
533548fdc7 Use atom-shell's version for creating node headers tarball. 2014-09-01 22:54:20 +08:00
Cheng Zhao
3b95f49a14 Upgrade node to fix child_process.fork. 2014-09-01 22:32:58 +08:00
Cheng Zhao
d9d1d03d4d linux: Dont' use native style border. 2014-09-01 20:22:38 +08:00
Cheng Zhao
9546120ce4 linux: Fix API changes of Chrome 37. 2014-09-01 20:10:14 +08:00
Cheng Zhao
48a5591508 Upgrade brightray. 2014-09-01 19:18:45 +08:00
Cheng Zhao
a413935e91 Initialize node after WebKit is initialized. 2014-09-01 18:43:43 +08:00
Cheng Zhao
241b07f763 Initailize V8 with gin. 2014-09-01 16:41:26 +08:00
Cheng Zhao
d874ba80db Upgrade libchromiumcontent for gin headers. 2014-09-01 16:08:08 +08:00
Cheng Zhao
3e46363ae1 Fix API changes of Chrome 37. 2014-09-01 15:36:37 +08:00
Cheng Zhao
d4a46fa35f Comment out debugger agent.
V8 has discarded support for debugger agent, we should reimplement it in
atom-shell.
2014-09-01 15:35:56 +08:00
Cheng Zhao
134f8236cc Update printing code to Chrome 37. 2014-09-01 15:35:39 +08:00
Cheng Zhao
55003716aa Upgrade node for Chrome 37. 2014-09-01 15:08:19 +08:00
Cheng Zhao
fe88330e87 Upgrade brightray to Chrome 37. 2014-09-01 13:59:01 +08:00
Cheng Zhao
ed68bd18b8 Upgrade libchromiumcontent to Chrome 37. 2014-09-01 13:33:03 +08:00
Cheng Zhao
45228493eb Merge pull request #610 from atom/devtools-extension
Add support for chrome devtools extension
2014-08-28 23:12:21 +08:00
Cheng Zhao
80fb44b926 docs: Add docs on how to use chrome devtools extension. 2014-08-28 16:33:27 +08:00
Cheng Zhao
aa8f5e54df dev-tools => devtools. 2014-08-28 16:00:29 +08:00
Cheng Zhao
8134585578 Remember loaded extensions. 2014-08-28 15:58:36 +08:00
Cheng Zhao
a59388ecdd Add "dev-tools-opened" and "dev-tools-closed" events. 2014-08-28 14:25:00 +08:00
Cheng Zhao
8051ad8b2a Add support for chrome.extension API in devtools extension. 2014-08-28 12:54:19 +08:00
Cheng Zhao
0a937cd2be Merge pull request #614 from atom/atom-shell-squirrel
Atom.exe should receive Squirrel events
2014-08-28 10:06:24 +08:00
Paul Betts
db11c631f6 Atom.exe should receive Squirrel events
This sets up Atom to be packaged into a Squirrel installer. See
https://github.com/Squirrel/Squirrel.Windows.Next/pull/17 for the details
2014-08-27 17:06:26 -07:00
Marcin Maliszkiewicz
90bfd4bf0f win: Don't overwrite Chrome hight DPI setting.
Also disable high DPI mode by default, Chrome enables it since
https://codereview.chromium.org/294293002
2014-08-27 20:14:41 +02:00
Cheng Zhao
39b98b0e4d Fix cpplint warnings. 2014-08-27 21:16:45 +08:00
Cheng Zhao
b6c2e7ef76 Ignore requests to other hosts. 2014-08-27 21:05:54 +08:00
Cheng Zhao
fe96a9de33 Don't use pure number as host name.
Numbers would be treated as IP addresses.
2014-08-27 20:49:57 +08:00
Cheng Zhao
b80f109524 Make "chrome-extension" a standard scheme.
If we do not do so, urls like "chrome-extension://extension-1" will
never get a hostname.
2014-08-27 20:48:49 +08:00
Cheng Zhao
cd40bdbec8 Add chrome-extension protocol for loading devtools extensions. 2014-08-27 16:01:15 +08:00
Cheng Zhao
1533600720 Upgrade libchromiumcontent to loose iframe sandbox. 2014-08-26 22:27:50 +08:00
Cheng Zhao
263c4b9ab4 Turn off web security for devtools. 2014-08-26 16:05:10 +08:00
Cheng Zhao
f1e72914f5 Update brightray for devtools zooming. 2014-08-26 15:11:26 +08:00
Cheng Zhao
400d5cef3f linux: Fix BrowserWindow.setResizable. 2014-08-26 13:37:37 +08:00
Cheng Zhao
af531d685e linux: Make BrowserWindow.setSkipTaskbar work dynamically. 2014-08-26 12:15:22 +08:00
Cheng Zhao
eb5f1f78bf linux: Set WM_CLASS and WM_WINDOW_ROLE for window, fixes #605. 2014-08-26 10:34:48 +08:00
Cheng Zhao
c81a4bcafc Don't use third party dependency in default_app. 2014-08-26 09:50:45 +08:00
Cheng Zhao
1beeda170c Merge pull request #606 from hokein/master
docs: Correct debugging chapter.
2014-08-25 18:55:09 +08:00
Haojian Wu
9ad81c054d docs: Correct debugging chapter. 2014-08-25 13:08:11 +08:00
Cheng Zhao
5604e75886 Merge pull request #603 from soh1988/patch-corrections
Correction to the API Documentation of the Browser FlashFrame
2014-08-23 19:18:38 +08:00
Cheng Zhao
2e7ef7ea44 Merge pull request #602 from soh1988/patch-minSize
Changing the Logical Or to Bitwise Or to change from Either to Either Or...
2014-08-23 19:17:54 +08:00
Chris Soh
a0867fa7c5 Changing the Logical Or to Bitwise Or to change from Either to Either Or Both values 2014-08-23 13:30:43 +08:00
Chris Soh
31f5855001 Adding the compulsory flag in the API documentation of BrowserWindow.flashFrame 2014-08-23 13:20:47 +08:00
Cheng Zhao
0b24883649 Merge pull request #599 from atom/printing
Add support for printing
2014-08-22 17:48:36 +08:00
Cheng Zhao
4fda81a0b4 Document the BrowserWindow.print(). 2014-08-22 15:14:49 +08:00
Cheng Zhao
17c0888932 Make print settings optional. 2014-08-22 15:05:30 +08:00
Cheng Zhao
d20ec6952a Revert "Move the code of getting printing settings to another class."
This reverts commit 57d06c5241.

Conflicts:
	atom/browser/printing/printing_config_service.cc
2014-08-22 15:03:39 +08:00
Cheng Zhao
e43b3309af Add "silent" and "print_background" option for printing. 2014-08-22 15:01:07 +08:00
Cheng Zhao
d0c1b63064 linux: Fix linking error. 2014-08-22 13:03:27 +08:00
Cheng Zhao
a98e26a307 Fix handling failed print. 2014-08-22 13:01:49 +08:00
Cheng Zhao
57d06c5241 Move the code of getting printing settings to another class. 2014-08-22 12:46:26 +08:00
Cheng Zhao
f28e4574b0 Simplify global-shortcut's code. 2014-08-22 10:53:37 +08:00
Cheng Zhao
c9b284d7f7 Remove more unused printing code. 2014-08-22 10:27:08 +08:00
Cheng Zhao
99a510701d Strip out print preview. 2014-08-21 22:14:27 +08:00
Cheng Zhao
eb3ecab6a8 Setup PrintingMessageFilter for printing. 2014-08-21 21:19:43 +08:00
Cheng Zhao
11b9a06639 Add BrowserWindow.print() method. 2014-08-21 21:00:49 +08:00
Cheng Zhao
87d5b72b76 Initailize PrintViewManagerBasic for browser window. 2014-08-21 20:49:18 +08:00
Cheng Zhao
c95869e515 Fix cpplint warnings. 2014-08-21 20:25:12 +08:00
Cheng Zhao
c2f7920068 Upgrade libchromiumcontent to contain printing headers. 2014-08-21 16:38:25 +08:00
Cheng Zhao
cb7196a9c1 Allow script initialized window.print(). 2014-08-21 16:32:41 +08:00
Cheng Zhao
7de0f71a75 Fix compiling with print messages. 2014-08-21 16:14:22 +08:00
Cheng Zhao
8dcb3726f9 Initialize the fake BrowserProcess object. 2014-08-21 15:45:34 +08:00
Cheng Zhao
d934526bb3 Add printing related source codes from chrome. 2014-08-21 15:43:11 +08:00
Cheng Zhao
cab546cbb7 No more need to flip rect for capturePage, fixes #589. 2014-08-21 12:40:31 +08:00
Cheng Zhao
058d0bbe19 linux: Add "dark-theme" option for BrowserWindow, fixes #352. 2014-08-21 12:25:43 +08:00
Cheng Zhao
a32669ac0d Merge pull request #594 from PeterDaveHello/patch-1
make CI build faster
2014-08-21 10:37:48 +08:00
Peter Dave Hello
cc4b3e9e6f make CI build faster 2014-08-20 22:49:37 +08:00
Cheng Zhao
fdcad1066e docs: Fix typos. 2014-08-20 10:57:39 +08:00
Cheng Zhao
41d43920f9 Merge pull request #590 from atom/browser-v8-debugger
Implement the "--debug" switch
2014-08-20 10:47:29 +08:00
Cheng Zhao
fecc90e67c docs: Add chapter on debugging with node-inspector. 2014-08-20 10:43:41 +08:00
Cheng Zhao
6e3b3fa5a2 Add "Debugging browser process" chapter. 2014-08-20 10:01:43 +08:00
Cheng Zhao
c12c0363a0 No need to enter isolate. 2014-08-20 08:15:50 +08:00
Cheng Zhao
1207dfde4c Add support for --debug switch. 2014-08-19 23:36:26 +08:00
Cheng Zhao
0f617c3d3c Remove the unused process.getCurrentStackTrace(). 2014-08-19 22:35:22 +08:00
Cheng Zhao
7b71ae6824 Enable setting only one side of minimum size, fixes #461. 2014-08-19 21:43:18 +08:00
Cheng Zhao
cfae3cd3af Add app.resolveProxy API, fixes #545. 2014-08-19 21:26:45 +08:00
Cheng Zhao
f470d21a55 Bump v0.15.9. 2014-08-18 19:05:56 +08:00
Cheng Zhao
af0a5744f2 Upgrade brightray for new URLRequestContextGetter interface. 2014-08-20 15:30:43 +08:00
Cheng Zhao
2bcb7393c4 Avoid calling GetRequestContext() in UI thread, fixes #591.
Since we can access job factory without touching the request context,
there is no need to make sure GetRequestContext() is called before using
the protocol module.
2014-08-20 13:48:38 +08:00
Cheng Zhao
60dcb0e67f Make process.activateUvLoop friendly to multi-context, fixes #587. 2014-08-20 13:01:23 +08:00
Cheng Zhao
c88b691db7 linux: Suppress test for "enable-larger-than-screen".
It is failing on some DEs.
2014-08-20 12:23:20 +08:00
Cheng Zhao
27f07974e0 Add --proxy-server and --no-proxy-server switches. 2014-08-20 11:57:15 +08:00
Cheng Zhao
a840799b46 Bump v0.15.8. 2014-08-18 09:49:08 +00:00
Cheng Zhao
c8ef79817a Merge pull request #585 from atom/menubar_underline
Support specifying accelerator for menu bar items by adding "&" in label
2014-08-18 16:31:22 +08:00
Cheng Zhao
29abba824d A little cleanup. 2014-08-18 16:19:23 +08:00
Cheng Zhao
6ccec45c61 views: Fix activating lower case accelerators. 2014-08-18 16:05:41 +08:00
Cheng Zhao
1dabd20d99 win: Underline's color tends to be a little lighter. 2014-08-18 15:41:57 +08:00
Cheng Zhao
fedb08899c views: Fix calculating underline's position. 2014-08-18 15:36:29 +08:00
Cheng Zhao
b8bfe8a9ad views: Always hide accelerator when submenu is activated. 2014-08-18 14:58:52 +08:00
Cheng Zhao
a230daa998 views: Pressing "Alt+Key" should bring up the menu bar. 2014-08-18 14:52:44 +08:00
Cheng Zhao
ba41634ad6 views: Show menubar's submenu when "Alt+Key" is pressed. 2014-08-18 14:42:21 +08:00
Cheng Zhao
e9536508a5 views: Show menubar's accelerator when "Alt" is pressed. 2014-08-18 14:12:12 +08:00
Cheng Zhao
965f2b1b6b views: Draw underline in menu bar for accelerators. 2014-08-18 13:36:00 +08:00
Cheng Zhao
e25417ab31 linux: Use "fg" of GtkStyle as text color, fixes #555. 2014-08-18 10:29:21 +08:00
Cheng Zhao
48c227c263 Upgrade libchromium for the accelerator fix. 2014-08-17 21:21:28 +08:00
Cheng Zhao
cbd6541e9a views: Fix compilation error. 2014-08-17 12:57:22 +08:00
Cheng Zhao
2a9f5a5fb8 Add "enable-larger-than-screen" option for BrowserWindow.
From now on BrowserWindow can only be resized larger than screen or
moved out of screen when this option is set to "true".

Fixes #582.
2014-08-17 12:23:00 +08:00
Cheng Zhao
78afa29ade Little formating on app.getDataPath. 2014-08-17 11:33:55 +08:00
Cheng Zhao
73bb05e530 mac: Make "Text to Speech" work, fixes atom/atom#3288. 2014-08-17 11:30:26 +08:00
Cheng Zhao
8cc23aca8d Upgrade to Chrome 36.0.1985.143. 2014-08-17 11:30:26 +08:00
Cheng Zhao
f96c6e4bd7 Merge pull request #578 from cornedor/appdata
Fixed  #442 added app.getDataPath()
2014-08-16 20:34:01 +08:00
Corné Dorrestijn
3afb4e017c Added the getDataPath function to the app api docs 2014-08-15 17:29:36 +02:00
Corne Dorrestijn
54ee12308d reused converted and fixed indentation 2014-08-15 16:52:16 +02:00
Cheng Zhao
fd09f13c9b Bump v0.15.7. 2014-08-15 15:07:11 +08:00
Cheng Zhao
86dd8e2dfa docs: Document the chrome command switches we support. 2014-08-15 13:06:52 +08:00
Cheng Zhao
1b70ca2098 Initialize job factory as early as possible.
Fixes atom/atom#3255.
2014-08-15 11:35:13 +08:00
Cheng Zhao
e8d1c69ea8 Enable the spec of testing crash of protocol module. 2014-08-15 11:08:06 +08:00
Cheng Zhao
1883da463f Merge pull request #577 from cornedor/verbose
Added verbose mode to the bootstrap script. Closes #574
2014-08-15 10:40:30 +08:00
Corne Dorrestijn
e9879a3e4b Removed whitespace and added vector import 2014-08-13 14:24:35 +02:00
Corne Dorrestijn
dec05988f4 Fixes for windows 2014-08-13 14:16:55 +02:00
Cheng Zhao
4087062798 Remove old symbols when generating symbols. 2014-08-13 20:08:07 +08:00
Cheng Zhao
31135321c0 Bump v0.15.6. 2014-08-13 18:19:38 +08:00
Cheng Zhao
226cbda7a6 Avoid creating our own URLRequestContextGetter. 2014-08-13 17:40:31 +08:00
Cheng Zhao
66ef1a067d Merge pull request #576 from atom/geolocation
Implement geolocation API
2014-08-13 14:53:07 +08:00
Cheng Zhao
8a7efcdcd2 Fix compilation error on Linux. 2014-08-13 14:43:21 +08:00
Cheng Zhao
adb8fb59bd Add network provider for google geolocation api. 2014-08-13 13:28:05 +08:00
Cheng Zhao
0ca9e8ee82 Add access token store. 2014-08-13 12:12:43 +08:00
Cheng Zhao
e7647ba183 mac: Fix crash when checking for update, fixes #575. 2014-08-13 11:28:19 +08:00
Corne Dorrestijn
be6599807d Added getAppData function to the app api 2014-08-12 17:01:56 +02:00
Cheng Zhao
a8ca0329b4 win: Show minimize button for unresizable window, fixes #411. 2014-08-12 22:58:19 +08:00
Corne Dorrestijn
6d9a88f415 Fixed inconsistent newlines 2014-08-12 14:28:18 +02:00
Corne Dorrestijn
0018d4b705 Added a verbose mode to the bootstrap script 2014-08-12 14:23:59 +02:00
Cheng Zhao
72e8b2882f Upgrade libchromiumcontent.
* Fix unresponsive event when in beforeunload handler.
* Compile with clang 3.4 under Linux.
2014-08-12 20:17:30 +08:00
Cheng Zhao
89539ca15e Update brightray. 2014-08-11 23:23:27 +08:00
Cheng Zhao
175d052a28 linux: Enable tests on window size.
After upgraded to Chrome36, those tests have become stable.
2014-08-11 21:00:04 +08:00
Cheng Zhao
d1a93a5135 views: Set a default maximum window size.
It is required to make the window able to be resized larger than the
screen.
2014-08-11 20:36:53 +08:00
Cheng Zhao
f96485f950 linux: Fix error when generating symbols.
Somehow strip would return 1 when a directory is passed, so we have to
wrap it in a script to avoid the error.
2014-08-11 11:08:29 +00:00
Cheng Zhao
79dfb2d2f3 Bump v0.15.5. 2014-08-11 17:44:16 +08:00
Cheng Zhao
de7ff0f944 Merge pull request #573 from atom/resource-dispatcher-delegate
Enable removing the X-Frame-Options header for frames
2014-08-11 16:31:35 +08:00
Cheng Zhao
80c77ef3a8 Fix cpplint warning. 2014-08-11 15:56:23 +08:00
Cheng Zhao
cad9580796 docs: Move security info from browser-window to web-security. 2014-08-11 15:37:44 +08:00
Cheng Zhao
253789353f docs: Add document on overriding X-Frame-Options. 2014-08-11 15:25:26 +08:00
Cheng Zhao
73262be2c2 Filter out x-frame-options header on user's request. 2014-08-11 15:03:57 +08:00
Cheng Zhao
0ad4c3ca93 Add custom ResourceDispatcherHostDelegate. 2014-08-11 14:08:23 +08:00
Cheng Zhao
b26e3a9629 Merge pull request #572 from atom/window-larger-than-screen
Enable window to be resized larger than screen
2014-08-11 12:17:48 +08:00
Cheng Zhao
c55f6d82d8 Update brightray for devtools experiments. 2014-08-11 10:52:54 +08:00
Cheng Zhao
4b90c02420 mac: Override system's default on resizing window no larger than screen. 2014-08-11 10:24:36 +08:00
Cheng Zhao
d4fb1c1f8c Add spec for resizing window larger than screen. 2014-08-11 10:22:56 +08:00
Cheng Zhao
445fe158cc Store window icon as ImageSkia. 2014-08-11 10:06:46 +08:00
Cheng Zhao
a696f06a23 Restructure headers of native_window. 2014-08-11 10:01:05 +08:00
Cheng Zhao
c019f13e8c docs: Update prerequisities in Windows build instructions. 2014-08-11 09:39:03 +08:00
Cheng Zhao
b4f00f3b40 Update with new ScopedPersistent interface. 2014-08-10 21:19:07 +08:00
Cheng Zhao
f60d8066f8 Use the function converter from native_mate. 2014-08-10 19:14:20 +08:00
Cheng Zhao
b8d5aa586e Merge pull request #567 from atom/linux-ci
Add Linux CI
2014-08-09 10:24:18 +08:00
Cheng Zhao
eeff20f1bc linux: Start xvfb in CI. 2014-08-09 09:59:06 +08:00
Cheng Zhao
9035ffff55 linux: Don't set CXX to clang when building node modules. 2014-08-09 09:24:17 +08:00
Cheng Zhao
ca522f06d3 linux: Do "apt-get update" in CI. 2014-08-08 23:53:58 +08:00
Cheng Zhao
7f534652a6 linux: Install all necessary deps on CI. 2014-08-08 23:41:11 +08:00
Cheng Zhao
b93564894c Make script quit when error happens in child processes. 2014-08-08 23:23:56 +08:00
Cheng Zhao
54b8a62920 linux: Install libgnome-keyring-dev on travis CI. 2014-08-08 23:10:20 +08:00
Cheng Zhao
bcfba96d29 Set compiler to gcc. 2014-08-08 22:38:35 +08:00
Cheng Zhao
8e21530550 Use travis-ci's multi-os feature. 2014-08-08 22:12:24 +08:00
Cheng Zhao
a4f59bc04e Merge pull request #565 from atom/deepak1556-appveyor_setup
Appveyor setup
2014-08-08 22:06:55 +08:00
Cheng Zhao
a378a719e9 Don't run tests. 2014-08-08 21:31:51 +08:00
Cheng Zhao
441ee0d978 Update brightray. 2014-08-08 20:41:24 +08:00
Cheng Zhao
8d7a59161a win: Don't call pylint in CI. 2014-08-08 17:38:22 +08:00
Cheng Zhao
d175a99811 Fix pylint warning. 2014-08-08 17:32:00 +08:00
Cheng Zhao
724b29d6d4 win: Fix calling lint scripts with win32 python. 2014-08-08 16:41:10 +08:00
Cheng Zhao
336908eba0 win: Use absolute path for ATL. 2014-08-08 15:45:24 +08:00
Cheng Zhao
0f5d929c09 win: Build with downloaded ATL instead of the ATL shipped by WDK. 2014-08-08 14:56:48 +08:00
Cheng Zhao
c4b0170a0a views: Only toggle menu bar when auto-hide-menu-bar is turned on. 2014-08-08 14:30:43 +08:00
Cheng Zhao
936860edd5 Merge pull request #564 from sryze/patch-1
Open output file in binary mode in download()
2014-08-08 14:27:26 +08:00
Cheng Zhao
1cadc9221a win: Download ATL binaries. 2014-08-08 14:18:09 +08:00
Sergey Zolotarev
4890eebd3a Open output file in binary mode in download()
This fixes #553.
2014-08-08 13:08:01 +07:00
Cheng Zhao
3a65942b97 Make node version switching faster. 2014-08-08 11:35:08 +08:00
Cheng Zhao
e06c558a86 Add lint scripts. 2014-08-08 10:58:26 +08:00
Cheng Zhao
0a0a408bf8 Upgrade to apm@0.89.0 2014-08-08 09:52:57 +08:00
Cheng Zhao
c9702b56e2 Build only Debug version. 2014-08-08 08:39:37 +08:00
Cheng Zhao
279eb23b38 No need of project_id in appveyor.yml. 2014-08-07 23:52:08 +08:00
Cheng Zhao
8eb650ce03 Merge branch 'appveyor_setup' of https://github.com/deepak1556/atom-shell into deepak1556-appveyor_setup
Conflicts:
	script/lib/util.py
2014-08-07 22:31:48 +08:00
Cheng Zhao
7f9ac88c31 Bump v0.15.4. 2014-08-07 19:42:08 +08:00
Cheng Zhao
424a00cf29 Don't set interval too short.
Otherwise it could be possible that the callback executes for multiple
times before it is cleared.
2014-08-07 19:40:41 +08:00
Cheng Zhao
3c078b4dab Merge pull request #558 from atom/menubar-autohide
Allow window menu bar to be hidden
2014-08-07 19:31:58 +08:00
Cheng Zhao
8cc49ffa80 menu_bar_show_ => menu_bar_visible_ 2014-08-07 16:48:30 +08:00
Cheng Zhao
58a09f6495 linux: Fix detecting Alt modifier. 2014-08-07 16:46:50 +08:00
Cheng Zhao
c2885f77c9 views: Focus on web view when window is focused. 2014-08-07 16:46:48 +08:00
Cheng Zhao
5d5a3138bc views: Toggle the menu bar only when a single Alt is released. 2014-08-07 15:54:05 +08:00
Cheng Zhao
09f9d0729c views: Show menu when "Alt" is up. 2014-08-07 15:07:34 +08:00
Cheng Zhao
3d989b6736 win: Fix the key code of Alt. 2014-08-07 15:02:27 +08:00
Cheng Zhao
daa00e6539 views: Add some asserts and comments. 2014-08-07 14:48:02 +08:00
Cheng Zhao
382dbb500c Also fix setInterval for #481. 2014-08-07 14:23:28 +08:00
Cheng Zhao
92d6fd641f views: Hide menu bar when web view is clicked. 2014-08-07 14:14:43 +08:00
Cheng Zhao
f219e7f0dd views: Switching to other window should hide the menubar. 2014-08-07 14:02:03 +08:00
Cheng Zhao
8a9e1824c3 views: Add support for auto-hide menubar. 2014-08-07 13:47:58 +08:00
Cheng Zhao
b139d97f3d Update brightray for devtools focus fix. 2014-08-07 10:52:17 +08:00
Cheng Zhao
d29efb7f81 Force updating timeout when setTimeout is called, fixes #481. 2014-08-07 10:37:38 +08:00
Cheng Zhao
53cedc6e5d Add spec for #481. 2014-08-07 10:37:38 +08:00
Cheng Zhao
4f4aabef7a Bump v0.15.3. 2014-08-06 23:37:51 +08:00
Cheng Zhao
a888e4b960 linux: Only use global menu bar under Unity.
Fixes atom/atom#3182.
2014-08-06 23:34:16 +08:00
Cheng Zhao
15c31ad1ba Create .version after all files have been downloaded. 2014-08-06 23:16:42 +08:00
Cheng Zhao
196be5291d Merge pull request #552 from atom/dialog-filters
Add support for extension filters for file dialogs
2014-08-06 22:02:22 +08:00
Cheng Zhao
fe9f94555b win: Implement the filters option. 2014-08-06 21:51:36 +08:00
Cheng Zhao
47e0a61dd8 docs: Document the filters option. 2014-08-06 15:00:31 +08:00
Cheng Zhao
5ba324ca9a gtk: Implement the filters option. 2014-08-06 14:49:02 +08:00
Cheng Zhao
0721b34847 mac: Implement the filters option. 2014-08-06 13:58:42 +08:00
Cheng Zhao
dc257f1f86 Add "filters" parameter for file dialogs. 2014-08-06 13:58:42 +08:00
Cheng Zhao
dfe111b95a Add support for multiple DPI images, fixes #541. 2014-08-06 13:56:49 +08:00
Cheng Zhao
a76ae8cd35 docs: Remove the outdated 32bit note in linux build instructions. 2014-08-05 22:44:21 +08:00
Cheng Zhao
866e20b4be Merge pull request #549 from cornedor/master
Add troubleshooting information for #500
2014-08-05 22:40:00 +08:00
Cheng Zhao
d25645ba67 win: Make BrowserWindow.setResizable change window frame dynamically. 2014-08-05 20:41:26 +08:00
Corné Dorrestijn
ad1efa67bc Add troubleshooting information for #500 2014-08-05 13:33:38 +02:00
Cheng Zhao
cbb14f5ca2 win: Disable the LegacyRenderWidgetHostHWND, fixes #506. 2014-08-05 18:49:55 +08:00
Cheng Zhao
a8cd101ff5 win: Fix window frame when DWM is disabled, closes #519. 2014-08-05 18:17:14 +08:00
Cheng Zhao
009e0790fe linux: Draw menubar text and background with native theme, fixes #540. 2014-08-05 18:05:34 +08:00
Cheng Zhao
d31ebb71db Fix cpplint warnings. 2014-08-05 08:46:06 +08:00
Cheng Zhao
2125a0be82 docs: Sort modules in alphabet sequence. 2014-08-05 00:05:26 +08:00
Cheng Zhao
6dc01945af Make Accelerator a standalone JS type.
This makes menu and global-shortcut share the same code on accelerator.
2014-08-05 00:03:58 +08:00
Cheng Zhao
28b9df24a6 Don't create junk file when posting crash report.
Fixes atom/atom#3166.
2014-08-04 22:58:34 +08:00
Cheng Zhao
94b4ceb8ce Bump v0.15.2. 2014-08-04 21:14:07 +08:00
Cheng Zhao
e3eaf909a5 Use the global_shortcut_listener_x11 from chrome36.
This fixes compilation error on Linux.
2014-08-04 12:52:42 +00:00
Cheng Zhao
33580f66df Run user's main script before everything is initialized, fixes #543. 2014-08-04 20:51:08 +08:00
Cheng Zhao
139316b975 Upgrade brightray, fix #498.
Previous 476f545 was using the wrong commit of brightray which didn't
actually contain the fix.
2014-08-04 20:51:07 +08:00
Cheng Zhao
8fe8cd46b9 Merge pull request #544 from hokein/master
📝 Update global-shortcut API document.
2014-08-04 20:12:26 +08:00
Cheng Zhao
e3118359ad Destroy web contents when window is closed.
Previously this was reverted because of Chromium's spammy error
loggings, but it also causes the renderer process not to exit when the
page has been closed. After fixing the spammy error logging, we can now
bring this back.

Fixes atom/atom#3141.
2014-08-04 14:55:08 +08:00
Haojian Wu
681de1b048 📝 Update global-shortcut API document. 2014-08-04 10:11:00 +08:00
Cheng Zhao
4880096f3d Restructure the update.py. 2014-08-03 23:13:04 +08:00
Cheng Zhao
9c038a2402 Merge pull request #534 from hokein/hotkey
Implement global shortcut API, fixes #439
2014-08-03 22:34:59 +08:00
Cheng Zhao
c4d9dc91a6 Merge pull request #537 from springmeyer/patch-1
fix node to build with target_arch=x64 on linux
2014-08-03 21:55:39 +08:00
Dane Springmeyer
16428baea2 make pylint happy 2014-07-31 11:58:45 -07:00
Dane Springmeyer
4cd3119125 fix indent 2014-07-31 11:22:22 -07:00
Dane Springmeyer
191b1aa719 only default to 64 bit build on darwin and 64bit linux
- maintains default to 32 bit on windows
2014-07-31 10:20:33 -07:00
Haojian Wu
035679057e Update GlobalShortcut API design.
* Rename Shortcut API to GlobalShortcut for better suite.
* Implement the new design interfaces.
* Put the chromium related source code to the same directory as in chrome.
2014-07-31 20:58:43 +08:00
Dane Springmeyer
978f73756b fix node to build with target_arch=x64 on linux
atom-shell on linux is incorrectly reporting `ia32` for `process.arch`.

This is happening because `-Dtarget_arch=ia32` is passed to ninja on linux inside `script/update.py` which leads to '-DARCH="ia32"' being set in the compile flags. I see that the current intention is to target 64 bit builds on linux (37275c64cd) and the binaries are in fact compiled as 64 bit despite this bug.  I guess ninja is somehow smartly ignoring the incorrect setting of the `-m32` flags at 6d772c3cda/common.gypi (L175-L178).

Until this is fixed it breaks usage of any node-pre-gyp packaged node addons because node-pre-gyp depends on process.arch being correct in order to require the right binary arch.
2014-07-30 20:51:23 -07:00
Haojian Wu
b2217474c1 Nits: Fix code style. 2014-07-31 09:12:44 +08:00
Haojian Wu
9342d59a7c 📝 Shortcut API document. 2014-07-31 09:12:43 +08:00
Haojian Wu
ad827eee90 Emit failed message when fail to register shortcut. 2014-07-31 09:12:43 +08:00
Haojian Wu
a8034364ff linux: Implement global keyboard shortcut API. 2014-07-31 09:12:42 +08:00
Yeechan Lu
c2c5111d75 win: Implement global keyboard shortcut API. 2014-07-31 09:12:42 +08:00
Haojian Wu
4b3bd9c3cc mac: Implement global keyboard shortcut API. 2014-07-31 09:12:41 +08:00
Robo
58c56ce7ae specify mode for windows 2014-07-02 02:02:23 +05:30
Robo
66983c7f67 inital config setup for x86 2014-07-02 00:09:54 +05:30
185 changed files with 10419 additions and 1312 deletions

View File

@@ -1,4 +1,8 @@
language: objective-c
language: cpp
compiler: clang
os:
- linux
- osx
notifications:
email:
@@ -6,3 +10,6 @@ notifications:
on_failure: change
script: './script/cibuild'
git:
depth: 10

28
appveyor.yml Normal file
View File

@@ -0,0 +1,28 @@
# appveyor file
# http://www.appveyor.com/docs/appveyor-yml
version: "{build}"
init:
- git config --global core.autocrlf input
environment:
matrix:
- nodejs_version: 0.10
platform:
- x86
install:
- ps: Install-Product node $env:nodejs_version
- cmd: SET PATH=C:\Program Files (x86)\MSBuild\12.0\bin\;%PATH%
- cmd: SET PATH=C:\python27;%PATH%
- cmd: python script/bootstrap.py
- cmd: python script/build.py -c Debug
test_script:
- node --version
- npm --version
- cmd: python script/cpplint.py
- cmd: python script/coffeelint.py
build: off

128
atom.gyp
View File

@@ -20,6 +20,7 @@
'atom/browser/api/lib/browser-window.coffee',
'atom/browser/api/lib/content-tracing.coffee',
'atom/browser/api/lib/dialog.coffee',
'atom/browser/api/lib/global-shortcut.coffee',
'atom/browser/api/lib/ipc.coffee',
'atom/browser/api/lib/menu.coffee',
'atom/browser/api/lib/menu-item.coffee',
@@ -27,6 +28,7 @@
'atom/browser/api/lib/protocol.coffee',
'atom/browser/api/lib/tray.coffee',
'atom/browser/api/lib/web-contents.coffee',
'atom/browser/lib/chrome-extension.coffee',
'atom/browser/lib/init.coffee',
'atom/browser/lib/objects-registry.coffee',
'atom/browser/lib/rpc-server.coffee',
@@ -37,6 +39,7 @@
'atom/common/api/lib/screen.coffee',
'atom/common/api/lib/shell.coffee',
'atom/common/lib/init.coffee',
'atom/renderer/lib/chrome-api.coffee',
'atom/renderer/lib/init.coffee',
'atom/renderer/lib/inspector.coffee',
'atom/renderer/lib/override.coffee',
@@ -45,6 +48,8 @@
'atom/renderer/api/lib/web-view.coffee',
],
'lib_sources': [
'atom/app/atom_content_client.cc',
'atom/app/atom_content_client.h',
'atom/app/atom_main_delegate.cc',
'atom/app/atom_main_delegate.h',
'atom/app/atom_main_delegate_mac.mm',
@@ -54,6 +59,8 @@
'atom/browser/api/atom_api_auto_updater.h',
'atom/browser/api/atom_api_content_tracing.cc',
'atom/browser/api/atom_api_dialog.cc',
'atom/browser/api/atom_api_global_shortcut.cc',
'atom/browser/api/atom_api_global_shortcut.h',
'atom/browser/api/atom_api_menu.cc',
'atom/browser/api/atom_api_menu.h',
'atom/browser/api/atom_api_menu_views.cc',
@@ -80,6 +87,8 @@
'atom/browser/auto_updater_linux.cc',
'atom/browser/auto_updater_mac.mm',
'atom/browser/auto_updater_win.cc',
'atom/browser/atom_access_token_store.cc',
'atom/browser/atom_access_token_store.h',
'atom/browser/atom_browser_client.cc',
'atom/browser/atom_browser_client.h',
'atom/browser/atom_browser_context.cc',
@@ -89,6 +98,8 @@
'atom/browser/atom_browser_main_parts_mac.mm',
'atom/browser/atom_javascript_dialog_manager.cc',
'atom/browser/atom_javascript_dialog_manager.h',
'atom/browser/atom_resource_dispatcher_host_delegate.cc',
'atom/browser/atom_resource_dispatcher_host_delegate.h',
'atom/browser/browser.cc',
'atom/browser/browser.h',
'atom/browser/browser_linux.cc',
@@ -110,12 +121,12 @@
'atom/browser/native_window_observer.h',
'atom/browser/net/adapter_request_job.cc',
'atom/browser/net/adapter_request_job.h',
'atom/browser/net/atom_url_request_context_getter.cc',
'atom/browser/net/atom_url_request_context_getter.h',
'atom/browser/net/atom_url_request_job_factory.cc',
'atom/browser/net/atom_url_request_job_factory.h',
'atom/browser/net/url_request_string_job.cc',
'atom/browser/net/url_request_string_job.h',
'atom/browser/node_debugger.cc',
'atom/browser/node_debugger.h',
'atom/browser/ui/accelerator_util.cc',
'atom/browser/ui/accelerator_util.h',
'atom/browser/ui/accelerator_util_mac.mm',
@@ -149,16 +160,19 @@
'atom/browser/ui/views/menu_delegate.h',
'atom/browser/ui/views/menu_layout.cc',
'atom/browser/ui/views/menu_layout.h',
'atom/browser/ui/views/submenu_button.cc',
'atom/browser/ui/views/submenu_button.h',
'atom/browser/ui/views/win_frame_view.cc',
'atom/browser/ui/views/win_frame_view.h',
'atom/browser/ui/win/notify_icon_host.cc',
'atom/browser/ui/win/notify_icon_host.h',
'atom/browser/ui/win/notify_icon.cc',
'atom/browser/ui/win/notify_icon.h',
'atom/browser/ui/x/x_window_utils.cc',
'atom/browser/ui/x/x_window_utils.h',
'atom/browser/window_list.cc',
'atom/browser/window_list.h',
'atom/browser/window_list_observer.h',
'atom/common/api/api_messages.cc',
'atom/common/api/api_messages.h',
'atom/common/api/atom_api_clipboard.cc',
'atom/common/api/atom_api_crash_reporter.cc',
@@ -172,8 +186,8 @@
'atom/common/api/atom_bindings.h',
'atom/common/api/object_life_monitor.cc',
'atom/common/api/object_life_monitor.h',
'atom/common/browser_v8_locker.cc',
'atom/common/browser_v8_locker.h',
'atom/common/common_message_generator.cc',
'atom/common/common_message_generator.h',
'atom/common/crash_reporter/crash_reporter.cc',
'atom/common/crash_reporter/crash_reporter.h',
'atom/common/crash_reporter/crash_reporter_linux.cc',
@@ -191,8 +205,9 @@
'atom/common/draggable_region.cc',
'atom/common/draggable_region.h',
'atom/common/linux/application_info.cc',
'atom/common/native_mate_converters/accelerator_converter.cc',
'atom/common/native_mate_converters/accelerator_converter.h',
'atom/common/native_mate_converters/file_path_converter.h',
'atom/common/native_mate_converters/function_converter.h',
'atom/common/native_mate_converters/gurl_converter.h',
'atom/common/native_mate_converters/image_converter.cc',
'atom/common/native_mate_converters/image_converter.h',
@@ -225,6 +240,35 @@
'atom/renderer/atom_render_view_observer.h',
'atom/renderer/atom_renderer_client.cc',
'atom/renderer/atom_renderer_client.h',
'chromium_src/chrome/browser/browser_process.cc',
'chromium_src/chrome/browser/browser_process.h',
'chromium_src/chrome/browser/chrome_notification_types.h',
'chromium_src/chrome/browser/extensions/global_shortcut_listener.cc',
'chromium_src/chrome/browser/extensions/global_shortcut_listener.h',
'chromium_src/chrome/browser/extensions/global_shortcut_listener_mac.mm',
'chromium_src/chrome/browser/extensions/global_shortcut_listener_mac.h',
'chromium_src/chrome/browser/extensions/global_shortcut_listener_x11.cc',
'chromium_src/chrome/browser/extensions/global_shortcut_listener_x11.h',
'chromium_src/chrome/browser/extensions/global_shortcut_listener_win.cc',
'chromium_src/chrome/browser/extensions/global_shortcut_listener_win.h',
'chromium_src/chrome/browser/printing/print_job.cc',
'chromium_src/chrome/browser/printing/print_job.h',
'chromium_src/chrome/browser/printing/print_job_manager.cc',
'chromium_src/chrome/browser/printing/print_job_manager.h',
'chromium_src/chrome/browser/printing/print_job_worker.cc',
'chromium_src/chrome/browser/printing/print_job_worker.h',
'chromium_src/chrome/browser/printing/print_job_worker_owner.h',
'chromium_src/chrome/browser/printing/print_view_manager_base.cc',
'chromium_src/chrome/browser/printing/print_view_manager_base.h',
'chromium_src/chrome/browser/printing/print_view_manager_basic.cc',
'chromium_src/chrome/browser/printing/print_view_manager_basic.h',
'chromium_src/chrome/browser/printing/print_view_manager_observer.h',
'chromium_src/chrome/browser/printing/printer_query.cc',
'chromium_src/chrome/browser/printing/printer_query.h',
'chromium_src/chrome/browser/printing/printing_message_filter.cc',
'chromium_src/chrome/browser/printing/printing_message_filter.h',
'chromium_src/chrome/browser/printing/printing_ui_web_contents_observer.cc',
'chromium_src/chrome/browser/printing/printing_ui_web_contents_observer.h',
'chromium_src/chrome/browser/ui/libgtk2ui/app_indicator_icon_menu.cc',
'chromium_src/chrome/browser/ui/libgtk2ui/app_indicator_icon_menu.h',
'chromium_src/chrome/browser/ui/libgtk2ui/gtk2_status_icon.cc',
@@ -233,6 +277,13 @@
'chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h',
'chromium_src/chrome/browser/ui/views/status_icons/status_tray_state_changer_win.cc',
'chromium_src/chrome/browser/ui/views/status_icons/status_tray_state_changer_win.h',
'chromium_src/chrome/common/print_messages.cc',
'chromium_src/chrome/common/print_messages.h',
'chromium_src/chrome/renderer/printing/print_web_view_helper.cc',
'chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc',
'chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm',
'chromium_src/chrome/renderer/printing/print_web_view_helper_win.cc',
'chromium_src/chrome/renderer/printing/print_web_view_helper.h',
'<@(native_mate_files)',
],
'framework_sources': [
@@ -423,6 +474,10 @@
'vendor/brightray/brightray.gyp:brightray',
'vendor/node/node.gyp:node_lib',
],
'defines': [
# This is defined in skia/skia_common.gypi.
'SK_SUPPORT_LEGACY_GETTOPDEVICE',
],
'sources': [
'<@(lib_sources)',
],
@@ -624,12 +679,45 @@
# Gyp action requires a output file, add a fake one here.
'<(PRODUCT_DIR)/dummy_file',
],
'action': [ 'strip', '<@(_inputs)' ],
'action': [
'tools/posix/strip.sh',
'<@(_inputs)',
],
},
],
}], # OS=="linux"
],
}, # target <(project_name>_dump_symbols
{
'target_name': 'copy_chromedriver',
'type': 'none',
'actions': [
{
'action_name': 'Copy ChromeDriver Binary',
'variables': {
'conditions': [
['OS=="win"', {
'chromedriver_binary': 'chromedriver.exe',
},{
'chromedriver_binary': 'chromedriver',
}],
],
},
'inputs': [
'<(libchromiumcontent_library_dir)/<(chromedriver_binary)',
],
'outputs': [
'<(PRODUCT_DIR)/<(chromedriver_binary)',
],
'action': [
'python',
'tools/copy_binary.py',
'<@(_inputs)',
'<@(_outputs)',
],
}
],
}, # copy_chromedriver
],
'conditions': [
['OS=="mac"', {
@@ -787,5 +875,31 @@
}, # target generate_node_lib
],
}], # OS==win
# Using Visual Studio Express.
['msvs_express==1', {
'target_defaults': {
'defines!': [
'_SECURE_ATL',
],
'msvs_settings': {
'VCLibrarianTool': {
'AdditionalLibraryDirectories': [
'<(atom_source_root)/external_binaries/atl/lib',
],
},
'VCLinkerTool': {
'AdditionalLibraryDirectories': [
'<(atom_source_root)/external_binaries/atl/lib',
],
'AdditionalDependencies': [
'atls.lib',
],
},
},
'msvs_system_include_dirs': [
'<(atom_source_root)/external_binaries/atl/include',
],
},
}], # msvs_express==1
],
}

View File

@@ -0,0 +1,30 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/app/atom_content_client.h"
#include <string>
#include <vector>
#include "atom/common/chrome_version.h"
namespace atom {
AtomContentClient::AtomContentClient() {
}
AtomContentClient::~AtomContentClient() {
}
std::string AtomContentClient::GetProduct() const {
return "Chrome/" CHROME_VERSION_STRING;
}
void AtomContentClient::AddAdditionalSchemes(
std::vector<std::string>* standard_schemes,
std::vector<std::string>* savable_schemes) {
standard_schemes->push_back("chrome-extension");
}
} // namespace atom

View File

@@ -0,0 +1,33 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_APP_ATOM_CONTENT_CLIENT_H_
#define ATOM_APP_ATOM_CONTENT_CLIENT_H_
#include <string>
#include <vector>
#include "brightray/common/content_client.h"
namespace atom {
class AtomContentClient : public brightray::ContentClient {
public:
AtomContentClient();
virtual ~AtomContentClient();
protected:
// content::ContentClient:
virtual std::string GetProduct() const OVERRIDE;
virtual void AddAdditionalSchemes(
std::vector<std::string>* standard_schemes,
std::vector<std::string>* savable_schemes) OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
};
} // namespace atom
#endif // ATOM_APP_ATOM_CONTENT_CLIENT_H_

View File

@@ -18,7 +18,6 @@
#include "atom/app/atom_main_delegate.h"
#include "atom/common/crash_reporter/win/crash_service_main.h"
#include "base/environment.h"
#include "base/win/registry.h"
#include "content/public/app/startup_helper_win.h"
#include "sandbox/win/src/sandbox_types.h"
#include "ui/gfx/win/dpi.h"
@@ -36,13 +35,6 @@ int Start(int argc, char *argv[]);
#if defined(OS_WIN)
namespace {
const wchar_t kRegistryProfilePath[] = L"SOFTWARE\\Google\\Chrome\\Profile";
const wchar_t kHighDPISupportW[] = L"high-dpi-support";
} // namespace
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
int argc = 0;
wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
@@ -109,10 +101,6 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
atom::AtomMainDelegate delegate;
// Now chrome relies on a regkey to enable high dpi support.
base::win::RegKey high_dpi_key(HKEY_CURRENT_USER);
high_dpi_key.CreateKey(kRegistryProfilePath, KEY_SET_VALUE);
high_dpi_key.WriteValue(kHighDPISupportW, 1);
gfx::EnableHighDPISupport();
content::ContentMainParams params(&delegate);

View File

@@ -6,6 +6,7 @@
#include <string>
#include "atom/app/atom_content_client.h"
#include "atom/browser/atom_browser_client.h"
#include "atom/renderer/atom_renderer_client.h"
#include "base/command_line.h"
@@ -22,18 +23,6 @@ AtomMainDelegate::AtomMainDelegate() {
AtomMainDelegate::~AtomMainDelegate() {
}
void AtomMainDelegate::AddDataPackFromPath(
ui::ResourceBundle* bundle, const base::FilePath& pak_dir) {
#if defined(OS_WIN)
bundle->AddDataPackFromPath(
pak_dir.Append(FILE_PATH_LITERAL("ui_resources_200_percent.pak")),
ui::SCALE_FACTOR_200P);
bundle->AddDataPackFromPath(
pak_dir.Append(FILE_PATH_LITERAL("webkit_resources_200_percent.pak")),
ui::SCALE_FACTOR_200P);
#endif
}
bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
// Disable logging out to debug.log on Windows
#if defined(OS_WIN)
@@ -74,6 +63,13 @@ void AtomMainDelegate::PreSandboxStartup() {
// Add a flag to mark the start of switches added by atom-shell.
command_line->AppendSwitch("atom-shell-switches-start");
#if defined(OS_WIN)
// Disable the LegacyRenderWidgetHostHWND, it made frameless windows unable
// to move and resize. We may consider enabling it again after upgraded to
// Chrome 38, which should have fixed the problem.
command_line->AppendSwitch(switches::kDisableLegacyIntermediateWindow);
#endif
// Disable renderer sandbox for most of node's functions.
command_line->AppendSwitch(switches::kNoSandbox);
@@ -92,4 +88,20 @@ content::ContentRendererClient*
return renderer_client_.get();
}
scoped_ptr<brightray::ContentClient> AtomMainDelegate::CreateContentClient() {
return scoped_ptr<brightray::ContentClient>(new AtomContentClient).Pass();
}
void AtomMainDelegate::AddDataPackFromPath(
ui::ResourceBundle* bundle, const base::FilePath& pak_dir) {
#if defined(OS_WIN)
bundle->AddDataPackFromPath(
pak_dir.Append(FILE_PATH_LITERAL("ui_resources_200_percent.pak")),
ui::SCALE_FACTOR_200P);
bundle->AddDataPackFromPath(
pak_dir.Append(FILE_PATH_LITERAL("webkit_resources_200_percent.pak")),
ui::SCALE_FACTOR_200P);
#endif
}
} // namespace atom

View File

@@ -16,24 +16,23 @@ class AtomMainDelegate : public brightray::MainDelegate {
~AtomMainDelegate();
protected:
// brightray::MainDelegate:
virtual void AddDataPackFromPath(
ui::ResourceBundle* bundle, const base::FilePath& pak_dir) OVERRIDE;
// content::ContentMainDelegate:
virtual bool BasicStartupComplete(int* exit_code) OVERRIDE;
virtual void PreSandboxStartup() OVERRIDE;
virtual content::ContentBrowserClient* CreateContentBrowserClient() OVERRIDE;
virtual content::ContentRendererClient*
CreateContentRendererClient() OVERRIDE;
// brightray::MainDelegate:
virtual scoped_ptr<brightray::ContentClient> CreateContentClient() OVERRIDE;
virtual void AddDataPackFromPath(
ui::ResourceBundle* bundle, const base::FilePath& pak_dir) OVERRIDE;
#if defined(OS_MACOSX)
virtual void OverrideChildProcessPath() OVERRIDE;
virtual void OverrideFrameworkBundlePath() OVERRIDE;
#endif
private:
virtual content::ContentBrowserClient* CreateContentBrowserClient() OVERRIDE;
virtual content::ContentRendererClient*
CreateContentRendererClient() OVERRIDE;
brightray::ContentClient content_client_;
scoped_ptr<content::ContentBrowserClient> browser_client_;
scoped_ptr<content::ContentRendererClient> renderer_client_;

View File

@@ -5,21 +5,76 @@
#include "atom/browser/api/atom_api_app.h"
#include <string>
#include <vector>
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/browser.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "base/values.h"
#include "base/command_line.h"
#include "atom/browser/browser.h"
#include "base/environment.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "native_mate/callback.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "atom/common/node_includes.h"
#if defined(OS_LINUX)
#include "base/nix/xdg_util.h"
#endif
using atom::Browser;
namespace atom {
namespace api {
namespace {
class ResolveProxyHelper {
public:
ResolveProxyHelper(const GURL& url, App::ResolveProxyCallback callback)
: callback_(callback) {
net::ProxyService* proxy_service = AtomBrowserContext::Get()->
url_request_context_getter()->GetURLRequestContext()->proxy_service();
// Start the request.
int result = proxy_service->ResolveProxy(
url, &proxy_info_,
base::Bind(&ResolveProxyHelper::OnResolveProxyCompleted,
base::Unretained(this)),
&pac_req_, net::BoundNetLog());
// Completed synchronously.
if (result != net::ERR_IO_PENDING)
OnResolveProxyCompleted(result);
}
void OnResolveProxyCompleted(int result) {
std::string proxy;
if (result == net::OK)
proxy = proxy_info_.ToPacString();
callback_.Run(proxy);
delete this;
}
private:
App::ResolveProxyCallback callback_;
net::ProxyInfo proxy_info_;
net::ProxyService::PacRequest* pac_req_;
DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper);
};
} // namespace
App::App() {
Browser::Get()->AddObserver(this);
}
@@ -60,6 +115,32 @@ void App::OnFinishLaunching() {
Emit("ready");
}
base::FilePath App::GetDataPath() {
base::FilePath path;
#if defined(OS_LINUX)
scoped_ptr<base::Environment> env(base::Environment::Create());
path = base::nix::GetXDGDirectory(env.get(),
base::nix::kXdgConfigHomeEnvVar,
base::nix::kDotConfigDir);
#else
PathService::Get(base::DIR_APP_DATA, &path);
#endif
return path.Append(base::FilePath::FromUTF8Unsafe(
Browser::Get()->GetName()));
}
void App::ResolveProxy(const GURL& url, ResolveProxyCallback callback) {
new ResolveProxyHelper(url, callback);
}
void App::SetDesktopName(const std::string& desktop_name) {
#if defined(OS_LINUX)
scoped_ptr<base::Environment> env(base::Environment::Create());
env->SetVar("CHROME_DESKTOP", desktop_name);
#endif
}
mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
Browser* browser = Browser::Get();
@@ -75,7 +156,10 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
.SetMethod("getName", base::Bind(&Browser::GetName,
base::Unretained(browser)))
.SetMethod("setName", base::Bind(&Browser::SetName,
base::Unretained(browser)));
base::Unretained(browser)))
.SetMethod("getDataPath", &App::GetDataPath)
.SetMethod("resolveProxy", &App::ResolveProxy)
.SetMethod("setDesktopName", &App::SetDesktopName);
}
// static

View File

@@ -7,11 +7,17 @@
#include <string>
#include "base/compiler_specific.h"
#include "atom/browser/api/event_emitter.h"
#include "atom/browser/browser_observer.h"
#include "base/callback.h"
#include "native_mate/handle.h"
class GURL;
namespace base {
class FilePath;
}
namespace atom {
namespace api {
@@ -19,6 +25,8 @@ namespace api {
class App : public mate::EventEmitter,
public BrowserObserver {
public:
typedef base::Callback<void(std::string)> ResolveProxyCallback;
static mate::Handle<App> Create(v8::Isolate* isolate);
protected:
@@ -40,6 +48,10 @@ class App : public mate::EventEmitter,
v8::Isolate* isolate);
private:
base::FilePath GetDataPath();
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
void SetDesktopName(const std::string& desktop_name);
DISALLOW_COPY_AND_ASSIGN(App);
};

View File

@@ -5,9 +5,9 @@
#include <set>
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/function_converter.h"
#include "base/bind.h"
#include "content/public/browser/tracing_controller.h"
#include "native_mate/callback.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"

View File

@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include <string>
#include <utility>
#include <vector>
#include "atom/browser/api/atom_api_window.h"
@@ -10,12 +11,31 @@
#include "atom/browser/ui/file_dialog.h"
#include "atom/browser/ui/message_box.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/function_converter.h"
#include "base/bind.h"
#include "native_mate/callback.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace mate {
template<>
struct Converter<file_dialog::Filter> {
static bool FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
file_dialog::Filter* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
if (!dict.Get("name", &(out->first)))
return false;
if (!dict.Get("extensions", &(out->second)))
return false;
return true;
}
};
} // namespace mate
namespace {
void ShowMessageBox(int type,
@@ -41,6 +61,7 @@ void ShowMessageBox(int type,
void ShowOpenDialog(const std::string& title,
const base::FilePath& default_path,
const file_dialog::Filters& filters,
int properties,
atom::NativeWindow* window,
mate::Arguments* args) {
@@ -49,18 +70,19 @@ void ShowOpenDialog(const std::string& title,
if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(args->isolate(),
peek,
&callback)) {
file_dialog::ShowOpenDialog(window, title, default_path, properties,
callback);
file_dialog::ShowOpenDialog(window, title, default_path, filters,
properties, callback);
} else {
std::vector<base::FilePath> paths;
if (file_dialog::ShowOpenDialog(window, title, default_path, properties,
&paths))
if (file_dialog::ShowOpenDialog(window, title, default_path, filters,
properties, &paths))
args->Return(paths);
}
}
void ShowSaveDialog(const std::string& title,
const base::FilePath& default_path,
const file_dialog::Filters& filters,
atom::NativeWindow* window,
mate::Arguments* args) {
v8::Handle<v8::Value> peek = args->PeekNext();
@@ -68,10 +90,11 @@ void ShowSaveDialog(const std::string& title,
if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(args->isolate(),
peek,
&callback)) {
file_dialog::ShowSaveDialog(window, title, default_path, callback);
file_dialog::ShowSaveDialog(window, title, default_path, filters, callback);
} else {
base::FilePath path;
if (file_dialog::ShowSaveDialog(window, title, default_path, &path))
if (file_dialog::ShowSaveDialog(window, title, default_path, filters,
&path))
args->Return(path);
}
}

View File

@@ -0,0 +1,98 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_global_shortcut.h"
#include <string>
#include "atom/common/native_mate_converters/accelerator_converter.h"
#include "base/stl_util.h"
#include "native_mate/callback.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
using extensions::GlobalShortcutListener;
namespace atom {
namespace api {
GlobalShortcut::GlobalShortcut() {
}
GlobalShortcut::~GlobalShortcut() {
UnregisterAll();
}
void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
if (accelerator_callback_map_.find(accelerator) ==
accelerator_callback_map_.end()) {
// This should never occur, because if it does, GlobalGlobalShortcutListener
// notifes us with wrong accelerator.
NOTREACHED();
return;
}
accelerator_callback_map_[accelerator].Run();
}
bool GlobalShortcut::Register(const ui::Accelerator& accelerator,
const base::Closure& callback) {
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(
accelerator, this)) {
return false;
}
accelerator_callback_map_[accelerator] = callback;
return true;
}
void GlobalShortcut::Unregister(const ui::Accelerator& accelerator) {
if (!ContainsKey(accelerator_callback_map_, accelerator))
return;
accelerator_callback_map_.erase(accelerator);
GlobalShortcutListener::GetInstance()->UnregisterAccelerator(
accelerator, this);
}
bool GlobalShortcut::IsRegistered(const ui::Accelerator& accelerator) {
return ContainsKey(accelerator_callback_map_, accelerator);
}
void GlobalShortcut::UnregisterAll() {
accelerator_callback_map_.clear();
GlobalShortcutListener::GetInstance()->UnregisterAccelerators(this);
}
mate::ObjectTemplateBuilder GlobalShortcut::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("register", &GlobalShortcut::Register)
.SetMethod("isRegistered", &GlobalShortcut::IsRegistered)
.SetMethod("unregister", &GlobalShortcut::Unregister)
.SetMethod("unregisterAll", &GlobalShortcut::UnregisterAll);
}
// static
mate::Handle<GlobalShortcut> GlobalShortcut::Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new GlobalShortcut);
}
} // namespace api
} // namespace atom
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("globalShortcut", atom::api::GlobalShortcut::Create(isolate));
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_global_shortcut, Initialize)

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
#define ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
#include <map>
#include <string>
#include "base/callback.h"
#include "chrome/browser/extensions/global_shortcut_listener.h"
#include "native_mate/wrappable.h"
#include "native_mate/handle.h"
#include "ui/base/accelerators/accelerator.h"
namespace atom {
namespace api {
class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
public mate::Wrappable {
public:
static mate::Handle<GlobalShortcut> Create(v8::Isolate* isolate);
protected:
GlobalShortcut();
virtual ~GlobalShortcut();
// mate::Wrappable implementations:
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) OVERRIDE;
private:
typedef std::map<ui::Accelerator, base::Closure> AcceleratorCallbackMap;
bool Register(const ui::Accelerator& accelerator,
const base::Closure& callback);
bool IsRegistered(const ui::Accelerator& accelerator);
void Unregister(const ui::Accelerator& accelerator);
void UnregisterAll();
// GlobalShortcutListener::Observer implementation.
virtual void OnKeyPressed(const ui::Accelerator& accelerator) OVERRIDE;
AcceleratorCallbackMap accelerator_callback_map_;
DISALLOW_COPY_AND_ASSIGN(GlobalShortcut);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_

View File

@@ -5,7 +5,7 @@
#include "atom/browser/api/atom_api_menu.h"
#include "atom/browser/native_window.h"
#include "atom/browser/ui/accelerator_util.h"
#include "atom/common/native_mate_converters/accelerator_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
@@ -92,12 +92,7 @@ bool Menu::GetAcceleratorForCommandId(int command_id,
GetWrapper(isolate),
"getAcceleratorForCommandId",
command_id);
if (shortcut->IsString()) {
std::string shortcut_str = mate::V8ToString(shortcut);
return accelerator_util::StringToAccelerator(shortcut_str, accelerator);
}
return false;
return mate::ConvertFromV8(isolate, shortcut, accelerator);
}
bool Menu::IsItemForCommandIdDynamic(int command_id) const {

View File

@@ -4,14 +4,12 @@
#include "atom/browser/api/atom_api_protocol.h"
#include "base/stl_util.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/net/adapter_request_job.h"
#include "atom/browser/net/atom_url_request_context_getter.h"
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/function_converter.h"
#include "content/public/browser/browser_thread.h"
#include "native_mate/callback.h"
#include "native_mate/dictionary.h"
#include "net/url_request/url_request_context.h"
@@ -152,8 +150,9 @@ class CustomProtocolHandler : public ProtocolHandler {
} // namespace
Protocol::Protocol() : job_factory_(
AtomBrowserContext::Get()->url_request_context_getter()->job_factory()) {
Protocol::Protocol()
: job_factory_(AtomBrowserContext::Get()->job_factory()) {
CHECK(job_factory_);
}
Protocol::JsProtocolHandler Protocol::GetProtocolHandler(
@@ -324,10 +323,6 @@ namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
// Make sure the job factory has been created.
atom::AtomBrowserContext::Get()->url_request_context_getter()->
GetURLRequestContext();
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("protocol", atom::api::Protocol::Create(isolate));

View File

@@ -36,6 +36,10 @@ void Tray::OnClicked() {
Emit("clicked");
}
void Tray::OnDoubleClicked() {
Emit("double-clicked");
}
void Tray::SetImage(const gfx::ImageSkia& image) {
tray_icon_->SetImage(image);
}
@@ -48,6 +52,14 @@ void Tray::SetToolTip(const std::string& tool_tip) {
tray_icon_->SetToolTip(tool_tip);
}
void Tray::SetTitle(const std::string& title) {
tray_icon_->SetTitle(title);
}
void Tray::SetHighlightMode(bool highlight) {
tray_icon_->SetHighlightMode(highlight);
}
void Tray::SetContextMenu(Menu* menu) {
tray_icon_->SetContextMenu(menu->model());
}
@@ -59,6 +71,8 @@ void Tray::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setImage", &Tray::SetImage)
.SetMethod("setPressedImage", &Tray::SetPressedImage)
.SetMethod("setToolTip", &Tray::SetToolTip)
.SetMethod("setTitle", &Tray::SetTitle)
.SetMethod("setHighlightMode", &Tray::SetHighlightMode)
.SetMethod("_setContextMenu", &Tray::SetContextMenu);
}

View File

@@ -37,10 +37,13 @@ class Tray : public mate::EventEmitter,
// TrayIcon implementations:
virtual void OnClicked() OVERRIDE;
virtual void OnDoubleClicked() OVERRIDE;
void SetImage(const gfx::ImageSkia& image);
void SetPressedImage(const gfx::ImageSkia& image);
void SetToolTip(const std::string& tool_tip);
void SetTitle(const std::string& title);
void SetHighlightMode(bool highlight);
void SetContextMenu(Menu* menu);
private:

View File

@@ -6,10 +6,8 @@
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/native_window.h"
#include "atom/common/native_mate_converters/function_converter.h"
#include "base/bind.h"
#include "base/callback.h"
#include "content/public/browser/render_process_host.h"
#include "native_mate/callback.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "ui/gfx/point.h"
@@ -18,8 +16,30 @@
#include "atom/common/node_includes.h"
namespace {
struct PrintSettings {
bool silent;
bool print_backgournd;
};
} // namespace
namespace mate {
template<>
struct Converter<PrintSettings> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
PrintSettings* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
dict.Get("silent", &(out->silent));
dict.Get("printBackground", &(out->print_backgournd));
return true;
}
};
template<>
struct Converter<gfx::Rect> {
static bool FromV8(v8::Isolate* isolate,
@@ -305,6 +325,22 @@ bool Window::IsWebViewFocused() {
return window_->IsWebViewFocused();
}
void Window::SetRepresentedFilename(const std::string& filename) {
window_->SetRepresentedFilename(filename);
}
std::string Window::GetRepresentedFilename() {
return window_->GetRepresentedFilename();
}
void Window::SetDocumentEdited(bool edited) {
window_->SetDocumentEdited(edited);
}
bool Window::IsDocumentEdited() {
return window_->IsDocumentEdited();
}
void Window::CapturePage(mate::Arguments* args) {
gfx::Rect rect;
base::Callback<void(v8::Handle<v8::Value>)> callback;
@@ -320,20 +356,18 @@ void Window::CapturePage(mate::Arguments* args) {
rect, base::Bind(&OnCapturePageDone, args->isolate(), callback));
}
void Window::SetRepresentedFilename(const std::string& filename) {
window_->SetRepresentedFilename(filename);
void Window::Print(mate::Arguments* args) {
PrintSettings settings = { false, false };;
if (args->Length() == 1 && !args->GetNext(&settings)) {
args->ThrowError();
return;
}
window_->Print(settings.silent, settings.print_backgournd);
}
std::string Window::GetRepresentedFilename() {
return window_->GetRepresentedFilename();
}
void Window::SetDocumentEdited(bool edited) {
window_->SetDocumentEdited(edited);
}
bool Window::IsDocumentEdited() {
return window_->IsDocumentEdited();
void Window::SetProgressBar(double progress) {
window_->SetProgressBar(progress);
}
mate::Handle<WebContents> Window::GetWebContents(v8::Isolate* isolate) const {
@@ -388,7 +422,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setRepresentedFilename", &Window::SetRepresentedFilename)
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
.SetMethod("IsDocumentEdited", &Window::IsDocumentEdited)
.SetMethod("isDocumentEdited", &Window::IsDocumentEdited)
.SetMethod("_openDevTools", &Window::OpenDevTools)
.SetMethod("closeDevTools", &Window::CloseDevTools)
.SetMethod("isDevToolsOpened", &Window::IsDevToolsOpened)
@@ -397,6 +431,8 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("blurWebView", &Window::BlurWebView)
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
.SetMethod("capturePage", &Window::CapturePage)
.SetMethod("print", &Window::Print)
.SetMethod("setProgressBar", &Window::SetProgressBar)
.SetMethod("_getWebContents", &Window::GetWebContents)
.SetMethod("_getDevToolsWebContents", &Window::GetDevToolsWebContents);
}

View File

@@ -97,11 +97,13 @@ class Window : public mate::EventEmitter,
void FocusOnWebView();
void BlurWebView();
bool IsWebViewFocused();
void CapturePage(mate::Arguments* args);
void SetRepresentedFilename(const std::string& filename);
std::string GetRepresentedFilename();
void SetDocumentEdited(bool edited);
bool IsDocumentEdited();
void CapturePage(mate::Arguments* args);
void Print(mate::Arguments* args);
void SetProgressBar(double progress);
// APIs for WebContents.
mate::Handle<WebContents> GetWebContents(v8::Isolate* isolate) const;

View File

@@ -35,6 +35,10 @@ BrowserWindow::openDevTools = ->
@devToolsWebContents = @getDevToolsWebContents()
@devToolsWebContents.once 'destroyed', => @devToolsWebContents = null
# Emit devtools events.
@devToolsWebContents.once 'did-finish-load', => @emit 'devtools-opened'
@devToolsWebContents.once 'destroyed', => @emit 'devtools-closed'
BrowserWindow::toggleDevTools = ->
if @isDevToolsOpened() then @closeDevTools() else @openDevTools()

View File

@@ -3,17 +3,28 @@ v8Util = process.atomBinding 'v8_util'
BrowserWindow = require 'browser-window'
fileDialogProperties =
openFile: 1, openDirectory: 2, multiSelections: 4, createDirectory: 8
openFile: 1 << 0
openDirectory: 1 << 1
multiSelections: 1 << 2
createDirectory: 1 << 3
messageBoxTypes = ['none', 'info', 'warning']
parseArgs = (window, options, callback) ->
unless window is null or window?.constructor is BrowserWindow
# Shift.
callback = options
options = window
window = null
if not callback? and typeof options is 'function'
# Shift.
callback = options
options = null
[window, options, callback]
module.exports =
showOpenDialog: (window, options, callback) ->
unless window?.constructor is BrowserWindow
# Shift.
callback = options
options = window
window = null
showOpenDialog: (args...) ->
[window, options, callback] = parseArgs args...
options ?= title: 'Open', properties: ['openFile']
options.properties ?= ['openFile']
@@ -25,6 +36,7 @@ module.exports =
options.title ?= ''
options.defaultPath ?= ''
options.filters ?= []
wrappedCallback =
if typeof callback is 'function'
@@ -34,20 +46,18 @@ module.exports =
binding.showOpenDialog String(options.title),
String(options.defaultPath),
options.filters
properties,
window,
wrappedCallback
showSaveDialog: (window, options, callback) ->
unless window?.constructor is BrowserWindow
# Shift.
callback = options
options = window
window = null
showSaveDialog: (args...) ->
[window, options, callback] = parseArgs args...
options ?= title: 'Save'
options.title ?= ''
options.defaultPath ?= ''
options.filters ?= []
wrappedCallback =
if typeof callback is 'function'
@@ -57,15 +67,12 @@ module.exports =
binding.showSaveDialog String(options.title),
String(options.defaultPath),
options.filters
window,
wrappedCallback
showMessageBox: (window, options, callback) ->
unless window?.constructor is BrowserWindow
# Shift.
callback = options
options = window
window = null
showMessageBox: (args...) ->
[window, options, callback] = parseArgs args...
options ?= type: 'none'
options.type ?= 'none'

View File

@@ -0,0 +1,5 @@
bindings = process.atomBinding 'global_shortcut'
globalShortcut = bindings.globalShortcut
module.exports = globalShortcut

View File

@@ -0,0 +1,53 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/atom_access_token_store.h"
#include <utility>
#include "atom/browser/atom_browser_context.h"
#ifndef GOOGLEAPIS_API_KEY
#define GOOGLEAPIS_API_KEY "AIzaSyAQfxPJiounkhOjODEO5ZieffeBv6yft2Q"
#endif
namespace atom {
namespace {
// Notice that we just combined the api key with the url together here, because
// if we use the standard {url: key} format Chromium would override our key with
// the predefined one in common.gypi of libchromiumcontent, which is empty.
const char* kGeolocationProviderUrl =
"https://www.googleapis.com/geolocation/v1/geolocate?key="
GOOGLEAPIS_API_KEY;
} // namespace
AtomAccessTokenStore::AtomAccessTokenStore() {
}
AtomAccessTokenStore::~AtomAccessTokenStore() {
}
void AtomAccessTokenStore::LoadAccessTokens(
const LoadAccessTokensCallbackType& callback) {
AccessTokenSet access_token_set;
// Equivelent to access_token_set[kGeolocationProviderUrl].
// Somehow base::string16 is causing compilation errors when used in a pair
// of std::map on Linux, this can work around it.
std::pair<GURL, base::string16> token_pair;
token_pair.first = GURL(kGeolocationProviderUrl);
access_token_set.insert(token_pair);
callback.Run(access_token_set,
AtomBrowserContext::Get()->url_request_context_getter());
}
void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url,
const base::string16& access_token) {
}
} // namespace atom

View File

@@ -0,0 +1,31 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_ATOM_ACCESS_TOKEN_STORE_H_
#define ATOM_BROWSER_ATOM_ACCESS_TOKEN_STORE_H_
#include "content/public/browser/access_token_store.h"
namespace atom {
class AtomBrowserContext;
class AtomAccessTokenStore : public content::AccessTokenStore {
public:
AtomAccessTokenStore();
virtual ~AtomAccessTokenStore();
// content::AccessTokenStore:
virtual void LoadAccessTokens(
const LoadAccessTokensCallbackType& callback) OVERRIDE;
virtual void SaveAccessToken(const GURL& server_url,
const base::string16& access_token) OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(AtomAccessTokenStore);
};
} // namespace atom
#endif // ATOM_BROWSER_ATOM_ACCESS_TOKEN_STORE_H_

View File

@@ -4,13 +4,16 @@
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/atom_access_token_store.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
#include "atom/browser/native_window.h"
#include "atom/browser/net/atom_url_request_context_getter.h"
#include "atom/browser/window_list.h"
#include "chrome/browser/printing/printing_message_filter.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
@@ -46,12 +49,19 @@ AtomBrowserClient::AtomBrowserClient()
AtomBrowserClient::~AtomBrowserClient() {
}
net::URLRequestContextGetter* AtomBrowserClient::CreateRequestContext(
content::BrowserContext* browser_context,
content::ProtocolHandlerMap* protocol_handlers,
content::ProtocolHandlerScopedVector protocol_interceptors) {
return static_cast<AtomBrowserContext*>(browser_context)->
CreateRequestContext(protocol_handlers);
void AtomBrowserClient::RenderProcessWillLaunch(
content::RenderProcessHost* host) {
host->AddFilter(new PrintingMessageFilter(host->GetID()));
}
void AtomBrowserClient::ResourceDispatcherHostCreated() {
resource_dispatcher_delegate_.reset(new AtomResourceDispatcherHostDelegate);
content::ResourceDispatcherHost::Get()->SetDelegate(
resource_dispatcher_delegate_.get());
}
content::AccessTokenStore* AtomBrowserClient::CreateAccessTokenStore() {
return new AtomAccessTokenStore;
}
void AtomBrowserClient::OverrideWebkitPrefs(
@@ -75,6 +85,12 @@ void AtomBrowserClient::OverrideWebkitPrefs(
prefs->allow_displaying_insecure_content = true;
prefs->allow_running_insecure_content = true;
// Turn off web security for devtools.
if (url.SchemeIs("chrome-devtools")) {
prefs->web_security_enabled = false;
return;
}
NativeWindow* window = NativeWindow::FromRenderView(
render_view_host->GetProcess()->GetID(),
render_view_host->GetRoutingID());

View File

@@ -11,6 +11,8 @@
namespace atom {
class AtomResourceDispatcherHostDelegate;
class AtomBrowserClient : public brightray::BrowserClient {
public:
AtomBrowserClient();
@@ -18,10 +20,10 @@ class AtomBrowserClient : public brightray::BrowserClient {
protected:
// content::ContentBrowserClient:
net::URLRequestContextGetter* CreateRequestContext(
content::BrowserContext* browser_context,
content::ProtocolHandlerMap* protocol_handlers,
content::ProtocolHandlerScopedVector protocol_interceptors) OVERRIDE;
virtual void RenderProcessWillLaunch(
content::RenderProcessHost* host) OVERRIDE;
virtual void ResourceDispatcherHostCreated() OVERRIDE;
virtual content::AccessTokenStore* CreateAccessTokenStore() OVERRIDE;
virtual void OverrideWebkitPrefs(content::RenderViewHost* render_view_host,
const GURL& url,
WebPreferences* prefs) OVERRIDE;
@@ -37,6 +39,8 @@ class AtomBrowserClient : public brightray::BrowserClient {
virtual brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
const content::MainFunctionParams&) OVERRIDE;
scoped_ptr<AtomResourceDispatcherHostDelegate> resource_dispatcher_delegate_;
// The render process which would be swapped out soon.
content::RenderProcessHost* dying_render_process_;

View File

@@ -5,72 +5,56 @@
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/net/atom_url_request_context_getter.h"
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/worker_pool.h"
#include "chrome/browser/browser_process.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_context.h"
#include "vendor/brightray/browser/network_delegate.h"
namespace atom {
#include "content/public/common/url_constants.h"
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/file_protocol_handler.h"
#include "net/url_request/url_request_intercepting_job_factory.h"
#include "url/url_constants.h"
using content::BrowserThread;
class AtomResourceContext : public content::ResourceContext {
public:
AtomResourceContext() : getter_(NULL) {}
void set_url_request_context_getter(AtomURLRequestContextGetter* getter) {
getter_ = getter;
}
protected:
virtual net::HostResolver* GetHostResolver() OVERRIDE {
DCHECK(getter_);
return getter_->host_resolver();
}
virtual net::URLRequestContext* GetRequestContext() OVERRIDE {
DCHECK(getter_);
return getter_->GetURLRequestContext();
}
virtual bool AllowMicAccess(const GURL& origin) OVERRIDE {
return true;
}
virtual bool AllowCameraAccess(const GURL& origin) OVERRIDE {
return true;
}
private:
AtomURLRequestContextGetter* getter_;
DISALLOW_COPY_AND_ASSIGN(AtomResourceContext);
};
namespace atom {
AtomBrowserContext::AtomBrowserContext()
: resource_context_(new AtomResourceContext) {
: fake_browser_process_(new BrowserProcess),
job_factory_(new AtomURLRequestJobFactory) {
}
AtomBrowserContext::~AtomBrowserContext() {
}
AtomURLRequestContextGetter* AtomBrowserContext::CreateRequestContext(
content::ProtocolHandlerMap* protocol_handlers) {
DCHECK(!url_request_getter_);
url_request_getter_ = new AtomURLRequestContextGetter(
GetPath(),
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE),
base::Bind(&AtomBrowserContext::CreateNetworkDelegate,
base::Unretained(this)),
protocol_handlers);
net::URLRequestJobFactory* AtomBrowserContext::CreateURLRequestJobFactory(
content::ProtocolHandlerMap* handlers,
content::URLRequestInterceptorScopedVector* interceptors) {
scoped_ptr<AtomURLRequestJobFactory> job_factory(job_factory_);
resource_context_->set_url_request_context_getter(url_request_getter_.get());
return url_request_getter_.get();
}
for (content::ProtocolHandlerMap::iterator it = handlers->begin();
it != handlers->end(); ++it)
job_factory->SetProtocolHandler(it->first, it->second.release());
handlers->clear();
content::ResourceContext* AtomBrowserContext::GetResourceContext() {
return resource_context_.get();
job_factory->SetProtocolHandler(
url::kDataScheme, new net::DataProtocolHandler);
job_factory->SetProtocolHandler(
url::kFileScheme, new net::FileProtocolHandler(
BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
// Set up interceptors in the reverse order.
scoped_ptr<net::URLRequestJobFactory> top_job_factory =
job_factory.PassAs<net::URLRequestJobFactory>();
content::URLRequestInterceptorScopedVector::reverse_iterator it;
for (it = interceptors->rbegin(); it != interceptors->rend(); ++it)
top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
top_job_factory.Pass(), make_scoped_ptr(*it)));
interceptors->weak_clear();
return top_job_factory.release();
}
// static

View File

@@ -5,13 +5,13 @@
#ifndef ATOM_BROWSER_ATOM_BROWSER_CONTEXT_H_
#define ATOM_BROWSER_ATOM_BROWSER_CONTEXT_H_
#include "base/memory/scoped_ptr.h"
#include "brightray/browser/browser_context.h"
class BrowserProcess;
namespace atom {
class AtomResourceContext;
class AtomURLRequestContextGetter;
class AtomURLRequestJobFactory;
class AtomBrowserContext : public brightray::BrowserContext {
public:
@@ -21,22 +21,19 @@ class AtomBrowserContext : public brightray::BrowserContext {
// Returns the browser context singleton.
static AtomBrowserContext* Get();
// Creates or returns the request context.
AtomURLRequestContextGetter* CreateRequestContext(
content::ProtocolHandlerMap*);
AtomURLRequestContextGetter* url_request_context_getter() const {
DCHECK(url_request_getter_);
return url_request_getter_.get();
}
AtomURLRequestJobFactory* job_factory() const { return job_factory_; }
protected:
// content::BrowserContext implementations:
virtual content::ResourceContext* GetResourceContext() OVERRIDE;
// brightray::URLRequestContextGetter::Delegate:
virtual net::URLRequestJobFactory* CreateURLRequestJobFactory(
content::ProtocolHandlerMap* handlers,
content::URLRequestInterceptorScopedVector* interceptors) OVERRIDE;
private:
scoped_ptr<AtomResourceContext> resource_context_;
scoped_refptr<AtomURLRequestContextGetter> url_request_getter_;
// A fake BrowserProcess object that used to feed the source code from chrome.
scoped_ptr<BrowserProcess> fake_browser_process_;
AtomURLRequestJobFactory* job_factory_; // Weak reference.
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
};

View File

@@ -8,13 +8,11 @@
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/browser.h"
#include "atom/browser/javascript_environment.h"
#include "atom/browser/node_debugger.h"
#include "atom/common/api/atom_bindings.h"
#include "atom/common/node_bindings.h"
#include "base/command_line.h"
#if defined(OS_WIN)
#include "ui/gfx/win/dpi.h"
#endif
#include "v8/include/v8-debug.h"
#if defined(USE_X11)
#include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
@@ -57,28 +55,32 @@ void AtomBrowserMainParts::PostEarlyInitialization() {
node_bindings_->Initialize();
// Support the "--debug" switch.
node_debugger_.reset(new NodeDebugger(js_env_->isolate()));
// Create the global environment.
global_env = node_bindings_->CreateEnvironment(js_env_->context());
// Make sure node can get correct environment when debugging.
if (node_debugger_->IsRunning())
global_env->AssignToContext(v8::Debug::GetDebugContext());
// Add atom-shell extended APIs.
atom_bindings_->BindTo(js_env_->isolate(), global_env->process_object());
}
void AtomBrowserMainParts::PreMainMessageLoopRun() {
// Run user's main script before most things get initialized, so we can have
// a chance to setup everything.
node_bindings_->PrepareMessageLoop();
node_bindings_->RunMessageLoop();
brightray::BrowserMainParts::PreMainMessageLoopRun();
#if defined(USE_X11)
libgtk2ui::GtkInitFromCommandLine(*CommandLine::ForCurrentProcess());
#endif
node_bindings_->PrepareMessageLoop();
node_bindings_->RunMessageLoop();
// Make sure the url request job factory is created before the
// will-finish-launching event.
static_cast<content::BrowserContext*>(AtomBrowserContext::Get())->
GetRequestContext();
#if !defined(OS_MACOSX)
// The corresponding call in OS X is in AtomApplicationDelegate.
Browser::Get()->WillFinishLaunching();

View File

@@ -13,6 +13,7 @@ class AtomBindings;
class Browser;
class JavascriptEnvironment;
class NodeBindings;
class NodeDebugger;
class AtomBrowserMainParts : public brightray::BrowserMainParts {
public:
@@ -40,6 +41,7 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
scoped_ptr<JavascriptEnvironment> js_env_;
scoped_ptr<NodeBindings> node_bindings_;
scoped_ptr<AtomBindings> atom_bindings_;
scoped_ptr<NodeDebugger> node_debugger_;
static AtomBrowserMainParts* self_;

View File

@@ -0,0 +1,50 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
#include <string>
#include "base/logging.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/resource_request_info.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
namespace atom {
namespace {
const char* kDisableXFrameOptions = "disable-x-frame-options";
} // namespace
AtomResourceDispatcherHostDelegate::AtomResourceDispatcherHostDelegate() {
}
AtomResourceDispatcherHostDelegate::~AtomResourceDispatcherHostDelegate() {
}
void AtomResourceDispatcherHostDelegate::OnResponseStarted(
net::URLRequest* request,
content::ResourceContext* resource_context,
content::ResourceResponse* response,
IPC::Sender* sender) {
// Check if frame's name contains "disable-x-frame-options"
int p, f;
if (!content::ResourceRequestInfo::GetRenderFrameForRequest(request, &p, &f))
return;
content::RenderFrameHost* frame = content::RenderFrameHost::FromID(p, f);
if (!frame)
return;
if (frame->GetFrameName().find(kDisableXFrameOptions) == std::string::npos)
return;
// Remove the "X-Frame-Options" from response headers.
net::HttpResponseHeaders* response_headers = request->response_headers();
if (response_headers && response_headers->HasHeader("x-frame-options"))
response_headers->RemoveHeader("x-frame-options");
}
} // namespace atom

View File

@@ -0,0 +1,31 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_ATOM_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
#define ATOM_BROWSER_ATOM_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
#include "base/compiler_specific.h"
#include "content/public/browser/resource_dispatcher_host_delegate.h"
namespace atom {
class AtomResourceDispatcherHostDelegate
: public content::ResourceDispatcherHostDelegate {
public:
AtomResourceDispatcherHostDelegate();
virtual ~AtomResourceDispatcherHostDelegate();
// content::ResourceDispatcherHostDelegate:
virtual void OnResponseStarted(net::URLRequest* request,
content::ResourceContext* resource_context,
content::ResourceResponse* response,
IPC::Sender* sender) OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(AtomResourceDispatcherHostDelegate);
};
} // namespace atom
#endif // ATOM_BROWSER_ATOM_RESOURCE_DISPATCHER_HOST_DELEGATE_H_

View File

@@ -48,11 +48,13 @@ void AutoUpdater::SetFeedURL(const std::string& feed) {
[[g_updater rac_valuesForKeyPath:@"state" observer:g_updater]
subscribeNext:^(NSNumber *stateNumber) {
int state = [stateNumber integerValue];
if (state == SQRLUpdaterStateCheckingForUpdate) {
delegate->OnCheckingForUpdate();
} else if (state == SQRLUpdaterStateDownloadingUpdate) {
delegate->OnUpdateAvailable();
}
// Dispatching the event on main thread.
dispatch_async(dispatch_get_main_queue(), ^{
if (state == SQRLUpdaterStateCheckingForUpdate)
delegate->OnCheckingForUpdate();
else if (state == SQRLUpdaterStateDownloadingUpdate)
delegate->OnUpdateAvailable();
});
}];
}
}
@@ -89,4 +91,5 @@ void AutoUpdater::CheckForUpdates() {
delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription));
}];
}
} // namespace auto_updater

View File

@@ -21,6 +21,7 @@ app.on('ready', function() {
'use-content-size': true,
});
mainWindow.loadUrl('file://' + __dirname + '/index.html');
mainWindow.focus();
if (process.platform == 'darwin') {
var template = [
@@ -34,6 +35,13 @@ app.on('ready', function() {
{
type: 'separator'
},
{
label: 'Services',
submenu: []
},
{
type: 'separator'
},
{
label: 'Hide Atom Shell',
accelerator: 'Command+H',

View File

@@ -2,7 +2,6 @@ var app = require('app');
var dialog = require('dialog');
var fs = require('fs');
var path = require('path');
var optimist = require('optimist');
// Quit when all windows are closed and no other one is listening to this.
app.on('window-all-closed', function() {
@@ -10,14 +9,29 @@ app.on('window-all-closed', function() {
app.quit();
});
var argv = optimist(process.argv.slice(1)).boolean('ci').argv;
// Parse command line options.
var argv = process.argv.slice(1);
var option = { file: null, version: null, webdriver: null };
for (var i in argv) {
if (argv[i] == '--version' || argv[i] == '-v') {
option.version = true;
break;
} else if (argv[i] == '--test-type=webdriver') {
option.webdriver = true;
} else if (argv[i][0] == '-') {
continue;
} else {
option.file = argv[i];
break;
}
}
// Start the specified app if there is one specified in command line, otherwise
// start the default app.
if (argv._.length > 0) {
if (option.file && !option.webdriver) {
try {
// Override app name and version.
var packagePath = path.resolve(argv._[0]);
var packagePath = path.resolve(option.file);
var packageJsonPath = path.join(packagePath, 'package.json');
if (fs.existsSync(packageJsonPath)) {
var packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
@@ -48,7 +62,7 @@ if (argv._.length > 0) {
throw e;
}
}
} else if (argv.version) {
} else if (option.version) {
console.log('v' + process.versions['atom-shell']);
process.exit(0);
} else {

View File

@@ -2,8 +2,5 @@
"name": "atom-shell-default-app",
"productName": "Atom Shell Default App",
"version": "0.1.0",
"main": "main.js",
"dependencies": {
"optimist": "*"
}
"main": "main.js"
}

View File

@@ -7,7 +7,9 @@
namespace atom {
JavascriptEnvironment::JavascriptEnvironment()
: isolate_(v8::Isolate::GetCurrent()),
: isolate_holder_(gin::IsolateHolder::kNonStrictMode),
isolate_(isolate_holder_.isolate()),
isolate_scope_(isolate_),
locker_(isolate_),
handle_scope_(isolate_),
context_(isolate_, v8::Context::New(isolate_)),

View File

@@ -6,7 +6,7 @@
#define ATOM_BROWSER_JAVASCRIPT_ENVIRONMENT_H_
#include "base/basictypes.h"
#include "v8/include/v8.h"
#include "gin/public/isolate_holder.h"
namespace atom {
@@ -20,7 +20,9 @@ class JavascriptEnvironment {
}
private:
gin::IsolateHolder isolate_holder_;
v8::Isolate* isolate_;
v8::Isolate::Scope isolate_scope_;
v8::Locker locker_;
v8::HandleScope handle_scope_;
v8::UniquePersistent<v8::Context> context_;

View File

@@ -0,0 +1,88 @@
app = require 'app'
fs = require 'fs'
path = require 'path'
url = require 'url'
# Mapping between hostname and file path.
hostPathMap = {}
hostPathMapNextKey = 0
getHostForPath = (path) ->
key = "extension-#{++hostPathMapNextKey}"
hostPathMap[key] = path
key
getPathForHost = (host) ->
hostPathMap[host]
# Cache extensionInfo.
extensionInfoMap = {}
getExtensionInfoFromPath = (srcDirectory) ->
manifest = JSON.parse fs.readFileSync(path.join(srcDirectory, 'manifest.json'))
unless extensionInfoMap[manifest.name]?
# We can not use 'file://' directly because all resources in the extension
# will be treated as relative to the root in Chrome.
page = url.format
protocol: 'chrome-extension'
slashes: true
hostname: getHostForPath srcDirectory
pathname: manifest.devtools_page
extensionInfoMap[manifest.name] =
startPage: page
name: manifest.name
srcDirectory: srcDirectory
extensionInfoMap[manifest.name]
# Load persistented extensions.
loadedExtensionsPath = path.join app.getDataPath(), 'DevTools Extensions'
try
loadedExtensions = JSON.parse fs.readFileSync(loadedExtensionsPath)
loadedExtensions = [] unless Array.isArray loadedExtensions
# Preheat the extensionInfo cache.
getExtensionInfoFromPath srcDirectory for srcDirectory in loadedExtensions
catch e
# Persistent loaded extensions.
app.on 'will-quit', ->
try
loadedExtensions = Object.keys(extensionInfoMap).map (key) -> extensionInfoMap[key].srcDirectory
try
fs.mkdirSync path.dirname(loadedExtensionsPath)
catch e
fs.writeFileSync loadedExtensionsPath, JSON.stringify(loadedExtensions)
catch e
# We can not use protocol or BrowserWindow until app is ready.
app.once 'ready', ->
protocol = require 'protocol'
BrowserWindow = require 'browser-window'
# The chrome-extension: can map a extension URL request to real file path.
protocol.registerProtocol 'chrome-extension', (request) ->
parsed = url.parse request.url
return unless parsed.hostname and parsed.path?
return unless /extension-\d+/.test parsed.hostname
directory = getPathForHost parsed.hostname
return unless directory?
return new protocol.RequestFileJob(path.join(directory, parsed.path))
BrowserWindow::_loadDevToolsExtensions = (extensionInfoArray) ->
@devToolsWebContents?.executeJavaScript "WebInspector.addExtensions(#{JSON.stringify(extensionInfoArray)});"
BrowserWindow.addDevToolsExtension = (srcDirectory) ->
extensionInfo = getExtensionInfoFromPath srcDirectory
window._loadDevToolsExtensions [extensionInfo] for window in BrowserWindow.getAllWindows()
extensionInfo.name
BrowserWindow.removeDevToolsExtension = (name) ->
delete extensionInfoMap[name]
# Load persistented extensions when devtools is opened.
init = BrowserWindow::_init
BrowserWindow::_init = ->
init.call this
@on 'devtools-opened', ->
@_loadDevToolsExtensions Object.keys(extensionInfoMap).map (key) -> extensionInfoMap[key]

View File

@@ -47,7 +47,7 @@ setImmediate ->
message = error.stack ? "#{error.name}: #{error.message}"
require('dialog').showMessageBox
type: 'warning'
title: 'An javascript error occured in the browser'
title: 'A javascript error occured in the browser'
message: 'uncaughtException'
detail: message
buttons: ['OK']
@@ -77,5 +77,14 @@ setImmediate ->
else if packageJson.name?
app.setName packageJson.name
# Set application's desktop name.
if packageJson.desktopName?
app.setDesktopName packageJson.desktopName
else
app.setDesktopName '#{app.getName()}.desktop'
# Load the chrome extension support.
require './chrome-extension.js'
# Finally load app's main.js and transfer control to C++.
module._load path.join(packagePath, packageJson.main), module, true

View File

@@ -27,6 +27,9 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h"
#include "chrome/browser/printing/print_view_manager_basic.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_entry.h"
@@ -38,28 +41,48 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/user_agent.h"
#include "ipc/ipc_message_macros.h"
#include "native_mate/dictionary.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/point.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
#include "vendor/brightray/browser/inspectable_web_contents.h"
#include "vendor/brightray/browser/inspectable_web_contents_view.h"
#include "webkit/common/webpreferences.h"
using content::NavigationEntry;
namespace atom {
namespace {
// Array of available web runtime features.
const char* kWebRuntimeFeatures[] = {
switches::kExperimentalFeatures,
switches::kExperimentalCanvasFeatures,
switches::kSubpixelFontScaling,
switches::kOverlayScrollbars,
switches::kOverlayFullscreenVideo,
switches::kSharedWorker,
};
std::string RemoveWhitespace(const std::string& str) {
std::string trimmed;
if (base::RemoveChars(str, " ", &trimmed))
return trimmed;
else
return str;
}
} // namespace
NativeWindow::NativeWindow(content::WebContents* web_contents,
const mate::Dictionary& options)
: content::WebContentsObserver(web_contents),
has_frame_(true),
enable_larger_than_screen_(false),
is_closed_(false),
node_integration_("except-iframe"),
has_dialog_attached_(false),
@@ -67,12 +90,13 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
weak_factory_(this),
inspectable_web_contents_(
brightray::InspectableWebContents::Create(web_contents)) {
printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
options.Get(switches::kFrame, &has_frame_);
options.Get(switches::kEnableLargerThanScreen, &enable_larger_than_screen_);
// Read icon before window is created.
gfx::ImageSkia icon;
if (options.Get(switches::kIcon, &icon))
icon_.reset(new gfx::Image(icon));
options.Get(switches::kIcon, &icon_);
// Read iframe security before any navigation.
options.Get(switches::kNodeIntegration, &node_integration_);
@@ -91,8 +115,8 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
// Override the user agent to contain application and atom-shell's version.
Browser* browser = Browser::Get();
std::string product_name = base::StringPrintf(
"%s/%s Chrome/%s Atom-Shell/" ATOM_VERSION_STRING,
browser->GetName().c_str(),
"%s/%s Chrome/%s AtomShell/" ATOM_VERSION_STRING,
RemoveWhitespace(browser->GetName()).c_str(),
browser->GetVersion().c_str(),
CHROME_VERSION_STRING);
web_contents->GetMutableRendererPrefs()->user_agent_override =
@@ -143,8 +167,8 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
} else if (options.Get(switches::kCenter, &center) && center) {
Center();
}
int min_height = -1, min_width = -1;
if (options.Get(switches::kMinHeight, &min_height) &&
int min_height = 0, min_width = 0;
if (options.Get(switches::kMinHeight, &min_height) |
options.Get(switches::kMinWidth, &min_width)) {
SetMinimumSize(gfx::Size(min_width, min_height));
}
@@ -194,11 +218,16 @@ std::string NativeWindow::GetRepresentedFilename() {
void NativeWindow::SetDocumentEdited(bool edited) {
}
bool NativeWindow::IsDocumentEdited() {
return false;
}
void NativeWindow::SetMenu(ui::MenuModel* menu) {
}
bool NativeWindow::IsDocumentEdited() {
return false;
void NativeWindow::Print(bool silent, bool print_background) {
printing::PrintViewManagerBasic::FromWebContents(GetWebContents())->
PrintNow(silent, print_background);
}
bool NativeWindow::HasModalDialog() {
@@ -251,18 +280,10 @@ void NativeWindow::CapturePage(const gfx::Rect& rect,
return;
}
gfx::Rect flipped_y_rect = rect;
flipped_y_rect.set_y(-rect.y());
gfx::Size size;
if (flipped_y_rect.IsEmpty())
size = render_widget_host_view->GetViewBounds().size();
else
size = flipped_y_rect.size();
GetWebContents()->GetRenderViewHost()->CopyFromBackingStore(
flipped_y_rect,
size,
rect,
rect.IsEmpty() ? render_widget_host_view->GetViewBounds().size() :
rect.size(),
base::Bind(&NativeWindow::OnCapturePageDone,
weak_factory_.GetWeakPtr(),
callback),
@@ -327,6 +348,24 @@ void NativeWindow::AppendExtraCommandLineSwitches(
if (zoom_factor_ != 1.0)
command_line->AppendSwitchASCII(switches::kZoomFactor,
base::DoubleToString(zoom_factor_));
if (web_preferences_.IsEmpty())
return;
bool b;
#if defined(OS_WIN)
// Check if DirectWrite is disabled.
if (web_preferences_.Get(switches::kDirectWrite, &b) && !b)
command_line->AppendSwitch(::switches::kDisableDirectWrite);
#endif
// This set of options are not availabe in WebPreferences, so we have to pass
// them via command line and enable them in renderer procss.
for (size_t i = 0; i < arraysize(kWebRuntimeFeatures); ++i) {
const char* feature = kWebRuntimeFeatures[i];
if (web_preferences_.Get(feature, &b))
command_line->AppendSwitchASCII(feature, b ? "true" : "false");
}
}
void NativeWindow::OverrideWebkitPrefs(const GURL& url, WebPreferences* prefs) {
@@ -335,25 +374,23 @@ void NativeWindow::OverrideWebkitPrefs(const GURL& url, WebPreferences* prefs) {
bool b;
std::vector<base::FilePath> list;
mate::Dictionary web_preferences(web_preferences_.isolate(),
web_preferences_.NewHandle());
if (web_preferences.Get("javascript", &b))
if (web_preferences_.Get("javascript", &b))
prefs->javascript_enabled = b;
if (web_preferences.Get("web-security", &b))
if (web_preferences_.Get("web-security", &b))
prefs->web_security_enabled = b;
if (web_preferences.Get("images", &b))
if (web_preferences_.Get("images", &b))
prefs->images_enabled = b;
if (web_preferences.Get("java", &b))
if (web_preferences_.Get("java", &b))
prefs->java_enabled = b;
if (web_preferences.Get("text-areas-are-resizable", &b))
if (web_preferences_.Get("text-areas-are-resizable", &b))
prefs->text_areas_are_resizable = b;
if (web_preferences.Get("webgl", &b))
if (web_preferences_.Get("webgl", &b))
prefs->experimental_webgl_enabled = b;
if (web_preferences.Get("webaudio", &b))
if (web_preferences_.Get("webaudio", &b))
prefs->webaudio_enabled = b;
if (web_preferences.Get("plugins", &b))
if (web_preferences_.Get("plugins", &b))
prefs->plugins_enabled = b;
if (web_preferences.Get("extra-plugin-dirs", &list))
if (web_preferences_.Get("extra-plugin-dirs", &list))
for (size_t i = 0; i < list.size(); ++i)
content::PluginService::GetInstance()->AddExtraPluginDir(list[i]);
}
@@ -449,6 +486,9 @@ void NativeWindow::MoveContents(content::WebContents* source,
}
void NativeWindow::CloseContents(content::WebContents* source) {
// Destroy the WebContents before we close the window.
DestroyWebContents();
// When the web contents is gone, close the window immediately, but the
// memory will not be freed until you call delete.
// In this way, it would be safe to manage windows via smart pointers. If you
@@ -525,8 +565,9 @@ void NativeWindow::DevToolsSaveToFile(const std::string& url,
if (it != saved_files_.end() && !save_as) {
path = it->second;
} else {
file_dialog::Filters filters;
base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url));
if (!file_dialog::ShowSaveDialog(this, url, default_path, &path)) {
if (!file_dialog::ShowSaveDialog(this, url, default_path, filters, &path)) {
base::StringValue url_value(url);
CallDevToolsFunction("InspectorFrontendAPI.canceledSaveURL", &url_value);
return;

View File

@@ -9,20 +9,19 @@
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "atom/browser/native_window_observer.h"
#include "atom/browser/ui/accelerator_util.h"
#include "base/cancelable_callback.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "atom/browser/native_window_observer.h"
#include "atom/browser/ui/accelerator_util.h"
#include "brightray/browser/default_web_contents_delegate.h"
#include "brightray/browser/inspectable_web_contents_delegate.h"
#include "brightray/browser/inspectable_web_contents_impl.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_observer.h"
#include "native_mate/scoped_persistent.h"
#include "vendor/brightray/browser/default_web_contents_delegate.h"
#include "vendor/brightray/browser/inspectable_web_contents_delegate.h"
#include "vendor/brightray/browser/inspectable_web_contents_impl.h"
#include "native_mate/persistent_dictionary.h"
#include "ui/gfx/image/image_skia.h"
struct WebPreferences;
@@ -36,7 +35,6 @@ class WebContents;
}
namespace gfx {
class Image;
class Point;
class Rect;
class Size;
@@ -138,10 +136,11 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
virtual void SetRepresentedFilename(const std::string& filename);
virtual std::string GetRepresentedFilename();
virtual void SetDocumentEdited(bool edited);
virtual void SetMenu(ui::MenuModel* menu);
virtual bool IsDocumentEdited();
virtual void SetMenu(ui::MenuModel* menu);
virtual bool HasModalDialog();
virtual gfx::NativeWindow GetNativeWindow() = 0;
virtual void SetProgressBar(double progress) = 0;
virtual bool IsClosed() const { return is_closed_; }
virtual void OpenDevTools();
@@ -158,6 +157,9 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
virtual void CapturePage(const gfx::Rect& rect,
const CapturePageCallback& callback);
// Print current page.
virtual void Print(bool silent, bool print_background);
// The same with closing a tab in a real browser.
//
// Should be called by platform code when user want to close the window.
@@ -253,8 +255,11 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
// Whether window has standard frame.
bool has_frame_;
// Whether window can be resized larger than screen.
bool enable_larger_than_screen_;
// Window icon.
scoped_ptr<gfx::Image> icon_;
gfx::ImageSkia icon_;
private:
// Schedule a notification unresponsive event.
@@ -294,7 +299,7 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
base::CancelableClosure window_unresposive_closure_;
// Web preferences.
mate::ScopedPersistent<v8::Object> web_preferences_;
mate::PersistentDictionary web_preferences_;
// Page's default zoom factor.
double zoom_factor_;

View File

@@ -65,6 +65,7 @@ class NativeWindowMac : public NativeWindow {
virtual bool IsDocumentEdited() OVERRIDE;
virtual bool HasModalDialog() OVERRIDE;
virtual gfx::NativeWindow GetNativeWindow() OVERRIDE;
virtual void SetProgressBar(double progress) OVERRIDE;
// Returns true if |point| in local Cocoa coordinate system falls within
// the draggable region.

View File

@@ -108,10 +108,12 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
@end
@interface AtomNSWindow : EventProcessingWindow {
@protected
@private
atom::NativeWindowMac* shell_;
bool enable_larger_than_screen_;
}
- (void)setShell:(atom::NativeWindowMac*)shell;
- (void)setEnableLargerThanScreen:(bool)enable;
@end
@implementation AtomNSWindow
@@ -120,6 +122,18 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
shell_ = shell;
}
- (void)setEnableLargerThanScreen:(bool)enable {
enable_larger_than_screen_ = enable;
}
// Enable the window to be larger than screen.
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)screen {
if (enable_larger_than_screen_)
return frameRect;
else
return [super constrainFrameRect:frameRect toScreen:screen];
}
- (IBAction)reload:(id)sender {
shell_->GetWebContents()->GetController().ReloadIgnoringCache(false);
}
@@ -128,6 +142,20 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
shell_->OpenDevTools();
}
// Returns an empty array for AXChildren attribute, this will force the
// SpeechSynthesisServer to use its classical way of speaking the selected text:
// by invoking the "Command+C" for current application and then speak out
// what's in the clipboard. Otherwise the "Text to Speech" would always speak
// out window's title.
// This behavior is taken by both FireFox and Chrome, see also FireFox's bug on
// more of how SpeechSynthesisServer chose which text to read:
// https://bugzilla.mozilla.org/show_bug.cgi?id=674612
- (id)accessibilityAttributeValue:(NSString*)attribute {
if ([attribute isEqualToString:@"AXChildren"])
return [NSArray array];
return [super accessibilityAttributeValue:attribute];
}
@end
@interface ControlRegionView : NSView {
@@ -165,6 +193,39 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
@end
@interface AtomProgressBar : NSProgressIndicator
@end
@implementation AtomProgressBar
- (void)drawRect:(NSRect)dirtyRect {
if (self.style != NSProgressIndicatorBarStyle)
return;
// Draw edges of rounded rect.
NSRect rect = NSInsetRect([self bounds], 1.0, 1.0);
CGFloat radius = rect.size.height / 2;
NSBezierPath* bezier_path = [NSBezierPath bezierPathWithRoundedRect:rect xRadius:radius yRadius:radius];
[bezier_path setLineWidth:2.0];
[[NSColor grayColor] set];
[bezier_path stroke];
// Fill the rounded rect.
rect = NSInsetRect(rect, 2.0, 2.0);
radius = rect.size.height / 2;
bezier_path = [NSBezierPath bezierPathWithRoundedRect:rect xRadius:radius yRadius:radius];
[bezier_path setLineWidth:1.0];
[bezier_path addClip];
// Calculate the progress width.
rect.size.width = floor(rect.size.width * ([self doubleValue] / [self maxValue]));
// Fill the progress bar with color blue.
[[NSColor colorWithSRGBRed:0.2 green:0.6 blue:1 alpha:1] set];
NSRectFill(rect);
}
@end
namespace atom {
NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
@@ -194,6 +255,7 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
defer:YES];
[atomWindow setShell:this];
[atomWindow setEnableLargerThanScreen:enable_larger_than_screen_];
window_.reset(atomWindow);
AtomNSWindowDelegate* delegate =
@@ -241,7 +303,6 @@ void NativeWindowMac::Close() {
void NativeWindowMac::CloseImmediately() {
[window_ close];
window_.reset();
}
void NativeWindowMac::Move(const gfx::Rect& pos) {
@@ -273,7 +334,7 @@ bool NativeWindowMac::IsFocused() {
}
void NativeWindowMac::Show() {
[window_ makeKeyAndOrderFront:nil];
[window_ orderFrontRegardless];
}
void NativeWindowMac::Hide() {
@@ -489,6 +550,39 @@ gfx::NativeWindow NativeWindowMac::GetNativeWindow() {
return window_;
}
void NativeWindowMac::SetProgressBar(double progress) {
NSDockTile* dock_tile = [NSApp dockTile];
// For the first time API invoked, we need to create a ContentView in DockTile.
if (dock_tile.contentView == NULL) {
NSImageView* image_view = [[NSImageView alloc] init];
[image_view setImage:[NSApp applicationIconImage]];
[dock_tile setContentView:image_view];
NSProgressIndicator* progress_indicator = [[AtomProgressBar alloc]
initWithFrame:NSMakeRect(0.0f, 0.0f, dock_tile.size.width, 15.0)];
[progress_indicator setStyle:NSProgressIndicatorBarStyle];
[progress_indicator setIndeterminate:NO];
[progress_indicator setBezeled:YES];
[progress_indicator setMinValue:0];
[progress_indicator setMaxValue:1];
[progress_indicator setHidden:NO];
[image_view addSubview:progress_indicator];
}
NSProgressIndicator* progress_indicator =
static_cast<NSProgressIndicator*>([[[dock_tile contentView] subviews]
objectAtIndex:0]);
if (progress < 0) {
[progress_indicator setHidden:YES];
} else if (progress > 1) {
[progress_indicator setIndeterminate:YES];
} else {
[progress_indicator setDoubleValue:progress];
}
[dock_tile display];
}
bool NativeWindowMac::IsWithinDraggableRegion(NSPoint point) const {
if (!draggable_region_)
return false;

View File

@@ -8,12 +8,6 @@
#include <shobjidl.h>
#endif
#if defined(USE_X11)
#include <X11/extensions/XInput2.h>
#include <X11/extensions/Xrandr.h>
#include <X11/Xlib.h>
#endif
#include <string>
#include <vector>
@@ -28,8 +22,6 @@
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/hit_test.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/views/background.h"
#include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
#include "ui/views/controls/webview/webview.h"
@@ -37,14 +29,23 @@
#include "ui/views/widget/widget.h"
#if defined(USE_X11)
#include "atom/browser/browser.h"
#include "atom/browser/ui/views/global_menu_bar_x11.h"
#include "atom/browser/ui/views/frameless_view.h"
#include "atom/browser/ui/x/x_window_utils.h"
#include "base/environment.h"
#include "base/nix/xdg_util.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/ui/libgtk2ui/unity_service.h"
#include "ui/base/x/x11_util.h"
#include "ui/gfx/x/x11_types.h"
#include "ui/views/window/native_frame_view.h"
#elif defined(OS_WIN)
#include "atom/browser/ui/views/win_frame_view.h"
#include "base/win/scoped_comptr.h"
#include "base/win/windows_version.h"
#include "ui/base/win/shell.h"
#include "ui/views/win/hwnd_util.h"
#endif
namespace atom {
@@ -58,6 +59,36 @@ const int kMenuBarHeight = 20;
const int kMenuBarHeight = 25;
#endif
#if defined(USE_X11)
// Counts how many window has already been created, it will be used to set the
// window role for X11.
int kWindowsCreated = 0;
bool ShouldUseGlobalMenuBar() {
// Some DE would pretend to be Unity but don't have global application menu,
// so we can not trust unity::IsRunning().
scoped_ptr<base::Environment> env(base::Environment::Create());
return unity::IsRunning() && (base::nix::GetDesktopEnvironment(env.get()) ==
base::nix::DESKTOP_ENVIRONMENT_UNITY);
}
#endif
bool IsAltKey(const content::NativeWebKeyboardEvent& event) {
#if defined(USE_X11)
// 164 and 165 represent VK_LALT and VK_RALT.
return event.windowsKeyCode == 164 || event.windowsKeyCode == 165;
#else
return event.windowsKeyCode == ui::VKEY_MENU;
#endif
}
bool IsAltModifier(const content::NativeWebKeyboardEvent& event) {
typedef content::NativeWebKeyboardEvent::Modifiers Modifiers;
return (event.modifiers == Modifiers::AltKey) ||
(event.modifiers == (Modifiers::AltKey | Modifiers::IsLeft)) ||
(event.modifiers == (Modifiers::AltKey | Modifiers::IsRight));
}
class NativeWindowClientView : public views::ClientView {
public:
NativeWindowClientView(views::Widget* widget,
@@ -81,13 +112,28 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
const mate::Dictionary& options)
: NativeWindow(web_contents, options),
window_(new views::Widget),
menu_bar_(NULL),
web_view_(inspectable_web_contents()->GetView()->GetView()),
menu_bar_autohide_(false),
menu_bar_visible_(false),
menu_bar_alt_pressed_(false),
keyboard_event_handler_(new views::UnhandledKeyboardEventHandler),
use_content_size_(false),
resizable_(true) {
options.Get(switches::kResizable, &resizable_);
options.Get(switches::kTitle, &title_);
options.Get(switches::kAutoHideMenuBar, &menu_bar_autohide_);
#if defined(OS_WIN)
// On Windows we rely on the CanResize() to indicate whether window can be
// resized, and it should be set before window is created.
options.Get(switches::kResizable, &resizable_);
#endif
if (enable_larger_than_screen_)
// We need to set a default maximum window size here otherwise Windows
// will not allow us to resize the window larger than scree.
// Setting directly to INT_MAX somehow doesn't work, so we just devide
// by 10, which should still be large enough.
maximum_size_.SetSize(INT_MAX / 10, INT_MAX / 10);
int width = 800, height = 600;
options.Get(switches::kWidth, &width);
@@ -101,18 +147,44 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
params.bounds = bounds;
params.delegate = this;
params.type = views::Widget::InitParams::TYPE_WINDOW;
params.top_level = true;
params.remove_standard_frame = !has_frame_;
#if defined(USE_X11)
// FIXME Find out how to do this dynamically on Linux.
bool skip_taskbar = false;
if (options.Get(switches::kSkipTaskbar, &skip_taskbar) && skip_taskbar)
params.type = views::Widget::InitParams::TYPE_BUBBLE;
// Set WM_WINDOW_ROLE.
params.wm_role_name = base::StringPrintf(
"%s/%s/%d", "Atom Shell", Browser::Get()->GetName().c_str(),
++kWindowsCreated);
// Set WM_CLASS.
params.wm_class_name = "atom-shell";
params.wm_class_class = "Atom Shell";
#endif
window_->Init(params);
#if defined(USE_X11)
// Set _GTK_THEME_VARIANT to dark if we have "dark-theme" option set.
bool use_dark_theme = false;
if (options.Get(switches::kDarkTheme, &use_dark_theme) && use_dark_theme) {
XDisplay* xdisplay = gfx::GetXDisplay();
XChangeProperty(xdisplay, GetAcceleratedWidget(),
XInternAtom(xdisplay, "_GTK_THEME_VARIANT", False),
XInternAtom(xdisplay, "UTF8_STRING", False),
8, PropModeReplace,
reinterpret_cast<const unsigned char*>("dark"),
4);
}
// Before the window is mapped the SetWMSpecState can not work, so we have
// to manually set the _NET_WM_STATE.
bool skip_taskbar = false;
if (options.Get(switches::kSkipTaskbar, &skip_taskbar) && skip_taskbar) {
std::vector<::Atom> state_atom_list;
state_atom_list.push_back(GetAtom("_NET_WM_STATE_SKIP_TASKBAR"));
ui::SetAtomArrayProperty(GetAcceleratedWidget(), "_NET_WM_STATE", "ATOM",
state_atom_list);
}
#endif
// Add web view.
SetLayoutManager(new MenuLayout(kMenuBarHeight));
set_background(views::Background::CreateStandardPanelBackground());
@@ -156,7 +228,7 @@ bool NativeWindowViews::IsFocused() {
}
void NativeWindowViews::Show() {
window_->Show();
window_->ShowInactive();
}
void NativeWindowViews::Hide() {
@@ -200,6 +272,15 @@ bool NativeWindowViews::IsFullscreen() {
}
void NativeWindowViews::SetSize(const gfx::Size& size) {
#if defined(USE_X11)
// On Linux the minimum and maximum size should be updated with window size
// when window is not resizable.
if (!resizable_) {
SetMaximumSize(size);
SetMinimumSize(size);
}
#endif
window_->SetSize(size);
}
@@ -219,8 +300,7 @@ void NativeWindowViews::SetContentSize(const gfx::Size& size) {
}
gfx::Rect bounds = window_->GetWindowBoundsInScreen();
bounds.set_size(size);
window_->SetBounds(ContentBoundsToWindowBounds(bounds));
SetSize(ContentBoundsToWindowBounds(gfx::Rect(bounds.origin(), size)).size());
}
gfx::Size NativeWindowViews::GetContentSize() {
@@ -229,7 +309,7 @@ gfx::Size NativeWindowViews::GetContentSize() {
gfx::Size content_size =
window_->non_client_view()->frame_view()->GetBoundsForClientView().size();
if (menu_bar_)
if (menu_bar_ && menu_bar_visible_)
content_size.set_height(content_size.height() - kMenuBarHeight);
return content_size;
}
@@ -267,8 +347,33 @@ gfx::Size NativeWindowViews::GetMaximumSize() {
}
void NativeWindowViews::SetResizable(bool resizable) {
#if defined(OS_WIN)
if (has_frame_) {
// WS_MAXIMIZEBOX => Maximize button
// WS_MINIMIZEBOX => Minimize button
// WS_THICKFRAME => Resize handle
DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE);
if (resizable)
style |= WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME;
else
style = (style & ~(WS_MAXIMIZEBOX | WS_THICKFRAME)) | WS_MINIMIZEBOX;
::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style);
}
#elif defined(USE_X11)
if (resizable != resizable_) {
// On Linux there is no "resizable" property of a window, we have to set
// both the minimum and maximum size to the window size to achieve it.
if (resizable) {
SetMaximumSize(gfx::Size());
SetMinimumSize(gfx::Size());
} else {
SetMaximumSize(GetSize());
SetMinimumSize(GetSize());
}
}
#endif
resizable_ = resizable;
// FIXME Implement me for X11.
}
bool NativeWindowViews::IsResizable() {
@@ -324,6 +429,9 @@ void NativeWindowViews::SetSkipTaskbar(bool skip) {
taskbar->DeleteTab(GetAcceleratedWidget());
else
taskbar->AddTab(GetAcceleratedWidget());
#elif defined(USE_X11)
SetWMSpecState(GetAcceleratedWidget(), skip,
GetAtom("_NET_WM_STATE_SKIP_TASKBAR"));
#endif
}
@@ -339,7 +447,7 @@ void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) {
RegisterAccelerators(menu_model);
#if defined(USE_X11)
if (unity::IsRunning() && !global_menu_bar_)
if (!global_menu_bar_ && ShouldUseGlobalMenuBar())
global_menu_bar_.reset(new GlobalMenuBarX11(this));
// Use global application menu bar when possible.
@@ -355,11 +463,14 @@ void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) {
if (!menu_bar_) {
gfx::Size content_size = GetContentSize();
menu_bar_ = new MenuBar;
AddChildViewAt(menu_bar_, 0);
menu_bar_.reset(new MenuBar);
menu_bar_->set_owned_by_client();
if (use_content_size_)
SetContentSize(content_size);
if (!menu_bar_autohide_) {
SetMenuBarVisibility(true);
if (use_content_size_)
SetContentSize(content_size);
}
}
menu_bar_->SetMenu(menu_model);
@@ -370,6 +481,33 @@ gfx::NativeWindow NativeWindowViews::GetNativeWindow() {
return window_->GetNativeWindow();
}
void NativeWindowViews::SetProgressBar(double progress) {
#if defined(OS_WIN)
if (base::win::GetVersion() < base::win::VERSION_WIN7)
return;
base::win::ScopedComPtr<ITaskbarList3> taskbar;
if (FAILED(taskbar.CreateInstance(CLSID_TaskbarList, NULL,
CLSCTX_INPROC_SERVER) ||
FAILED(taskbar->HrInit()))) {
return;
}
HWND frame = views::HWNDForNativeWindow(GetNativeWindow());
if (progress > 1.0) {
taskbar->SetProgressState(frame, TBPF_INDETERMINATE);
} else if (progress < 0) {
taskbar->SetProgressState(frame, TBPF_NOPROGRESS);
} else if (progress >= 0) {
taskbar->SetProgressValue(frame,
static_cast<int>(progress * 100),
progress);
}
#elif defined(USE_X11)
if (unity::IsRunning()) {
unity::SetProgressFraction(progress);
}
#endif
}
gfx::AcceleratedWidget NativeWindowViews::GetAcceleratedWidget() {
return GetNativeWindow()->GetHost()->GetAcceleratedWidget();
}
@@ -406,6 +544,15 @@ void NativeWindowViews::OnWidgetActivationChanged(
NotifyWindowFocus();
else
NotifyWindowBlur();
if (active && GetWebContents() && !IsDevToolsOpened())
GetWebContents()->Focus();
// Hide menu bar when window is blured.
if (!active && menu_bar_autohide_ && menu_bar_visible_) {
SetMenuBarVisibility(false);
Layout();
}
}
void NativeWindowViews::DeleteDelegate() {
@@ -433,10 +580,7 @@ bool NativeWindowViews::ShouldHandleSystemCommands() const {
}
gfx::ImageSkia NativeWindowViews::GetWindowAppIcon() {
if (icon_)
return *(icon_->ToImageSkia());
else
return gfx::ImageSkia();
return icon_;
}
gfx::ImageSkia NativeWindowViews::GetWindowIcon() {
@@ -480,9 +624,11 @@ views::ClientView* NativeWindowViews::CreateClientView(views::Widget* widget) {
views::NonClientFrameView* NativeWindowViews::CreateNonClientFrameView(
views::Widget* widget) {
#if defined(OS_WIN)
WinFrameView* frame_view = new WinFrameView;
frame_view->Init(this, widget);
return frame_view;
if (ui::win::IsAeroGlassEnabled()) {
WinFrameView* frame_view = new WinFrameView;
frame_view->Init(this, widget);
return frame_view;
}
#elif defined(OS_LINUX)
if (has_frame_) {
return new views::NativeFrameView(widget);
@@ -491,15 +637,66 @@ views::NonClientFrameView* NativeWindowViews::CreateNonClientFrameView(
frame_view->Init(this, widget);
return frame_view;
}
#else
return NULL;
#endif
return NULL;
}
gfx::ImageSkia NativeWindowViews::GetDevToolsWindowIcon() {
return GetWindowAppIcon();
}
void NativeWindowViews::HandleMouseDown() {
// Hide menu bar when web view is clicked.
if (menu_bar_autohide_ && menu_bar_visible_) {
SetMenuBarVisibility(false);
Layout();
}
}
void NativeWindowViews::HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent& event) {
keyboard_event_handler_->HandleKeyboardEvent(event, GetFocusManager());
if (!menu_bar_)
return;
// Show accelerator when "Alt" is pressed.
if (menu_bar_visible_ && IsAltKey(event))
menu_bar_->SetAcceleratorVisibility(
event.type == blink::WebInputEvent::RawKeyDown);
// Show the submenu when "Alt+Key" is pressed.
if (event.type == blink::WebInputEvent::RawKeyDown && !IsAltKey(event) &&
IsAltModifier(event)) {
if (!menu_bar_visible_ &&
(menu_bar_->GetAcceleratorIndex(event.windowsKeyCode) != -1)) {
SetMenuBarVisibility(true);
Layout();
}
menu_bar_->ActivateAccelerator(event.windowsKeyCode);
return;
}
if (!menu_bar_autohide_)
return;
// Toggle the menu bar only when a single Alt is released.
if (event.type == blink::WebInputEvent::RawKeyDown && IsAltKey(event) &&
IsAltModifier(event)) {
// When a single Alt is pressed:
menu_bar_alt_pressed_ = true;
} else if (event.type == blink::WebInputEvent::KeyUp && IsAltKey(event) &&
event.modifiers == 0 && 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_);
Layout();
} else {
// When any other keys except single Alt have been pressed/released:
menu_bar_alt_pressed_ = false;
}
}
bool NativeWindowViews::AcceleratorPressed(const ui::Accelerator& accelerator) {
@@ -528,11 +725,29 @@ gfx::Rect NativeWindowViews::ContentBoundsToWindowBounds(
const gfx::Rect& bounds) {
gfx::Rect window_bounds =
window_->non_client_view()->GetWindowBoundsForClientBounds(bounds);
if (menu_bar_)
if (menu_bar_ && menu_bar_visible_)
window_bounds.set_height(window_bounds.height() + kMenuBarHeight);
return window_bounds;
}
void NativeWindowViews::SetMenuBarVisibility(bool visible) {
if (!menu_bar_)
return;
// Always show the accelerator when the auto-hide menu bar shows.
if (menu_bar_autohide_)
menu_bar_->SetAcceleratorVisibility(visible);
menu_bar_visible_ = visible;
if (visible) {
DCHECK_EQ(child_count(), 1);
AddChildView(menu_bar_.get());
} else {
DCHECK_EQ(child_count(), 2);
RemoveChildView(menu_bar_.get());
}
}
// static
NativeWindow* NativeWindow::Create(content::WebContents* web_contents,
const mate::Dictionary& options) {

View File

@@ -16,7 +16,6 @@
namespace views {
class UnhandledKeyboardEventHandler;
class Widget;
}
namespace atom {
@@ -72,6 +71,7 @@ class NativeWindowViews : public NativeWindow,
virtual bool IsKiosk() OVERRIDE;
virtual void SetMenu(ui::MenuModel* menu_model) OVERRIDE;
virtual gfx::NativeWindow GetNativeWindow() OVERRIDE;
virtual void SetProgressBar(double value) OVERRIDE;
gfx::AcceleratedWidget GetAcceleratedWidget();
@@ -106,7 +106,11 @@ class NativeWindowViews : public NativeWindow,
virtual views::NonClientFrameView* CreateNonClientFrameView(
views::Widget* widget) OVERRIDE;
// brightray::InspectableWebContentsDelegate:
virtual gfx::ImageSkia GetDevToolsWindowIcon() OVERRIDE;
// content::WebContentsDelegate:
virtual void HandleMouseDown() OVERRIDE;
virtual void HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent& event) OVERRIDE;
@@ -121,10 +125,17 @@ class NativeWindowViews : public NativeWindow,
// in client area we need to substract/add menu bar's height in convertions.
gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& content_bounds);
// Show/Hide the menu bar.
void SetMenuBarVisibility(bool visible);
scoped_ptr<views::Widget> window_;
MenuBar* menu_bar_;
views::View* web_view_; // Managed by inspectable_web_contents_.
scoped_ptr<MenuBar> menu_bar_;
bool menu_bar_autohide_;
bool menu_bar_visible_;
bool menu_bar_alt_pressed_;
#if defined(USE_X11)
scoped_ptr<GlobalMenuBarX11> global_menu_bar_;
#endif

View File

@@ -1,186 +0,0 @@
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/net/atom_url_request_context_getter.h"
#include <algorithm>
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "base/strings/string_util.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/worker_pool.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/cookie_store_factory.h"
#include "content/public/common/url_constants.h"
#include "net/cert/cert_verifier.h"
#include "net/cookies/cookie_monster.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_cache.h"
#include "net/http/http_server_properties_impl.h"
#include "net/proxy/dhcp_proxy_script_fetcher_factory.h"
#include "net/proxy/proxy_config_service.h"
#include "net/proxy/proxy_script_fetcher_impl.h"
#include "net/proxy/proxy_service.h"
#include "net/proxy/proxy_service_v8.h"
#include "net/ssl/default_server_bound_cert_store.h"
#include "net/ssl/server_bound_cert_service.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/file_protocol_handler.h"
#include "net/url_request/static_http_user_agent_settings.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_storage.h"
#include "vendor/brightray/browser/network_delegate.h"
#include "webkit/browser/quota/special_storage_policy.h"
namespace atom {
using content::BrowserThread;
AtomURLRequestContextGetter::AtomURLRequestContextGetter(
const base::FilePath& base_path,
base::MessageLoop* io_loop,
base::MessageLoop* file_loop,
base::Callback<scoped_ptr<brightray::NetworkDelegate>(void)> factory,
content::ProtocolHandlerMap* protocol_handlers)
: base_path_(base_path),
io_loop_(io_loop),
file_loop_(file_loop),
job_factory_(NULL),
network_delegate_factory_(factory) {
// Must first be created on the UI thread.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
std::swap(protocol_handlers_, *protocol_handlers);
// We must create the proxy config service on the UI loop on Linux because it
// must synchronously run on the glib message loop. This will be passed to
// the URLRequestContextStorage on the IO thread in GetURLRequestContext().
proxy_config_service_.reset(
net::ProxyService::CreateSystemProxyConfigService(
io_loop_->message_loop_proxy(),
file_loop_));
}
AtomURLRequestContextGetter::~AtomURLRequestContextGetter() {
}
net::URLRequestContext* AtomURLRequestContextGetter::GetURLRequestContext() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
base::AutoLock auto_lock(lock_);
if (!url_request_context_.get()) {
url_request_context_.reset(new net::URLRequestContext());
network_delegate_ = network_delegate_factory_.Run().Pass();
url_request_context_->set_network_delegate(network_delegate_.get());
storage_.reset(
new net::URLRequestContextStorage(url_request_context_.get()));
auto cookie_config = content::CookieStoreConfig(
base_path_.Append(FILE_PATH_LITERAL("Cookies")),
content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES,
nullptr,
nullptr);
storage_->set_cookie_store(content::CreateCookieStore(cookie_config));
storage_->set_server_bound_cert_service(new net::ServerBoundCertService(
new net::DefaultServerBoundCertStore(NULL),
base::WorkerPool::GetTaskRunner(true)));
storage_->set_http_user_agent_settings(
new net::StaticHttpUserAgentSettings(
"en-us,en", base::EmptyString()));
scoped_ptr<net::HostResolver> host_resolver(
net::HostResolver::CreateDefaultResolver(NULL));
net::DhcpProxyScriptFetcherFactory dhcp_factory;
storage_->set_cert_verifier(net::CertVerifier::CreateDefault());
storage_->set_transport_security_state(new net::TransportSecurityState);
storage_->set_proxy_service(
net::CreateProxyServiceUsingV8ProxyResolver(
proxy_config_service_.release(),
new net::ProxyScriptFetcherImpl(url_request_context_.get()),
dhcp_factory.Create(url_request_context_.get()),
host_resolver.get(),
NULL,
url_request_context_->network_delegate()));
storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults);
storage_->set_http_auth_handler_factory(
net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get()));
scoped_ptr<net::HttpServerProperties> server_properties(
new net::HttpServerPropertiesImpl);
storage_->set_http_server_properties(server_properties.Pass());
base::FilePath cache_path = base_path_.Append(FILE_PATH_LITERAL("Cache"));
net::HttpCache::DefaultBackend* main_backend =
new net::HttpCache::DefaultBackend(
net::DISK_CACHE,
net::CACHE_BACKEND_DEFAULT,
cache_path,
0,
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE));
net::HttpNetworkSession::Params network_session_params;
network_session_params.cert_verifier =
url_request_context_->cert_verifier();
network_session_params.transport_security_state =
url_request_context_->transport_security_state();
network_session_params.server_bound_cert_service =
url_request_context_->server_bound_cert_service();
network_session_params.proxy_service =
url_request_context_->proxy_service();
network_session_params.ssl_config_service =
url_request_context_->ssl_config_service();
network_session_params.http_auth_handler_factory =
url_request_context_->http_auth_handler_factory();
network_session_params.network_delegate =
url_request_context_->network_delegate();
network_session_params.http_server_properties =
url_request_context_->http_server_properties();
network_session_params.ignore_certificate_errors = false;
// Give |storage_| ownership at the end in case it's |mapped_host_resolver|.
storage_->set_host_resolver(host_resolver.Pass());
network_session_params.host_resolver =
url_request_context_->host_resolver();
net::HttpCache* main_cache = new net::HttpCache(
network_session_params, main_backend);
storage_->set_http_transaction_factory(main_cache);
DCHECK(!job_factory_);
job_factory_ = new AtomURLRequestJobFactory;
for (content::ProtocolHandlerMap::iterator it = protocol_handlers_.begin();
it != protocol_handlers_.end();
++it) {
bool set_protocol = job_factory_->SetProtocolHandler(
it->first,
it->second.release());
DCHECK(set_protocol);
}
protocol_handlers_.clear();
scoped_ptr<net::FileProtocolHandler> file_protocol_handler(
new net::FileProtocolHandler(
content::BrowserThread::GetBlockingPool()->
GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
job_factory_->SetProtocolHandler(content::kDataScheme,
new net::DataProtocolHandler);
job_factory_->SetProtocolHandler(content::kFileScheme,
file_protocol_handler.release());
storage_->set_job_factory(job_factory_);
}
return url_request_context_.get();
}
scoped_refptr<base::SingleThreadTaskRunner>
AtomURLRequestContextGetter::GetNetworkTaskRunner() const {
return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
}
net::HostResolver* AtomURLRequestContextGetter::host_resolver() {
return url_request_context_->host_resolver();
}
} // namespace atom

View File

@@ -1,76 +0,0 @@
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_NET_ATOM_URL_REQUEST_CONTEXT_GETTER_H_
#define ATOM_BROWSER_NET_ATOM_URL_REQUEST_CONTEXT_GETTER_H_
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "content/public/browser/content_browser_client.h"
#include "net/url_request/url_request_context_getter.h"
namespace base {
class MessageLoop;
}
namespace brightray {
class NetworkDelegate;
}
namespace net {
class HostResolver;
class ProxyConfigService;
class URLRequestContextStorage;
}
namespace atom {
class AtomURLRequestJobFactory;
class AtomURLRequestContextGetter : public net::URLRequestContextGetter {
public:
AtomURLRequestContextGetter(
const base::FilePath& base_path,
base::MessageLoop* io_loop,
base::MessageLoop* file_loop,
base::Callback<scoped_ptr<brightray::NetworkDelegate>(void)>,
content::ProtocolHandlerMap* protocol_handlers);
// net::URLRequestContextGetter implementations:
virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE;
virtual scoped_refptr<base::SingleThreadTaskRunner>
GetNetworkTaskRunner() const OVERRIDE;
net::HostResolver* host_resolver();
net::URLRequestContextStorage* storage() const { return storage_.get(); }
AtomURLRequestJobFactory* job_factory() const { return job_factory_; }
protected:
virtual ~AtomURLRequestContextGetter();
private:
base::FilePath base_path_;
base::MessageLoop* io_loop_;
base::MessageLoop* file_loop_;
AtomURLRequestJobFactory* job_factory_;
base::Callback<scoped_ptr<brightray::NetworkDelegate>(void)>
network_delegate_factory_;
base::Lock lock_;
scoped_ptr<net::ProxyConfigService> proxy_config_service_;
scoped_ptr<brightray::NetworkDelegate> network_delegate_;
scoped_ptr<net::URLRequestContextStorage> storage_;
scoped_ptr<net::URLRequestContext> url_request_context_;
content::ProtocolHandlerMap protocol_handlers_;
DISALLOW_COPY_AND_ASSIGN(AtomURLRequestContextGetter);
};
} // namespace atom
#endif // ATOM_BROWSER_NET_ATOM_URL_REQUEST_CONTEXT_GETTER_H_

View File

@@ -0,0 +1,202 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/node_debugger.h"
#include <string>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/browser_thread.h"
#include "net/socket/tcp_listen_socket.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace {
// NodeDebugger is stored in Isolate's data, slots 0, 1, 3 have already been
// taken by gin, blink and node, using 2 is a safe option for now.
const int kIsolateSlot = 2;
const char* kContentLength = "Content-Length";
} // namespace
NodeDebugger::NodeDebugger(v8::Isolate* isolate)
: isolate_(isolate),
thread_("NodeDebugger"),
content_length_(-1),
weak_factory_(this) {
bool use_debug_agent = false;
int port = 5858;
bool wait_for_connection = false;
std::string port_str;
base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
if (cmd->HasSwitch("debug")) {
use_debug_agent = true;
port_str = cmd->GetSwitchValueASCII("debug");
}
if (cmd->HasSwitch("debug-brk")) {
use_debug_agent = true;
wait_for_connection = true;
port_str = cmd->GetSwitchValueASCII("debug-brk");
}
if (use_debug_agent) {
if (!port_str.empty())
base::StringToInt(port_str, &port);
isolate_->SetData(kIsolateSlot, this);
v8::Debug::SetMessageHandler(DebugMessageHandler);
if (wait_for_connection)
v8::Debug::DebugBreak(isolate_);
// Start a new IO thread.
base::Thread::Options options;
options.message_loop_type = base::MessageLoop::TYPE_IO;
if (!thread_.StartWithOptions(options)) {
LOG(ERROR) << "Unable to start debugger thread";
return;
}
// Start the server in new IO thread.
thread_.message_loop()->PostTask(
FROM_HERE,
base::Bind(&NodeDebugger::StartServer, weak_factory_.GetWeakPtr(),
port));
}
}
NodeDebugger::~NodeDebugger() {
thread_.Stop();
}
bool NodeDebugger::IsRunning() const {
return thread_.IsRunning();
}
void NodeDebugger::StartServer(int port) {
server_ = net::TCPListenSocket::CreateAndListen("127.0.0.1", port, this);
if (!server_) {
LOG(ERROR) << "Cannot start debugger server";
return;
}
}
void NodeDebugger::CloseSession() {
accepted_socket_.reset();
}
void NodeDebugger::OnMessage(const std::string& message) {
if (message.find("\"type\":\"request\",\"command\":\"disconnect\"}") !=
std::string::npos)
CloseSession();
base::string16 message16 = base::UTF8ToUTF16(message);
v8::Debug::SendCommand(
isolate_,
reinterpret_cast<const uint16_t*>(message16.data()), message16.size());
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::Bind(&v8::Debug::ProcessDebugMessages));
}
void NodeDebugger::SendMessage(const std::string& message) {
if (accepted_socket_) {
std::string header = base::StringPrintf(
"%s: %d\r\n\r\n", kContentLength, static_cast<int>(message.size()));
accepted_socket_->Send(header);
accepted_socket_->Send(message);
}
}
void NodeDebugger::SendConnectMessage() {
accepted_socket_->Send(base::StringPrintf(
"Type: connect\r\n"
"V8-Version: %s\r\n"
"Protocol-Version: 1\r\n"
"Embedding-Host: %s\r\n"
"%s: 0\r\n",
v8::V8::GetVersion(), "Atom-Shell", kContentLength), true);
}
// static
void NodeDebugger::DebugMessageHandler(const v8::Debug::Message& message) {
NodeDebugger* self = static_cast<NodeDebugger*>(
message.GetIsolate()->GetData(kIsolateSlot));
if (self) {
std::string message8(*v8::String::Utf8Value(message.GetJSON()));
self->thread_.message_loop()->PostTask(
FROM_HERE,
base::Bind(&NodeDebugger::SendMessage, self->weak_factory_.GetWeakPtr(),
message8));
}
}
void NodeDebugger::DidAccept(net::StreamListenSocket* server,
scoped_ptr<net::StreamListenSocket> socket) {
// Only accept one session.
if (accepted_socket_) {
socket->Send(std::string("Remote debugging session already active"), true);
return;
}
accepted_socket_ = socket.Pass();
SendConnectMessage();
}
void NodeDebugger::DidRead(net::StreamListenSocket* socket,
const char* data,
int len) {
buffer_.append(data, len);
do {
if (buffer_.size() == 0)
return;
// Read the "Content-Length" header.
if (content_length_ < 0) {
size_t pos = buffer_.find("\r\n\r\n");
if (pos == std::string::npos)
return;
// We can be sure that the header is "Content-Length: xxx\r\n".
std::string content_length = buffer_.substr(16, pos - 16);
if (!base::StringToInt(content_length, &content_length_)) {
DidClose(accepted_socket_.get());
return;
}
// Strip header from buffer.
buffer_ = buffer_.substr(pos + 4);
}
// Read the message.
if (buffer_.size() >= static_cast<size_t>(content_length_)) {
std::string message = buffer_.substr(0, content_length_);
buffer_ = buffer_.substr(content_length_);
OnMessage(message);
// Get ready for next message.
content_length_ = -1;
}
} while (true);
}
void NodeDebugger::DidClose(net::StreamListenSocket* socket) {
// If we lost the connection, then simulate a disconnect msg:
OnMessage("{\"seq\":1,\"type\":\"request\",\"command\":\"disconnect\"}");
}
} // namespace atom

View File

@@ -0,0 +1,59 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_NODE_DEBUGGER_H_
#define ATOM_BROWSER_NODE_DEBUGGER_H_
#include <string>
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread.h"
#include "net/socket/stream_listen_socket.h"
#include "v8/include/v8-debug.h"
namespace atom {
// Add support for node's "--debug" switch.
class NodeDebugger : public net::StreamListenSocket::Delegate {
public:
explicit NodeDebugger(v8::Isolate* isolate);
virtual ~NodeDebugger();
bool IsRunning() const;
private:
void StartServer(int port);
void CloseSession();
void OnMessage(const std::string& message);
void SendMessage(const std::string& message);
void SendConnectMessage();
static void DebugMessageHandler(const v8::Debug::Message& message);
// net::StreamListenSocket::Delegate:
virtual void DidAccept(net::StreamListenSocket* server,
scoped_ptr<net::StreamListenSocket> socket) OVERRIDE;
virtual void DidRead(net::StreamListenSocket* socket,
const char* data,
int len) OVERRIDE;
virtual void DidClose(net::StreamListenSocket* socket) OVERRIDE;
v8::Isolate* isolate_;
base::Thread thread_;
scoped_ptr<net::StreamListenSocket> server_;
scoped_ptr<net::StreamListenSocket> accepted_socket_;
std::string buffer_;
int content_length_;
base::WeakPtrFactory<NodeDebugger> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(NodeDebugger);
};
} // namespace atom
#endif // ATOM_BROWSER_NODE_DEBUGGER_H_

View File

@@ -17,7 +17,7 @@
<key>CFBundleIconFile</key>
<string>atom.icns</string>
<key>CFBundleVersion</key>
<string>0.15.1</string>
<string>0.16.3</string>
<key>LSMinimumSystemVersion</key>
<string>10.8.0</string>
<key>NSMainNibFile</key>

View File

@@ -50,8 +50,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,15,1,0
PRODUCTVERSION 0,15,1,0
FILEVERSION 0,16,3,0
PRODUCTVERSION 0,16,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -68,12 +68,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Atom-Shell"
VALUE "FileVersion", "0.15.1"
VALUE "FileVersion", "0.16.3"
VALUE "InternalName", "atom.exe"
VALUE "LegalCopyright", "Copyright (C) 2013 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "atom.exe"
VALUE "ProductName", "Atom-Shell"
VALUE "ProductVersion", "0.15.1"
VALUE "ProductVersion", "0.16.3"
VALUE "SquirrelAwareVersion", "1"
END
END
BLOCK "VarFileInfo"

View File

@@ -159,6 +159,9 @@ int EventFlagsFromNSEvent(NSEvent* event) {
[NSApp setWindowsMenu:submenu];
else if ([[item title] isEqualToString:@"Help"])
[NSApp setHelpMenu:submenu];
if ([[item title] isEqualToString:@"Services"] &&
[submenu numberOfItems] == 0)
[NSApp setServicesMenu:submenu];
} else {
// The MenuModel works on indexes so we can't just set the command id as the
// tag like we do in other menus. Also set the represented object to be

View File

@@ -6,6 +6,7 @@
#define ATOM_BROWSER_UI_FILE_DIALOG_H_
#include <string>
#include <utility>
#include <vector>
#include "base/callback_forward.h"
@@ -17,11 +18,15 @@ class NativeWindow;
namespace file_dialog {
// <description, extensions>
typedef std::pair<std::string, std::vector<std::string> > Filter;
typedef std::vector<Filter> Filters;
enum FileDialogProperty {
FILE_DIALOG_OPEN_FILE = 1,
FILE_DIALOG_OPEN_DIRECTORY = 2,
FILE_DIALOG_MULTI_SELECTIONS = 4,
FILE_DIALOG_CREATE_DIRECTORY = 8,
FILE_DIALOG_OPEN_FILE = 1 << 0,
FILE_DIALOG_OPEN_DIRECTORY = 1 << 1,
FILE_DIALOG_MULTI_SELECTIONS = 1 << 2,
FILE_DIALOG_CREATE_DIRECTORY = 1 << 3,
};
typedef base::Callback<void(
@@ -33,23 +38,27 @@ typedef base::Callback<void(
bool ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
int properties,
std::vector<base::FilePath>* paths);
void ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
int properties,
const OpenDialogCallback& callback);
bool ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
base::FilePath* path);
void ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
const SaveDialogCallback& callback);
} // namespace file_dialog

View File

@@ -17,6 +17,7 @@
#include "atom/browser/native_window.h"
#include "base/callback.h"
#include "base/file_util.h"
#include "base/strings/string_util.h"
#include "chrome/browser/ui/libgtk2ui/gtk2_signal.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
@@ -45,12 +46,24 @@ void SetGtkTransientForAura(GtkWidget* dialog, aura::Window* parent) {
g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, parent);
}
// Makes sure that .jpg also shows .JPG.
gboolean FileFilterCaseInsensitive(const GtkFileFilterInfo* file_info,
std::string* file_extension) {
return EndsWith(file_info->filename, *file_extension, false);
}
// Deletes |data| when gtk_file_filter_add_custom() is done with it.
void OnFileFilterDataDestroyed(std::string* file_extension) {
delete file_extension;
}
class FileChooserDialog {
public:
FileChooserDialog(GtkFileChooserAction action,
atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path)
const base::FilePath& default_path,
const Filters& filters)
: dialog_scope_(new atom::NativeWindow::DialogScope(parent_window)) {
const char* confirm_text = GTK_STOCK_OK;
if (action == GTK_FILE_CHOOSER_ACTION_SAVE)
@@ -86,6 +99,9 @@ class FileChooserDialog {
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog_),
default_path.value().c_str());
}
if (!filters.empty())
AddFilters(filters);
}
virtual ~FileChooserDialog() {
@@ -135,6 +151,8 @@ class FileChooserDialog {
GtkWidget* dialog() const { return dialog_; }
private:
void AddFilters(const Filters& filters);
GtkWidget* dialog_;
SaveDialogCallback save_callback_;
@@ -162,17 +180,40 @@ void FileChooserDialog::OnFileDialogResponse(GtkWidget* widget, int response) {
delete this;
}
void FileChooserDialog::AddFilters(const Filters& filters) {
for (size_t i = 0; i < filters.size(); ++i) {
const Filter& filter = filters[i];
GtkFileFilter* gtk_filter = gtk_file_filter_new();
for (size_t j = 0; j < filter.second.size(); ++j) {
scoped_ptr<std::string> file_extension(
new std::string("." + filter.second[j]));
gtk_file_filter_add_custom(
gtk_filter,
GTK_FILE_FILTER_FILENAME,
reinterpret_cast<GtkFileFilterFunc>(FileFilterCaseInsensitive),
file_extension.release(),
reinterpret_cast<GDestroyNotify>(OnFileFilterDataDestroyed));
}
gtk_file_filter_set_name(gtk_filter, filter.first.c_str());
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog_), gtk_filter);
}
}
} // namespace
bool ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
int properties,
std::vector<base::FilePath>* paths) {
GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
if (properties & FILE_DIALOG_OPEN_DIRECTORY)
action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
FileChooserDialog open_dialog(action, parent_window, title, default_path);
FileChooserDialog open_dialog(action, parent_window, title, default_path,
filters);
if (properties & FILE_DIALOG_MULTI_SELECTIONS)
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(open_dialog.dialog()),
TRUE);
@@ -190,13 +231,14 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window,
void ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
int properties,
const OpenDialogCallback& callback) {
GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
if (properties & FILE_DIALOG_OPEN_DIRECTORY)
action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
FileChooserDialog* open_dialog = new FileChooserDialog(
action, parent_window, title, default_path);
action, parent_window, title, default_path, filters);
if (properties & FILE_DIALOG_MULTI_SELECTIONS)
gtk_file_chooser_set_select_multiple(
GTK_FILE_CHOOSER(open_dialog->dialog()), TRUE);
@@ -207,9 +249,10 @@ void ShowOpenDialog(atom::NativeWindow* parent_window,
bool ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
base::FilePath* path) {
FileChooserDialog save_dialog(
GTK_FILE_CHOOSER_ACTION_SAVE, parent_window, title, default_path);
FileChooserDialog save_dialog(GTK_FILE_CHOOSER_ACTION_SAVE, parent_window,
title, default_path, filters);
gtk_widget_show_all(save_dialog.dialog());
int response = gtk_dialog_run(GTK_DIALOG(save_dialog.dialog()));
if (response == GTK_RESPONSE_ACCEPT) {
@@ -223,9 +266,11 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
void ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
const SaveDialogCallback& callback) {
FileChooserDialog* save_dialog = new FileChooserDialog(
GTK_FILE_CHOOSER_ACTION_SAVE, parent_window, title, default_path);
GTK_FILE_CHOOSER_ACTION_SAVE, parent_window, title, default_path,
filters);
save_dialog->RunSaveAsynchronous(callback);
}

View File

@@ -9,15 +9,45 @@
#include "atom/browser/native_window.h"
#include "base/file_util.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/strings/sys_string_conversions.h"
namespace file_dialog {
namespace {
CFStringRef CreateUTIFromExtension(const std::string& ext) {
base::ScopedCFTypeRef<CFStringRef> ext_cf(base::SysUTF8ToCFStringRef(ext));
return UTTypeCreatePreferredIdentifierForTag(
kUTTagClassFilenameExtension, ext_cf.get(), NULL);
}
void SetAllowedFileTypes(NSSavePanel* dialog, const Filters& filters) {
NSMutableSet* file_type_set = [NSMutableSet set];
for (size_t i = 0; i < filters.size(); ++i) {
const Filter& filter = filters[i];
for (size_t j = 0; j < filter.second.size(); ++j) {
base::ScopedCFTypeRef<CFStringRef> uti(
CreateUTIFromExtension(filter.second[j]));
[file_type_set addObject:base::mac::CFToNSCast(uti.get())];
// Always allow the extension itself, in case the UTI doesn't map
// back to the original extension correctly. This occurs with dynamic
// UTIs on 10.7 and 10.8.
// See http://crbug.com/148840, http://openradar.me/12316273
base::ScopedCFTypeRef<CFStringRef> ext_cf(
base::SysUTF8ToCFStringRef(filter.second[j]));
[file_type_set addObject:base::mac::CFToNSCast(ext_cf.get())];
}
}
[dialog setAllowedFileTypes:[file_type_set allObjects]];
}
void SetupDialog(NSSavePanel* dialog,
const std::string& title,
const base::FilePath& default_path) {
const base::FilePath& default_path,
const Filters& filters) {
if (!title.empty())
[dialog setTitle:base::SysUTF8ToNSString(title)];
@@ -39,7 +69,10 @@ void SetupDialog(NSSavePanel* dialog,
[dialog setNameFieldStringValue:default_filename];
[dialog setCanSelectHiddenExtension:YES];
[dialog setAllowsOtherFileTypes:YES];
if (filters.empty())
[dialog setAllowsOtherFileTypes:YES];
else
SetAllowedFileTypes(dialog, filters);
}
void SetupDialogForProperties(NSOpenPanel* dialog, int properties) {
@@ -83,12 +116,13 @@ void ReadDialogPaths(NSOpenPanel* dialog, std::vector<base::FilePath>* paths) {
bool ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
int properties,
std::vector<base::FilePath>* paths) {
DCHECK(paths);
NSOpenPanel* dialog = [NSOpenPanel openPanel];
SetupDialog(dialog, title, default_path);
SetupDialog(dialog, title, default_path, filters);
SetupDialogForProperties(dialog, properties);
int chosen = RunModalDialog(dialog, parent_window);
@@ -102,11 +136,12 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window,
void ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
int properties,
const OpenDialogCallback& c) {
NSOpenPanel* dialog = [NSOpenPanel openPanel];
SetupDialog(dialog, title, default_path);
SetupDialog(dialog, title, default_path, filters);
SetupDialogForProperties(dialog, properties);
// Duplicate the callback object here since c is a reference and gcd would
@@ -129,11 +164,12 @@ void ShowOpenDialog(atom::NativeWindow* parent_window,
bool ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
base::FilePath* path) {
DCHECK(path);
NSSavePanel* dialog = [NSSavePanel savePanel];
SetupDialog(dialog, title, default_path);
SetupDialog(dialog, title, default_path, filters);
int chosen = RunModalDialog(dialog, parent_window);
if (chosen == NSFileHandlingPanelCancelButton || ![[dialog URL] isFileURL])
@@ -146,10 +182,11 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
void ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
const SaveDialogCallback& c) {
NSSavePanel* dialog = [NSSavePanel savePanel];
SetupDialog(dialog, title, default_path);
SetupDialog(dialog, title, default_path, filters);
__block SaveDialogCallback callback = c;

View File

@@ -30,103 +30,30 @@ bool IsDirectory(const base::FilePath& path) {
file_info.is_directory : path.EndsWithSeparator();
}
// Get the file type description from the registry. This will be "Text Document"
// for .txt files, "JPEG Image" for .jpg files, etc. If the registry doesn't
// have an entry for the file type, we return false, true if the description was
// found. 'file_ext' must be in form ".txt".
static bool GetRegistryDescriptionFromExtension(const std::wstring& file_ext,
std::wstring* reg_description) {
DCHECK(reg_description);
base::win::RegKey reg_ext(HKEY_CLASSES_ROOT, file_ext.c_str(), KEY_READ);
std::wstring reg_app;
if (reg_ext.ReadValue(NULL, &reg_app) == ERROR_SUCCESS && !reg_app.empty()) {
base::win::RegKey reg_link(HKEY_CLASSES_ROOT, reg_app.c_str(), KEY_READ);
if (reg_link.ReadValue(NULL, reg_description) == ERROR_SUCCESS)
return true;
}
return false;
}
// Set up a filter for a Save/Open dialog, which will consist of |file_ext| file
// extensions (internally separated by semicolons), |ext_desc| as the text
// descriptions of the |file_ext| types (optional), and (optionally) the default
// 'All Files' view. The purpose of the filter is to show only files of a
// particular type in a Windows Save/Open dialog box. The resulting filter is
// returned. The filters created here are:
// 1. only files that have 'file_ext' as their extension
// 2. all files (only added if 'include_all_files' is true)
// Example:
// file_ext: { "*.txt", "*.htm;*.html" }
// ext_desc: { "Text Document" }
// returned: "Text Document\0*.txt\0HTML Document\0*.htm;*.html\0"
// "All Files\0*.*\0\0" (in one big string)
// If a description is not provided for a file extension, it will be retrieved
// from the registry. If the file extension does not exist in the registry, it
// will be omitted from the filter, as it is likely a bogus extension.
void FormatFilterForExtensions(
std::vector<std::wstring>* file_ext,
std::vector<std::wstring>* ext_desc,
bool include_all_files,
std::vector<COMDLG_FILTERSPEC>* file_types) {
DCHECK(file_ext->size() >= ext_desc->size());
if (file_ext->empty())
include_all_files = true;
for (size_t i = 0; i < file_ext->size(); ++i) {
std::wstring ext = (*file_ext)[i];
std::wstring desc;
if (i < ext_desc->size())
desc = (*ext_desc)[i];
if (ext.empty()) {
// Force something reasonable to appear in the dialog box if there is no
// extension provided.
include_all_files = true;
continue;
}
if (desc.empty()) {
DCHECK(ext.find(L'.') != std::wstring::npos);
std::wstring first_extension = ext.substr(ext.find(L'.'));
size_t first_separator_index = first_extension.find(L';');
if (first_separator_index != std::wstring::npos)
first_extension = first_extension.substr(0, first_separator_index);
// Find the extension name without the preceeding '.' character.
std::wstring ext_name = first_extension;
size_t ext_index = ext_name.find_first_not_of(L'.');
if (ext_index != std::wstring::npos)
ext_name = ext_name.substr(ext_index);
if (!GetRegistryDescriptionFromExtension(first_extension, &desc)) {
// The extension doesn't exist in the registry. Create a description
// based on the unknown extension type (i.e. if the extension is .qqq,
// the we create a description "QQQ File (.qqq)").
include_all_files = true;
// TODO(zcbenz): should be localized.
desc = base::i18n::ToUpper(base::WideToUTF16(ext_name)) + L" File";
}
desc += L" (*." + ext_name + L")";
// Store the description.
ext_desc->push_back(desc);
}
COMDLG_FILTERSPEC spec = { (*ext_desc)[i].c_str(), (*file_ext)[i].c_str() };
file_types->push_back(spec);
void ConvertFilters(const Filters& filters,
std::vector<std::wstring>* buffer,
std::vector<COMDLG_FILTERSPEC>* filterspec) {
if (filters.empty()) {
COMDLG_FILTERSPEC spec = { L"All Files (*.*)", L"*.*" };
filterspec->push_back(spec);
return;
}
if (include_all_files) {
// TODO(zcbenz): Should be localized.
ext_desc->push_back(L"All Files (*.*)");
file_ext->push_back(L"*.*");
buffer->reserve(filters.size() * 2);
for (size_t i = 0; i < filters.size(); ++i) {
const Filter& filter = filters[i];
COMDLG_FILTERSPEC spec = {
(*ext_desc)[ext_desc->size() - 1].c_str(),
(*file_ext)[file_ext->size() - 1].c_str(),
};
file_types->push_back(spec);
COMDLG_FILTERSPEC spec;
buffer->push_back(base::UTF8ToWide(filter.first));
spec.pszName = buffer->back().c_str();
std::vector<std::string> extensions(filter.second);
for (size_t j = 0; j < extensions.size(); ++j)
extensions[j].insert(0, "*.");
buffer->push_back(base::UTF8ToWide(JoinString(extensions, ";")));
spec.pszSpec = buffer->back().c_str();
filterspec->push_back(spec);
}
}
@@ -135,26 +62,18 @@ void FormatFilterForExtensions(
template <typename T>
class FileDialog {
public:
FileDialog(const base::FilePath& default_path,
const std::string title,
int options,
const std::vector<std::wstring>& file_ext,
const std::vector<std::wstring>& desc_ext)
: file_ext_(file_ext),
desc_ext_(desc_ext) {
std::vector<COMDLG_FILTERSPEC> filters;
FormatFilterForExtensions(&file_ext_, &desc_ext_, true, &filters);
FileDialog(const base::FilePath& default_path, const std::string& title,
const Filters& filters, int options) {
std::wstring file_part;
if (!IsDirectory(default_path))
file_part = default_path.BaseName().value();
dialog_.reset(new T(
file_part.c_str(),
options,
NULL,
filters.data(),
filters.size()));
std::vector<std::wstring> buffer;
std::vector<COMDLG_FILTERSPEC> filterspec;
ConvertFilters(filters, &buffer, &filterspec);
dialog_.reset(new T(file_part.c_str(), options, NULL,
filterspec.data(), filterspec.size()));
if (!title.empty())
GetPtr()->SetTitle(base::UTF8ToUTF16(title).c_str());
@@ -174,8 +93,6 @@ class FileDialog {
IFileDialog* GetPtr() const { return dialog_->GetPtr(); }
const std::vector<std::wstring> file_ext() const { return file_ext_; }
private:
// Set up the initial directory for the dialog.
void SetDefaultFolder(const base::FilePath file_path) {
@@ -193,10 +110,6 @@ class FileDialog {
scoped_ptr<T> dialog_;
std::vector<std::wstring> file_ext_;
std::vector<std::wstring> desc_ext_;
std::vector<COMDLG_FILTERSPEC> filters_;
DISALLOW_COPY_AND_ASSIGN(FileDialog);
};
@@ -205,6 +118,7 @@ class FileDialog {
bool ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
int properties,
std::vector<base::FilePath>* paths) {
int options = FOS_FORCEFILESYSTEM | FOS_FILEMUSTEXIST;
@@ -214,11 +128,7 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window,
options |= FOS_ALLOWMULTISELECT;
FileDialog<CShellFileOpenDialog> open_dialog(
default_path,
title,
options,
std::vector<std::wstring>(),
std::vector<std::wstring>());
default_path, title, filters, options);
if (!open_dialog.Show(parent_window))
return false;
@@ -255,12 +165,14 @@ bool ShowOpenDialog(atom::NativeWindow* parent_window,
void ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
int properties,
const OpenDialogCallback& callback) {
std::vector<base::FilePath> paths;
bool result = ShowOpenDialog(parent_window,
title,
default_path,
filters,
properties,
&paths);
callback.Run(result, paths);
@@ -269,52 +181,51 @@ void ShowOpenDialog(atom::NativeWindow* parent_window,
bool ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
base::FilePath* path) {
// TODO(zcbenz): Accept custom filters from caller.
std::vector<std::wstring> file_ext;
std::wstring extension = default_path.Extension();
if (!extension.empty())
file_ext.push_back(extension.insert(0, L"*"));
FileDialog<CShellFileSaveDialog> save_dialog(
default_path,
title,
FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT,
file_ext,
std::vector<std::wstring>());
default_path, title, filters,
FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT);
if (!save_dialog.Show(parent_window))
return false;
wchar_t file_name[MAX_PATH];
HRESULT hr = save_dialog.GetDialog()->GetFilePath(file_name, MAX_PATH);
wchar_t buffer[MAX_PATH];
HRESULT hr = save_dialog.GetDialog()->GetFilePath(buffer, MAX_PATH);
if (FAILED(hr))
return false;
std::string file_name = base::WideToUTF8(std::wstring(buffer));
// Append extension according to selected filter.
UINT filter_index = 1;
save_dialog.GetPtr()->GetFileTypeIndex(&filter_index);
std::wstring selected_filter = save_dialog.file_ext()[filter_index - 1];
if (selected_filter != L"*.*") {
std::wstring result = file_name;
if (!EndsWith(result, selected_filter.substr(1), false)) {
if (result[result.length() - 1] != L'.')
result.push_back(L'.');
result.append(selected_filter.substr(2));
*path = base::FilePath(result);
return true;
if (!filters.empty()) {
UINT filter_index = 1;
save_dialog.GetPtr()->GetFileTypeIndex(&filter_index);
const Filter& filter = filters[filter_index - 1];
bool matched = false;
for (size_t i = 0; i < filter.second.size(); ++i) {
if (EndsWith(file_name, filter.second[i], false)) {
matched = true;
break;;
}
}
if (!matched && !filter.second.empty())
file_name += ("." + filter.second[0]);
}
*path = base::FilePath(file_name);
*path = base::FilePath(base::UTF8ToUTF16(file_name));
return true;
}
void ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const Filters& filters,
const SaveDialogCallback& callback) {
base::FilePath path;
bool result = ShowSaveDialog(parent_window, title, default_path, &path);
bool result = ShowSaveDialog(parent_window, title, default_path, filters,
&path);
callback.Run(result, path);
}

View File

@@ -71,7 +71,7 @@ class MessageDialog : public views::WidgetDelegate,
virtual views::ClientView* CreateClientView(views::Widget* widget) OVERRIDE;
// Overridden from views::View:
virtual gfx::Size GetPreferredSize() OVERRIDE;
virtual gfx::Size GetPreferredSize() const OVERRIDE;
virtual void Layout() OVERRIDE;
virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
@@ -160,7 +160,6 @@ MessageDialog::MessageDialog(NativeWindow* parent_window,
views::Widget::InitParams params;
params.delegate = this;
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.top_level = true;
if (parent_) {
params.parent = parent_->GetNativeWindow();
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
@@ -264,7 +263,7 @@ views::ClientView* MessageDialog::CreateClientView(views::Widget* widget) {
return new MessageDialogClientView(this, widget);
}
gfx::Size MessageDialog::GetPreferredSize() {
gfx::Size MessageDialog::GetPreferredSize() const {
gfx::Size size(0, buttons_[0]->GetPreferredSize().height());
for (size_t i = 0; i < buttons_.size(); ++i)
size.Enlarge(buttons_[i]->GetPreferredSize().width(), 0);

View File

@@ -12,8 +12,18 @@ TrayIcon::TrayIcon() {
TrayIcon::~TrayIcon() {
}
void TrayIcon::SetTitle(const std::string& title) {
}
void TrayIcon::SetHighlightMode(bool highlight) {
}
void TrayIcon::NotifyClicked() {
FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnClicked());
}
void TrayIcon::NotifyDoubleClicked() {
FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDoubleClicked());
}
} // namespace atom

View File

@@ -31,12 +31,21 @@ class TrayIcon {
// status icon (e.g. Ubuntu Unity).
virtual void SetToolTip(const std::string& tool_tip) = 0;
// Sets the title displayed aside of the status icon in the status bar. This
// only works on OS X.
virtual void SetTitle(const std::string& title);
// Sets whether the status icon is highlighted when it is clicked. This only
// works on OS X.
virtual void SetHighlightMode(bool highlight);
// Set the context menu for this icon.
virtual void SetContextMenu(ui::SimpleMenuModel* menu_model) = 0;
void AddObserver(TrayIconObserver* obs) { observers_.AddObserver(obs); }
void RemoveObserver(TrayIconObserver* obs) { observers_.RemoveObserver(obs); }
void NotifyClicked();
void NotifyDoubleClicked();
protected:
TrayIcon();

View File

@@ -25,6 +25,8 @@ class TrayIconCocoa : public TrayIcon {
virtual void SetImage(const gfx::ImageSkia& image) OVERRIDE;
virtual void SetPressedImage(const gfx::ImageSkia& image) OVERRIDE;
virtual void SetToolTip(const std::string& tool_tip) OVERRIDE;
virtual void SetTitle(const std::string& title) OVERRIDE;
virtual void SetHighlightMode(bool highlight) OVERRIDE;
virtual void SetContextMenu(ui::SimpleMenuModel* menu_model) OVERRIDE;
private:

View File

@@ -13,6 +13,7 @@
}
- (id)initWithIcon:(atom::TrayIconCocoa*)icon;
- (void)handleClick:(id)sender;
- (void)handleDoubleClick:(id)sender;
@end // @interface StatusItemController
@@ -24,10 +25,13 @@
}
- (void)handleClick:(id)sender {
DCHECK(trayIcon_);
trayIcon_->NotifyClicked();
}
- (void)handleDoubleClick:(id)sender {
trayIcon_->NotifyDoubleClicked();
}
@end
namespace atom {
@@ -40,6 +44,7 @@ TrayIconCocoa::TrayIconCocoa() {
[item_ setEnabled:YES];
[item_ setTarget:controller_];
[item_ setAction:@selector(handleClick:)];
[item_ setDoubleAction:@selector(handleDoubleClick:)];
[item_ setHighlightMode:YES];
}
@@ -68,6 +73,14 @@ void TrayIconCocoa::SetToolTip(const std::string& tool_tip) {
[item_ setToolTip:base::SysUTF8ToNSString(tool_tip)];
}
void TrayIconCocoa::SetTitle(const std::string& title) {
[item_ setTitle:base::SysUTF8ToNSString(title)];
}
void TrayIconCocoa::SetHighlightMode(bool highlight) {
[item_ setHighlightMode:highlight];
}
void TrayIconCocoa::SetContextMenu(ui::SimpleMenuModel* menu_model) {
menu_.reset([[AtomMenuController alloc] initWithModel:menu_model]);
[item_ setMenu:[menu_ menu]];

View File

@@ -10,6 +10,7 @@ namespace atom {
class TrayIconObserver {
public:
virtual void OnClicked() {}
virtual void OnDoubleClicked() {}
protected:
virtual ~TrayIconObserver() {}

View File

@@ -95,16 +95,16 @@ void FramelessView::UpdateWindowIcon() {
void FramelessView::UpdateWindowTitle() {
}
gfx::Size FramelessView::GetPreferredSize() {
gfx::Size FramelessView::GetPreferredSize() const {
return frame_->non_client_view()->GetWindowBoundsForClientBounds(
gfx::Rect(frame_->client_view()->GetPreferredSize())).size();
}
gfx::Size FramelessView::GetMinimumSize() {
gfx::Size FramelessView::GetMinimumSize() const {
return window_->GetMinimumSize();
}
gfx::Size FramelessView::GetMaximumSize() {
gfx::Size FramelessView::GetMaximumSize() const {
return window_->GetMaximumSize();
}

View File

@@ -38,9 +38,9 @@ class FramelessView : public views::NonClientFrameView {
virtual void UpdateWindowTitle() OVERRIDE;
// Overridden from View:
virtual gfx::Size GetPreferredSize() OVERRIDE;
virtual gfx::Size GetMinimumSize() OVERRIDE;
virtual gfx::Size GetMaximumSize() OVERRIDE;
virtual gfx::Size GetPreferredSize() const OVERRIDE;
virtual gfx::Size GetMinimumSize() const OVERRIDE;
virtual gfx::Size GetMaximumSize() const OVERRIDE;
virtual const char* GetClassName() const OVERRIDE;
// Not owned.

View File

@@ -4,16 +4,21 @@
#include "atom/browser/ui/views/menu_bar.h"
#if defined(USE_X11)
#include "gtk/gtk.h"
#endif
#include "atom/browser/ui/views/menu_delegate.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "atom/browser/ui/views/submenu_button.h"
#include "ui/base/models/menu_model.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/menu_button.h"
#include "ui/views/layout/box_layout.h"
#if defined(OS_WIN)
#include "ui/gfx/color_utils.h"
#elif defined(USE_X11)
#include "chrome/browser/ui/libgtk2ui/owned_widget_gtk2.h"
#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"
#endif
namespace atom {
@@ -25,24 +30,34 @@ const char kViewClassName[] = "AtomMenuBar";
// Default color of the menu bar.
const SkColor kDefaultColor = SkColorSetARGB(255, 233, 233, 233);
// Filter out the "&" in menu label.
base::string16 FilterMenuButtonLabel(const base::string16& label) {
base::string16 out;
base::RemoveChars(label, base::ASCIIToUTF16("&").c_str(), &out);
return out;
#if defined(USE_X11)
void GetMenuBarColor(SkColor* enabled, SkColor* disabled, SkColor* highlight,
SkColor* hover, SkColor* background) {
libgtk2ui::OwnedWidgetGtk fake_menu_bar;
fake_menu_bar.Own(gtk_menu_bar_new());
GtkStyle* style = gtk_rc_get_style(fake_menu_bar.get());
*enabled = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_NORMAL]);
*disabled = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_INSENSITIVE]);
*highlight = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_SELECTED]);
*hover = libgtk2ui::GdkColorToSkColor(style->fg[GTK_STATE_PRELIGHT]);
*background = libgtk2ui::GdkColorToSkColor(style->bg[GTK_STATE_NORMAL]);
}
#endif
} // namespace
MenuBar::MenuBar()
: menu_model_(NULL) {
: background_color_(kDefaultColor),
menu_model_(NULL) {
#if defined(OS_WIN)
SkColor background_color = color_utils::GetSysSkColor(COLOR_MENUBAR);
#else
SkColor background_color = kDefaultColor;
background_color_ = color_utils::GetSysSkColor(COLOR_MENUBAR);
#elif defined(USE_X11)
GetMenuBarColor(&enabled_color_, &disabled_color_, &highlight_color_,
&hover_color_, &background_color_);
#endif
set_background(views::Background::CreateSolidBackground(background_color));
set_background(views::Background::CreateSolidBackground(background_color_));
SetLayoutManager(new views::BoxLayout(
views::BoxLayout::kHorizontal, 0, 0, 0));
}
@@ -55,13 +70,43 @@ void MenuBar::SetMenu(ui::MenuModel* model) {
RemoveAllChildViews(true);
for (int i = 0; i < model->GetItemCount(); ++i) {
views::MenuButton* button = new views::MenuButton(
this, FilterMenuButtonLabel(model->GetLabelAt(i)), this, false);
SubmenuButton* button = new SubmenuButton(this, model->GetLabelAt(i), this);
button->set_tag(i);
#if defined(USE_X11)
button->SetTextColor(views::Button::STATE_NORMAL, enabled_color_);
button->SetTextColor(views::Button::STATE_DISABLED, disabled_color_);
button->SetTextColor(views::Button::STATE_PRESSED, highlight_color_);
button->SetTextColor(views::Button::STATE_HOVERED, hover_color_);
button->SetUnderlineColor(enabled_color_);
#elif defined(OS_WIN)
button->SetUnderlineColor(color_utils::GetSysSkColor(COLOR_GRAYTEXT));
#endif
AddChildView(button);
}
}
void MenuBar::SetAcceleratorVisibility(bool visible) {
for (int i = 0; i < child_count(); ++i)
static_cast<SubmenuButton*>(child_at(i))->SetAcceleratorVisibility(visible);
}
int MenuBar::GetAcceleratorIndex(base::char16 key) {
for (int i = 0; i < child_count(); ++i) {
SubmenuButton* button = static_cast<SubmenuButton*>(child_at(i));
if (button->accelerator() == key)
return i;
}
return -1;
}
void MenuBar::ActivateAccelerator(base::char16 key) {
int i = GetAcceleratorIndex(key);
if (i != -1)
static_cast<SubmenuButton*>(child_at(i))->Activate();
}
int MenuBar::GetItemCount() const {
return menu_model_->GetItemCount();
}
@@ -98,6 +143,9 @@ void MenuBar::ButtonPressed(views::Button* sender, const ui::Event& event) {
void MenuBar::OnMenuButtonClicked(views::View* source,
const gfx::Point& point) {
// Hide the accelerator when a submenu is activated.
SetAcceleratorVisibility(false);
if (!menu_model_)
return;

View File

@@ -31,6 +31,16 @@ class MenuBar : public views::View,
// Replaces current menu with a new one.
void SetMenu(ui::MenuModel* menu_model);
// Shows underline under accelerators.
void SetAcceleratorVisibility(bool visible);
// Returns which submenu has accelerator |key|, -1 would be returned when
// there is no matching submenu.
int GetAcceleratorIndex(base::char16 key);
// Shows the submenu whose accelerator is |key|.
void ActivateAccelerator(base::char16 key);
// Returns there are how many items in the root menu.
int GetItemCount() const;
@@ -52,6 +62,15 @@ class MenuBar : public views::View,
const gfx::Point& point) OVERRIDE;
private:
SkColor background_color_;
#if defined(USE_X11)
SkColor enabled_color_;
SkColor disabled_color_;
SkColor highlight_color_;
SkColor hover_color_;
#endif
ui::MenuModel* menu_model_;
scoped_ptr<MenuDelegate> menu_delegate_;

View File

@@ -73,7 +73,7 @@ bool MenuDelegate::IsTriggerableEvent(views::MenuItemView* source,
return delegate()->IsTriggerableEvent(source, e);
}
bool MenuDelegate::GetAccelerator(int id, ui::Accelerator* accelerator) {
bool MenuDelegate::GetAccelerator(int id, ui::Accelerator* accelerator) const {
return delegate()->GetAccelerator(id, accelerator);
}

View File

@@ -35,7 +35,7 @@ class MenuDelegate : public views::MenuDelegate {
virtual bool IsTriggerableEvent(views::MenuItemView* source,
const ui::Event& e) OVERRIDE;
virtual bool GetAccelerator(int id,
ui::Accelerator* accelerator) OVERRIDE;
ui::Accelerator* accelerator) const OVERRIDE;
virtual base::string16 GetLabel(int id) const OVERRIDE;
virtual const gfx::FontList* GetLabelFontList(int id) const OVERRIDE;
virtual bool IsCommandEnabled(int id) const OVERRIDE;

View File

@@ -24,13 +24,13 @@ void MenuLayout::Layout(views::View* host) {
gfx::Rect web_view_bounds = gfx::Rect(
0, menu_height_, size.width(), size.height() - menu_height_);
views::View* menu_bar = host->child_at(0);
views::View* web_view = host->child_at(1);
menu_bar->SetBoundsRect(menu_Bar_bounds);
views::View* web_view = host->child_at(0);
views::View* menu_bar = host->child_at(1);
web_view->SetBoundsRect(web_view_bounds);
menu_bar->SetBoundsRect(menu_Bar_bounds);
}
gfx::Size MenuLayout::GetPreferredSize(views::View* host) {
gfx::Size MenuLayout::GetPreferredSize(const views::View* host) const {
gfx::Size size = views::FillLayout::GetPreferredSize(host);
if (!HasMenu(host))
return size;
@@ -39,7 +39,8 @@ gfx::Size MenuLayout::GetPreferredSize(views::View* host) {
return size;
}
int MenuLayout::GetPreferredHeightForWidth(views::View* host, int width) {
int MenuLayout::GetPreferredHeightForWidth(
const views::View* host, int width) const {
int height = views::FillLayout::GetPreferredHeightForWidth(host, width);
if (!HasMenu(host))
return height;

View File

@@ -16,8 +16,9 @@ class MenuLayout : public views::FillLayout {
// views::LayoutManager:
virtual void Layout(views::View* host) OVERRIDE;
virtual gfx::Size GetPreferredSize(views::View* host) OVERRIDE;
virtual int GetPreferredHeightForWidth(views::View* host, int width) OVERRIDE;
virtual gfx::Size GetPreferredSize(const views::View* host) const OVERRIDE;
virtual int GetPreferredHeightForWidth(
const views::View* host, int width) const OVERRIDE;
private:
bool HasMenu(const views::View* host) const;

View File

@@ -0,0 +1,98 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/ui/views/submenu_button.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/text_utils.h"
#include "ui/views/controls/button/label_button_border.h"
namespace atom {
namespace {
// Filter out the "&" in menu label.
base::string16 FilterAccecelator(const base::string16& label) {
base::string16 out;
base::RemoveChars(label, base::ASCIIToUTF16("&").c_str(), &out);
return out;
}
} // namespace
SubmenuButton::SubmenuButton(views::ButtonListener* listener,
const base::string16& title,
views::MenuButtonListener* menu_button_listener)
: views::MenuButton(listener, FilterAccecelator(title),
menu_button_listener, false),
accelerator_(0),
show_underline_(false),
underline_start_(-1),
underline_end_(-1),
text_width_(0),
text_height_(0),
underline_color_(SK_ColorBLACK) {
#if defined(OS_LINUX)
// Dont' use native style border.
SetBorder(CreateDefaultBorder().PassAs<views::Border>());
#endif
if (GetUnderlinePosition(title, &accelerator_, &underline_start_,
&underline_end_))
gfx::Canvas::SizeStringInt(GetText(), GetFontList(), &text_width_,
&text_height_, 0, 0);
}
SubmenuButton::~SubmenuButton() {
}
void SubmenuButton::SetAcceleratorVisibility(bool visible) {
if (visible == show_underline_)
return;
show_underline_ = visible;
SchedulePaint();
}
void SubmenuButton::SetUnderlineColor(SkColor color) {
underline_color_ = color;
}
void SubmenuButton::OnPaint(gfx::Canvas* canvas) {
views::MenuButton::OnPaint(canvas);
if (show_underline_ && (underline_start_ != underline_end_)) {
int padding = (width() - text_width_) / 2;
int underline_height = (height() + text_height_) / 2 - 2;
canvas->DrawLine(gfx::Point(underline_start_ + padding, underline_height),
gfx::Point(underline_end_ + padding, underline_height),
underline_color_);
}
}
bool SubmenuButton::GetUnderlinePosition(const base::string16& text,
base::char16* accelerator,
int* start, int* end) {
int pos, span;
base::string16 trimmed = gfx::RemoveAcceleratorChar(text, '&', &pos, &span);
if (pos > -1 && span != 0) {
*accelerator = base::ToUpperASCII(trimmed[pos]);
GetCharacterPosition(trimmed, pos, start);
GetCharacterPosition(trimmed, pos + span, end);
return true;
}
return false;
}
void SubmenuButton::GetCharacterPosition(
const base::string16& text, int index, int* pos) {
int height;
gfx::Canvas::SizeStringInt(text.substr(0, index), GetFontList(), pos, &height,
0, 0);
}
} // namespace atom

View File

@@ -0,0 +1,53 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_UI_VIEWS_SUBMENU_BUTTON_H_
#define ATOM_BROWSER_UI_VIEWS_SUBMENU_BUTTON_H_
#include "ui/views/controls/button/menu_button.h"
namespace atom {
// Special button that used by menu bar to show submenus.
class SubmenuButton : public views::MenuButton {
public:
SubmenuButton(views::ButtonListener* listener,
const base::string16& title,
views::MenuButtonListener* menu_button_listener);
virtual ~SubmenuButton();
void SetAcceleratorVisibility(bool visible);
void SetUnderlineColor(SkColor color);
void SetEnabledColor(SkColor color);
void SetBackgroundColor(SkColor color);
base::char16 accelerator() const { return accelerator_; }
// views::MenuButton:
virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
private:
bool GetUnderlinePosition(const base::string16& text,
base::char16* accelerator,
int* start, int* end);
void GetCharacterPosition(
const base::string16& text, int index, int* pos);
base::char16 accelerator_;
bool show_underline_;
int underline_start_;
int underline_end_;
int text_width_;
int text_height_;
SkColor underline_color_;
DISALLOW_COPY_AND_ASSIGN(SubmenuButton);
};
} // namespace atom
#endif // ATOM_BROWSER_UI_VIEWS_SUBMENU_BUTTON_H_

View File

@@ -39,12 +39,12 @@ int WinFrameView::NonClientHitTest(const gfx::Point& point) {
return FramelessView::NonClientHitTest(point);
}
gfx::Size WinFrameView::GetMinimumSize() {
gfx::Size WinFrameView::GetMinimumSize() const {
gfx::Size size = FramelessView::GetMinimumSize();
return gfx::win::DIPToScreenSize(size);
}
gfx::Size WinFrameView::GetMaximumSize() {
gfx::Size WinFrameView::GetMaximumSize() const {
gfx::Size size = FramelessView::GetMaximumSize();
return gfx::win::DIPToScreenSize(size);
}

View File

@@ -20,8 +20,8 @@ class WinFrameView : public FramelessView {
virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE;
// views::View:
virtual gfx::Size GetMinimumSize() OVERRIDE;
virtual gfx::Size GetMaximumSize() OVERRIDE;
virtual gfx::Size GetMinimumSize() const OVERRIDE;
virtual gfx::Size GetMaximumSize() const OVERRIDE;
virtual const char* GetClassName() const OVERRIDE;
private:

View File

@@ -0,0 +1,34 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/ui/x/x_window_utils.h"
#include "ui/base/x/x11_util.h"
namespace atom {
::Atom GetAtom(const char* name) {
return XInternAtom(gfx::GetXDisplay(), name, false);
}
void SetWMSpecState(::Window xwindow, bool enabled, ::Atom state) {
XEvent xclient;
memset(&xclient, 0, sizeof(xclient));
xclient.type = ClientMessage;
xclient.xclient.window = xwindow;
xclient.xclient.message_type = GetAtom("_NET_WM_STATE");
xclient.xclient.format = 32;
xclient.xclient.data.l[0] = enabled ? 1 : 0;
xclient.xclient.data.l[1] = state;
xclient.xclient.data.l[2] = None;
xclient.xclient.data.l[3] = 1;
xclient.xclient.data.l[4] = 0;
XDisplay* xdisplay = gfx::GetXDisplay();
XSendEvent(xdisplay, DefaultRootWindow(xdisplay), False,
SubstructureRedirectMask | SubstructureNotifyMask,
&xclient);
}
} // namespace atom

View File

@@ -0,0 +1,22 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_UI_X_X_WINDOW_UTILS_H_
#define ATOM_BROWSER_UI_X_X_WINDOW_UTILS_H_
#include <X11/extensions/XInput2.h>
#include <X11/extensions/Xrandr.h>
#include <X11/Xlib.h>
namespace atom {
::Atom GetAtom(const char* name);
// Sends a message to the x11 window manager, enabling or disabling the |state|
// for _NET_WM_STATE.
void SetWMSpecState(::Window xwindow, bool enabled, ::Atom state);
} // namespace atom
#endif // ATOM_BROWSER_UI_X_X_WINDOW_UTILS_H_

View File

@@ -28,7 +28,7 @@ int32_t IDWeakMap::Add(v8::Isolate* isolate, v8::Handle<v8::Object> object) {
object->SetHiddenValue(mate::StringToV8(isolate, "IDWeakMapKey"),
mate::Converter<int32_t>::ToV8(isolate, key));
map_[key] = new mate::RefCountedPersistent<v8::Object>(object);
map_[key] = new mate::RefCountedPersistent<v8::Object>(isolate, object);
map_[key]->SetWeak(this, WeakCallback);
return key;
}

View File

@@ -4,13 +4,13 @@
#include "atom/common/api/atom_bindings.h"
#include <algorithm>
#include <string>
#include "atom/common/atom_version.h"
#include "atom/common/native_mate_converters/function_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "base/callback.h"
#include "base/logging.h"
#include "native_mate/callback.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
@@ -19,9 +19,6 @@ namespace atom {
namespace {
// Async handle to wake up uv loop.
uv_async_t g_next_tick_uv_handle;
// Async handle to execute the stored v8 callback.
uv_async_t g_callback_uv_handle;
@@ -31,70 +28,26 @@ base::Closure g_v8_callback;
// Dummy class type that used for crashing the program.
struct DummyClass { bool crash; };
// Async handler to call next process.nextTick callbacks.
void UvCallNextTick(uv_async_t* handle) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
node::Environment* env = node::Environment::GetCurrent(isolate);
node::Environment::TickInfo* tick_info = env->tick_info();
if (tick_info->in_tick())
return;
if (tick_info->length() == 0) {
tick_info->set_index(0);
return;
}
tick_info->set_in_tick(true);
env->tick_callback_function()->Call(env->process_object(), 0, NULL);
tick_info->set_in_tick(false);
}
// Async handler to execute the stored v8 callback.
void UvOnCallback(uv_async_t* handle) {
g_v8_callback.Run();
}
// Called when there is a fatal error in V8, we just crash the process here so
// we can get the stack trace.
void FatalErrorCallback(const char* location, const char* message) {
LOG(ERROR) << "Fatal error in V8: " << location << " " << message;
static_cast<DummyClass*>(NULL)->crash = true;
}
v8::Handle<v8::Value> DumpStackFrame(v8::Isolate* isolate,
v8::Handle<v8::StackFrame> stack_frame) {
mate::Dictionary frame_dict(isolate);
frame_dict.Set("line", stack_frame->GetLineNumber());
frame_dict.Set("column", stack_frame->GetColumn());
return mate::ConvertToV8(isolate, frame_dict);;
}
void Crash() {
static_cast<DummyClass*>(NULL)->crash = true;
}
void ActivateUVLoop() {
uv_async_send(&g_next_tick_uv_handle);
// Called when there is a fatal error in V8, we just crash the process here so
// we can get the stack trace.
void FatalErrorCallback(const char* location, const char* message) {
LOG(ERROR) << "Fatal error in V8: " << location << " " << message;
Crash();
}
void Log(const base::string16& message) {
logging::LogMessage("CONSOLE", 0, 0).stream() << message;
}
v8::Handle<v8::Value> GetCurrentStackTrace(v8::Isolate* isolate,
int stack_limit) {
v8::Local<v8::StackTrace> stack_trace = v8::StackTrace::CurrentStackTrace(
isolate, stack_limit, v8::StackTrace::kDetailed);
int frame_count = stack_trace->GetFrameCount();
v8::Local<v8::Array> result = v8::Array::New(isolate, frame_count);
for (int i = 0; i < frame_count; ++i)
result->Set(i, DumpStackFrame(isolate, stack_trace->GetFrame(i)));
return result;
}
void ScheduleCallback(const base::Closure& callback) {
g_v8_callback = callback;
uv_async_send(&g_callback_uv_handle);
@@ -104,9 +57,10 @@ void ScheduleCallback(const base::Closure& callback) {
AtomBindings::AtomBindings() {
uv_async_init(uv_default_loop(), &g_next_tick_uv_handle, UvCallNextTick);
uv_async_init(uv_default_loop(), &call_next_tick_async_, OnCallNextTick);
call_next_tick_async_.data = this;
uv_async_init(uv_default_loop(), &g_callback_uv_handle, UvOnCallback);
v8::V8::SetFatalErrorHandler(FatalErrorCallback);
}
AtomBindings::~AtomBindings() {
@@ -114,12 +68,14 @@ AtomBindings::~AtomBindings() {
void AtomBindings::BindTo(v8::Isolate* isolate,
v8::Handle<v8::Object> process) {
v8::V8::SetFatalErrorHandler(FatalErrorCallback);
mate::Dictionary dict(isolate, process);
dict.SetMethod("crash", &Crash);
dict.SetMethod("activateUvLoop", &ActivateUVLoop);
dict.SetMethod("log", &Log);
dict.SetMethod("getCurrentStackTrace", &GetCurrentStackTrace);
dict.SetMethod("scheduleCallback", &ScheduleCallback);
dict.SetMethod("activateUvLoop",
base::Bind(&AtomBindings::ActivateUVLoop, base::Unretained(this)));
v8::Handle<v8::Object> versions;
if (dict.Get("versions", &versions))
@@ -127,4 +83,40 @@ void AtomBindings::BindTo(v8::Isolate* isolate,
mate::StringToV8(isolate, ATOM_VERSION_STRING));
}
void AtomBindings::ActivateUVLoop(v8::Isolate* isolate) {
node::Environment* env = node::Environment::GetCurrent(isolate);
if (std::find(pending_next_ticks_.begin(), pending_next_ticks_.end(), env) !=
pending_next_ticks_.end())
return;
pending_next_ticks_.push_back(env);
uv_async_send(&call_next_tick_async_);
}
// static
void AtomBindings::OnCallNextTick(uv_async_t* handle) {
AtomBindings* self = static_cast<AtomBindings*>(handle->data);
for (std::list<node::Environment*>::const_iterator it =
self->pending_next_ticks_.begin();
it != self->pending_next_ticks_.end(); ++it) {
node::Environment* env = *it;
node::Environment::TickInfo* tick_info = env->tick_info();
v8::Context::Scope context_scope(env->context());
if (tick_info->in_tick())
continue;
if (tick_info->length() == 0) {
tick_info->set_index(0);
continue;
}
tick_info->set_in_tick(true);
env->tick_callback_function()->Call(env->process_object(), 0, NULL);
tick_info->set_in_tick(false);
}
self->pending_next_ticks_.clear();
}
} // namespace atom

View File

@@ -5,10 +5,15 @@
#ifndef ATOM_COMMON_API_ATOM_BINDINGS_H_
#define ATOM_COMMON_API_ATOM_BINDINGS_H_
#include "base/basictypes.h"
#include "base/callback_forward.h"
#include <list>
#include "base/strings/string16.h"
#include "v8/include/v8.h"
#include "vendor/node/deps/uv/include/uv.h"
namespace node {
class Environment;
}
namespace atom {
@@ -22,6 +27,13 @@ class AtomBindings {
virtual void BindTo(v8::Isolate* isolate, v8::Handle<v8::Object> process);
private:
void ActivateUVLoop(v8::Isolate* isolate);
static void OnCallNextTick(uv_async_t* handle);
uv_async_t call_next_tick_async_;
std::list<node::Environment*> pending_next_ticks_;
DISALLOW_COPY_AND_ASSIGN(AtomBindings);
};

View File

@@ -16,7 +16,7 @@ void ObjectLifeMonitor::BindTo(v8::Isolate* isolate,
target->SetHiddenValue(MATE_STRING_NEW(isolate, "destructor"), destructor);
ObjectLifeMonitor* olm = new ObjectLifeMonitor();
olm->handle_.reset(target);
olm->handle_.reset(isolate, target);
olm->handle_.SetWeak(olm, WeakCallback);
}

View File

@@ -6,8 +6,8 @@
#define ATOM_VERSION_H
#define ATOM_MAJOR_VERSION 0
#define ATOM_MINOR_VERSION 15
#define ATOM_PATCH_VERSION 1
#define ATOM_MINOR_VERSION 16
#define ATOM_PATCH_VERSION 3
#define ATOM_VERSION_IS_RELEASE 1

View File

@@ -1,21 +0,0 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/common/browser_v8_locker.h"
namespace node {
extern bool g_standalone_mode;
}
namespace atom {
BrowserV8Locker::BrowserV8Locker(v8::Isolate* isolate) {
if (node::g_standalone_mode)
locker_.reset(new v8::Locker(isolate));
}
BrowserV8Locker::~BrowserV8Locker() {
}
} // namespace atom

View File

@@ -1,28 +0,0 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_COMMON_BROWSER_V8_LOCKER_H_
#define ATOM_COMMON_BROWSER_V8_LOCKER_H_
#include "base/memory/scoped_ptr.h"
#include "v8/include/v8.h"
namespace atom {
// Like v8::Locker, but only do lock when in browser process.
class BrowserV8Locker {
public:
explicit BrowserV8Locker(v8::Isolate* isolate);
~BrowserV8Locker();
private:
void* operator new(size_t size);
void operator delete(void*, size_t);
scoped_ptr<v8::Locker> locker_;
};
} // namespace atom
#endif // ATOM_COMMON_BROWSER_V8_LOCKER_H_

View File

@@ -8,7 +8,7 @@
#ifndef ATOM_COMMON_CHROME_VERSION_H_
#define ATOM_COMMON_CHROME_VERSION_H_
#define CHROME_VERSION_STRING "36.0.1985.125"
#define CHROME_VERSION_STRING "37.0.2062.102"
#define CHROME_VERSION "v" CHROME_VERSION_STRING
#endif // ATOM_COMMON_CHROME_VERSION_H_

View File

@@ -1,33 +1,34 @@
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
// Get basic type definitions.
#define IPC_MESSAGE_IMPL
#include "atom/common/api/api_messages.h"
#include "atom/common/common_message_generator.h"
// Generate constructors.
#include "ipc/struct_constructor_macros.h"
#include "atom/common/api/api_messages.h"
#include "atom/common/common_message_generator.h"
// Generate destructors.
#include "ipc/struct_destructor_macros.h"
#include "atom/common/api/api_messages.h"
#include "atom/common/common_message_generator.h"
// Generate param traits write methods.
#include "ipc/param_traits_write_macros.h"
namespace IPC {
#include "atom/common/api/api_messages.h"
#include "atom/common/common_message_generator.h"
} // namespace IPC
// Generate param traits read methods.
#include "ipc/param_traits_read_macros.h"
namespace IPC {
#include "atom/common/api/api_messages.h"
#include "atom/common/common_message_generator.h"
} // namespace IPC
// Generate param traits log methods.
#include "ipc/param_traits_log_macros.h"
namespace IPC {
#include "atom/common/api/api_messages.h"
#include "atom/common/common_message_generator.h"
} // namespace IPC

View File

@@ -0,0 +1,8 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
// Multiply-included file, no traditional include guard.
#include "atom/common/api/api_messages.h"
#include "chrome/common/print_messages.h"

View File

@@ -350,6 +350,8 @@ void ExecUploadProcessOrTerminate(const BreakpadInfo& info,
"--timeout=60", // Set a timeout so we don't hang forever.
"--tries=1", // Don't retry if the upload fails.
"--quiet", // Be silent.
"-O", // output reply to /dev/null.
"/dev/null",
NULL,
};
static const char msg[] = "Cannot upload crash dump: cannot exec "

View File

@@ -25,3 +25,11 @@ wrapWithActivateUvLoop = (func) ->
process.nextTick = wrapWithActivateUvLoop process.nextTick
global.setImmediate = wrapWithActivateUvLoop timers.setImmediate
global.clearImmediate = timers.clearImmediate
# setTimeout needs to update the polling timeout of the event loop, when called
# under Chromium's event loop the node's event loop won't get a chance to update
# the timeout, so we have to force the node's event loop to recalculate the
# timeout in browser process.
if process.type is 'browser'
global.setTimeout = wrapWithActivateUvLoop timers.setTimeout
global.setInterval = wrapWithActivateUvLoop timers.setInterval

View File

@@ -0,0 +1,22 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/common/native_mate_converters/accelerator_converter.h"
#include <string>
#include "atom/browser/ui/accelerator_util.h"
namespace mate {
// static
bool Converter<ui::Accelerator>::FromV8(
v8::Isolate* isolate, v8::Handle<v8::Value> val, ui::Accelerator* out) {
std::string keycode;
if (!ConvertFromV8(isolate, val, &keycode))
return false;
return accelerator_util::StringToAccelerator(keycode, out);
}
} // namespace mate

View File

@@ -0,0 +1,24 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_ACCELERATOR_CONVERTER_H_
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_ACCELERATOR_CONVERTER_H_
#include "native_mate/converter.h"
namespace ui {
class Accelerator;
}
namespace mate {
template<>
struct Converter<ui::Accelerator> {
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
ui::Accelerator* out);
};
} // namespace mate
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_ACCELERATOR_CONVERTER_H_

View File

@@ -1,209 +0,0 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_FUNCTION_CONVERTER_H_
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_FUNCTION_CONVERTER_H_
#include "atom/common/browser_v8_locker.h"
#include "base/bind.h"
#include "base/callback.h"
#include "native_mate/constructor.h"
#include "native_mate/scoped_persistent.h"
namespace mate {
namespace internal {
typedef scoped_refptr<RefCountedPersistent<v8::Function> > SafeV8Function;
// Helper to convert type to V8 with storage type (const T& to T).
template<typename T>
v8::Handle<v8::Value> ConvertToV8(v8::Isolate* isolate, T a) {
return Converter<typename base::internal::CallbackParamTraits<T>::StorageType>
::ToV8(isolate, a);
}
// This set of templates invokes a V8::Function by converting the C++ types.
template<typename Sig>
struct V8FunctionInvoker;
template<typename R>
struct V8FunctionInvoker<R()> {
static R Go(v8::Isolate* isolate, SafeV8Function function) {
R ret;
atom::BrowserV8Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Function> holder = function->NewHandle();
v8::Handle<v8::Value> val(holder->Call(holder, 0, NULL));
Converter<R>::FromV8(isolate, val, &ret);
return ret;
}
};
template<>
struct V8FunctionInvoker<void()> {
static void Go(v8::Isolate* isolate, SafeV8Function function) {
atom::BrowserV8Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Function> holder = function->NewHandle();
holder->Call(holder, 0, NULL);
}
};
template<typename R, typename P1>
struct V8FunctionInvoker<R(P1)> {
static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1) {
R ret;
atom::BrowserV8Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Function> holder = function->NewHandle();
v8::Handle<v8::Value> args[] = {
ConvertToV8(isolate, a1),
};
v8::Handle<v8::Value> val(holder->Call(holder, arraysize(args), args));
Converter<R>::FromV8(isolate, val, &ret);
return ret;
}
};
template<typename P1>
struct V8FunctionInvoker<void(P1)> {
static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1) {
atom::BrowserV8Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Function> holder = function->NewHandle();
v8::Handle<v8::Value> args[] = {
ConvertToV8(isolate, a1),
};
holder->Call(holder, arraysize(args), args);
}
};
template<typename R, typename P1, typename P2>
struct V8FunctionInvoker<R(P1, P2)> {
static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2) {
R ret;
atom::BrowserV8Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Function> holder = function->NewHandle();
v8::Handle<v8::Value> args[] = {
ConvertToV8(isolate, a1),
ConvertToV8(isolate, a2),
};
v8::Handle<v8::Value> val(holder->Call(holder, arraysize(args), args));
Converter<R>::FromV8(isolate, val, &ret);
return ret;
}
};
template<typename P1, typename P2>
struct V8FunctionInvoker<void(P1, P2)> {
static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2) {
atom::BrowserV8Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Function> holder = function->NewHandle();
v8::Handle<v8::Value> args[] = {
ConvertToV8(isolate, a1),
ConvertToV8(isolate, a2),
};
holder->Call(holder, arraysize(args), args);
}
};
template<typename R, typename P1, typename P2, typename P3>
struct V8FunctionInvoker<R(P1, P2, P3)> {
static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2,
P3 a3) {
R ret;
atom::BrowserV8Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Function> holder = function->NewHandle();
v8::Handle<v8::Value> args[] = {
ConvertToV8(isolate, a1),
ConvertToV8(isolate, a2),
ConvertToV8(isolate, a3),
};
v8::Handle<v8::Value> val(holder->Call(holder, arraysize(args), args));
Converter<R>::FromV8(isolate, val, &ret);
return ret;
}
};
template<typename P1, typename P2, typename P3>
struct V8FunctionInvoker<void(P1, P2, P3)> {
static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2,
P3 a3) {
atom::BrowserV8Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Function> holder = function->NewHandle();
v8::Handle<v8::Value> args[] = {
ConvertToV8(isolate, a1),
ConvertToV8(isolate, a2),
ConvertToV8(isolate, a3),
};
holder->Call(holder, arraysize(args), args);
}
};
template<typename R, typename P1, typename P2, typename P3, typename P4>
struct V8FunctionInvoker<R(P1, P2, P3, P4)> {
static R Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2,
P3 a3, P4 a4) {
R ret;
atom::BrowserV8Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Function> holder = function->NewHandle();
v8::Handle<v8::Value> args[] = {
ConvertToV8(isolate, a1),
ConvertToV8(isolate, a2),
ConvertToV8(isolate, a3),
ConvertToV8(isolate, a4),
};
v8::Handle<v8::Value> val(holder->Call(holder, arraysize(args), args));
Converter<R>::FromV8(isolate, val, &ret);
return ret;
}
};
template<typename P1, typename P2, typename P3, typename P4>
struct V8FunctionInvoker<void(P1, P2, P3, P4)> {
static void Go(v8::Isolate* isolate, SafeV8Function function, P1 a1, P2 a2,
P3 a3, P4 a4) {
atom::BrowserV8Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Function> holder = function->NewHandle();
v8::Handle<v8::Value> args[] = {
ConvertToV8(isolate, a1),
ConvertToV8(isolate, a2),
ConvertToV8(isolate, a3),
ConvertToV8(isolate, a4),
};
holder->Call(holder, arraysize(args), args);
}
};
} // namespace internal
template<typename Sig>
struct Converter<base::Callback<Sig> > {
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
const base::Callback<Sig>& val) {
return CreateFunctionTemplate(isolate, val)->GetFunction();
}
static bool FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
base::Callback<Sig>* out) {
if (!val->IsFunction())
return false;
internal::SafeV8Function function(
new RefCountedPersistent<v8::Function>(val));
*out = base::Bind(&internal::V8FunctionInvoker<Sig>::Go, isolate, function);
return true;
}
};
} // namespace mate
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_FUNCTION_CONVERTER_H_

View File

@@ -5,6 +5,7 @@
#include "atom/common/native_mate_converters/image_converter.h"
#include <string>
#include <vector>
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "base/file_util.h"
@@ -18,12 +19,83 @@ namespace mate {
namespace {
ui::ScaleFactor GetScaleFactorFromFileName(const base::FilePath& path) {
struct ScaleFactorPair {
const char* name;
float scale;
};
ScaleFactorPair kScaleFactorPairs[] = {
// The "@2x" is put as first one to make scale matching faster.
{ "@2x" , 2.0f },
{ "@3x" , 3.0f },
{ "@1x" , 1.0f },
{ "@1.25x" , 1.25f },
{ "@1.33x" , 1.33f },
{ "@1.4x" , 1.4f },
{ "@1.5x" , 1.5f },
{ "@1.8x" , 1.8f },
{ "@2.5x" , 2.5f },
};
float GetScaleFactorFromPath(const base::FilePath& path) {
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
if (EndsWith(filename, "@2x", true))
return ui::SCALE_FACTOR_200P;
else
return ui::SCALE_FACTOR_100P;
// There is no scale info in the file path.
if (!EndsWith(filename, "x", true))
return 1.0f;
// We don't try to convert string to float here because it is very very
// expensive.
for (unsigned i = 0; i < arraysize(kScaleFactorPairs); ++i) {
if (EndsWith(filename, kScaleFactorPairs[i].name, true))
return kScaleFactorPairs[i].scale;
}
return 1.0f;
}
void AppendIfExists(std::vector<base::FilePath>* paths,
const base::FilePath& path) {
if (base::PathExists(path))
paths->push_back(path);
}
void PopulatePossibleFilePaths(std::vector<base::FilePath>* paths,
const base::FilePath& path) {
AppendIfExists(paths, path);
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
if (MatchPattern(filename, "*@*x"))
return;
for (unsigned i = 0; i < arraysize(kScaleFactorPairs); ++i)
AppendIfExists(paths,
path.InsertBeforeExtensionASCII(kScaleFactorPairs[i].name));
}
bool AddImageSkiaRepFromPath(gfx::ImageSkia* image,
const base::FilePath& path) {
std::string file_contents;
if (!base::ReadFileToString(path, &file_contents))
return false;
const unsigned char* data =
reinterpret_cast<const unsigned char*>(file_contents.data());
size_t size = file_contents.size();
scoped_ptr<SkBitmap> decoded(new SkBitmap());
// Try PNG first.
if (!gfx::PNGCodec::Decode(data, size, decoded.get()))
// Try JPEG.
decoded.reset(gfx::JPEGCodec::Decode(data, size));
if (decoded) {
image->AddRepresentation(gfx::ImageSkiaRep(
*decoded.release(), GetScaleFactorFromPath(path)));
return true;
}
return false;
}
} // namespace
@@ -33,25 +105,16 @@ bool Converter<gfx::ImageSkia>::FromV8(v8::Isolate* isolate,
gfx::ImageSkia* out) {
base::FilePath path;
if (Converter<base::FilePath>::FromV8(isolate, val, &path)) {
std::string file_contents;
if (!base::ReadFileToString(path, &file_contents))
std::vector<base::FilePath> paths;
PopulatePossibleFilePaths(&paths, path);
if (paths.empty())
return false;
const unsigned char* data =
reinterpret_cast<const unsigned char*>(file_contents.data());
size_t size = file_contents.size();
scoped_ptr<SkBitmap> decoded(new SkBitmap());
// Try PNG first.
if (!gfx::PNGCodec::Decode(data, size, decoded.get()))
// Try JPEG.
decoded.reset(gfx::JPEGCodec::Decode(data, size));
if (decoded) {
*out = gfx::ImageSkia(gfx::ImageSkiaRep(*decoded.release(),
GetScaleFactorFromFileName(path)));
return true;
for (size_t i = 0; i < paths.size(); ++i) {
if (!AddImageSkiaRepFromPath(out, paths[i]))
return false;
}
return true;
}
return false;

View File

@@ -7,13 +7,13 @@
#include <string>
#include <vector>
#include "atom/common/browser_v8_locker.h"
#include "base/command_line.h"
#include "base/base_paths.h"
#include "base/files/file_path.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "content/public/browser/browser_thread.h"
#include "native_mate/locker.h"
#if defined(OS_WIN)
#include "base/strings/utf_string_conversions.h"
@@ -66,6 +66,7 @@ REFERENCE_MODULE(atom_browser_dialog);
REFERENCE_MODULE(atom_browser_menu);
REFERENCE_MODULE(atom_browser_power_monitor);
REFERENCE_MODULE(atom_browser_protocol);
REFERENCE_MODULE(atom_browser_global_shortcut);
REFERENCE_MODULE(atom_browser_tray);
REFERENCE_MODULE(atom_browser_window);
REFERENCE_MODULE(atom_common_clipboard);
@@ -245,7 +246,7 @@ void NodeBindings::UvRunOnce() {
node::Environment* env = uv_env() ? uv_env() : global_env;
// Use Locker in browser process.
BrowserV8Locker locker(env->isolate());
mate::Locker locker(env->isolate());
v8::HandleScope handle_scope(env->isolate());
// Enter node context while dealing with uv events.

View File

@@ -48,6 +48,26 @@ const char kWebPreferences[] = "web-preferences";
// The factor of which page should be zoomed.
const char kZoomFactor[] = "zoom-factor";
// The menu bar is hidden unless "Alt" is pressed.
const char kAutoHideMenuBar[] = "auto-hide-menu-bar";
// Enable window to be resized larger than screen.
const char kEnableLargerThanScreen[] = "enable-larger-than-screen";
// Forces to use dark theme on Linux.
const char kDarkTheme[] = "dark-theme";
// Enable DirectWrite on Windows.
const char kDirectWrite[] = "direct-write";
// Web runtime features.
const char kExperimentalFeatures[] = "experimental-features";
const char kExperimentalCanvasFeatures[] = "experimental-canvas-features";
const char kSubpixelFontScaling[] = "subpixel-font-scaling";
const char kOverlayScrollbars[] = "overlay-scrollbars";
const char kOverlayFullscreenVideo[] = "overlay-fullscreen-video";
const char kSharedWorker[] = "shared-worker";
} // namespace switches
} // namespace atom

View File

@@ -32,6 +32,17 @@ extern const char kAcceptFirstMouse[];
extern const char kUseContentSize[];
extern const char kWebPreferences[];
extern const char kZoomFactor[];
extern const char kAutoHideMenuBar[];
extern const char kEnableLargerThanScreen[];
extern const char kDarkTheme[];
extern const char kDirectWrite[];
extern const char kExperimentalFeatures[];
extern const char kExperimentalCanvasFeatures[];
extern const char kSubpixelFontScaling[];
extern const char kOverlayScrollbars[];
extern const char kOverlayFullscreenVideo[];
extern const char kSharedWorker[];
} // namespace switches

View File

@@ -19,6 +19,7 @@ void XDGUtil(const std::string& util, const std::string& arg) {
argv.push_back(arg);
base::LaunchOptions options;
options.allow_new_privs = true;
// xdg-open can fall back on mailcap which eventually might plumb through
// to a command that needs a terminal. Set the environment variable telling
// it that we definitely don't have a terminal available and that it should

View File

@@ -5,6 +5,7 @@
#ifndef ATOM_RENDERER_ATOM_RENDER_VIEW_OBSERVER_H_
#define ATOM_RENDERER_ATOM_RENDER_VIEW_OBSERVER_H_
#include "base/strings/string16.h"
#include "content/public/renderer/render_view_observer.h"
namespace base {

View File

@@ -11,12 +11,16 @@
#include "atom/common/options_switches.h"
#include "atom/renderer/api/atom_renderer_bindings.h"
#include "atom/renderer/atom_render_view_observer.h"
#include "chrome/renderer/printing/print_web_view_helper.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_thread.h"
#include "base/command_line.h"
#include "native_mate/converter.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
#include "atom/common/node_includes.h"
@@ -31,6 +35,19 @@ const char* kSecurityManualEnableIframe = "manual-enable-iframe";
const char* kSecurityDisable = "disable";
const char* kSecurityEnableNodeIntegration = "enable-node-integration";
bool IsSwitchEnabled(base::CommandLine* command_line,
const char* switch_string,
bool* enabled) {
std::string value = command_line->GetSwitchValueASCII(switch_string);
if (value == "true")
*enabled = true;
else if (value == "false")
*enabled = false;
else
return false;
return true;
}
// Helper class to forward the WillReleaseScriptContext message to the client.
class AtomRenderFrameObserver : public content::RenderFrameObserver {
public:
@@ -70,10 +87,6 @@ AtomRendererClient::AtomRendererClient()
node_integration_ = ALL;
if (IsNodeBindingEnabled()) {
// Always enable harmony when node binding is on.
std::string flags("--harmony");
v8::V8::SetFlagsFromString(flags.c_str(), static_cast<int>(flags.size()));
node_bindings_.reset(NodeBindings::Create(false));
atom_bindings_.reset(new AtomRendererBindings);
}
@@ -82,7 +95,9 @@ AtomRendererClient::AtomRendererClient()
AtomRendererClient::~AtomRendererClient() {
}
void AtomRendererClient::RenderThreadStarted() {
void AtomRendererClient::WebKitInitialized() {
EnableWebRuntimeFeatures();
if (!IsNodeBindingEnabled())
return;
@@ -93,18 +108,23 @@ void AtomRendererClient::RenderThreadStarted() {
// Create a default empty environment which would be used when we need to
// run V8 code out of a window context (like running a uv callback).
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Isolate* isolate = blink::mainThreadIsolate();
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
global_env = node::Environment::New(context);
}
void AtomRendererClient::RenderThreadStarted() {
content::RenderThread::Get()->AddObserver(this);
}
void AtomRendererClient::RenderFrameCreated(
content::RenderFrame* render_frame) {
new AtomRenderFrameObserver(render_frame, this);
}
void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) {
new printing::PrintWebViewHelper(render_view);
new AtomRenderViewObserver(render_view, this);
}
@@ -197,6 +217,10 @@ bool AtomRendererClient::IsNodeBindingEnabled(blink::WebFrame* frame) {
// Node integration is enabled in main frame unless explictly disabled.
else if (frame == main_frame_)
return true;
// Enable node integration in chrome extensions.
else if (frame != NULL &&
GURL(frame->document().url()).SchemeIs("chrome-extension"))
return true;
else if (node_integration_ == MANUAL_ENABLE_IFRAME &&
frame != NULL &&
frame->uniqueName().utf8().find(kSecurityEnableNodeIntegration)
@@ -208,4 +232,21 @@ bool AtomRendererClient::IsNodeBindingEnabled(blink::WebFrame* frame) {
return true;
}
void AtomRendererClient::EnableWebRuntimeFeatures() {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
bool b;
if (IsSwitchEnabled(command_line, switches::kExperimentalFeatures, &b))
blink::WebRuntimeFeatures::enableExperimentalFeatures(b);
if (IsSwitchEnabled(command_line, switches::kExperimentalCanvasFeatures, &b))
blink::WebRuntimeFeatures::enableExperimentalCanvasFeatures(b);
if (IsSwitchEnabled(command_line, switches::kSubpixelFontScaling, &b))
blink::WebRuntimeFeatures::enableSubpixelFontScaling(b);
if (IsSwitchEnabled(command_line, switches::kOverlayScrollbars, &b))
blink::WebRuntimeFeatures::enableOverlayScrollbars(b);
if (IsSwitchEnabled(command_line, switches::kOverlayFullscreenVideo, &b))
blink::WebRuntimeFeatures::enableOverlayFullscreenVideo(b);
if (IsSwitchEnabled(command_line, switches::kSharedWorker, &b))
blink::WebRuntimeFeatures::enableSharedWorker(b);
}
} // namespace atom

Some files were not shown because too many files have changed in this diff Show More