Compare commits

..

267 Commits

Author SHA1 Message Date
Cheng Zhao
2ce1d3a784 Fix building on cygwin. 2014-02-25 19:06:15 +08:00
Cheng Zhao
a81ef7847d Bump v0.10.1. 2014-02-25 19:02:12 +08:00
Cheng Zhao
2117d06274 Disable in process stack dumping on Windows.
It would force the process to run in console.
2014-02-25 18:47:11 +08:00
Cheng Zhao
a5ec8a9110 Do not define _DEBUG.
The vc++ compiler would define some internal contants if we define
_DEBUG, since we are linking to the release build of chromiumcontent,
this would result in linking errors.
2014-02-25 18:24:07 +08:00
Cheng Zhao
30b3657c0e Update libchromiumcontent to 1df8e7cdac8aa74c91c19ae0691ce512d560ab3e. 2014-02-25 08:53:17 +08:00
Cheng Zhao
06a4f83bb7 linux: Fix upload script. 2014-02-24 05:41:16 +00:00
Cheng Zhao
7a8e43c65e linux: Fix create-dist. 2014-02-24 13:44:23 +08:00
Cheng Zhao
90cc1a7062 Bump v0.10.0. 2014-02-24 05:30:52 +00:00
Cheng Zhao
7d93b4a48f Fix polluting devtools in some cases. 2014-02-24 13:14:01 +08:00
Cheng Zhao
a2ecb554cc Merge pull request #178 from atom/debug-devtools
Add BrowserWindow.debugDevTools() API
2014-02-24 13:07:32 +08:00
Cheng Zhao
f65f95e95c The DevTools window should manage lifetime itself. 2014-02-24 12:17:10 +08:00
Cheng Zhao
eaedac2536 Add the debugDevTools JS API. 2014-02-24 12:08:33 +08:00
Cheng Zhao
8b9d35d84e Separate devtools code out. 2014-02-24 11:53:13 +08:00
Cheng Zhao
99c0de6a1a Disable stack dumping on MAC.
It would prevent the system crash reporter.
2014-02-24 11:48:11 +08:00
Cheng Zhao
f2bef6c26d Setup devtools frontend. 2014-02-24 11:28:21 +08:00
Cheng Zhao
1f57994e2a Setup devtools client for the correct contents. 2014-02-24 10:09:32 +08:00
Cheng Zhao
618040efc1 Add DebugDevTools API. 2014-02-24 09:52:20 +08:00
Cheng Zhao
ed34aa6fb3 Disable node integration in devtools. 2014-02-21 22:42:33 +08:00
Cheng Zhao
57639133a9 Merge pull request #149 from atom/linux
Add support for Linux
2014-02-21 17:33:29 +08:00
Cheng Zhao
1b7c308475 linux: Make native modules work. 2014-02-21 17:22:05 +08:00
Cheng Zhao
2b2a55d870 Update apm: fix node arch on Linux. 2014-02-21 16:23:04 +08:00
Cheng Zhao
c26a9b23a7 gtk: Should init gdk when using screen module. 2014-02-21 15:50:35 +08:00
Cheng Zhao
6c36f7e5c9 gtk: Window.focus should not change visibility. 2014-02-21 15:34:38 +08:00
Cheng Zhao
eb9673a152 linux: Implement libuv message loop polling. 2014-02-21 13:21:02 +08:00
Cheng Zhao
fbe963c7f3 💄 Fix cpplint warnings. 2014-02-21 12:57:45 +08:00
Cheng Zhao
18f8af7822 Only append arguments for browser process. 2014-02-21 01:04:27 +08:00
Cheng Zhao
3576c6d2ff Fix race condition when initializing request context getter.
Note that we are calling GetURLRequestContext() in the UI thread when
using the protocol module, this should in fact not be allowed, but for
now we just use the workaround of making sure the request context getter
has been initialized before we use the protocol module.
2014-02-21 00:56:18 +08:00
Cheng Zhao
b4ee01d43d linux: Fix one compiler warning. 2014-02-20 18:58:56 +08:00
Cheng Zhao
679aa43113 📝 List libraries required for Linux. 2014-02-20 18:56:59 +08:00
Cheng Zhao
2b82eafff4 📝 Update docs on using native modules. 2014-02-20 18:51:57 +08:00
Cheng Zhao
94b3de557e 📝 Add docs on building for Linux. 2014-02-20 18:39:24 +08:00
Cheng Zhao
c56480fd89 Update libchromiumcontent to use the thin version. 2014-02-20 18:20:29 +08:00
Cheng Zhao
e9879b150e Update runas to 0.5.* 2014-02-20 16:43:26 +08:00
Cheng Zhao
ea8d349b1b 💄 Fix cpplinting. 2014-02-19 21:25:18 +08:00
Cheng Zhao
87b78a89fb Menu::attachToWindow is available on Linux. 2014-02-19 13:10:09 +00:00
Cheng Zhao
27cd6688c1 BrowserWindow::setMenu is available on Linux. 2014-02-19 13:06:45 +00:00
Cheng Zhao
c340cac02c Build with symbols on debug build. 2014-02-19 11:39:51 +00:00
Cheng Zhao
0a9c371ca2 linux: Fix crash when using protocol module early. 2014-02-19 11:39:01 +00:00
Cheng Zhao
4a000a35c4 Enable convient stack printing. 2014-02-19 19:07:52 +08:00
Cheng Zhao
d89fb15daf Merge branch 'master' into linux 2014-02-19 11:04:15 +00:00
Cheng Zhao
d698ecf017 linux: Make test.py work. 2014-02-14 15:17:24 +00:00
Cheng Zhao
2b7b4a16f5 linux: Make binary search for libraries under current directory. 2014-02-14 15:11:57 +00:00
Cheng Zhao
526aaecc52 linux: Add dummy implementation of node bindings. 2014-02-14 14:39:57 +00:00
Cheng Zhao
e3d5b62000 gtk: Add dummy implementation of dialog. 2014-02-14 14:07:23 +00:00
Cheng Zhao
6bd56f2a52 gtk: Add utils imported from chrome. 2014-02-14 13:59:41 +00:00
Cheng Zhao
426e7645bc gtk: Add dummy implementation of Menu. 2014-02-14 13:41:20 +00:00
Cheng Zhao
521fb7d54c linux: Fix compilation error. 2014-02-14 13:34:59 +00:00
Cheng Zhao
4051d2ebdb Merge branch 'master' into linux
Conflicts:
	atom.gyp
	vendor/apm
	vendor/brightray
2014-02-14 13:17:00 +00:00
Cheng Zhao
b4fa3cd925 Bump v0.9.3. 2014-02-12 22:14:13 -08:00
Cheng Zhao
984d60f935 Override default window.close, fixes #70. 2014-02-17 18:19:55 +08:00
Cheng Zhao
65f258160e Merge pull request #176 from atom/unload-on-upgrade
Close all windows before installing update
2014-02-17 18:14:14 +08:00
Cheng Zhao
a76183c188 Do not print download progress in CI. 2014-02-17 17:50:25 +08:00
Cheng Zhao
fde4c544b8 💄 2014-02-17 17:50:16 +08:00
Cheng Zhao
274c9d04b1 Enable the quitAndInstall to be cancelled by beforeunload handler. 2014-02-17 16:25:00 +08:00
Cheng Zhao
07fc2b41af Fix using BrowserWindow as parameter for ipc.sendChannel. 2014-02-17 15:24:42 +08:00
Cheng Zhao
a9efe77ceb Fix quitAndInstall when there is no window. 2014-02-17 15:06:25 +08:00
Cheng Zhao
b932461b45 Fix crash when calling quitAndUpdate without any update. 2014-02-17 14:56:23 +08:00
Cheng Zhao
6b3ff63358 Close all windows before installing update. 2014-02-17 14:51:22 +08:00
Cheng Zhao
dd4e36a42e Bump v0.9.2. 2014-02-12 20:52:46 +08:00
Cheng Zhao
93687efee9 win: Use util.format to format arguments in console.log. 2014-02-12 20:32:30 +08:00
Cheng Zhao
9ba7db8815 win: Fix detecting attached modal dialog. 2014-02-10 20:07:38 +08:00
Cheng Zhao
f4a2c12d75 Use keydown event for accelerator.
This follows the behaivor on OS X, fixed #174.
2014-02-06 19:43:30 +08:00
Cheng Zhao
74a83e3d7c The translate-crash-log-addresses script is abandonded. 2014-02-06 18:35:54 +08:00
Cheng Zhao
283aa79c17 Fix assertions when building against Debug libchromiumcontent.
Imported from https://github.com/brightray/brightray/pull/50.
2014-02-05 11:18:32 +08:00
Cheng Zhao
dc69c7b694 Merge pull request #173 from atom/cj-fix-release-name
Parse the 4th argument into a date.
2014-02-03 16:58:53 -08:00
probablycorey
a78807b309 Bump v0.9.1. 2014-02-03 12:41:53 -08:00
probablycorey
e7248b486f Parse the 4th argument into a date. 2014-02-03 12:39:54 -08:00
Cheng Zhao
c2afa3521e Fix building on Windows. 2014-02-03 09:21:45 +08:00
Cheng Zhao
6ae38d86df Bump v0.9.0. 2014-01-30 13:32:16 -08:00
Cheng Zhao
9f0d9e0fad Merge pull request #162 from atom/cj-replace-sparkle-with-squirrel
Replace sparkle with squirrel
2014-02-02 04:56:13 -08:00
Cheng Zhao
45b626e0cc 📝 Add docs on new auto updater API. 2014-02-02 20:55:35 +08:00
Cheng Zhao
c13724b342 Fix ci. 2014-02-02 19:58:25 +08:00
probablycorey
5da1e9ed10 Handle all download events from AutoUpdater::CheckForUpdates 2014-02-01 15:55:57 -08:00
probablycorey
a8913f5ea0 Remove version string from feed url 2014-01-31 16:14:16 -08:00
probablycorey
a59756485e Handle all download events in completed block.
'update-downloaded' and 'update-not-available' events are now called
in the completed block.
2014-01-31 16:13:01 -08:00
probablycorey
6949af5427 Emit 'update-available' and 'checking-for-update' events. 2014-01-31 16:11:11 -08:00
probablycorey
da602a7c01 Include the version with the update request 2014-01-31 16:02:38 -08:00
Cheng Zhao
50eb5454d4 Still subscribe to "updates" for update notifications.
It seems that we should subscribeError to checkForUpdatesCommand to
catch all errors, and the "updates" would only work when there is no
error happened.
2014-01-31 21:47:59 +08:00
Cheng Zhao
8ee1e1d208 Subscribe to checkForUpdatesCommand's return value. 2014-01-31 21:31:42 +08:00
Cheng Zhao
73ec7783af No need to add "static" for functions in anonymouse namespace. 2014-01-31 21:10:51 +08:00
Cheng Zhao
a8f172752a 💄 Fix cpplint warning. 2014-01-31 20:28:33 +08:00
Cheng Zhao
b7e120b68c Merge branch 'master' into cj-replace-sparkle-with-squirrel 2014-01-31 19:36:26 +08:00
Cheng Zhao
a85075103f Move resources file under resources/ 2014-01-31 19:34:31 +08:00
Cheng Zhao
fe30880ec0 Add Info.plist for Atom Framework, fixes #171. 2014-01-31 17:40:47 +08:00
Cheng Zhao
c81128b675 Merge pull request #172 from atom/secure-iframe
Add "node-integration" option to BrowserWindow
2014-01-31 00:52:32 -08:00
Cheng Zhao
2634328720 Fix how we filter out atom-shell switches in process.argv. 2014-01-31 16:40:20 +08:00
Cheng Zhao
0df59e2714 💄 Fix cppling warning. 2014-01-31 15:53:01 +08:00
Cheng Zhao
18fdbb6432 Add docs on the node-integration setting. 2014-01-31 15:22:32 +08:00
Cheng Zhao
bd51a4c8cf Fix crash when opening multiple pages at the same time. 2014-01-31 15:09:13 +08:00
Cheng Zhao
6478244fbf Put common constants into one file. 2014-01-31 12:18:30 +08:00
Cheng Zhao
e0f660301c Specify the commit of libchromiumcontent to download. 2014-01-31 12:09:43 +08:00
Cheng Zhao
192014cc3f Do not use plain string iterals. 2014-01-31 10:41:20 +08:00
Cheng Zhao
61b69a4e8a Fix loss of --node-integration token after refresh. 2014-01-31 10:30:16 +08:00
Cheng Zhao
ec00da416f Rename iframe-security to node-integration. 2014-01-30 23:20:12 +08:00
Cheng Zhao
d4929de33c Add iframe-security support. 2014-01-30 22:47:21 +08:00
Cheng Zhao
a0b15661ed Append --iframe-security to renderer process. 2014-01-30 21:57:01 +08:00
Cheng Zhao
9a58706e1f Don't pollute process.argv of browser process. 2014-01-30 21:20:02 +08:00
Cheng Zhao
ce586e0835 Don't append duplicate arguments to renderer process. 2014-01-30 21:06:56 +08:00
probablycorey
795c31918a Merge remote-tracking branch 'origin/master' into cj-replace-sparkle-with-squirrel 2014-01-29 14:55:20 -08:00
Cheng Zhao
2592487c3f Sort devDependencies. 2014-01-28 09:36:32 +08:00
Cheng Zhao
f05daa8bdc Make bump-version accept major/minor/patch/build. 2014-01-27 18:37:39 +08:00
Cheng Zhao
75ec34884d Bump v0.8.7. 2014-01-23 05:02:28 -08:00
Cheng Zhao
96cb4fd6d7 Merge pull request #166 from atom/cz-v8-locker
Wrap callbacks with v8 locker in browser process
2014-01-27 00:15:22 -08:00
Cheng Zhao
d63de1ae15 Wrap callbacks with v8::Locker.
In browser process, because of the use of v8::Locker in ProxyResolverV8,
creating HandleScope requires entering locker first, so in browser
process we should just use v8::Locker whenever we need to use V8 in a
callback called from non-V8 places (like dialog's callback, work pushed
to MessageLoop).

But also notice that the renderer process doesn't use v8::Locker, so we
have to be careful not to use it, otherwise blink would crash when
creating HandleScope.
2014-01-27 15:14:11 +08:00
Cheng Zhao
5250871e69 Remove unneeded HandleScopes.
It's not necessary to create HandleScope in v8 native binding functions,
because it's guarrenteed that the there is a upper HandleScope when the
native function is called. So unless we are urgent to free the handles,
not using HandleScope in native binding functions is a cleaner and safer
choice.
2014-01-27 15:01:06 +08:00
Cheng Zhao
426bc97194 Use node_isolate instead of Isolate::GetCurrent(). 2014-01-27 14:04:34 +08:00
Cheng Zhao
76098255f0 Should decode when setting __filename from location. 2014-01-24 21:20:30 +08:00
Cheng Zhao
e8594b492e It's safe to send message to nil. 2014-01-22 12:00:34 +08:00
Cheng Zhao
d4e362ec89 Add error and update-not-available events for auto updater. 2014-01-21 22:50:46 +08:00
Cheng Zhao
df399f7c8c Implement auto_updater with Squirrel. 2014-01-21 22:13:34 +08:00
Cheng Zhao
ef8e5505c8 Merge branch 'master' into cj-replace-sparkle-with-squirrel 2014-01-21 20:40:19 +08:00
Cheng Zhao
71fd147c47 Fix gyp error on CI. 2014-01-21 20:34:35 +08:00
Cheng Zhao
c271d89677 Fix cpplint warnings. 2014-01-21 20:25:01 +08:00
probablycorey
7cf040e7ca I don't think fix_framework_link_command is needed anymore.
tool -L says Squirrel (and its dependencies) already use @rpath

```
@rpath/Squirrel.framework/Squirrel (compatibility version 1.0.0, current version 1.0.0)
@rpath/ReactiveCocoa.framework/ReactiveCocoa (compatibility version 1.0.0, current version 1.0.0)
@rpath/Mantle.framework/Mantle (compatibility version 1.0.0, current version 1.0.0)
```
2014-01-20 16:32:56 -08:00
probablycorey
a6c92f20c8 Link Sparkle frameworks 2014-01-20 16:25:48 -08:00
probablycorey
400e963b8b Download Squirrel frameworks instead of Sparkle 2014-01-20 16:25:33 -08:00
probablycorey
2a7244a366 Remove references to Sparkle 2014-01-20 16:22:49 -08:00
probablycorey
5741bad918 💄 2014-01-20 16:22:32 -08:00
Cheng Zhao
1d7445c5aa Fix uv loop hack on child_process. 2014-01-18 17:01:30 +08:00
Cheng Zhao
4a1f8cf1c9 Activate uv loop when uv loop's watcher queue changes, fixes #159. 2014-01-18 16:56:46 +08:00
Cheng Zhao
a2bf1b3907 Update to latest apm. 2014-01-18 16:29:24 +08:00
Cheng Zhao
b2d4d76bcf 📝 Update docs on source code structure. 2014-01-16 10:31:59 +08:00
Cheng Zhao
9ac555c302 move atom_menu_controller_mac to browser/ui/cocoa. 2014-01-16 10:22:33 +08:00
Cheng Zhao
43711083f7 Move atom_event_processing_window to browser/ui/cocoa. 2014-01-16 10:09:36 +08:00
Cheng Zhao
9b07c2b894 Move nsalert_synchronous_sheet_mac to browser/ui/cocoa. 2014-01-16 10:06:05 +08:00
Cheng Zhao
2c28725722 gtk: Support frameless window. 2014-01-15 15:15:45 +00:00
Cheng Zhao
53a4f34433 📝 Add docs on window events. 2014-01-15 14:42:47 +00:00
Cheng Zhao
406f0b7bc7 Implement "blur" window event. 2014-01-15 14:38:38 +00:00
Cheng Zhao
6912a0513a gtk: Set WebKit's style from current theme. 2014-01-15 14:31:26 +00:00
Cheng Zhao
0398577e93 gtk: Implement basic native window methods. 2014-01-15 13:28:00 +00:00
Cheng Zhao
42dc9c1ec6 Add dummy implementation of crash reporter. 2014-01-15 12:01:03 +00:00
Cheng Zhao
2f798c5116 Merge branch 'master' into linux
Conflicts:
	vendor/apm
2014-01-15 11:18:40 +00:00
Cheng Zhao
363f1da77e Bump v0.8.6. 2014-01-14 01:34:07 -08:00
Cheng Zhao
8655dec00e Crash when there is fatal error in V8. 2014-01-23 20:30:44 +08:00
Cheng Zhao
fbc68ecce5 Bump v0.8.5. 2014-01-14 16:24:53 +08:00
Cheng Zhao
8d4ac15834 :lipstip: Remove unneed output. 2014-01-14 16:04:47 +08:00
Cheng Zhao
249366c90a Restart renderer process for all navigations and reloads, fixes #157. 2014-01-14 16:03:01 +08:00
Cheng Zhao
931182b677 Fix crash when calling dialog's callback. 2014-01-14 14:18:32 +08:00
Cheng Zhao
2a129f892f Bump v0.8.4. 2014-01-13 18:46:19 +08:00
Cheng Zhao
57a27876ec Fix warnings of node_lib. 2014-01-13 18:43:09 +08:00
Cheng Zhao
fc2e069efe Fix warnings of openssl-cli. 2014-01-13 18:41:40 +08:00
Cheng Zhao
58d4ec5587 Update node-pathwatcher to v0.14.0. 2014-01-13 18:25:04 +08:00
Cheng Zhao
b0c23294fe Also use uv loop fixes in browser process. 2014-01-13 13:57:08 +08:00
Cheng Zhao
290dd36bb0 Activate uv loop when calling childProcess.fork.
Fixes #156.
2014-01-13 11:52:24 +08:00
Cheng Zhao
84529de10d Update apm: update node version to v0.11.10. 2014-01-10 18:50:53 +08:00
Cheng Zhao
bde4a732c4 Bump node version to v0.11.10. 2014-01-10 18:37:05 +08:00
Cheng Zhao
535b936c87 Update node to v0.11.10. 2014-01-10 18:24:44 +08:00
Cheng Zhao
dc880b16f1 Merge pull request #155 from atom/fix-q
Fix executing process.nextTick's callbacks
2014-01-10 02:13:07 -08:00
Cheng Zhao
5eb1f52421 Make sure nextTick is called when activating uv loop. 2014-01-10 16:47:33 +08:00
Cheng Zhao
3747048218 💄 get_uv_env() => uv_env(). 2014-01-10 16:29:38 +08:00
Cheng Zhao
a1a091d805 Add spec for q. 2014-01-10 15:58:14 +08:00
Cheng Zhao
e536d0e7a8 Leak the node environment when unloading. 2014-01-10 11:04:54 +08:00
Cheng Zhao
e050494e5d Merge pull request #154 from atom/safe-context
Wrap uv loop with web page context in renderer
2014-01-09 06:28:35 -08:00
Cheng Zhao
bbc01e704c Monitor file events in pathwatcher spec. 2014-01-09 22:13:48 +08:00
Cheng Zhao
fff743053a Store all created environments in renderer. 2014-01-09 22:13:06 +08:00
Cheng Zhao
e7b7efeb0a Wrap uv loop with web page context in renderer. 2014-01-09 21:35:29 +08:00
Cheng Zhao
968fc71b78 Add spec for using setTimeout in pure uv callback. 2014-01-09 20:34:17 +08:00
Cheng Zhao
d0494024a9 Add process.scheduleCallback.
It will schedule a callback to be executed by pure uv loop.
2014-01-09 20:33:07 +08:00
Cheng Zhao
a12754f980 Add spec for pathwatcher module. 2014-01-09 20:29:54 +08:00
Cheng Zhao
c76f510cea Bump v0.8.3. 2014-01-07 08:26:12 -08:00
Cheng Zhao
968f75529a Fix possible crashes when quiting message loop. 2014-01-08 11:55:54 +08:00
Cheng Zhao
93d5a2e195 Fix invoking non-exist method when quiting. 2014-01-08 10:51:32 +08:00
Cheng Zhao
367285f3f3 Merge pull request #152 from atom/gfx-module
Add screen module
2014-01-07 04:46:24 -08:00
Cheng Zhao
95b2003193 📝 Add docs on screen module. 2014-01-07 20:35:13 +08:00
Cheng Zhao
bcdc44c1c6 Support converting v8 value to arbitrary vector or map. 2014-01-07 20:29:17 +08:00
Cheng Zhao
4ae2738ce5 Add screen.getPrimaryDisplay() API. 2014-01-07 20:15:55 +08:00
Cheng Zhao
e09a2ff811 Add support to convert gfx::Rect and gfx::Size to v8 value. 2014-01-07 20:15:23 +08:00
Cheng Zhao
7253a35455 Add initial screen module. 2014-01-07 20:00:25 +08:00
Cheng Zhao
1b1cf87115 Add support to convert gfx::Point to v8 value. 2014-01-07 20:00:02 +08:00
Cheng Zhao
3ec755e978 💄 2014-01-07 19:44:37 +08:00
Cheng Zhao
cf4616de7f api::EventEmitter could also be used by renderer. 2014-01-07 19:32:40 +08:00
Cheng Zhao
2755fbaadf Update apm. 2014-01-07 02:50:52 -08:00
Cheng Zhao
6f222651d7 Bump v0.8.2. 2014-01-07 18:44:37 +08:00
Cheng Zhao
fe4841a1cd Set module's filename to path of html.
The relative require relies on module.filename to work as expected.
2014-01-07 14:30:18 +08:00
Cheng Zhao
fe8a2b9ee0 Still support 'atom-delegate' API for old apps. 2014-01-07 09:50:00 +08:00
Cheng Zhao
b939232670 mac: Should set default size when creating window. 2014-01-06 18:58:30 +08:00
Cheng Zhao
a4253e3899 linux: Implemnt browser methods. 2014-01-02 14:47:54 +00:00
Cheng Zhao
52b5f769f0 linux: Add empty implementation of auto updater. 2014-01-02 14:15:02 +00:00
Cheng Zhao
b73a114f8f gtk: Implement accelerator_util. 2014-01-02 14:12:05 +00:00
Cheng Zhao
7ca152070a Update brightray. 2014-01-01 02:31:33 +00:00
Cheng Zhao
f24ccd3841 linux: Implement platform_util. 2013-12-31 12:59:33 +00:00
Cheng Zhao
66ac11ca5f linux: Implement brightray's stub functions. 2013-12-31 12:24:53 +00:00
Cheng Zhao
7afef0fcdb Fix entry function under Linux. 2013-12-31 11:51:17 +00:00
Cheng Zhao
627f487b36 Disable compilation errors in node under Linux. 2013-12-31 11:40:19 +00:00
Cheng Zhao
c64a793364 Build with clang under Linux. 2013-12-31 11:27:31 +00:00
Cheng Zhao
63852a8c82 Update brightray for linux_clang flag. 2013-12-31 11:16:18 +00:00
Cheng Zhao
c97afdbdb3 Update apm. 2013-12-31 08:33:17 +00:00
Cheng Zhao
6c5ea4ea32 Compile coffee script on Linux. 2013-12-31 08:01:08 +00:00
Cheng Zhao
cac3973731 Flip the y axis in CapturePage API, fixes #148. 2013-12-31 14:40:42 +08:00
Cheng Zhao
19a35b58f0 Merge pull request #147 from atom/remote-docs
Revise the docs on remote module
2013-12-30 18:02:14 -08:00
Cheng Zhao
5e51ad30d7 Add notes about remote buffer in capturePage API's docs. 2013-12-31 10:00:29 +08:00
Cheng Zhao
e1e5cb5ba4 Add notes on remote buffer. 2013-12-30 23:15:15 +08:00
Cheng Zhao
8d124c7157 Revise the docs of remote module. 2013-12-30 22:06:33 +08:00
Cheng Zhao
67ed72294b Bump v0.8.1. 2013-12-29 23:09:19 +08:00
Cheng Zhao
1bb5481071 Fix circulate require. 2013-12-29 22:33:53 +08:00
Cheng Zhao
876063b1ba Fix console.log under Windows.
The process.log is not added until the next iteration of uv loop.
2013-12-29 22:32:26 +08:00
Cheng Zhao
7d193033f5 💄 Fix wrong order of parameter when killing process. 2013-12-29 22:11:54 +08:00
Cheng Zhao
074ea374e0 We are now on v0.8.0 release. 2013-12-27 16:22:34 +08:00
Cheng Zhao
f6c3a69595 Merge pull request #146 from atom/window-open
Implement window.open in pure js
2013-12-26 23:54:19 -08:00
Cheng Zhao
f28881e203 Fix crash caused by BrowserWindow.destroy(). 2013-12-27 15:41:00 +08:00
Cheng Zhao
6312c1108a Add spec for window.open. 2013-12-27 14:58:13 +08:00
Cheng Zhao
0de40febab Add basic support for window.open's features. 2013-12-27 14:57:53 +08:00
Cheng Zhao
1701f572e2 Fix crash when calling method of destroyed object. 2013-12-27 14:47:50 +08:00
Cheng Zhao
15a9be6b93 Implement a simple window.open with pure js. 2013-12-27 14:39:23 +08:00
Cheng Zhao
a60be1563f Do not implement window.open. 2013-12-27 14:32:24 +08:00
Cheng Zhao
a2522efb25 Build for x64 architecture on OS X, fixes #132. 2013-12-27 14:17:35 +08:00
Cheng Zhao
7c3f22a333 Bump v0.8.0. 2013-12-27 14:09:10 +08:00
Cheng Zhao
2945e1b50a Merge pull request #140 from atom/chrome31
Update to Chrome 31
2013-12-26 22:07:17 -08:00
Cheng Zhao
aedacd39d2 Rename 'finish-launching' event to 'ready',
'finish-launching' is more like a OS X message name, and in atom-shell
it means initialization has done, so 'ready' seems to be a better name
and more easy to remember.

The 'will-finish-launching' event just represents the corresponding
message on OS X and is the same with 'ready' on other platforms, so we
keep its name to indicate that it's only useful for OS X specified
code.
2013-12-27 11:08:26 +08:00
Cheng Zhao
d3f33152d0 Get rid of the ugly ATOM_BROWSER_INTERNAL_NEW message. 2013-12-26 18:41:21 +08:00
Cheng Zhao
cfca12d4a5 Use the gyp vendored by brightray. 2013-12-25 18:47:19 +08:00
Cheng Zhao
754cd88cc2 Update brightray: Fix building on Windows. 2013-12-24 16:05:50 +08:00
Cheng Zhao
031426d54e Use our fork of V8ValueConverter for all cases. 2013-12-23 22:42:21 +08:00
Cheng Zhao
980e8ca4dc Free the node environment when releasing context. 2013-12-23 22:19:51 +08:00
Cheng Zhao
df0094b6cb Move node integration from RenderViewObserver to RendererClient. 2013-12-23 22:08:45 +08:00
Cheng Zhao
02d94c8b2e Print pid when logging. 2013-12-23 22:04:49 +08:00
Cheng Zhao
902be9bab5 Update node: Removed two unused patches. 2013-12-20 14:20:24 +08:00
Cheng Zhao
f646d2dda8 Enable high DPI support. 2013-12-20 14:14:07 +08:00
Cheng Zhao
92b19f89d9 Remove the unzip spec completely. 2013-12-17 23:21:40 +08:00
Cheng Zhao
d8eb465eb9 Fix protocol spec on Windows. 2013-12-17 23:03:36 +08:00
Cheng Zhao
c04a9933cc Fix __filename on Windows. 2013-12-17 22:16:15 +08:00
Cheng Zhao
5b12f80d01 Discard the require('atom-delegate') API. 2013-12-17 22:08:45 +08:00
Cheng Zhao
75c44ca057 Fix initializing V8 on Windows. 2013-12-17 21:55:56 +08:00
Cheng Zhao
56f709ff1f Continue fixing compilation erros on Windows. 2013-12-17 18:34:45 +08:00
Cheng Zhao
0215c2fbee Make all the windows code compile for Chrome 31. 2013-12-17 17:52:57 +08:00
Cheng Zhao
6e079d8bc4 Also search C:/Program Files (x86) for node binary. 2013-12-17 13:14:54 +08:00
Cheng Zhao
a4715f936b Merge branch 'master' into chrome31
Conflicts:
	common/atom_version.h
2013-12-17 12:58:25 +08:00
Cheng Zhao
1d88b31edd Use node-runas for testing native modules. 2013-12-17 12:00:21 +08:00
Cheng Zhao
e07e26ca76 Fix third party module specs. 2013-12-16 22:46:16 +08:00
Cheng Zhao
c82e73a4ec Update apm: Fix installing for node v0.11.x. 2013-12-16 22:37:43 +08:00
Cheng Zhao
eda4249bf8 Add deps/npm and deps/mdb_v8 in node headers. 2013-12-16 22:37:17 +08:00
Cheng Zhao
09201e3e65 Update brightray: Remove webkit hacks. 2013-12-16 21:19:12 +08:00
Cheng Zhao
2ca2d37e93 Clean out node_modules in cibuild. 2013-12-16 15:15:33 +08:00
Cheng Zhao
d3416e2873 Bump node version to v0.11.9. 2013-12-16 14:52:15 +08:00
Cheng Zhao
4e4e316005 Include Environment declarations in node_common.h. 2013-12-16 14:46:05 +08:00
Cheng Zhao
8fc1e055bf Update apm for node version and architecture change. 2013-12-16 14:40:03 +08:00
Cheng Zhao
d51ea21afa Use singular form of spec names. 2013-12-16 00:31:40 +08:00
Cheng Zhao
abf982e4e5 Remove the on_watcher_queue_updated hack. 2013-12-15 19:50:43 +08:00
Cheng Zhao
998e9792fb Make setImmediate have the same side effect with upstream node. 2013-12-15 19:09:00 +08:00
Cheng Zhao
c87b21148c Supress the unzip module spec.
The unzip module is not compatible with node v0.11.x, so we do not need
to test it anymore.
2013-12-15 19:08:10 +08:00
Cheng Zhao
7e67f7632d 💄 Fix cpplint warnings. 2013-12-15 17:09:35 +08:00
Cheng Zhao
cd68396bd5 Disable use of deprecated functions in specs. 2013-12-15 17:02:43 +08:00
Cheng Zhao
474e1fcd3b Fix protocol module specs. 2013-12-15 16:53:07 +08:00
Cheng Zhao
cfeeec37eb Fix capturePage() spec. 2013-12-15 16:32:49 +08:00
Cheng Zhao
0a84c30d3b Redirect window.onerror to uncaughtException. 2013-12-15 16:32:41 +08:00
Cheng Zhao
7ba03ce23d Add setImmediate function in renderer. 2013-12-15 16:21:23 +08:00
Cheng Zhao
cc5db4dab9 Suppress the EventEmitter's warning for ObjectsRegistry.
It's possible that many objects subscribed to it.
2013-12-15 16:15:18 +08:00
Cheng Zhao
aa3e8385df Set __filename to the html file in renderer. 2013-12-15 16:11:00 +08:00
Cheng Zhao
886ebdb002 Use node's Environment feature to add "require" in renderer. 2013-12-15 14:20:28 +08:00
Kevin Sawicki
ea2f87683a Merge pull request #144 from shama/typo
Fix a couple minor typos in docs
2013-12-13 08:44:06 -08:00
Kyle Robinson Young
c116f6b35c Fix a couple minor typos in docs 2013-12-12 22:31:19 -08:00
Cheng Zhao
2413eebd7b Disable accelerated compositing to fix everything. 2013-12-13 00:57:08 +08:00
Cheng Zhao
7708e7a8c4 Update node for renderer node integration fixes. 2013-12-12 16:49:56 +08:00
Cheng Zhao
1c0b391419 Fix the black devtools view.
Without using UnderlayOpenGLHostingWindow the devtools view would just
be black.
2013-12-12 15:49:08 +08:00
Cheng Zhao
28f5d184b3 Do not depend on node to set include_dirs.
Part of atom/node#2.
2013-12-12 14:07:00 +08:00
Cheng Zhao
fc00da9732 Update brightray, which contains all our patches in master. 2013-12-12 10:43:50 +08:00
Cheng Zhao
9ea75b7519 We are now at v0.8.0-pre. 2013-12-12 10:43:34 +08:00
Cheng Zhao
61c63a6af9 Fix crashes about persistent v8 functions. 2013-12-12 00:10:09 +08:00
Cheng Zhao
e4bfa373de Fix node integration to browser after updated to Chrome31. 2013-12-11 23:59:03 +08:00
Cheng Zhao
d53915c6ab Fix recursive calling of handle(). 2013-12-11 23:57:37 +08:00
Cheng Zhao
409a431892 Huge commit to use new V8 and Content APIs.
Still got a lots of linking errors!
2013-12-11 15:48:19 +08:00
Cheng Zhao
d82cfc023f 💄 There should be no space between & and type name. 2013-12-10 14:27:25 +08:00
Cheng Zhao
f9c41f33e5 node::ObjectWrap how had a handle() method. 2013-12-10 14:15:37 +08:00
Cheng Zhao
4ec4b01218 base/string16.h was moved to base/strings/string16.h. 2013-12-10 14:14:05 +08:00
Cheng Zhao
0a37852757 Update to node v0.11.9. 2013-12-10 14:07:32 +08:00
Cheng Zhao
42ffa5813f Update libchromiumcontent and brightray to use Chrome31. 2013-12-09 17:23:32 +08:00
Cheng Zhao
597e17b540 Fix template related compilation errors of VC++. 2013-12-09 16:34:10 +08:00
199 changed files with 5317 additions and 2112 deletions

3
.gitmodules vendored
View File

@@ -4,9 +4,6 @@
[submodule "vendor/node"]
path = vendor/node
url = https://github.com/atom/node.git
[submodule "vendor/gyp"]
path = vendor/gyp
url = https://github.com/svn2github/gyp.git
[submodule "vendor/depot_tools"]
path = vendor/depot_tools
url = https://chromium.googlesource.com/chromium/tools/depot_tools.git

View File

@@ -20,9 +20,12 @@
#include "common/crash_reporter/win/crash_service_main.h"
#include "content/public/app/startup_helper_win.h"
#include "sandbox/win/src/sandbox_types.h"
#else // defined(OS_WIN)
#elif defined(OS_LINUX) // defined(OS_WIN)
#include "app/atom_main_delegate.h" // NOLINT
#include "content/public/app/content_main.h"
#else // defined(OS_LINUX)
#include "app/atom_library_main.h"
#endif // defined(OS_MACOSX) || defined(OS_LINUX)
#endif // defined(OS_MACOSX)
// Declaration of node::Start.
namespace node {
@@ -98,7 +101,18 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
return content::ContentMain(instance, &sandbox_info, &delegate);
}
#else // defined(OS_WIN)
#elif defined(OS_LINUX) // defined(OS_WIN)
int main(int argc, const char* argv[]) {
char* node_indicator = getenv("ATOM_SHELL_INTERNAL_RUN_AS_NODE");
if (node_indicator != NULL && strcmp(node_indicator, "1") == 0)
return node::Start(argc, const_cast<char**>(argv));
atom::AtomMainDelegate delegate;
return content::ContentMain(argc, argv, &delegate);
}
#else // defined(OS_LINUX)
int main(int argc, const char* argv[]) {
char* node_indicator = getenv("ATOM_SHELL_INTERNAL_RUN_AS_NODE");
@@ -108,4 +122,4 @@ int main(int argc, const char* argv[]) {
return AtomMain(argc, argv);
}
#endif // defined(OS_MACOSX) || defined(OS_LINUX)
#endif // defined(OS_MACOSX)

View File

@@ -5,6 +5,7 @@
#include "app/atom_main_delegate.h"
#include "base/command_line.h"
#include "base/debug/stack_trace.h"
#include "base/logging.h"
#include "browser/atom_browser_client.h"
#include "content/public/common/content_switches.h"
@@ -23,19 +24,28 @@ AtomMainDelegate::~AtomMainDelegate() {
bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
// Disable logging out to debug.log on Windows
#if defined(OS_WIN)
logging::InitLogging(
L"debug.log",
logging::LoggingSettings settings;
#if defined(DEBUG)
logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG ,
settings.logging_dest = logging::LOG_TO_ALL;
settings.log_file = L"debug.log";
settings.lock_log = logging::LOCK_LOG_FILE;
settings.delete_old = logging::DELETE_OLD_LOG_FILE;
#else
logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
#endif // defined(NDEBUG)
logging::LOCK_LOG_FILE,
logging::DELETE_OLD_LOG_FILE,
logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS);
logging::SetLogItems(true, false, true, false);
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
#endif
settings.dcheck_state =
logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS;
logging::InitLogging(settings);
#endif // defined(OS_WIN)
// Logging with pid and timestamp.
logging::SetLogItems(true, false, true, false);
// Enable convient stack printing.
#if defined(DEBUG) && defined(OS_LINUX)
base::debug::EnableInProcessStackDumping();
#endif
return brightray::MainDelegate::BasicStartupComplete(exit_code);
}
@@ -43,13 +53,29 @@ void AtomMainDelegate::PreSandboxStartup() {
#if defined(OS_MACOSX)
OverrideChildProcessPath();
OverrideFrameworkBundlePath();
SetProcessName();
#endif
InitializeResourceBundle();
// Disable renderer sandbox for most of node's functions.
CommandLine* command_line = CommandLine::ForCurrentProcess();
std::string process_type = command_line->GetSwitchValueASCII(
switches::kProcessType);
// Only append arguments for browser process.
if (!process_type.empty())
return;
// Add a flag to mark the start of switches added by atom-shell.
command_line->AppendSwitch("atom-shell-switches-start");
// Disable renderer sandbox for most of node's functions.
command_line->AppendSwitch(switches::kNoSandbox);
// Disable accelerated compositing since it caused a lot of troubles (black
// devtools, screen flashes) and needed lots of effort to make it right.
command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
// Add a flag to mark the end of switches added by atom-shell.
command_line->AppendSwitch("atom-shell-switches-end");
}
void AtomMainDelegate::InitializeResourceBundle() {

View File

@@ -23,7 +23,6 @@ class AtomMainDelegate : public brightray::MainDelegate {
virtual base::FilePath GetResourcesPakFilePath();
virtual void OverrideChildProcessPath();
virtual void OverrideFrameworkBundlePath();
virtual void SetProcessName();
#endif
private:

View File

@@ -45,22 +45,4 @@ void AtomMainDelegate::OverrideChildProcessPath() {
PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
}
void AtomMainDelegate::SetProcessName() {
const auto& command_line = *CommandLine::ForCurrentProcess();
auto process_type = command_line.GetSwitchValueASCII(switches::kProcessType);
std::string suffix;
if (process_type == switches::kRendererProcess)
suffix = "Renderer";
else if (process_type == switches::kPluginProcess ||
process_type == switches::kPpapiPluginProcess)
suffix = "Plug-In Host";
else if (process_type == switches::kUtilityProcess)
suffix = "Utility";
else
return;
base::mac::SetProcessName(base::mac::NSToCFCast(base::SysUTF8ToNSString(
brightray::GetApplicationName() + " " + suffix)));
}
} // namespace atom

164
atom.gyp
View File

@@ -8,7 +8,7 @@
'app/atom_main.h',
],
'bundle_sources': [
'browser/mac/atom.icns',
'browser/resources/mac/atom.icns',
],
'coffee_sources': [
'browser/api/lib/app.coffee',
@@ -21,14 +21,17 @@
'browser/api/lib/menu-item.coffee',
'browser/api/lib/power-monitor.coffee',
'browser/api/lib/protocol.coffee',
'browser/atom/atom.coffee',
'browser/atom/objects-registry.coffee',
'browser/atom/rpc-server.coffee',
'browser/lib/init.coffee',
'browser/lib/objects-registry.coffee',
'browser/lib/rpc-server.coffee',
'common/api/lib/callbacks-registry.coffee',
'common/api/lib/clipboard.coffee',
'common/api/lib/crash-reporter.coffee',
'common/api/lib/id-weak-map.coffee',
'common/api/lib/screen.coffee',
'common/api/lib/shell.coffee',
'common/lib/init.coffee',
'renderer/lib/init.coffee',
'renderer/api/lib/ipc.coffee',
'renderer/api/lib/remote.coffee',
],
@@ -46,10 +49,10 @@
'browser/api/atom_api_dialog.h',
'browser/api/atom_api_event.cc',
'browser/api/atom_api_event.h',
'browser/api/atom_api_event_emitter.cc',
'browser/api/atom_api_event_emitter.h',
'browser/api/atom_api_menu.cc',
'browser/api/atom_api_menu.h',
'browser/api/atom_api_menu_gtk.cc',
'browser/api/atom_api_menu_gtk.h',
'browser/api/atom_api_menu_mac.h',
'browser/api/atom_api_menu_mac.mm',
'browser/api/atom_api_menu_win.cc',
@@ -64,8 +67,8 @@
'browser/api/atom_browser_bindings.h',
'browser/auto_updater.cc',
'browser/auto_updater.h',
'browser/auto_updater_delegate.cc',
'browser/auto_updater_delegate.h',
'browser/auto_updater_linux.cc',
'browser/auto_updater_mac.mm',
'browser/auto_updater_win.cc',
'browser/atom_application_mac.h',
@@ -83,11 +86,16 @@
'browser/atom_javascript_dialog_manager.h',
'browser/browser.cc',
'browser/browser.h',
'browser/browser_linux.cc',
'browser/browser_mac.mm',
'browser/browser_win.cc',
'browser/browser_observer.h',
'browser/devtools_delegate.cc',
'browser/devtools_delegate.h',
'browser/native_window.cc',
'browser/native_window.h',
'browser/native_window_gtk.cc',
'browser/native_window_gtk.h',
'browser/native_window_mac.h',
'browser/native_window_mac.mm',
'browser/native_window_win.cc',
@@ -103,20 +111,29 @@
'browser/net/url_request_string_job.h',
'browser/ui/accelerator_util.cc',
'browser/ui/accelerator_util.h',
'browser/ui/accelerator_util_gtk.cc',
'browser/ui/accelerator_util_mac.mm',
'browser/ui/accelerator_util_win.cc',
'browser/ui/atom_event_processing_window.h',
'browser/ui/atom_event_processing_window.mm',
'browser/ui/atom_menu_controller_mac.h',
'browser/ui/atom_menu_controller_mac.mm',
'browser/ui/cocoa/atom_menu_controller.h',
'browser/ui/cocoa/atom_menu_controller.mm',
'browser/ui/cocoa/event_processing_window.h',
'browser/ui/cocoa/event_processing_window.mm',
'browser/ui/cocoa/nsalert_synchronous_sheet.h',
'browser/ui/cocoa/nsalert_synchronous_sheet.mm',
'browser/ui/file_dialog.h',
'browser/ui/file_dialog_gtk.cc',
'browser/ui/file_dialog_mac.mm',
'browser/ui/file_dialog_win.cc',
'browser/ui/gtk/gtk_custom_menu.cc',
'browser/ui/gtk/gtk_custom_menu.h',
'browser/ui/gtk/gtk_custom_menu_item.cc',
'browser/ui/gtk/gtk_custom_menu_item.h',
'browser/ui/gtk/gtk_window_util.cc',
'browser/ui/gtk/gtk_window_util.h',
'browser/ui/message_box.h',
'browser/ui/message_box_gtk.cc',
'browser/ui/message_box_mac.mm',
'browser/ui/message_box_win.cc',
'browser/ui/nsalert_synchronous_sheet_mac.h',
'browser/ui/nsalert_synchronous_sheet_mac.mm',
'browser/ui/win/menu_2.cc',
'browser/ui/win/menu_2.h',
'browser/ui/win/native_menu_win.cc',
@@ -130,8 +147,12 @@
'common/api/atom_api_clipboard.h',
'common/api/atom_api_crash_reporter.cc',
'common/api/atom_api_crash_reporter.h',
'common/api/atom_api_event_emitter.cc',
'common/api/atom_api_event_emitter.h',
'common/api/atom_api_id_weak_map.cc',
'common/api/atom_api_id_weak_map.h',
'common/api/atom_api_screen.cc',
'common/api/atom_api_screen.h',
'common/api/atom_api_shell.cc',
'common/api/atom_api_shell.h',
'common/api/atom_api_v8_util.cc',
@@ -143,6 +164,8 @@
'common/api/object_life_monitor.h',
'common/crash_reporter/crash_reporter.cc',
'common/crash_reporter/crash_reporter.h',
'common/crash_reporter/crash_reporter_linux.cc',
'common/crash_reporter/crash_reporter_linux.h',
'common/crash_reporter/crash_reporter_mac.h',
'common/crash_reporter/crash_reporter_mac.mm',
'common/crash_reporter/crash_reporter_win.cc',
@@ -153,8 +176,11 @@
'common/crash_reporter/win/crash_service_main.h',
'common/draggable_region.cc',
'common/draggable_region.h',
'common/linux/application_info.cc',
'common/node_bindings.cc',
'common/node_bindings.h',
'common/node_bindings_linux.cc',
'common/node_bindings_linux.h',
'common/node_bindings_mac.cc',
'common/node_bindings_mac.h',
'common/node_bindings_win.cc',
@@ -162,12 +188,15 @@
'common/options_switches.cc',
'common/options_switches.h',
'common/platform_util.h',
'common/platform_util_linux.cc',
'common/platform_util_mac.mm',
'common/platform_util_win.cc',
'common/swap_or_assign.h',
'common/v8_conversions.h',
'common/v8_value_converter_impl.cc',
'common/v8_value_converter_impl.h',
'common/v8/node_common.h',
'common/v8/scoped_persistent.h',
'common/v8/native_type_conversions.h',
'common/v8/v8_value_converter.cc',
'common/v8/v8_value_converter.h',
'renderer/api/atom_api_renderer_ipc.cc',
'renderer/api/atom_api_renderer_ipc.h',
'renderer/api/atom_renderer_bindings.cc',
@@ -184,20 +213,13 @@
'conditions': [
['OS=="win"', {
'app_sources': [
'app/win/resource.h',
'app/win/atom.ico',
'app/win/atom.rc',
'browser/resources/win/resource.h',
'browser/resources/win/atom.ico',
'browser/resources/win/atom.rc',
'<(libchromiumcontent_src_dir)/content/app/startup_helper_win.cc',
],
}], # OS=="win"
],
'fix_framework_link_command': [
'install_name_tool',
'-change',
'@loader_path/../Frameworks/Sparkle.framework/Versions/A/Sparkle',
'@rpath/Sparkle.framework/Versions/A/Sparkle',
'${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}'
],
'atom_source_root': '<!(python tools/atom_source_root.py)',
},
'target_defaults': {
@@ -210,9 +232,8 @@
],
'configurations': {
'Debug': {
'defines': [
'DEBUG',
],
'defines': [ 'DEBUG' ],
'cflags': [ '-g', '-O0' ],
},
},
},
@@ -242,7 +263,7 @@
'<(project_name)_helper',
],
'xcode_settings': {
'INFOPLIST_FILE': 'browser/mac/Info.plist',
'INFOPLIST_FILE': 'browser/resources/mac/Info.plist',
'LD_RUNPATH_SEARCH_PATHS': [
'@executable_path/../Frameworks',
],
@@ -256,7 +277,9 @@
'files': [
'<(PRODUCT_DIR)/<(product_name) Helper.app',
'<(PRODUCT_DIR)/<(framework_name).framework',
'frameworks/Sparkle.framework',
'frameworks/Squirrel.framework',
'frameworks/ReactiveCocoa.framework',
'frameworks/Mantle.framework',
],
},
{
@@ -267,12 +290,6 @@
},
],
'postbuilds': [
{
'postbuild_name': 'Fix Framework Link',
'action': [
'<@(fix_framework_link_command)',
],
},
{
# This postbuid step is responsible for creating the following
# helpers:
@@ -311,6 +328,24 @@
},
],
}], # OS=="win"
['OS=="linux"', {
'copies': [
{
'destination': '<(PRODUCT_DIR)',
'files': [
'<(libchromiumcontent_library_dir)/libchromiumcontent.so',
'<(libchromiumcontent_library_dir)/libffmpegsumo.so',
'<(libchromiumcontent_resources_dir)/content_shell.pak',
],
},
{
'destination': '<(PRODUCT_DIR)/resources/browser',
'files': [
'browser/default_app',
]
},
],
}], # OS=="linux"
],
}, # target <(project_name)
{
@@ -318,7 +353,7 @@
'type': 'static_library',
'dependencies': [
'vendor/brightray/brightray.gyp:brightray',
'vendor/node/node.gyp:node',
'vendor/node/node.gyp:node_lib',
],
'sources': [
'<@(lib_sources)',
@@ -326,6 +361,15 @@
'include_dirs': [
'.',
'vendor',
'vendor/brightray',
# Include directories for uv and node.
'vendor/node/src',
'vendor/node/deps/http_parser',
'vendor/node/deps/uv/include',
# The `node.h` is using `#include"v8.h"`.
'vendor/brightray/vendor/download/libchromiumcontent/src/v8/include',
# The `node.h` is using `#include"ares.h"`.
'vendor/node/deps/cares/include',
],
'direct_dependent_settings': {
'include_dirs': [
@@ -350,12 +394,24 @@
'vendor/breakpad/breakpad.gyp:breakpad_handler',
'vendor/breakpad/breakpad.gyp:breakpad_sender',
],
}],
}], # OS=="win"
['OS=="mac"', {
'dependencies': [
'vendor/breakpad/breakpad.gyp:breakpad',
],
}],
}], # OS=="mac"
['OS=="linux"', {
'link_settings': {
'ldflags': [
# Make binary search for libraries under current directory, so we
# don't have to manually set $LD_LIBRARY_PATH:
# http://serverfault.com/questions/279068/cant-find-so-in-the-same-directory-as-the-executable
'-rpath \$$ORIGIN',
# Make native module dynamic loading work.
'-rdynamic',
],
},
}], # OS=="linux"
],
}, # target <(product_name)_lib
{
@@ -382,8 +438,7 @@
'<(RULE_INPUT_PATH)',
'<(PRODUCT_DIR)/<(product_name).app/Contents/Resources/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js',
],
}], # OS=="mac"
['OS=="win"', {
},{ # OS=="mac"
'outputs': [
'<(PRODUCT_DIR)/resources/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js',
],
@@ -393,7 +448,7 @@
'<(RULE_INPUT_PATH)',
'<(PRODUCT_DIR)/resources/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js',
],
}], # OS=="win"
}], # OS=="win" or OS=="linux"
],
},
],
@@ -479,15 +534,18 @@
'link_settings': {
'libraries': [
'$(SDKROOT)/System/Library/Frameworks/Carbon.framework',
'frameworks/Sparkle.framework',
'frameworks/Squirrel.framework',
'frameworks/ReactiveCocoa.framework',
'frameworks/Mantle.framework',
],
},
'mac_bundle': 1,
'mac_bundle_resources': [
'browser/mac/MainMenu.xib',
'common/resources/mac/MainMenu.xib',
'<(libchromiumcontent_resources_dir)/content_shell.pak',
],
'xcode_settings': {
'INFOPLIST_FILE': 'common/resources/mac/Info.plist',
'LIBRARY_SEARCH_PATHS': [
'<(libchromiumcontent_library_dir)',
],
@@ -516,12 +574,6 @@
},
],
'postbuilds': [
{
'postbuild_name': 'Fix Framework Link',
'action': [
'<@(fix_framework_link_command)',
],
},
{
'postbuild_name': 'Add symlinks for framework subdirectories',
'action': [
@@ -548,19 +600,11 @@
],
'mac_bundle': 1,
'xcode_settings': {
'INFOPLIST_FILE': 'renderer/mac/Info.plist',
'INFOPLIST_FILE': 'renderer/resources/mac/Info.plist',
'LD_RUNPATH_SEARCH_PATHS': [
'@executable_path/../../..',
],
},
'postbuilds': [
{
'postbuild_name': 'Fix Framework Link',
'action': [
'<@(fix_framework_link_command)',
],
},
],
}, # target helper
],
}], # OS==Mac

View File

@@ -7,8 +7,9 @@
#include "base/values.h"
#include "base/command_line.h"
#include "browser/browser.h"
#include "common/v8_conversions.h"
#include "vendor/node/src/node.h"
#include "common/v8/native_type_conversions.h"
#include "common/v8/node_common.h"
namespace atom {
@@ -48,97 +49,69 @@ void App::OnWillFinishLaunching() {
}
void App::OnFinishLaunching() {
Emit("finish-launching");
Emit("ready");
}
// static
v8::Handle<v8::Value> App::New(const v8::Arguments &args) {
v8::HandleScope scope;
void App::New(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope scope(args.GetIsolate());
if (!args.IsConstructCall())
return node::ThrowError("Require constructor call");
new App(args.This());
return args.This();
}
// static
v8::Handle<v8::Value> App::Quit(const v8::Arguments &args) {
v8::HandleScope scope;
void App::Quit(const v8::FunctionCallbackInfo<v8::Value>& args) {
Browser::Get()->Quit();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> App::Exit(const v8::Arguments &args) {
v8::HandleScope scope;
void App::Exit(const v8::FunctionCallbackInfo<v8::Value>& args) {
exit(args[0]->IntegerValue());
return v8::Undefined();
}
// static
v8::Handle<v8::Value> App::Terminate(const v8::Arguments &args) {
v8::HandleScope scope;
void App::Terminate(const v8::FunctionCallbackInfo<v8::Value>& args) {
Browser::Get()->Terminate();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> App::Focus(const v8::Arguments &args) {
v8::HandleScope scope;
void App::Focus(const v8::FunctionCallbackInfo<v8::Value>& args) {
Browser::Get()->Focus();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> App::GetVersion(const v8::Arguments &args) {
return ToV8Value(Browser::Get()->GetVersion());
void App::GetVersion(const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetReturnValue().Set(ToV8Value(Browser::Get()->GetVersion()));
}
// static
v8::Handle<v8::Value> App::SetVersion(const v8::Arguments &args) {
v8::HandleScope scope;
void App::SetVersion(const v8::FunctionCallbackInfo<v8::Value>& args) {
std::string version;
if (!FromV8Arguments(args, &version))
return node::ThrowError("Bad argument");
Browser::Get()->SetVersion(version);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> App::GetName(const v8::Arguments &args) {
return ToV8Value(Browser::Get()->GetName());
void App::GetName(const v8::FunctionCallbackInfo<v8::Value>& args) {
return args.GetReturnValue().Set(ToV8Value(Browser::Get()->GetName()));
}
// static
v8::Handle<v8::Value> App::SetName(const v8::Arguments &args) {
v8::HandleScope scope;
void App::SetName(const v8::FunctionCallbackInfo<v8::Value>& args) {
std::string name;
if (!FromV8Arguments(args, &name))
return node::ThrowError("Bad argument");
Browser::Get()->SetName(name);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> App::AppendSwitch(const v8::Arguments &args) {
v8::HandleScope scope;
void App::AppendSwitch(const v8::FunctionCallbackInfo<v8::Value>& args) {
std::string switch_string;
if (!FromV8Arguments(args, &switch_string))
return node::ThrowError("Bad argument");
@@ -150,27 +123,21 @@ v8::Handle<v8::Value> App::AppendSwitch(const v8::Arguments &args) {
CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switch_string, value);
}
return v8::Undefined();
}
// static
v8::Handle<v8::Value> App::AppendArgument(const v8::Arguments &args) {
v8::HandleScope scope;
void App::AppendArgument(const v8::FunctionCallbackInfo<v8::Value>& args) {
std::string value;
if (!FromV8Arguments(args, &value))
return node::ThrowError("Bad argument");
CommandLine::ForCurrentProcess()->AppendArg(value);
return v8::Undefined();
}
#if defined(OS_MACOSX)
// static
v8::Handle<v8::Value> App::DockBounce(const v8::Arguments& args) {
void App::DockBounce(const v8::FunctionCallbackInfo<v8::Value>& args) {
std::string type;
if (!FromV8Arguments(args, &type))
return node::ThrowError("Bad argument");
@@ -184,34 +151,30 @@ v8::Handle<v8::Value> App::DockBounce(const v8::Arguments& args) {
else
return node::ThrowTypeError("Invalid bounce type");
return ToV8Value(request_id);
args.GetReturnValue().Set(request_id);
}
// static
v8::Handle<v8::Value> App::DockCancelBounce(const v8::Arguments& args) {
void App::DockCancelBounce(const v8::FunctionCallbackInfo<v8::Value>& args) {
Browser::Get()->DockCancelBounce(FromV8Value(args[0]));
return v8::Undefined();
}
// static
v8::Handle<v8::Value> App::DockSetBadgeText(const v8::Arguments& args) {
void App::DockSetBadgeText(const v8::FunctionCallbackInfo<v8::Value>& args) {
Browser::Get()->DockSetBadgeText(FromV8Value(args[0]));
return v8::Undefined();
}
// static
v8::Handle<v8::Value> App::DockGetBadgeText(const v8::Arguments& args) {
void App::DockGetBadgeText(const v8::FunctionCallbackInfo<v8::Value>& args) {
std::string text(Browser::Get()->DockGetBadgeText());
return ToV8Value(text);
args.GetReturnValue().Set(ToV8Value(text));
}
#endif // defined(OS_MACOSX)
// static
void App::Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope scope;
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(App::New);
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(New);
t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(v8::String::NewSymbol("Application"));

View File

@@ -6,8 +6,8 @@
#define ATOM_BROWSER_API_ATOM_API_APP_H_
#include "base/compiler_specific.h"
#include "browser/api/atom_api_event_emitter.h"
#include "browser/browser_observer.h"
#include "common/api/atom_api_event_emitter.h"
namespace atom {
@@ -33,24 +33,24 @@ class App : public EventEmitter,
virtual void OnFinishLaunching() OVERRIDE;
private:
static v8::Handle<v8::Value> New(const v8::Arguments &args);
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static v8::Handle<v8::Value> Quit(const v8::Arguments &args);
static v8::Handle<v8::Value> Exit(const v8::Arguments &args);
static v8::Handle<v8::Value> Terminate(const v8::Arguments &args);
static v8::Handle<v8::Value> Focus(const v8::Arguments &args);
static v8::Handle<v8::Value> GetVersion(const v8::Arguments &args);
static v8::Handle<v8::Value> SetVersion(const v8::Arguments &args);
static v8::Handle<v8::Value> GetName(const v8::Arguments &args);
static v8::Handle<v8::Value> SetName(const v8::Arguments &args);
static v8::Handle<v8::Value> AppendSwitch(const v8::Arguments &args);
static v8::Handle<v8::Value> AppendArgument(const v8::Arguments &args);
static void Quit(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Exit(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Terminate(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Focus(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetVersion(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetVersion(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetName(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetName(const v8::FunctionCallbackInfo<v8::Value>& args);
static void AppendSwitch(const v8::FunctionCallbackInfo<v8::Value>& args);
static void AppendArgument(const v8::FunctionCallbackInfo<v8::Value>& args);
#if defined(OS_MACOSX)
static v8::Handle<v8::Value> DockBounce(const v8::Arguments& args);
static v8::Handle<v8::Value> DockCancelBounce(const v8::Arguments& args);
static v8::Handle<v8::Value> DockSetBadgeText(const v8::Arguments& args);
static v8::Handle<v8::Value> DockGetBadgeText(const v8::Arguments& args);
static void DockBounce(const v8::FunctionCallbackInfo<v8::Value>& args);
static void DockCancelBounce(const v8::FunctionCallbackInfo<v8::Value>& args);
static void DockSetBadgeText(const v8::FunctionCallbackInfo<v8::Value>& args);
static void DockGetBadgeText(const v8::FunctionCallbackInfo<v8::Value>& args);
#endif // defined(OS_MACOSX)
DISALLOW_COPY_AND_ASSIGN(App);

View File

@@ -4,9 +4,12 @@
#include "browser/api/atom_api_auto_updater.h"
#include "base/time/time.h"
#include "base/values.h"
#include "browser/auto_updater.h"
#include "common/v8_conversions.h"
#include "common/v8/native_type_conversions.h"
#include "common/v8/node_common.h"
namespace atom {
@@ -15,117 +18,82 @@ namespace api {
AutoUpdater::AutoUpdater(v8::Handle<v8::Object> wrapper)
: EventEmitter(wrapper) {
auto_updater::AutoUpdater::SetDelegate(this);
auto_updater::AutoUpdater::Init();
}
AutoUpdater::~AutoUpdater() {
auto_updater::AutoUpdater::SetDelegate(NULL);
}
void AutoUpdater::WillInstallUpdate(const std::string& version,
const base::Closure& install) {
continue_update_ = install;
void AutoUpdater::OnError(const std::string& error) {
base::ListValue args;
args.AppendString(version);
bool prevent_default = Emit("will-install-update-raw", &args);
if (!prevent_default)
install.Run();
args.AppendString(error);
Emit("error", &args);
}
void AutoUpdater::ReadyForUpdateOnQuit(const std::string& version,
const base::Closure& quit_and_install) {
void AutoUpdater::OnCheckingForUpdate() {
Emit("checking-for-update");
}
void AutoUpdater::OnUpdateAvailable() {
Emit("update-available");
}
void AutoUpdater::OnUpdateNotAvailable() {
Emit("update-not-available");
}
void AutoUpdater::OnUpdateDownloaded(const std::string& release_notes,
const std::string& release_name,
const base::Time& release_date,
const std::string& update_url,
const base::Closure& quit_and_install) {
quit_and_install_ = quit_and_install;
base::ListValue args;
args.AppendString(version);
Emit("ready-for-update-on-quit-raw", &args);
args.AppendString(release_notes);
args.AppendString(release_name);
args.AppendDouble(release_date.ToJsTime());
args.AppendString(update_url);
Emit("update-downloaded-raw", &args);
}
// static
v8::Handle<v8::Value> AutoUpdater::New(const v8::Arguments &args) {
v8::HandleScope scope;
void AutoUpdater::New(const v8::FunctionCallbackInfo<v8::Value>& args) {
if (!args.IsConstructCall())
return node::ThrowError("Require constructor call");
new AutoUpdater(args.This());
return args.This();
}
// static
v8::Handle<v8::Value> AutoUpdater::SetFeedURL(const v8::Arguments &args) {
void AutoUpdater::SetFeedURL(const v8::FunctionCallbackInfo<v8::Value>& args) {
auto_updater::AutoUpdater::SetFeedURL(FromV8Value(args[0]));
return v8::Undefined();
}
// static
v8::Handle<v8::Value> AutoUpdater::SetAutomaticallyChecksForUpdates(
const v8::Arguments &args) {
auto_updater::AutoUpdater::SetAutomaticallyChecksForUpdates(
args[0]->BooleanValue());
return v8::Undefined();
}
// static
v8::Handle<v8::Value> AutoUpdater::SetAutomaticallyDownloadsUpdates(
const v8::Arguments &args) {
auto_updater::AutoUpdater::SetAutomaticallyDownloadsUpdates(
args[0]->BooleanValue());
return v8::Undefined();
}
// static
v8::Handle<v8::Value> AutoUpdater::CheckForUpdates(const v8::Arguments &args) {
void AutoUpdater::CheckForUpdates(
const v8::FunctionCallbackInfo<v8::Value>& args) {
auto_updater::AutoUpdater::CheckForUpdates();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> AutoUpdater::CheckForUpdatesInBackground(
const v8::Arguments &args) {
auto_updater::AutoUpdater::CheckForUpdatesInBackground();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> AutoUpdater::ContinueUpdate(const v8::Arguments &args) {
void AutoUpdater::QuitAndInstall(
const v8::FunctionCallbackInfo<v8::Value>& args) {
AutoUpdater* self = AutoUpdater::Unwrap<AutoUpdater>(args.This());
self->continue_update_.Run();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> AutoUpdater::QuitAndInstall(const v8::Arguments &args) {
AutoUpdater* self = AutoUpdater::Unwrap<AutoUpdater>(args.This());
self->quit_and_install_.Run();
return v8::Undefined();
if (!self->quit_and_install_.is_null())
self->quit_and_install_.Run();
}
// static
void AutoUpdater::Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope scope;
v8::Local<v8::FunctionTemplate> t(
v8::FunctionTemplate::New(AutoUpdater::New));
t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(v8::String::NewSymbol("AutoUpdater"));
NODE_SET_PROTOTYPE_METHOD(t, "setFeedUrl", SetFeedURL);
NODE_SET_PROTOTYPE_METHOD(t,
"setAutomaticallyChecksForUpdates",
SetAutomaticallyChecksForUpdates);
NODE_SET_PROTOTYPE_METHOD(t,
"setAutomaticallyDownloadsUpdates",
SetAutomaticallyDownloadsUpdates);
NODE_SET_PROTOTYPE_METHOD(t, "checkForUpdates", CheckForUpdates);
NODE_SET_PROTOTYPE_METHOD(t,
"checkForUpdatesInBackground",
CheckForUpdatesInBackground);
NODE_SET_PROTOTYPE_METHOD(t, "continueUpdate", ContinueUpdate);
NODE_SET_PROTOTYPE_METHOD(t, "quitAndInstall", QuitAndInstall);
target->Set(v8::String::NewSymbol("AutoUpdater"), t->GetFunction());

View File

@@ -7,8 +7,8 @@
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "browser/api/atom_api_event_emitter.h"
#include "browser/auto_updater_delegate.h"
#include "common/api/atom_api_event_emitter.h"
namespace atom {
@@ -24,28 +24,27 @@ class AutoUpdater : public EventEmitter,
protected:
explicit AutoUpdater(v8::Handle<v8::Object> wrapper);
virtual void WillInstallUpdate(const std::string& version,
const base::Closure& install) OVERRIDE;
virtual void ReadyForUpdateOnQuit(
const std::string& version,
// AutoUpdaterDelegate implementations.
virtual void OnError(const std::string& error) OVERRIDE;
virtual void OnCheckingForUpdate() OVERRIDE;
virtual void OnUpdateAvailable() OVERRIDE;
virtual void OnUpdateNotAvailable() OVERRIDE;
virtual void OnUpdateDownloaded(
const std::string& release_notes,
const std::string& release_name,
const base::Time& release_date,
const std::string& update_url,
const base::Closure& quit_and_install) OVERRIDE;
private:
static v8::Handle<v8::Value> New(const v8::Arguments &args);
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static v8::Handle<v8::Value> SetFeedURL(const v8::Arguments &args);
static v8::Handle<v8::Value> SetAutomaticallyChecksForUpdates(
const v8::Arguments &args);
static v8::Handle<v8::Value> SetAutomaticallyDownloadsUpdates(
const v8::Arguments &args);
static v8::Handle<v8::Value> CheckForUpdates(const v8::Arguments &args);
static v8::Handle<v8::Value> CheckForUpdatesInBackground(
const v8::Arguments &args);
static void SetFeedURL(const v8::FunctionCallbackInfo<v8::Value>& args);
static void CheckForUpdates(const v8::FunctionCallbackInfo<v8::Value>& args);
static v8::Handle<v8::Value> ContinueUpdate(const v8::Arguments &args);
static v8::Handle<v8::Value> QuitAndInstall(const v8::Arguments &args);
static void ContinueUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
static void QuitAndInstall(const v8::FunctionCallbackInfo<v8::Value>& args);
base::Closure continue_update_;
base::Closure quit_and_install_;
DISALLOW_COPY_AND_ASSIGN(AutoUpdater);

View File

@@ -5,22 +5,18 @@
#include "browser/api/atom_api_browser_ipc.h"
#include "common/api/api_messages.h"
#include "common/v8_conversions.h"
#include "common/v8/node_common.h"
#include "common/v8/native_type_conversions.h"
#include "content/public/browser/render_view_host.h"
#include "vendor/node/src/node.h"
#include "vendor/node/src/node_internals.h"
using content::RenderViewHost;
using content::V8ValueConverter;
namespace atom {
namespace api {
// static
v8::Handle<v8::Value> BrowserIPC::Send(const v8::Arguments &args) {
v8::HandleScope scope;
void BrowserIPC::Send(const v8::FunctionCallbackInfo<v8::Value>& args) {
string16 channel;
int process_id, routing_id;
scoped_ptr<base::Value> arguments;
@@ -34,17 +30,15 @@ v8::Handle<v8::Value> BrowserIPC::Send(const v8::Arguments &args) {
if (!render_view_host)
return node::ThrowError("Invalid render view host");
render_view_host->Send(new AtomViewMsg_Message(
args.GetReturnValue().Set(render_view_host->Send(new AtomViewMsg_Message(
routing_id,
channel,
*static_cast<base::ListValue*>(arguments.get())));
return v8::Undefined();
*static_cast<base::ListValue*>(arguments.get()))));
}
// static
void BrowserIPC::Initialize(v8::Handle<v8::Object> target) {
node::SetMethod(target, "send", Send);
NODE_SET_METHOD(target, "send", Send);
}
} // namespace api

View File

@@ -17,7 +17,7 @@ class BrowserIPC {
static void Initialize(v8::Handle<v8::Object> target);
private:
static v8::Handle<v8::Value> Send(const v8::Arguments &args);
static void Send(const v8::FunctionCallbackInfo<v8::Value>& args);
DISALLOW_IMPLICIT_CONSTRUCTORS(BrowserIPC);
};

View File

@@ -8,10 +8,8 @@
#include "browser/native_window.h"
#include "browser/ui/file_dialog.h"
#include "browser/ui/message_box.h"
#include "common/v8_conversions.h"
#include "vendor/node/src/node_internals.h"
using node::node_isolate;
#include "common/v8/node_common.h"
#include "common/v8/native_type_conversions.h"
namespace atom {
@@ -20,19 +18,17 @@ namespace api {
namespace {
template<typename T>
void CallV8Function(v8::Persistent<v8::Function> callback, T arg) {
DCHECK(!callback.IsEmpty());
void CallV8Function(const RefCountedV8Function& callback, T arg) {
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
v8::HandleScope scope;
v8::Handle<v8::Value> value = ToV8Value(arg);
callback->Call(callback, 1, &value);
callback.Dispose(node_isolate);
callback->NewHandle(node_isolate)->Call(
v8::Context::GetCurrent()->Global(), 1, &value);
}
template<typename T>
void CallV8Function2(v8::Persistent<v8::Function> callback,
bool result,
T arg) {
void CallV8Function2(const RefCountedV8Function& callback, bool result, T arg) {
if (result)
return CallV8Function<T>(callback, arg);
else
@@ -40,8 +36,6 @@ void CallV8Function2(v8::Persistent<v8::Function> callback,
}
void Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope scope;
NODE_SET_METHOD(target, "showMessageBox", ShowMessageBox);
NODE_SET_METHOD(target, "showOpenDialog", ShowOpenDialog);
NODE_SET_METHOD(target, "showSaveDialog", ShowSaveDialog);
@@ -49,9 +43,7 @@ void Initialize(v8::Handle<v8::Object> target) {
} // namespace
v8::Handle<v8::Value> ShowMessageBox(const v8::Arguments &args) {
v8::HandleScope scope;
void ShowMessageBox(const v8::FunctionCallbackInfo<v8::Value>& args) {
int type;
std::vector<std::string> buttons;
std::string title, message, detail;
@@ -68,9 +60,9 @@ v8::Handle<v8::Value> ShowMessageBox(const v8::Arguments &args) {
title,
message,
detail);
return scope.Close(v8::Integer::New(chosen));
args.GetReturnValue().Set(chosen);
} else {
v8::Persistent<v8::Function> callback = FromV8Value(args[6]);
RefCountedV8Function callback = FromV8Value(args[6]);
atom::ShowMessageBox(
native_window,
(MessageBoxType)type,
@@ -79,13 +71,10 @@ v8::Handle<v8::Value> ShowMessageBox(const v8::Arguments &args) {
message,
detail,
base::Bind(&CallV8Function<int>, callback));
return v8::Undefined();
}
}
v8::Handle<v8::Value> ShowOpenDialog(const v8::Arguments &args) {
v8::HandleScope scope;
void ShowOpenDialog(const v8::FunctionCallbackInfo<v8::Value>& args) {
std::string title;
base::FilePath default_path;
int properties;
@@ -101,15 +90,15 @@ v8::Handle<v8::Value> ShowOpenDialog(const v8::Arguments &args) {
default_path,
properties,
&paths))
return v8::Undefined();
return;
v8::Handle<v8::Array> result = v8::Array::New(paths.size());
for (size_t i = 0; i < paths.size(); ++i)
result->Set(i, ToV8Value(paths[i]));
return scope.Close(result);
args.GetReturnValue().Set(result);
} else {
v8::Persistent<v8::Function> callback = FromV8Value(args[4]);
RefCountedV8Function callback = FromV8Value(args[4]);
file_dialog::ShowOpenDialog(
native_window,
title,
@@ -117,13 +106,10 @@ v8::Handle<v8::Value> ShowOpenDialog(const v8::Arguments &args) {
properties,
base::Bind(&CallV8Function2<const std::vector<base::FilePath>&>,
callback));
return v8::Undefined();
}
}
v8::Handle<v8::Value> ShowSaveDialog(const v8::Arguments &args) {
v8::HandleScope scope;
void ShowSaveDialog(const v8::FunctionCallbackInfo<v8::Value>& args) {
std::string title;
base::FilePath default_path;
if (!FromV8Arguments(args, &title, &default_path))
@@ -133,21 +119,18 @@ v8::Handle<v8::Value> ShowSaveDialog(const v8::Arguments &args) {
if (!args[3]->IsFunction()) {
base::FilePath path;
if (!file_dialog::ShowSaveDialog(native_window,
title,
default_path,
&path))
return v8::Undefined();
return scope.Close(ToV8Value(path));
if (file_dialog::ShowSaveDialog(native_window,
title,
default_path,
&path))
args.GetReturnValue().Set(ToV8Value(path));
} else {
v8::Persistent<v8::Function> callback = FromV8Value(args[3]);
RefCountedV8Function callback = FromV8Value(args[3]);
file_dialog::ShowSaveDialog(
native_window,
title,
default_path,
base::Bind(&CallV8Function2<const base::FilePath&>, callback));
return v8::Undefined();
}
}

View File

@@ -11,9 +11,9 @@ namespace atom {
namespace api {
v8::Handle<v8::Value> ShowMessageBox(const v8::Arguments &args);
v8::Handle<v8::Value> ShowOpenDialog(const v8::Arguments &args);
v8::Handle<v8::Value> ShowSaveDialog(const v8::Arguments &args);
void ShowMessageBox(const v8::FunctionCallbackInfo<v8::Value>& args);
void ShowOpenDialog(const v8::FunctionCallbackInfo<v8::Value>& args);
void ShowSaveDialog(const v8::FunctionCallbackInfo<v8::Value>& args);
} // namespace api

View File

@@ -6,15 +6,14 @@
#include "browser/native_window.h"
#include "common/api/api_messages.h"
#include "common/v8_conversions.h"
using node::node_isolate;
#include "common/v8/node_common.h"
#include "common/v8/native_type_conversions.h"
namespace atom {
namespace api {
v8::Persistent<v8::FunctionTemplate> Event::constructor_template_;
ScopedPersistent<v8::Function> Event::constructor_template_;
Event::Event()
: sender_(NULL),
@@ -29,24 +28,20 @@ Event::~Event() {
// static
v8::Handle<v8::Object> Event::CreateV8Object() {
v8::HandleScope scope;
if (constructor_template_.IsEmpty()) {
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(New);
constructor_template_ = v8::Persistent<v8::FunctionTemplate>::New(
node_isolate, t);
constructor_template_->InstanceTemplate()->SetInternalFieldCount(1);
constructor_template_->SetClassName(v8::String::NewSymbol("Event"));
t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(v8::String::NewSymbol("Event"));
NODE_SET_PROTOTYPE_METHOD(t, "preventDefault", PreventDefault);
NODE_SET_PROTOTYPE_METHOD(t, "sendReply", SendReply);
NODE_SET_PROTOTYPE_METHOD(t, "destroy", Destroy);
constructor_template_.reset(t->GetFunction());
}
v8::Handle<v8::Object> v8_event =
constructor_template_->GetFunction()->NewInstance(0, NULL);
return scope.Close(v8_event);
v8::Handle<v8::Function> t = constructor_template_.NewHandle(node_isolate);
return t->NewInstance(0, NULL);
}
void Event::SetSenderAndMessage(NativeWindow* sender, IPC::Message* message) {
@@ -64,26 +59,22 @@ void Event::OnWindowClosed() {
}
// static
v8::Handle<v8::Value> Event::New(const v8::Arguments& args) {
void Event::New(const v8::FunctionCallbackInfo<v8::Value>& args) {
Event* event = new Event;
event->Wrap(args.This());
return args.This();
}
// static
v8::Handle<v8::Value> Event::PreventDefault(const v8::Arguments& args) {
void Event::PreventDefault(const v8::FunctionCallbackInfo<v8::Value>& args) {
Event* event = Unwrap<Event>(args.This());
if (event == NULL)
return node::ThrowError("Event is already destroyed");
event->prevent_default_ = true;
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Event::SendReply(const v8::Arguments& args) {
void Event::SendReply(const v8::FunctionCallbackInfo<v8::Value>& args) {
Event* event = Unwrap<Event>(args.This());
if (event == NULL)
return node::ThrowError("Event is already destroyed");
@@ -97,14 +88,11 @@ v8::Handle<v8::Value> Event::SendReply(const v8::Arguments& args) {
event->sender_->Send(event->message_);
delete event;
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Event::Destroy(const v8::Arguments& args) {
void Event::Destroy(const v8::FunctionCallbackInfo<v8::Value>& args) {
delete Unwrap<Event>(args.This());
return v8::Undefined();
}
} // namespace api

View File

@@ -7,8 +7,9 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/string16.h"
#include "base/strings/string16.h"
#include "browser/native_window_observer.h"
#include "common/v8/scoped_persistent.h"
#include "vendor/node/src/node_object_wrap.h"
namespace IPC {
@@ -32,9 +33,6 @@ class Event : public node::ObjectWrap,
// Pass the sender and message to be replied.
void SetSenderAndMessage(NativeWindow* sender, IPC::Message* message);
// Accessor to return handle_, this follows Google C++ Style.
v8::Persistent<v8::Object>& handle() { return handle_; }
// Whether event.preventDefault() is called.
bool prevent_default() const { return prevent_default_; }
@@ -45,13 +43,13 @@ class Event : public node::ObjectWrap,
virtual void OnWindowClosed() OVERRIDE;
private:
static v8::Handle<v8::Value> New(const v8::Arguments& args);
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static v8::Handle<v8::Value> PreventDefault(const v8::Arguments& args);
static v8::Handle<v8::Value> SendReply(const v8::Arguments& args);
static v8::Handle<v8::Value> Destroy(const v8::Arguments& args);
static void PreventDefault(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SendReply(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Destroy(const v8::FunctionCallbackInfo<v8::Value>& args);
static v8::Persistent<v8::FunctionTemplate> constructor_template_;
static ScopedPersistent<v8::Function> constructor_template_;
// Replyer for the synchronous messages.
NativeWindow* sender_;

View File

@@ -5,7 +5,8 @@
#include "browser/api/atom_api_menu.h"
#include "browser/ui/accelerator_util.h"
#include "common/v8_conversions.h"
#include "common/v8/node_common.h"
#include "common/v8/native_type_conversions.h"
#define UNWRAP_MEMNU_AND_CHECK \
Menu* self = ObjectWrap::Unwrap<Menu>(args.This()); \
@@ -23,7 +24,8 @@ v8::Handle<v8::Value> CallDelegate(v8::Handle<v8::Value> default_value,
v8::Handle<v8::Object> menu,
const char* method,
int command_id) {
v8::HandleScope scope;
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
v8::Handle<v8::Value> delegate = menu->Get(v8::String::New("delegate"));
if (!delegate->IsObject())
@@ -36,7 +38,7 @@ v8::Handle<v8::Value> CallDelegate(v8::Handle<v8::Value> default_value,
v8::Handle<v8::Value> argv = v8::Integer::New(command_id);
return scope.Close(
return handle_scope.Close(
function->Call(v8::Context::GetCurrent()->Global(), 1, &argv));
}
@@ -51,32 +53,36 @@ Menu::~Menu() {
}
bool Menu::IsCommandIdChecked(int command_id) const {
v8::HandleScope scope;
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
return CallDelegate(v8::False(),
handle(),
const_cast<Menu*>(this)->handle(),
"isCommandIdChecked",
command_id)->BooleanValue();
}
bool Menu::IsCommandIdEnabled(int command_id) const {
v8::HandleScope scope;
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
return CallDelegate(v8::True(),
handle(),
const_cast<Menu*>(this)->handle(),
"isCommandIdEnabled",
command_id)->BooleanValue();
}
bool Menu::IsCommandIdVisible(int command_id) const {
v8::HandleScope scope;
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
return CallDelegate(v8::True(),
handle(),
const_cast<Menu*>(this)->handle(),
"isCommandIdVisible",
command_id)->BooleanValue();
}
bool Menu::GetAcceleratorForCommandId(int command_id,
ui::Accelerator* accelerator) {
v8::HandleScope scope;
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
v8::Handle<v8::Value> shortcut = CallDelegate(v8::Undefined(),
handle(),
"getAcceleratorForCommandId",
@@ -90,48 +96,48 @@ bool Menu::GetAcceleratorForCommandId(int command_id,
}
bool Menu::IsItemForCommandIdDynamic(int command_id) const {
v8::HandleScope scope;
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
return CallDelegate(v8::False(),
handle(),
const_cast<Menu*>(this)->handle(),
"isItemForCommandIdDynamic",
command_id)->BooleanValue();
}
string16 Menu::GetLabelForCommandId(int command_id) const {
v8::HandleScope scope;
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
return FromV8Value(CallDelegate(v8::False(),
handle(),
const_cast<Menu*>(this)->handle(),
"getLabelForCommandId",
command_id));
}
string16 Menu::GetSublabelForCommandId(int command_id) const {
v8::HandleScope scope;
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
return FromV8Value(CallDelegate(v8::False(),
handle(),
const_cast<Menu*>(this)->handle(),
"getSubLabelForCommandId",
command_id));
}
void Menu::ExecuteCommand(int command_id, int event_flags) {
v8::HandleScope scope;
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
CallDelegate(v8::False(), handle(), "executeCommand", command_id);
}
// static
v8::Handle<v8::Value> Menu::New(const v8::Arguments &args) {
v8::HandleScope scope;
void Menu::New(const v8::FunctionCallbackInfo<v8::Value>& args) {
if (!args.IsConstructCall())
return node::ThrowError("Require constructor call");
Menu::Create(args.This());
return args.This();
}
// static
v8::Handle<v8::Value> Menu::InsertItem(const v8::Arguments &args) {
void Menu::InsertItem(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
int index, command_id;
@@ -143,12 +149,10 @@ v8::Handle<v8::Value> Menu::InsertItem(const v8::Arguments &args) {
self->model_->AddItem(command_id, label);
else
self->model_->InsertItemAt(index, command_id, label);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Menu::InsertCheckItem(const v8::Arguments &args) {
void Menu::InsertCheckItem(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
int index, command_id;
@@ -160,12 +164,10 @@ v8::Handle<v8::Value> Menu::InsertCheckItem(const v8::Arguments &args) {
self->model_->AddCheckItem(command_id, label);
else
self->model_->InsertCheckItemAt(index, command_id, label);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Menu::InsertRadioItem(const v8::Arguments &args) {
void Menu::InsertRadioItem(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
int index, command_id, group_id;
@@ -177,12 +179,10 @@ v8::Handle<v8::Value> Menu::InsertRadioItem(const v8::Arguments &args) {
self->model_->AddRadioItem(command_id, label, group_id);
else
self->model_->InsertRadioItemAt(index, command_id, label, group_id);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Menu::InsertSeparator(const v8::Arguments &args) {
void Menu::InsertSeparator(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
int index;
@@ -193,12 +193,10 @@ v8::Handle<v8::Value> Menu::InsertSeparator(const v8::Arguments &args) {
self->model_->AddSeparator(ui::NORMAL_SEPARATOR);
else
self->model_->InsertSeparatorAt(index, ui::NORMAL_SEPARATOR);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Menu::InsertSubMenu(const v8::Arguments &args) {
void Menu::InsertSubMenu(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
int index, command_id;
@@ -215,12 +213,10 @@ v8::Handle<v8::Value> Menu::InsertSubMenu(const v8::Arguments &args) {
else
self->model_->InsertSubMenuAt(
index, command_id, label, submenu->model_.get());
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Menu::SetIcon(const v8::Arguments &args) {
void Menu::SetIcon(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
int index;
@@ -229,12 +225,10 @@ v8::Handle<v8::Value> Menu::SetIcon(const v8::Arguments &args) {
return node::ThrowTypeError("Bad argument");
// FIXME use webkit_glue's image decoder here.
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Menu::SetSublabel(const v8::Arguments &args) {
void Menu::SetSublabel(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
int index;
@@ -243,74 +237,72 @@ v8::Handle<v8::Value> Menu::SetSublabel(const v8::Arguments &args) {
return node::ThrowTypeError("Bad argument");
self->model_->SetSublabel(index, label);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Menu::Clear(const v8::Arguments &args) {
void Menu::Clear(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
self->model_->Clear();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Menu::GetIndexOfCommandId(const v8::Arguments &args) {
void Menu::GetIndexOfCommandId(
const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
int index = args[0]->IntegerValue();
return v8::Integer::New(self->model_->GetIndexOfCommandId(index));
int index = FromV8Value(args[0]);
args.GetReturnValue().Set(self->model_->GetIndexOfCommandId(index));
}
// static
v8::Handle<v8::Value> Menu::GetItemCount(const v8::Arguments &args) {
void Menu::GetItemCount(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
return v8::Integer::New(self->model_->GetItemCount());
args.GetReturnValue().Set(self->model_->GetItemCount());
}
// static
v8::Handle<v8::Value> Menu::GetCommandIdAt(const v8::Arguments &args) {
void Menu::GetCommandIdAt(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
int index = args[0]->IntegerValue();
return v8::Integer::New(self->model_->GetCommandIdAt(index));
int index = FromV8Value(args[0]);
args.GetReturnValue().Set(self->model_->GetCommandIdAt(index));
}
// static
v8::Handle<v8::Value> Menu::GetLabelAt(const v8::Arguments &args) {
void Menu::GetLabelAt(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
int index = args[0]->IntegerValue();
return ToV8Value(self->model_->GetLabelAt(index));
int index = FromV8Value(args[0]);
args.GetReturnValue().Set(ToV8Value(self->model_->GetLabelAt(index)));
}
// static
v8::Handle<v8::Value> Menu::GetSublabelAt(const v8::Arguments &args) {
void Menu::GetSublabelAt(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
int index = args[0]->IntegerValue();
return ToV8Value(self->model_->GetSublabelAt(index));
int index = FromV8Value(args[0]);
args.GetReturnValue().Set(ToV8Value(self->model_->GetSublabelAt(index)));
}
// static
v8::Handle<v8::Value> Menu::IsItemCheckedAt(const v8::Arguments &args) {
void Menu::IsItemCheckedAt(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
int index = args[0]->IntegerValue();
return v8::Boolean::New(self->model_->IsItemCheckedAt(index));
int index = FromV8Value(args[0]);
args.GetReturnValue().Set(self->model_->IsItemCheckedAt(index));
}
// static
v8::Handle<v8::Value> Menu::IsEnabledAt(const v8::Arguments &args) {
void Menu::IsEnabledAt(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
return v8::Boolean::New(self->model_->IsEnabledAt(args[0]->IntegerValue()));
int index = FromV8Value(args[0]);
args.GetReturnValue().Set(self->model_->IsEnabledAt(index));
}
// static
v8::Handle<v8::Value> Menu::IsVisibleAt(const v8::Arguments &args) {
void Menu::IsVisibleAt(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
return v8::Boolean::New(self->model_->IsVisibleAt(args[0]->IntegerValue()));
int index = FromV8Value(args[0]);
args.GetReturnValue().Set(self->model_->IsVisibleAt(index));
}
// static
v8::Handle<v8::Value> Menu::Popup(const v8::Arguments &args) {
void Menu::Popup(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_MEMNU_AND_CHECK;
atom::NativeWindow* window;
@@ -318,13 +310,10 @@ v8::Handle<v8::Value> Menu::Popup(const v8::Arguments &args) {
return node::ThrowTypeError("Bad argument");
self->Popup(window);
return v8::Undefined();
}
// static
void Menu::Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope scope;
v8::Local<v8::FunctionTemplate> t(v8::FunctionTemplate::New(Menu::New));
t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(v8::String::NewSymbol("Menu"));
@@ -351,7 +340,7 @@ void Menu::Initialize(v8::Handle<v8::Object> target) {
NODE_SET_PROTOTYPE_METHOD(t, "popup", Popup);
#if defined(OS_WIN)
#if defined(OS_WIN) || defined(TOOLKIT_GTK)
NODE_SET_PROTOTYPE_METHOD(t, "attachToWindow", AttachToWindow);
#endif

View File

@@ -6,7 +6,7 @@
#define ATOM_BROWSER_API_ATOM_API_MENU_H_
#include "base/memory/scoped_ptr.h"
#include "browser/api/atom_api_event_emitter.h"
#include "common/api/atom_api_event_emitter.h"
#include "ui/base/models/simple_menu_model.h"
namespace atom {
@@ -44,36 +44,38 @@ class Menu : public EventEmitter,
scoped_ptr<ui::SimpleMenuModel> model_;
private:
static v8::Handle<v8::Value> New(const v8::Arguments &args);
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static v8::Handle<v8::Value> InsertItem(const v8::Arguments &args);
static v8::Handle<v8::Value> InsertCheckItem(const v8::Arguments &args);
static v8::Handle<v8::Value> InsertRadioItem(const v8::Arguments &args);
static v8::Handle<v8::Value> InsertSeparator(const v8::Arguments &args);
static v8::Handle<v8::Value> InsertSubMenu(const v8::Arguments &args);
static void InsertItem(const v8::FunctionCallbackInfo<v8::Value>& args);
static void InsertCheckItem(const v8::FunctionCallbackInfo<v8::Value>& args);
static void InsertRadioItem(const v8::FunctionCallbackInfo<v8::Value>& args);
static void InsertSeparator(const v8::FunctionCallbackInfo<v8::Value>& args);
static void InsertSubMenu(const v8::FunctionCallbackInfo<v8::Value>& args);
static v8::Handle<v8::Value> SetIcon(const v8::Arguments &args);
static v8::Handle<v8::Value> SetSublabel(const v8::Arguments &args);
static void SetIcon(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetSublabel(const v8::FunctionCallbackInfo<v8::Value>& args);
static v8::Handle<v8::Value> Clear(const v8::Arguments &args);
static void Clear(const v8::FunctionCallbackInfo<v8::Value>& args);
static v8::Handle<v8::Value> GetIndexOfCommandId(const v8::Arguments &args);
static v8::Handle<v8::Value> GetItemCount(const v8::Arguments &args);
static v8::Handle<v8::Value> GetCommandIdAt(const v8::Arguments &args);
static v8::Handle<v8::Value> GetLabelAt(const v8::Arguments &args);
static v8::Handle<v8::Value> GetSublabelAt(const v8::Arguments &args);
static v8::Handle<v8::Value> IsItemCheckedAt(const v8::Arguments &args);
static v8::Handle<v8::Value> IsEnabledAt(const v8::Arguments &args);
static v8::Handle<v8::Value> IsVisibleAt(const v8::Arguments &args);
static void GetIndexOfCommandId(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetItemCount(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetCommandIdAt(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetLabelAt(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetSublabelAt(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsItemCheckedAt(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsEnabledAt(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsVisibleAt(const v8::FunctionCallbackInfo<v8::Value>& args);
static v8::Handle<v8::Value> Popup(const v8::Arguments &args);
static void Popup(const v8::FunctionCallbackInfo<v8::Value>& args);
#if defined(OS_WIN)
static v8::Handle<v8::Value> AttachToWindow(const v8::Arguments &args);
#if defined(OS_WIN) || defined(TOOLKIT_GTK)
static void AttachToWindow(const v8::FunctionCallbackInfo<v8::Value>& args);
#elif defined(OS_MACOSX)
static v8::Handle<v8::Value> SetApplicationMenu(const v8::Arguments &args);
static v8::Handle<v8::Value> SendActionToFirstResponder(
const v8::Arguments &args);
static void SetApplicationMenu(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void SendActionToFirstResponder(
const v8::FunctionCallbackInfo<v8::Value>& args);
#endif
DISALLOW_COPY_AND_ASSIGN(Menu);

View File

@@ -0,0 +1,32 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "browser/api/atom_api_menu_gtk.h"
namespace atom {
namespace api {
MenuGtk::MenuGtk(v8::Handle<v8::Object> wrapper)
: Menu(wrapper) {
}
MenuGtk::~MenuGtk() {
}
void MenuGtk::Popup(NativeWindow* native_window) {
}
// static
void Menu::AttachToWindow(const v8::FunctionCallbackInfo<v8::Value>& args) {
}
// static
Menu* Menu::Create(v8::Handle<v8::Object> wrapper) {
return new MenuGtk(wrapper);
}
} // namespace api
} // namespace atom

View File

@@ -0,0 +1,30 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_GTK_H_
#define ATOM_BROWSER_API_ATOM_API_MENU_GTK_H_
#include "browser/api/atom_api_menu.h"
namespace atom {
namespace api {
class MenuGtk : public Menu {
public:
explicit MenuGtk(v8::Handle<v8::Object> wrapper);
virtual ~MenuGtk();
protected:
virtual void Popup(NativeWindow* window) OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(MenuGtk);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_MENU_GTK_H_

View File

@@ -7,7 +7,7 @@
#include "browser/api/atom_api_menu.h"
#import "browser/ui/atom_menu_controller_mac.h"
#import "browser/ui/cocoa/atom_menu_controller.h"
namespace atom {
@@ -21,7 +21,7 @@ class MenuMac : public Menu {
protected:
virtual void Popup(NativeWindow* window) OVERRIDE;
scoped_nsobject<AtomMenuController> menu_controller_;
base::scoped_nsobject<AtomMenuController> menu_controller_;
private:
friend class Menu;

View File

@@ -4,11 +4,12 @@
#import "browser/api/atom_api_menu_mac.h"
#include "base/message_loop.h"
#include "base/mac/scoped_sending_event.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/sys_string_conversions.h"
#include "browser/native_window.h"
#include "common/v8_conversions.h"
#include "common/v8/node_common.h"
#include "common/v8/native_type_conversions.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
@@ -24,7 +25,7 @@ MenuMac::~MenuMac() {
}
void MenuMac::Popup(NativeWindow* native_window) {
scoped_nsobject<AtomMenuController> menu_controller(
base::scoped_nsobject<AtomMenuController> menu_controller(
[[AtomMenuController alloc] initWithModel:model_.get()]);
NSWindow* window = native_window->GetNativeWindow();
@@ -46,7 +47,8 @@ void MenuMac::Popup(NativeWindow* native_window) {
{
// Make sure events can be pumped while the menu is up.
MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
base::MessageLoop::ScopedNestableTaskAllower allow(
base::MessageLoop::current());
// One of the events that could be pumped is |window.close()|.
// User-initiated event-tracking loops protect against this by
@@ -71,9 +73,7 @@ void MenuMac::SendActionToFirstResponder(const std::string& action) {
}
// static
v8::Handle<v8::Value> Menu::SetApplicationMenu(const v8::Arguments &args) {
v8::HandleScope scope;
void Menu::SetApplicationMenu(const v8::FunctionCallbackInfo<v8::Value>& args) {
if (!args[0]->IsObject())
return node::ThrowTypeError("Bad argument");
@@ -81,28 +81,22 @@ v8::Handle<v8::Value> Menu::SetApplicationMenu(const v8::Arguments &args) {
if (!menu)
return node::ThrowError("Menu is destroyed");
scoped_nsobject<AtomMenuController> menu_controller(
base::scoped_nsobject<AtomMenuController> menu_controller(
[[AtomMenuController alloc] initWithModel:menu->model_.get()]);
[NSApp setMainMenu:[menu_controller menu]];
// Ensure the menu_controller_ is destroyed after main menu is set.
menu_controller.swap(menu->menu_controller_);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Menu::SendActionToFirstResponder(
const v8::Arguments &args) {
v8::HandleScope scope;
void Menu::SendActionToFirstResponder(
const v8::FunctionCallbackInfo<v8::Value>& args) {
std::string action;
if (!FromV8Arguments(args, &action))
return node::ThrowTypeError("Bad argument");
MenuMac::SendActionToFirstResponder(action);
return v8::Undefined();
}
// static

View File

@@ -6,10 +6,12 @@
#include "browser/native_window_win.h"
#include "browser/ui/win/menu_2.h"
#include "common/v8_conversions.h"
#include "common/v8/native_type_conversions.h"
#include "ui/gfx/point.h"
#include "ui/gfx/screen.h"
#include "common/v8/node_common.h"
namespace atom {
namespace api {
@@ -28,9 +30,7 @@ void MenuWin::Popup(NativeWindow* native_window) {
}
// static
v8::Handle<v8::Value> Menu::AttachToWindow(const v8::Arguments& args) {
v8::HandleScope scope;
void Menu::AttachToWindow(const v8::FunctionCallbackInfo<v8::Value>& args) {
Menu* self = ObjectWrap::Unwrap<Menu>(args.This());
if (self == NULL)
return node::ThrowError("Menu is already destroyed");
@@ -40,8 +40,6 @@ v8::Handle<v8::Value> Menu::AttachToWindow(const v8::Arguments& args) {
return node::ThrowTypeError("Bad argument");
static_cast<NativeWindowWin*>(native_window)->SetMenu(self->model_.get());
return v8::Undefined();
}
// static

View File

@@ -5,6 +5,9 @@
#include "browser/api/atom_api_power_monitor.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_monitor_device_source.h"
#include "common/v8/node_common.h"
namespace atom {
@@ -35,20 +38,18 @@ void PowerMonitor::OnResume() {
}
// static
v8::Handle<v8::Value> PowerMonitor::New(const v8::Arguments& args) {
v8::HandleScope scope;
void PowerMonitor::New(const v8::FunctionCallbackInfo<v8::Value>& args) {
if (!args.IsConstructCall())
return node::ThrowError("Require constructor call");
new PowerMonitor(args.This());
return args.This();
}
// static
void PowerMonitor::Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope scope;
#if defined(OS_MACOSX)
base::PowerMonitorDeviceSource::AllocateSystemIOPorts();
#endif
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(
PowerMonitor::New);

View File

@@ -5,10 +5,9 @@
#ifndef ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
#define ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
#include "browser/api/atom_api_event_emitter.h"
#include "base/compiler_specific.h"
#include "base/power_monitor/power_observer.h"
#include "common/api/atom_api_event_emitter.h"
namespace atom {
@@ -29,7 +28,7 @@ class PowerMonitor : public EventEmitter,
virtual void OnResume() OVERRIDE;
private:
static v8::Handle<v8::Value> New(const v8::Arguments &args);
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
DISALLOW_COPY_AND_ASSIGN(PowerMonitor);
};

View File

@@ -9,11 +9,11 @@
#include "browser/net/adapter_request_job.h"
#include "browser/net/atom_url_request_context_getter.h"
#include "browser/net/atom_url_request_job_factory.h"
#include "common/v8_conversions.h"
#include "common/v8/native_type_conversions.h"
#include "content/public/browser/browser_thread.h"
#include "net/url_request/url_request_context.h"
#include "vendor/node/src/node.h"
#include "vendor/node/src/node_internals.h"
#include "common/v8/node_common.h"
namespace atom {
@@ -24,10 +24,10 @@ typedef net::URLRequestJobFactory::ProtocolHandler ProtocolHandler;
namespace {
// The protocol module object.
v8::Persistent<v8::Object> g_protocol_object;
ScopedPersistent<v8::Object> g_protocol_object;
// Registered protocol handlers.
typedef std::map<std::string, v8::Persistent<v8::Function>> HandlersMap;
typedef std::map<std::string, RefCountedV8Function> HandlersMap;
static HandlersMap g_handlers;
static const char* kEarlyUseProtocolError = "This method can only be used"
@@ -35,25 +35,24 @@ static const char* kEarlyUseProtocolError = "This method can only be used"
// Emit an event for the protocol module.
void EmitEventInUI(const std::string& event, const std::string& parameter) {
v8::HandleScope scope;
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
v8::Handle<v8::Value> argv[] = {
ToV8Value(event),
ToV8Value(parameter),
ToV8Value(event),
ToV8Value(parameter),
};
node::MakeCallback(g_protocol_object, "emit", arraysize(argv), argv);
node::MakeCallback(g_protocol_object.NewHandle(node_isolate),
"emit", 2, argv);
}
// Convert the URLRequest object to V8 object.
v8::Handle<v8::Object> ConvertURLRequestToV8Object(
const net::URLRequest* request) {
v8::Local<v8::Object> obj = v8::Object::New();
obj->Set(v8::String::New("method"),
v8::String::New(request->method().c_str()));
obj->Set(v8::String::New("url"),
v8::String::New(request->url().spec().c_str()));
obj->Set(v8::String::New("referrer"),
v8::String::New(request->referrer().c_str()));
obj->Set(ToV8Value("method"), ToV8Value(request->method()));
obj->Set(ToV8Value("url"), ToV8Value(request->url().spec()));
obj->Set(ToV8Value("referrer"), ToV8Value(request->referrer()));
return obj;
}
@@ -74,13 +73,16 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
virtual void GetJobTypeInUI() OVERRIDE {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
// Call the JS handler.
v8::HandleScope scope;
v8::Handle<v8::Value> argv[] = {
ConvertURLRequestToV8Object(request()),
};
v8::Handle<v8::Value> result = g_handlers[request()->url().scheme()]->Call(
v8::Context::GetCurrent()->Global(), arraysize(argv), argv);
RefCountedV8Function callback = g_handlers[request()->url().scheme()];
v8::Handle<v8::Value> result = callback->NewHandle(node_isolate)->Call(
v8::Context::GetCurrent()->Global(), 1, argv);
// Determine the type of the job we are going to create.
if (result->IsString()) {
@@ -180,14 +182,15 @@ class CustomProtocolHandler : public ProtocolHandler {
} // namespace
// static
v8::Handle<v8::Value> Protocol::RegisterProtocol(const v8::Arguments& args) {
void Protocol::RegisterProtocol(
const v8::FunctionCallbackInfo<v8::Value>& args) {
std::string scheme;
v8::Persistent<v8::Function> callback;
RefCountedV8Function callback;
if (!FromV8Arguments(args, &scheme, &callback))
return node::ThrowTypeError("Bad argument");
if (g_handlers.find(scheme) != g_handlers.end() ||
net::URLRequest::IsHandledProtocol(scheme))
GetRequestJobFactory()->IsHandledProtocol(scheme))
return node::ThrowError("The scheme is already registered");
if (AtomBrowserContext::Get()->url_request_context_getter() == NULL)
@@ -199,12 +202,11 @@ v8::Handle<v8::Value> Protocol::RegisterProtocol(const v8::Arguments& args) {
content::BrowserThread::PostTask(content::BrowserThread::IO,
FROM_HERE,
base::Bind(&RegisterProtocolInIO, scheme));
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Protocol::UnregisterProtocol(const v8::Arguments& args) {
void Protocol::UnregisterProtocol(
const v8::FunctionCallbackInfo<v8::Value>& args) {
std::string scheme;
if (!FromV8Arguments(args, &scheme))
return node::ThrowTypeError("Bad argument");
@@ -221,19 +223,23 @@ v8::Handle<v8::Value> Protocol::UnregisterProtocol(const v8::Arguments& args) {
content::BrowserThread::PostTask(content::BrowserThread::IO,
FROM_HERE,
base::Bind(&UnregisterProtocolInIO, scheme));
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Protocol::IsHandledProtocol(const v8::Arguments& args) {
return ToV8Value(net::URLRequest::IsHandledProtocol(FromV8Value(args[0])));
}
// static
v8::Handle<v8::Value> Protocol::InterceptProtocol(const v8::Arguments& args) {
void Protocol::IsHandledProtocol(
const v8::FunctionCallbackInfo<v8::Value>& args) {
std::string scheme;
v8::Persistent<v8::Function> callback;
if (!FromV8Arguments(args, &scheme))
return node::ThrowTypeError("Bad argument");
args.GetReturnValue().Set(GetRequestJobFactory()->IsHandledProtocol(scheme));
}
// static
void Protocol::InterceptProtocol(
const v8::FunctionCallbackInfo<v8::Value>& args) {
std::string scheme;
RefCountedV8Function callback;
if (!FromV8Arguments(args, &scheme, &callback))
return node::ThrowTypeError("Bad argument");
@@ -252,11 +258,11 @@ v8::Handle<v8::Value> Protocol::InterceptProtocol(const v8::Arguments& args) {
content::BrowserThread::PostTask(content::BrowserThread::IO,
FROM_HERE,
base::Bind(&InterceptProtocolInIO, scheme));
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Protocol::UninterceptProtocol(const v8::Arguments& args) {
void Protocol::UninterceptProtocol(
const v8::FunctionCallbackInfo<v8::Value>& args) {
std::string scheme;
if (!FromV8Arguments(args, &scheme))
return node::ThrowTypeError("Bad argument");
@@ -274,7 +280,6 @@ v8::Handle<v8::Value> Protocol::UninterceptProtocol(const v8::Arguments& args) {
FROM_HERE,
base::Bind(&UninterceptProtocolInIO,
scheme));
return v8::Undefined();
}
// static
@@ -361,14 +366,19 @@ void Protocol::UninterceptProtocolInIO(const std::string& scheme) {
// static
void Protocol::Initialize(v8::Handle<v8::Object> target) {
// Remember the protocol object, used for emitting event later.
g_protocol_object = v8::Persistent<v8::Object>::New(
node::node_isolate, target);
g_protocol_object.reset(target);
node::SetMethod(target, "registerProtocol", RegisterProtocol);
node::SetMethod(target, "unregisterProtocol", UnregisterProtocol);
node::SetMethod(target, "isHandledProtocol", IsHandledProtocol);
node::SetMethod(target, "interceptProtocol", InterceptProtocol);
node::SetMethod(target, "uninterceptProtocol", UninterceptProtocol);
#if defined(OS_LINUX)
// Make sure the job factory has been created.
AtomBrowserContext::Get()->url_request_context_getter()->
GetURLRequestContext();
#endif
NODE_SET_METHOD(target, "registerProtocol", RegisterProtocol);
NODE_SET_METHOD(target, "unregisterProtocol", UnregisterProtocol);
NODE_SET_METHOD(target, "isHandledProtocol", IsHandledProtocol);
NODE_SET_METHOD(target, "interceptProtocol", InterceptProtocol);
NODE_SET_METHOD(target, "uninterceptProtocol", UninterceptProtocol);
}
} // namespace api

View File

@@ -20,12 +20,16 @@ class Protocol {
static void Initialize(v8::Handle<v8::Object> target);
private:
static v8::Handle<v8::Value> RegisterProtocol(const v8::Arguments& args);
static v8::Handle<v8::Value> UnregisterProtocol(const v8::Arguments& args);
static v8::Handle<v8::Value> IsHandledProtocol(const v8::Arguments& args);
static void RegisterProtocol(const v8::FunctionCallbackInfo<v8::Value>& args);
static void UnregisterProtocol(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsHandledProtocol(
const v8::FunctionCallbackInfo<v8::Value>& args);
static v8::Handle<v8::Value> InterceptProtocol(const v8::Arguments& args);
static v8::Handle<v8::Value> UninterceptProtocol(const v8::Arguments& args);
static void InterceptProtocol(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void UninterceptProtocol(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void RegisterProtocolInIO(const std::string& scheme);
static void UnregisterProtocolInIO(const std::string& scheme);

View File

@@ -4,14 +4,17 @@
#include "browser/api/atom_api_window.h"
#include "base/process_util.h"
#include "base/bind.h"
#include "base/process/kill.h"
#include "browser/native_window.h"
#include "common/v8_conversions.h"
#include "common/v8/native_type_conversions.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/render_process_host.h"
#include "ui/gfx/point.h"
#include "ui/gfx/size.h"
#include "common/v8/node_common.h"
#include "vendor/node/src/node_buffer.h"
using content::NavigationController;
@@ -87,24 +90,20 @@ void Window::OnRendererCrashed() {
Emit("crashed");
}
void Window::OnCapturePageDone(v8::Persistent<v8::Function> callback,
void Window::OnCapturePageDone(const RefCountedV8Function& callback,
const std::vector<unsigned char>& data) {
v8::HandleScope scope;
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
// TODO(zcbenz): Use new Buffer API when we updated to node v0.12.x.
node::Buffer* buffer = node::Buffer::New(
v8::Local<v8::Value> buffer = node::Buffer::New(
reinterpret_cast<const char*>(data.data()),
data.size());
v8::Handle<v8::Value> arg = buffer->handle_;
callback->Call(v8::Context::GetCurrent()->Global(), 1, &arg);
callback.Dispose(v8::Isolate::GetCurrent());
callback->NewHandle(node_isolate)->Call(
v8::Context::GetCurrent()->Global(), 1, &buffer);
}
// static
v8::Handle<v8::Value> Window::New(const v8::Arguments &args) {
v8::HandleScope scope;
void Window::New(const v8::FunctionCallbackInfo<v8::Value>& args) {
if (!args.IsConstructCall())
return node::ThrowError("Require constructor call");
@@ -119,112 +118,85 @@ v8::Handle<v8::Value> Window::New(const v8::Arguments &args) {
// Give js code a chance to do initialization.
node::MakeCallback(args.This(), "_init", 0, NULL);
return args.This();
}
// static
v8::Handle<v8::Value> Window::Destroy(const v8::Arguments &args) {
void Window::Destroy(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
base::ProcessHandle handle = self->window_->GetRenderProcessHandle();
delete self;
// Check if the render process is terminated, it could happen that the render
// became a zombie.
if (!base::WaitForSingleProcess(handle,
base::TimeDelta::FromMilliseconds(500)))
base::KillProcess(handle, 0, true);
return v8::Undefined();
// Make sure the renderer process is terminated, it could happen that the
// renderer process became a zombie.
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(base::IgnoreResult(base::KillProcess), handle, 0, false),
base::TimeDelta::FromMilliseconds(5000));
}
// static
v8::Handle<v8::Value> Window::Close(const v8::Arguments &args) {
void Window::Close(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
self->window_->Close();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::Focus(const v8::Arguments &args) {
void Window::Focus(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
self->window_->Focus(args[0]->IsBoolean() ? args[0]->BooleanValue(): true);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::IsFocused(const v8::Arguments &args) {
void Window::IsFocused(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
return ToV8Value(self->window_->IsFocused());
args.GetReturnValue().Set(self->window_->IsFocused());
}
// static
v8::Handle<v8::Value> Window::Show(const v8::Arguments &args) {
void Window::Show(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
self->window_->Show();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::Hide(const v8::Arguments &args) {
void Window::Hide(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
self->window_->Hide();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::IsVisible(const v8::Arguments& args) {
void Window::IsVisible(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
return ToV8Value(self->window_->IsVisible());
return args.GetReturnValue().Set(self->window_->IsVisible());
}
// static
v8::Handle<v8::Value> Window::Maximize(const v8::Arguments &args) {
void Window::Maximize(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
self->window_->Maximize();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::Unmaximize(const v8::Arguments &args) {
void Window::Unmaximize(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
self->window_->Unmaximize();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::Minimize(const v8::Arguments &args) {
void Window::Minimize(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
self->window_->Minimize();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::Restore(const v8::Arguments &args) {
void Window::Restore(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
self->window_->Restore();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::SetFullscreen(const v8::Arguments &args) {
void Window::SetFullscreen(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
bool fs;
@@ -232,18 +204,16 @@ v8::Handle<v8::Value> Window::SetFullscreen(const v8::Arguments &args) {
return node::ThrowTypeError("Bad argument");
self->window_->SetFullscreen(fs);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::IsFullscreen(const v8::Arguments &args) {
void Window::IsFullscreen(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
return ToV8Value(self->window_->IsFullscreen());
args.GetReturnValue().Set(self->window_->IsFullscreen());
}
// static
v8::Handle<v8::Value> Window::SetSize(const v8::Arguments &args) {
void Window::SetSize(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
int width, height;
@@ -251,11 +221,10 @@ v8::Handle<v8::Value> Window::SetSize(const v8::Arguments &args) {
return node::ThrowTypeError("Bad argument");
self->window_->SetSize(gfx::Size(width, height));
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::GetSize(const v8::Arguments &args) {
void Window::GetSize(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
gfx::Size size = self->window_->GetSize();
@@ -263,11 +232,11 @@ v8::Handle<v8::Value> Window::GetSize(const v8::Arguments &args) {
ret->Set(0, ToV8Value(size.width()));
ret->Set(1, ToV8Value(size.height()));
return ret;
args.GetReturnValue().Set(ret);
}
// static
v8::Handle<v8::Value> Window::SetMinimumSize(const v8::Arguments &args) {
void Window::SetMinimumSize(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
int width, height;
@@ -275,11 +244,10 @@ v8::Handle<v8::Value> Window::SetMinimumSize(const v8::Arguments &args) {
return node::ThrowTypeError("Bad argument");
self->window_->SetMinimumSize(gfx::Size(width, height));
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::GetMinimumSize(const v8::Arguments &args) {
void Window::GetMinimumSize(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
gfx::Size size = self->window_->GetMinimumSize();
@@ -287,24 +255,22 @@ v8::Handle<v8::Value> Window::GetMinimumSize(const v8::Arguments &args) {
ret->Set(0, ToV8Value(size.width()));
ret->Set(1, ToV8Value(size.height()));
return ret;
args.GetReturnValue().Set(ret);
}
// static
v8::Handle<v8::Value> Window::SetMaximumSize(const v8::Arguments &args) {
void Window::SetMaximumSize(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
int width, height;
if (!FromV8Arguments(args, &width, &height))
return node::ThrowTypeError("Bad argument");
self->window_->SetMaximumSize(gfx::Size(width, height));
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::GetMaximumSize(const v8::Arguments &args) {
void Window::GetMaximumSize(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
gfx::Size size = self->window_->GetMaximumSize();
@@ -312,11 +278,11 @@ v8::Handle<v8::Value> Window::GetMaximumSize(const v8::Arguments &args) {
ret->Set(0, ToV8Value(size.width()));
ret->Set(1, ToV8Value(size.height()));
return ret;
args.GetReturnValue().Set(ret);
}
// static
v8::Handle<v8::Value> Window::SetResizable(const v8::Arguments &args) {
void Window::SetResizable(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
bool resizable;
@@ -324,18 +290,16 @@ v8::Handle<v8::Value> Window::SetResizable(const v8::Arguments &args) {
return node::ThrowTypeError("Bad argument");
self->window_->SetResizable(resizable);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::IsResizable(const v8::Arguments &args) {
void Window::IsResizable(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
return ToV8Value(self->window_->IsResizable());
args.GetReturnValue().Set(self->window_->IsResizable());
}
// static
v8::Handle<v8::Value> Window::SetAlwaysOnTop(const v8::Arguments &args) {
void Window::SetAlwaysOnTop(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
bool top;
@@ -343,27 +307,22 @@ v8::Handle<v8::Value> Window::SetAlwaysOnTop(const v8::Arguments &args) {
return node::ThrowTypeError("Bad argument");
self->window_->SetAlwaysOnTop(top);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::IsAlwaysOnTop(const v8::Arguments &args) {
void Window::IsAlwaysOnTop(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
return ToV8Value(self->window_->IsAlwaysOnTop());
args.GetReturnValue().Set(self->window_->IsAlwaysOnTop());
}
// static
v8::Handle<v8::Value> Window::Center(const v8::Arguments &args) {
void Window::Center(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
self->window_->Center();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::SetPosition(const v8::Arguments &args) {
void Window::SetPosition(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
int x, y;
@@ -371,11 +330,10 @@ v8::Handle<v8::Value> Window::SetPosition(const v8::Arguments &args) {
return node::ThrowTypeError("Bad argument");
self->window_->SetPosition(gfx::Point(x, y));
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::GetPosition(const v8::Arguments &args) {
void Window::GetPosition(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
gfx::Point pos = self->window_->GetPosition();
@@ -383,11 +341,11 @@ v8::Handle<v8::Value> Window::GetPosition(const v8::Arguments &args) {
ret->Set(0, ToV8Value(pos.x()));
ret->Set(1, ToV8Value(pos.y()));
return ret;
args.GetReturnValue().Set(ret);
}
// static
v8::Handle<v8::Value> Window::SetTitle(const v8::Arguments &args) {
void Window::SetTitle(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
std::string title;
@@ -395,27 +353,23 @@ v8::Handle<v8::Value> Window::SetTitle(const v8::Arguments &args) {
return node::ThrowTypeError("Bad argument");
self->window_->SetTitle(title);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::GetTitle(const v8::Arguments &args) {
void Window::GetTitle(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
return ToV8Value(self->window_->GetTitle());
args.GetReturnValue().Set(ToV8Value(self->window_->GetTitle()));
}
// static
v8::Handle<v8::Value> Window::FlashFrame(const v8::Arguments &args) {
void Window::FlashFrame(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
self->window_->FlashFrame(
args[0]->IsBoolean() ? args[0]->BooleanValue(): true);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::SetKiosk(const v8::Arguments &args) {
void Window::SetKiosk(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
bool kiosk;
@@ -423,42 +377,34 @@ v8::Handle<v8::Value> Window::SetKiosk(const v8::Arguments &args) {
return node::ThrowTypeError("Bad argument");
self->window_->SetKiosk(kiosk);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::IsKiosk(const v8::Arguments &args) {
void Window::IsKiosk(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
return ToV8Value(self->window_->IsKiosk());
args.GetReturnValue().Set(self->window_->IsKiosk());
}
// static
v8::Handle<v8::Value> Window::OpenDevTools(const v8::Arguments &args) {
void Window::OpenDevTools(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
self->window_->OpenDevTools();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::CloseDevTools(const v8::Arguments &args) {
void Window::CloseDevTools(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
self->window_->CloseDevTools();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::IsDevToolsOpened(const v8::Arguments& args) {
void Window::IsDevToolsOpened(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
return ToV8Value(self->window_->IsDevToolsOpened());
args.GetReturnValue().Set(self->window_->IsDevToolsOpened());
}
// static
v8::Handle<v8::Value> Window::InspectElement(const v8::Arguments& args) {
void Window::InspectElement(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
int x, y;
@@ -466,39 +412,38 @@ v8::Handle<v8::Value> Window::InspectElement(const v8::Arguments& args) {
return node::ThrowTypeError("Bad argument");
self->window_->InspectElement(x, y);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::FocusOnWebView(const v8::Arguments &args) {
void Window::DebugDevTools(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
self->window_->DebugDevTools();
}
// static
void Window::FocusOnWebView(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
self->window_->FocusOnWebView();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::BlurWebView(const v8::Arguments &args) {
void Window::BlurWebView(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
self->window_->BlurWebView();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::IsWebViewFocused(const v8::Arguments& args) {
void Window::IsWebViewFocused(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
return ToV8Value(self->window_->IsWebViewFocused());
args.GetReturnValue().Set(self->window_->IsWebViewFocused());
}
// static
v8::Handle<v8::Value> Window::CapturePage(const v8::Arguments& args) {
void Window::CapturePage(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
gfx::Rect rect;
v8::Persistent<v8::Function> callback;
RefCountedV8Function callback;
if (!FromV8Arguments(args, &rect, &callback) &&
!FromV8Arguments(args, &callback))
return node::ThrowTypeError("Bad argument");
@@ -506,64 +451,57 @@ v8::Handle<v8::Value> Window::CapturePage(const v8::Arguments& args) {
self->window_->CapturePage(rect, base::Bind(&Window::OnCapturePageDone,
base::Unretained(self),
callback));
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::GetPageTitle(const v8::Arguments &args) {
void Window::GetPageTitle(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
return ToV8Value(self->window_->GetWebContents()->GetTitle());
args.GetReturnValue().Set(ToV8Value(
self->window_->GetWebContents()->GetTitle()));
}
// static
v8::Handle<v8::Value> Window::IsLoading(const v8::Arguments &args) {
void Window::IsLoading(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
return ToV8Value(self->window_->GetWebContents()->IsLoading());
args.GetReturnValue().Set(self->window_->GetWebContents()->IsLoading());
}
// static
v8::Handle<v8::Value> Window::IsWaitingForResponse(const v8::Arguments &args) {
void Window::IsWaitingForResponse(
const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
return ToV8Value(self->window_->GetWebContents()->IsWaitingForResponse());
args.GetReturnValue().Set(
self->window_->GetWebContents()->IsWaitingForResponse());
}
// static
v8::Handle<v8::Value> Window::Stop(const v8::Arguments &args) {
void Window::Stop(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
self->window_->GetWebContents()->Stop();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::GetRoutingID(const v8::Arguments &args) {
void Window::GetRoutingID(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
return ToV8Value(self->window_->GetWebContents()->GetRoutingID());
args.GetReturnValue().Set(self->window_->GetWebContents()->GetRoutingID());
}
// static
v8::Handle<v8::Value> Window::GetProcessID(const v8::Arguments &args) {
void Window::GetProcessID(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
return ToV8Value(
args.GetReturnValue().Set(
self->window_->GetWebContents()->GetRenderProcessHost()->GetID());
}
// static
v8::Handle<v8::Value> Window::IsCrashed(const v8::Arguments &args) {
void Window::IsCrashed(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
return ToV8Value(self->window_->GetWebContents()->IsCrashed());
args.GetReturnValue().Set(self->window_->GetWebContents()->IsCrashed());
}
// static
v8::Handle<v8::Value> Window::LoadURL(const v8::Arguments &args) {
void Window::LoadURL(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
GURL url;
@@ -577,12 +515,10 @@ v8::Handle<v8::Value> Window::LoadURL(const v8::Arguments &args) {
params.transition_type = content::PAGE_TRANSITION_TYPED;
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
controller.LoadURLWithParams(params);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::GetURL(const v8::Arguments &args) {
void Window::GetURL(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
NavigationController& controller =
@@ -591,31 +527,31 @@ v8::Handle<v8::Value> Window::GetURL(const v8::Arguments &args) {
if (controller.GetActiveEntry())
url = controller.GetActiveEntry()->GetVirtualURL();
return ToV8Value(url);
args.GetReturnValue().Set(ToV8Value(url));
}
// static
v8::Handle<v8::Value> Window::CanGoBack(const v8::Arguments &args) {
void Window::CanGoBack(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
NavigationController& controller =
self->window_->GetWebContents()->GetController();
return ToV8Value(controller.CanGoBack());
args.GetReturnValue().Set(controller.CanGoBack());
}
// static
v8::Handle<v8::Value> Window::CanGoForward(const v8::Arguments &args) {
void Window::CanGoForward(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
NavigationController& controller =
self->window_->GetWebContents()->GetController();
return ToV8Value(controller.CanGoForward());
args.GetReturnValue().Set(controller.CanGoForward());
}
// static
v8::Handle<v8::Value> Window::CanGoToOffset(const v8::Arguments &args) {
void Window::CanGoToOffset(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
int offset;
@@ -625,33 +561,29 @@ v8::Handle<v8::Value> Window::CanGoToOffset(const v8::Arguments &args) {
NavigationController& controller =
self->window_->GetWebContents()->GetController();
return ToV8Value(controller.CanGoToOffset(offset));
args.GetReturnValue().Set(controller.CanGoToOffset(offset));
}
// static
v8::Handle<v8::Value> Window::GoBack(const v8::Arguments &args) {
void Window::GoBack(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
NavigationController& controller =
self->window_->GetWebContents()->GetController();
controller.GoBack();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::GoForward(const v8::Arguments &args) {
void Window::GoForward(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
NavigationController& controller =
self->window_->GetWebContents()->GetController();
controller.GoForward();
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::GoToIndex(const v8::Arguments &args) {
void Window::GoToIndex(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
int index;
@@ -661,12 +593,10 @@ v8::Handle<v8::Value> Window::GoToIndex(const v8::Arguments &args) {
NavigationController& controller =
self->window_->GetWebContents()->GetController();
controller.GoToIndex(index);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::GoToOffset(const v8::Arguments &args) {
void Window::GoToOffset(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
int offset;
@@ -676,37 +606,30 @@ v8::Handle<v8::Value> Window::GoToOffset(const v8::Arguments &args) {
NavigationController& controller =
self->window_->GetWebContents()->GetController();
controller.GoToOffset(offset);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::Reload(const v8::Arguments &args) {
void Window::Reload(const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
NavigationController& controller =
self->window_->GetWebContents()->GetController();
controller.Reload(args[0]->IsBoolean() ? args[0]->BooleanValue(): false);
return v8::Undefined();
}
// static
v8::Handle<v8::Value> Window::ReloadIgnoringCache(const v8::Arguments &args) {
void Window::ReloadIgnoringCache(
const v8::FunctionCallbackInfo<v8::Value>& args) {
UNWRAP_WINDOW_AND_CHECK;
NavigationController& controller =
self->window_->GetWebContents()->GetController();
controller.ReloadIgnoringCache(
args[0]->IsBoolean() ? args[0]->BooleanValue(): false);
return v8::Undefined();
}
// static
void Window::Initialize(v8::Handle<v8::Object> target) {
v8::HandleScope scope;
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(Window::New);
t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(v8::String::NewSymbol("BrowserWindow"));
@@ -746,6 +669,7 @@ void Window::Initialize(v8::Handle<v8::Object> target) {
NODE_SET_PROTOTYPE_METHOD(t, "closeDevTools", CloseDevTools);
NODE_SET_PROTOTYPE_METHOD(t, "isDevToolsOpened", IsDevToolsOpened);
NODE_SET_PROTOTYPE_METHOD(t, "inspectElement", InspectElement);
NODE_SET_PROTOTYPE_METHOD(t, "debugDevTools", DebugDevTools);
NODE_SET_PROTOTYPE_METHOD(t, "focusOnWebView", FocusOnWebView);
NODE_SET_PROTOTYPE_METHOD(t, "blurWebView", BlurWebView);
NODE_SET_PROTOTYPE_METHOD(t, "isWebViewFocused", IsWebViewFocused);

View File

@@ -8,8 +8,9 @@
#include <vector>
#include "base/memory/scoped_ptr.h"
#include "browser/api/atom_api_event_emitter.h"
#include "browser/native_window_observer.h"
#include "common/api/atom_api_event_emitter.h"
#include "common/v8/scoped_persistent.h"
namespace base {
class DictionaryValue;
@@ -47,73 +48,76 @@ class Window : public EventEmitter,
virtual void OnRendererCrashed() OVERRIDE;
private:
static v8::Handle<v8::Value> New(const v8::Arguments &args);
static v8::Handle<v8::Value> Destroy(const v8::Arguments &args);
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Destroy(const v8::FunctionCallbackInfo<v8::Value>& args);
// APIs for NativeWindow.
static v8::Handle<v8::Value> Close(const v8::Arguments &args);
static v8::Handle<v8::Value> Focus(const v8::Arguments &args);
static v8::Handle<v8::Value> IsFocused(const v8::Arguments &args);
static v8::Handle<v8::Value> Show(const v8::Arguments &args);
static v8::Handle<v8::Value> Hide(const v8::Arguments &args);
static v8::Handle<v8::Value> IsVisible(const v8::Arguments &args);
static v8::Handle<v8::Value> Maximize(const v8::Arguments &args);
static v8::Handle<v8::Value> Unmaximize(const v8::Arguments &args);
static v8::Handle<v8::Value> Minimize(const v8::Arguments &args);
static v8::Handle<v8::Value> Restore(const v8::Arguments &args);
static v8::Handle<v8::Value> SetFullscreen(const v8::Arguments &args);
static v8::Handle<v8::Value> IsFullscreen(const v8::Arguments &args);
static v8::Handle<v8::Value> SetSize(const v8::Arguments &args);
static v8::Handle<v8::Value> GetSize(const v8::Arguments &args);
static v8::Handle<v8::Value> SetMinimumSize(const v8::Arguments &args);
static v8::Handle<v8::Value> GetMinimumSize(const v8::Arguments &args);
static v8::Handle<v8::Value> SetMaximumSize(const v8::Arguments &args);
static v8::Handle<v8::Value> GetMaximumSize(const v8::Arguments &args);
static v8::Handle<v8::Value> SetResizable(const v8::Arguments &args);
static v8::Handle<v8::Value> IsResizable(const v8::Arguments &args);
static v8::Handle<v8::Value> SetAlwaysOnTop(const v8::Arguments &args);
static v8::Handle<v8::Value> IsAlwaysOnTop(const v8::Arguments &args);
static v8::Handle<v8::Value> Center(const v8::Arguments &args);
static v8::Handle<v8::Value> SetPosition(const v8::Arguments &args);
static v8::Handle<v8::Value> GetPosition(const v8::Arguments &args);
static v8::Handle<v8::Value> SetTitle(const v8::Arguments &args);
static v8::Handle<v8::Value> GetTitle(const v8::Arguments &args);
static v8::Handle<v8::Value> FlashFrame(const v8::Arguments &args);
static v8::Handle<v8::Value> SetKiosk(const v8::Arguments &args);
static v8::Handle<v8::Value> IsKiosk(const v8::Arguments &args);
static v8::Handle<v8::Value> OpenDevTools(const v8::Arguments &args);
static v8::Handle<v8::Value> CloseDevTools(const v8::Arguments &args);
static v8::Handle<v8::Value> IsDevToolsOpened(const v8::Arguments &args);
static v8::Handle<v8::Value> InspectElement(const v8::Arguments &args);
static v8::Handle<v8::Value> FocusOnWebView(const v8::Arguments &args);
static v8::Handle<v8::Value> BlurWebView(const v8::Arguments &args);
static v8::Handle<v8::Value> IsWebViewFocused(const v8::Arguments& args);
static v8::Handle<v8::Value> CapturePage(const v8::Arguments& args);
static void Close(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Focus(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsFocused(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Show(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Hide(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsVisible(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Maximize(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Unmaximize(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Minimize(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Restore(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetFullscreen(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsFullscreen(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetSize(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetSize(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetMinimumSize(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetMinimumSize(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetMaximumSize(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetMaximumSize(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetResizable(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsResizable(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetAlwaysOnTop(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsAlwaysOnTop(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Center(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetPosition(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetPosition(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetTitle(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetTitle(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FlashFrame(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetKiosk(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsKiosk(const v8::FunctionCallbackInfo<v8::Value>& args);
static void OpenDevTools(const v8::FunctionCallbackInfo<v8::Value>& args);
static void CloseDevTools(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsDevToolsOpened(const v8::FunctionCallbackInfo<v8::Value>& args);
static void InspectElement(const v8::FunctionCallbackInfo<v8::Value>& args);
static void DebugDevTools(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FocusOnWebView(const v8::FunctionCallbackInfo<v8::Value>& args);
static void BlurWebView(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsWebViewFocused(const v8::FunctionCallbackInfo<v8::Value>& args);
static void CapturePage(const v8::FunctionCallbackInfo<v8::Value>& args);
// APIs for WebContents.
static v8::Handle<v8::Value> GetPageTitle(const v8::Arguments &args);
static v8::Handle<v8::Value> IsLoading(const v8::Arguments &args);
static v8::Handle<v8::Value> IsWaitingForResponse(const v8::Arguments &args);
static v8::Handle<v8::Value> Stop(const v8::Arguments &args);
static v8::Handle<v8::Value> GetRoutingID(const v8::Arguments &args);
static v8::Handle<v8::Value> GetProcessID(const v8::Arguments &args);
static v8::Handle<v8::Value> IsCrashed(const v8::Arguments &args);
static void GetPageTitle(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsLoading(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsWaitingForResponse(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void Stop(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetRoutingID(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetProcessID(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsCrashed(const v8::FunctionCallbackInfo<v8::Value>& args);
// APIs for NavigationController.
static v8::Handle<v8::Value> LoadURL(const v8::Arguments &args);
static v8::Handle<v8::Value> GetURL(const v8::Arguments &args);
static v8::Handle<v8::Value> CanGoBack(const v8::Arguments &args);
static v8::Handle<v8::Value> CanGoForward(const v8::Arguments &args);
static v8::Handle<v8::Value> CanGoToOffset(const v8::Arguments &args);
static v8::Handle<v8::Value> GoBack(const v8::Arguments &args);
static v8::Handle<v8::Value> GoForward(const v8::Arguments &args);
static v8::Handle<v8::Value> GoToIndex(const v8::Arguments &args);
static v8::Handle<v8::Value> GoToOffset(const v8::Arguments &args);
static v8::Handle<v8::Value> Reload(const v8::Arguments &args);
static v8::Handle<v8::Value> ReloadIgnoringCache(const v8::Arguments &args);
static void LoadURL(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetURL(const v8::FunctionCallbackInfo<v8::Value>& args);
static void CanGoBack(const v8::FunctionCallbackInfo<v8::Value>& args);
static void CanGoForward(const v8::FunctionCallbackInfo<v8::Value>& args);
static void CanGoToOffset(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GoBack(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GoForward(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GoToIndex(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GoToOffset(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Reload(const v8::FunctionCallbackInfo<v8::Value>& args);
static void ReloadIgnoringCache(
const v8::FunctionCallbackInfo<v8::Value>& args);
// Called when capturePage is done.
void OnCapturePageDone(v8::Persistent<v8::Function> callback,
void OnCapturePageDone(const RefCountedV8Function& callback,
const std::vector<unsigned char>& data);
scoped_ptr<NativeWindow> window_;

View File

@@ -8,13 +8,10 @@
#include "base/logging.h"
#include "browser/api/atom_api_event.h"
#include "common/v8_conversions.h"
#include "common/v8/native_type_conversions.h"
#include "content/public/browser/browser_thread.h"
#include "vendor/node/src/node.h"
#include "vendor/node/src/node_internals.h"
using content::V8ValueConverter;
using node::node_isolate;
#include "common/v8/node_common.h"
namespace atom {
@@ -24,31 +21,14 @@ AtomBrowserBindings::AtomBrowserBindings() {
AtomBrowserBindings::~AtomBrowserBindings() {
}
void AtomBrowserBindings::AfterLoad() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
v8::HandleScope scope;
v8::Handle<v8::Object> global = node::g_context->Global();
v8::Handle<v8::Object> atom =
global->Get(v8::String::New("__atom"))->ToObject();
DCHECK(!atom.IsEmpty());
browser_main_parts_ = v8::Persistent<v8::Object>::New(
node_isolate,
atom->Get(v8::String::New("browserMainParts"))->ToObject());
DCHECK(!browser_main_parts_.IsEmpty());
}
void AtomBrowserBindings::OnRendererMessage(int process_id,
int routing_id,
const string16& channel,
const base::ListValue& args) {
v8::HandleScope scope;
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
v8::Handle<v8::Context> context = v8::Context::GetCurrent();
scoped_ptr<V8ValueConverter> converter(new V8ValueConverterImpl());
scoped_ptr<V8ValueConverter> converter(new V8ValueConverter);
// process.emit(channel, 'message', process_id, routing_id);
std::vector<v8::Handle<v8::Value>> arguments;
@@ -56,17 +36,20 @@ void AtomBrowserBindings::OnRendererMessage(int process_id,
arguments.push_back(ToV8Value(channel));
const base::Value* value;
if (args.Get(0, &value))
arguments.push_back(converter->ToV8Value(value, context));
arguments.push_back(converter->ToV8Value(value, global_env->context()));
arguments.push_back(v8::Integer::New(process_id));
arguments.push_back(v8::Integer::New(routing_id));
for (size_t i = 1; i < args.GetSize(); i++) {
const base::Value* value;
if (args.Get(i, &value))
arguments.push_back(converter->ToV8Value(value, context));
arguments.push_back(converter->ToV8Value(value, global_env->context()));
}
node::MakeCallback(node::process, "emit", arguments.size(), &arguments[0]);
node::MakeCallback(global_env->process_object(),
"emit",
arguments.size(),
&arguments[0]);
}
void AtomBrowserBindings::OnRendererMessageSync(
@@ -76,11 +59,10 @@ void AtomBrowserBindings::OnRendererMessageSync(
const base::ListValue& args,
NativeWindow* sender,
IPC::Message* message) {
v8::HandleScope scope;
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
v8::Handle<v8::Context> context = v8::Context::GetCurrent();
scoped_ptr<V8ValueConverter> converter(new V8ValueConverterImpl());
scoped_ptr<V8ValueConverter> converter(new V8ValueConverter);
// Create the event object.
v8::Handle<v8::Object> event = api::Event::CreateV8Object();
@@ -92,7 +74,7 @@ void AtomBrowserBindings::OnRendererMessageSync(
arguments.push_back(ToV8Value(channel));
const base::Value* value;
if (args.Get(0, &value))
arguments.push_back(converter->ToV8Value(value, context));
arguments.push_back(converter->ToV8Value(value, global_env->context()));
arguments.push_back(event);
arguments.push_back(v8::Integer::New(process_id));
arguments.push_back(v8::Integer::New(routing_id));
@@ -100,10 +82,13 @@ void AtomBrowserBindings::OnRendererMessageSync(
for (size_t i = 1; i < args.GetSize(); i++) {
const base::Value* value;
if (args.Get(i, &value))
arguments.push_back(converter->ToV8Value(value, context));
arguments.push_back(converter->ToV8Value(value, global_env->context()));
}
node::MakeCallback(node::process, "emit", arguments.size(), &arguments[0]);
node::MakeCallback(global_env->process_object(),
"emit",
arguments.size(),
&arguments[0]);
}
} // namespace atom

View File

@@ -5,8 +5,9 @@
#ifndef ATOM_BROWSER_API_ATOM_BROWSER_BINDINGS_
#define ATOM_BROWSER_API_ATOM_BROWSER_BINDINGS_
#include "base/string16.h"
#include "base/strings/string16.h"
#include "common/api/atom_bindings.h"
#include "common/v8/scoped_persistent.h"
namespace base {
class ListValue;
@@ -25,9 +26,6 @@ class AtomBrowserBindings : public AtomBindings {
AtomBrowserBindings();
virtual ~AtomBrowserBindings();
// Called when the node.js main script has been loaded.
virtual void AfterLoad();
// Called when received a message from renderer.
void OnRendererMessage(int process_id,
int routing_id,
@@ -42,14 +40,7 @@ class AtomBrowserBindings : public AtomBindings {
NativeWindow* sender,
IPC::Message* message);
// The require('atom').browserMainParts object.
v8::Handle<v8::Object> browser_main_parts() {
return browser_main_parts_;
}
private:
v8::Persistent<v8::Object> browser_main_parts_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserBindings);
};

View File

@@ -1,6 +1,7 @@
bindings = process.atomBinding 'app'
EventEmitter = require('events').EventEmitter
bindings = process.atomBinding 'app'
Application = bindings.Application
Application::__proto__ = EventEmitter.prototype
@@ -9,9 +10,6 @@ app = new Application
app.getHomeDir = ->
process.env[if process.platform is 'win32' then 'USERPROFILE' else 'HOME']
app.getBrowserWindows = ->
require('../../atom/objects-registry.js').getAllWindows()
app.setApplicationMenu = (menu) ->
require('menu').setApplicationMenu menu
@@ -24,10 +22,13 @@ app.commandLine =
if process.platform is 'darwin'
app.dock =
bounce: (type = 'informational') -> bindings.dockBounce type
bounce: (type='informational') -> bindings.dockBounce type
cancelBounce: bindings.dockCancelBounce
setBadge: bindings.dockSetBadgeText
getBadge: bindings.dockGetBadgeText
# Support old event name.
app.once 'ready', -> app.emit 'finish-launching'
# Only one App object pemitted.
module.exports = app

View File

@@ -1 +1,6 @@
module.exports = global.__atom
module.exports =
browserMainParts:
preMainMessageLoopRun: ->
setImmediate ->
module.exports.browserMainParts.preMainMessageLoopRun()

View File

@@ -4,9 +4,22 @@ EventEmitter = require('events').EventEmitter
AutoUpdater::__proto__ = EventEmitter.prototype
autoUpdater = new AutoUpdater
autoUpdater.on 'will-install-update-raw', (event, version) ->
@emit 'will-install-update', event, version, => @continueUpdate()
autoUpdater.on 'ready-for-update-on-quit-raw', (event, version) ->
@emit 'ready-for-update-on-quit', event, version, => @quitAndInstall()
autoUpdater.on 'update-downloaded-raw', (args...) ->
args[3] = new Date(args[3]) # releaseDate
@emit 'update-downloaded', args..., => @quitAndInstall()
autoUpdater.quitAndInstall = ->
# If we don't have any window then quitAndInstall immediately.
BrowserWindow = require 'browser-window'
windows = BrowserWindow.getAllWindows()
if windows.length is 0
AutoUpdater::quitAndInstall.call this
return
# Do the restart after all windows have been closed.
app = require 'app'
app.removeAllListeners 'window-all-closed'
app.once 'window-all-closed', AutoUpdater::quitAndInstall.bind(this)
win.close() for win in windows
module.exports = autoUpdater

View File

@@ -1,16 +1,27 @@
EventEmitter = require('events').EventEmitter
IDWeakMap = require 'id-weak-map'
app = require 'app'
v8Util = process.atomBinding 'v8_util'
BrowserWindow = process.atomBinding('window').BrowserWindow
BrowserWindow::__proto__ = EventEmitter.prototype
# Store all created windows in the weak map.
BrowserWindow.windows = new IDWeakMap
BrowserWindow::_init = ->
# Simulate the application menu on platforms other than OS X.
if process.platform isnt 'darwin'
menu = app.getApplicationMenu()
@setMenu menu if menu?
# Remember the window.
id = BrowserWindow.windows.add this
# Remove the window from weak map immediately when it's destroyed, since we
# could be iterating windows before GC happended.
@once 'destroyed', ->
BrowserWindow.windows.remove id if BrowserWindow.windows.has id
# Tell the rpc server that a render view has been deleted and we need to
# release all objects owned by it.
@on 'render-view-deleted', (event, processId, routingId) ->
@@ -23,19 +34,24 @@ BrowserWindow::restart = ->
@loadUrl(@getUrl())
BrowserWindow::setMenu = (menu) ->
throw new Error('BrowserWindow.setMenu is only available on Windows') unless process.platform is 'win32'
if process.platform is 'darwin'
throw new Error('BrowserWindow.setMenu is not available on OS X')
throw new TypeError('Invalid menu') unless menu?.constructor?.name is 'Menu'
@menu = menu # Keep a reference of menu in case of GC.
@menu.attachToWindow this
BrowserWindow.getAllWindows = ->
windows = BrowserWindow.windows
windows.get key for key in windows.keys()
BrowserWindow.getFocusedWindow = ->
windows = app.getBrowserWindows()
windows = BrowserWindow.getAllWindows()
return window for window in windows when window.isFocused()
BrowserWindow.fromProcessIdAndRoutingId = (processId, routingId) ->
windows = app.getBrowserWindows()
windows = BrowserWindow.getAllWindows()
return window for window in windows when window.getProcessId() == processId and
window.getRoutingId() == routingId

View File

@@ -5,6 +5,7 @@ sendWrap = (channel, processId, routingId, args...) ->
BrowserWindow = require 'browser-window'
if processId?.constructor is BrowserWindow
window = processId
args = [routingId, args...]
processId = window.getProcessId()
routingId = window.getRoutingId()

View File

@@ -1,9 +1,7 @@
BrowserWindow = require 'browser-window'
EventEmitter = require('events').EventEmitter
IDWeakMap = require 'id-weak-map'
MenuItem = require 'menu-item'
app = require 'app'
bindings = process.atomBinding 'menu'
Menu = bindings.Menu
@@ -52,7 +50,7 @@ Menu.setApplicationMenu = (menu) ->
if process.platform is 'darwin'
bindings.setApplicationMenu menu
else
windows = app.getBrowserWindows()
windows = BrowserWindow.getAllWindows()
w.setMenu menu for w in windows
Menu.getApplicationMenu = -> applicationMenu

View File

@@ -1,73 +0,0 @@
fs = require 'fs'
path = require 'path'
if process.platform is 'win32'
# Redirect node's console to use our own implementations, since node can not
# handle output when running as GUI program.
console.log = console.error = console.warn = process.log
process.stdout.write = process.stderr.write = process.log
# Always returns EOF for stdin stream.
Readable = require('stream').Readable
stdin = new Readable
stdin.push null
process.__defineGetter__ 'stdin', -> stdin
# Provide default Content API implementations.
atom = {}
atom.browserMainParts =
preMainMessageLoopRun: ->
# This is the start of the whole application, usually we should initialize
# the main window here.
# Store atom object in global scope, apps can just override methods of it to
# implement various logics.
global.__atom = atom
# Add browser/api/lib to require's search paths,
# which contains javascript part of Atom's built-in libraries.
globalPaths = require('module').globalPaths
globalPaths.push path.join process.resourcesPath, 'browser', 'api', 'lib'
# And also common/api/lib
globalPaths.push path.join process.resourcesPath, 'common', 'api', 'lib'
# Don't quit on fatal error.
process.on 'uncaughtException', (error) ->
# Show error in GUI.
message = error.stack ? "#{error.name}: #{error.message}"
require('dialog').showMessageBox
type: 'warning'
title: 'An javascript error occured in the browser'
message: 'uncaughtException'
detail: message
buttons: ['OK']
# Load the RPC server.
require './rpc-server.js'
# Now we try to load app's package.json.
packageJson = null
packagePath = path.join process.resourcesPath, 'app'
try
# First we try to load process.resourcesPath/app
packageJson = JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json')))
catch error
# If not found then we load browser/default_app
packagePath = path.join process.resourcesPath, 'browser', 'default_app'
packageJson = JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json')))
# Set application's version.
app = require 'app'
app.setVersion packageJson.version if packageJson.version?
# Set application's name.
if packageJson.productName?
app.setName packageJson.productName
else if packageJson.name?
app.setName packageJson.name
# Finally load app's main.js and transfer control to C++.
require path.join(packagePath, packageJson.main)

View File

@@ -4,14 +4,39 @@
#include "browser/atom_browser_client.h"
#include "base/command_line.h"
#include "browser/atom_browser_context.h"
#include "browser/atom_browser_main_parts.h"
#include "browser/native_window.h"
#include "browser/net/atom_url_request_context_getter.h"
#include "webkit/glue/webpreferences.h"
#include "browser/window_list.h"
#include "common/options_switches.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
#include "webkit/common/webpreferences.h"
namespace atom {
AtomBrowserClient::AtomBrowserClient() {
namespace {
struct FindByProcessId {
explicit FindByProcessId(int child_process_id)
: child_process_id_(child_process_id) {
}
bool operator() (NativeWindow* const window) {
int id = window->GetWebContents()->GetRenderProcessHost()->GetID();
return id == child_process_id_;
}
int child_process_id_;
};
} // namespace
AtomBrowserClient::AtomBrowserClient()
: dying_render_process_(NULL) {
}
AtomBrowserClient::~AtomBrowserClient() {
@@ -50,8 +75,42 @@ bool AtomBrowserClient::ShouldSwapProcessesForNavigation(
content::SiteInstance* site_instance,
const GURL& current_url,
const GURL& new_url) {
// Restart renderer process if navigating to the same url.
return current_url == new_url;
if (site_instance->HasProcess())
dying_render_process_ = site_instance->GetProcess();
// Restart renderer process for all navigations.
return true;
}
void AtomBrowserClient::AppendExtraCommandLineSwitches(
CommandLine* command_line,
int child_process_id) {
WindowList* list = WindowList::GetInstance();
NativeWindow* window = NULL;
// Find the owner of this child process.
WindowList::const_iterator iter = std::find_if(
list->begin(), list->end(), FindByProcessId(child_process_id));
if (iter != list->end())
window = *iter;
// If the render process is a newly started one, which means the window still
// uses the old going-to-be-swapped render process, then we try to find the
// window from the swapped render process.
if (window == NULL && dying_render_process_ != NULL) {
child_process_id = dying_render_process_->GetID();
WindowList::const_iterator iter = std::find_if(
list->begin(), list->end(), FindByProcessId(child_process_id));
if (iter != list->end())
window = *iter;
}
// Append --node-integration to renderer process.
if (window != NULL)
command_line->AppendSwitchASCII(switches::kNodeIntegration,
window->node_integration());
dying_render_process_ = NULL;
}
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(

View File

@@ -25,11 +25,16 @@ class AtomBrowserClient : public brightray::BrowserClient {
content::SiteInstance* site_instance,
const GURL& current_url,
const GURL& new_url) OVERRIDE;
virtual void AppendExtraCommandLineSwitches(CommandLine* command_line,
int child_process_id) OVERRIDE;
private:
virtual brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
const content::MainFunctionParams&) OVERRIDE;
// The render process which would be swapped out soon.
content::RenderProcessHost* dying_render_process_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
};

View File

@@ -33,6 +33,14 @@ class AtomResourceContext : public content::ResourceContext {
return getter_->GetURLRequestContext();
}
virtual bool AllowMicAccess(const GURL& origin) OVERRIDE {
return true;
}
virtual bool AllowCameraAccess(const GURL& origin) OVERRIDE {
return true;
}
private:
AtomURLRequestContextGetter* getter_;
@@ -53,7 +61,8 @@ AtomURLRequestContextGetter* AtomBrowserContext::CreateRequestContext(
GetPath(),
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE),
CreateNetworkDelegate().Pass(),
base::Bind(&AtomBrowserContext::CreateNetworkDelegate,
base::Unretained(this)),
protocol_handlers);
resource_context_->set_url_request_context_getter(url_request_getter_.get());

View File

@@ -4,15 +4,18 @@
#include "browser/atom_browser_main_parts.h"
#include "base/power_monitor/power_monitor.h"
#include "browser/api/atom_browser_bindings.h"
#include "browser/atom_browser_client.h"
#include "browser/atom_browser_context.h"
#include "browser/browser.h"
#include "common/node_bindings.h"
#include "net/proxy/proxy_resolver_v8.h"
#include "vendor/node/src/node.h"
#include "vendor/node/src/node_internals.h"
#if defined(OS_WIN)
#include "ui/gfx/win/dpi.h"
#endif
#include "common/v8/node_common.h"
namespace atom {
@@ -43,37 +46,29 @@ brightray::BrowserContext* AtomBrowserMainParts::CreateBrowserContext() {
void AtomBrowserMainParts::PostEarlyInitialization() {
brightray::BrowserMainParts::PostEarlyInitialization();
#if defined(OS_MACOSX)
base::PowerMonitor::AllocateSystemIOPorts();
#endif
node_bindings_->Initialize();
v8::V8::Initialize();
// Create context.
v8::Locker locker(node_isolate);
v8::HandleScope handle_scope(node_isolate);
v8::Local<v8::Context> context = v8::Context::New(node_isolate);
// Create the global environment.
global_env = node_bindings_->CreateEnvironment(context);
// Wrap whole process in one global context.
node::g_context->Enter();
context->Enter();
atom_bindings_->BindTo(node::process);
node_bindings_->Load();
atom_bindings_->AfterLoad();
// Add atom-shell extended APIs.
atom_bindings_->BindTo(global_env->process_object());
}
void AtomBrowserMainParts::PreMainMessageLoopRun() {
node_bindings_->PrepareMessageLoop();
brightray::BrowserMainParts::PreMainMessageLoopRun();
{
v8::HandleScope scope;
v8::Context::Scope context_scope(node::g_context);
v8::Handle<v8::Value> args;
node::MakeCallback(atom_bindings_->browser_main_parts(),
"preMainMessageLoopRun",
0, &args);
}
node_bindings_->PrepareMessageLoop();
node_bindings_->RunMessageLoop();
// Make sure the url request job factory is created before the
@@ -89,8 +84,17 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
}
int AtomBrowserMainParts::PreCreateThreads() {
// TODO(zcbenz): Calling CreateIsolate() on Windows when updated to Chrome30.
// Note that we are overriding the PreCreateThreads of brightray, since we
// are integrating node in browser, we can just be sure that an V8 instance
// would be prepared, while the ProxyResolverV8::CreateIsolate() would
// try to create a V8 isolate, which messed everything on Windows, so we
// have to override and call RememberDefaultIsolate on Windows instead.
net::ProxyResolverV8::RememberDefaultIsolate();
#if defined(OS_WIN)
gfx::EnableHighDPISupport();
#endif
return 0;
}

View File

@@ -4,7 +4,7 @@
#include "browser/atom_javascript_dialog_manager.h"
#include "base/utf_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
namespace atom {

View File

@@ -26,7 +26,9 @@ class AtomJavaScriptDialogManager : public content::JavaScriptDialogManager {
const string16& message_text,
bool is_reload,
const DialogClosedCallback& callback) OVERRIDE;
virtual void ResetJavaScriptState(
virtual void CancelActiveAndPendingDialogs(
content::WebContents* web_contents) OVERRIDE {}
virtual void WebContentsDestroyed(
content::WebContents* web_contents) OVERRIDE {}
};

View File

@@ -19,13 +19,8 @@ class AutoUpdater {
static AutoUpdaterDelegate* GetDelegate();
static void SetDelegate(AutoUpdaterDelegate* delegate);
static void Init();
static void SetFeedURL(const std::string& url);
static void SetAutomaticallyChecksForUpdates(bool yes);
static void SetAutomaticallyDownloadsUpdates(bool yes);
static void CheckForUpdates();
static void CheckForUpdatesInBackground();
private:
static AutoUpdaterDelegate* delegate_;

View File

@@ -1,21 +0,0 @@
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "browser/auto_updater_delegate.h"
#include "base/callback.h"
namespace auto_updater {
void AutoUpdaterDelegate::WillInstallUpdate(const std::string& version,
const base::Closure& install) {
install.Run();
}
void AutoUpdaterDelegate::ReadyForUpdateOnQuit(
const std::string& version,
const base::Closure& quit_and_install) {
}
} // namespace auto_updater

View File

@@ -9,17 +9,32 @@
#include "base/callback_forward.h"
namespace base {
class Time;
}
namespace auto_updater {
class AutoUpdaterDelegate {
public:
// The application is going to relaunch to install update.
virtual void WillInstallUpdate(const std::string& version,
const base::Closure& install);
// An error happened.
virtual void OnError(const std::string& error) {}
// User has chosen to update on quit.
virtual void ReadyForUpdateOnQuit(const std::string& version,
const base::Closure& quit_and_install);
// Checking to see if there is an update
virtual void OnCheckingForUpdate() {}
// There is an update available and it is being downloaded
virtual void OnUpdateAvailable() {}
// There is no available update.
virtual void OnUpdateNotAvailable() {}
// There is a new update which has been downloaded.
virtual void OnUpdateDownloaded(const std::string& release_notes,
const std::string& release_name,
const base::Time& release_date,
const std::string& update_url,
const base::Closure& quit_and_install) {}
protected:
virtual ~AutoUpdaterDelegate() {}

View File

@@ -0,0 +1,17 @@
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "browser/auto_updater.h"
namespace auto_updater {
// static
void AutoUpdater::SetFeedURL(const std::string& url) {
}
// static
void AutoUpdater::CheckForUpdates() {
}
} // namespace auto_updater

View File

@@ -4,106 +4,89 @@
#include "browser/auto_updater.h"
// Sparkle's headers are throwing compilation warnings, supress them.
#pragma GCC diagnostic ignored "-Wmissing-method-return-type"
#import <Sparkle/Sparkle.h>
#import <ReactiveCocoa/RACCommand.h>
#import <ReactiveCocoa/RACSignal.h>
#import <ReactiveCocoa/NSObject+RACPropertySubscribing.h>
#import <Squirrel/Squirrel.h>
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "base/strings/sys_string_conversions.h"
#include "browser/auto_updater_delegate.h"
using auto_updater::AutoUpdaterDelegate;
#include <iostream>
namespace auto_updater {
namespace {
struct NSInvocationDeleter {
inline void operator()(NSInvocation* invocation) const {
[invocation release];
}
};
// The gloal SQRLUpdater object.
SQRLUpdater* g_updater = nil;
typedef scoped_ptr<NSInvocation, NSInvocationDeleter> ScopedNSInvocation;
// We are passing the NSInvocation as scoped_ptr, because we want to make sure
// whether or not the callback is called, the NSInvocation should alwasy be
// released, the only way to ensure it is to use scoped_ptr.
void CallNSInvocation(ScopedNSInvocation invocation) {
[invocation.get() invoke];
void RelaunchToInstallUpdate() {
[[g_updater relaunchToInstallUpdate] subscribeError:^(NSError* error) {
AutoUpdaterDelegate* delegate = AutoUpdater::GetDelegate();
if (delegate)
delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription));
}];
}
} // namespace
@interface SUUpdaterDelegate : NSObject {
}
@end
@implementation SUUpdaterDelegate
- (BOOL)updater:(SUUpdater*)updater
shouldPostponeRelaunchForUpdate:(SUAppcastItem*)update
untilInvoking:(NSInvocation*)invocation {
AutoUpdaterDelegate* delegate = auto_updater::AutoUpdater::GetDelegate();
if (!delegate)
return NO;
std::string version(base::SysNSStringToUTF8([update versionString]));
ScopedNSInvocation invocation_ptr([invocation retain]);
delegate->WillInstallUpdate(
version,
base::Bind(&CallNSInvocation, base::Passed(invocation_ptr.Pass())));
return YES;
}
- (void)updater:(SUUpdater*)updater
willInstallUpdateOnQuit:(SUAppcastItem*)update
immediateInstallationInvocation:(NSInvocation*)invocation {
AutoUpdaterDelegate* delegate = auto_updater::AutoUpdater::GetDelegate();
if (!delegate)
return;
std::string version(base::SysNSStringToUTF8([update versionString]));
ScopedNSInvocation invocation_ptr([invocation retain]);
delegate->ReadyForUpdateOnQuit(
version,
base::Bind(&CallNSInvocation, base::Passed(invocation_ptr.Pass())));
}
@end
namespace auto_updater {
// static
void AutoUpdater::Init() {
SUUpdaterDelegate* delegate = [[SUUpdaterDelegate alloc] init];
[[SUUpdater sharedUpdater] setDelegate:delegate];
}
void AutoUpdater::SetFeedURL(const std::string& feed) {
if (g_updater == nil) {
// Initialize the SQRLUpdater.
NSURL* url = [NSURL URLWithString:base::SysUTF8ToNSString(feed)];
NSURLRequest* urlRequest = [NSURLRequest requestWithURL:url];
g_updater = [[SQRLUpdater alloc] initWithUpdateRequest:urlRequest];
// static
void AutoUpdater::SetFeedURL(const std::string& url) {
NSString* url_str(base::SysUTF8ToNSString(url));
[[SUUpdater sharedUpdater] setFeedURL:[NSURL URLWithString:url_str]];
}
AutoUpdaterDelegate* delegate = GetDelegate();
if (!delegate)
return;
// static
void AutoUpdater::SetAutomaticallyChecksForUpdates(bool yes) {
[[SUUpdater sharedUpdater] setAutomaticallyChecksForUpdates:yes];
}
// static
void AutoUpdater::SetAutomaticallyDownloadsUpdates(bool yes) {
[[SUUpdater sharedUpdater] setAutomaticallyDownloadsUpdates:yes];
[[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();
}
}];
}
}
// static
void AutoUpdater::CheckForUpdates() {
[[SUUpdater sharedUpdater] checkForUpdates:nil];
}
AutoUpdaterDelegate* delegate = GetDelegate();
if (!delegate)
return;
// static
void AutoUpdater::CheckForUpdatesInBackground() {
[[SUUpdater sharedUpdater] checkForUpdatesInBackground];
[[[[g_updater.checkForUpdatesCommand
execute:nil]
// Send a `nil` after everything...
concat:[RACSignal return:nil]]
// But only take the first value. If an update is sent, we'll get that.
// Otherwise, we'll get our inserted `nil` value.
take:1]
subscribeNext:^(SQRLDownloadedUpdate *downloadedUpdate) {
if (downloadedUpdate) {
SQRLUpdate* update = downloadedUpdate.update;
// There is a new update that has been downloaded.
delegate->OnUpdateDownloaded(
base::SysNSStringToUTF8(update.releaseNotes),
base::SysNSStringToUTF8(update.releaseName),
base::Time::FromDoubleT(update.releaseDate.timeIntervalSince1970),
base::SysNSStringToUTF8(update.updateURL.absoluteString),
base::Bind(RelaunchToInstallUpdate));
} else {
// When the completed event is sent with no update, then we know there
// is no update available.
delegate->OnUpdateNotAvailable();
}
} error:^(NSError *error) {
delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription));
}];
}
} // namespace auto_updater

View File

@@ -6,28 +6,12 @@
namespace auto_updater {
// static
void AutoUpdater::Init() {
}
// static
void AutoUpdater::SetFeedURL(const std::string& url) {
}
// static
void AutoUpdater::SetAutomaticallyChecksForUpdates(bool yes) {
}
// static
void AutoUpdater::SetAutomaticallyDownloadsUpdates(bool yes) {
}
// static
void AutoUpdater::CheckForUpdates() {
}
// static
void AutoUpdater::CheckForUpdatesInBackground() {
}
} // namespace auto_updater

44
browser/browser_linux.cc Normal file
View File

@@ -0,0 +1,44 @@
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "browser/browser.h"
#include <stdlib.h>
#include "browser/native_window.h"
#include "browser/window_list.h"
#include "common/atom_version.h"
namespace atom {
void Browser::Terminate() {
is_quiting_ = true;
exit(0);
}
void Browser::Focus() {
// Focus on the first visible window.
WindowList* list = WindowList::GetInstance();
for (WindowList::iterator iter = list->begin(); iter != list->end(); ++iter) {
NativeWindow* window = *iter;
if (window->IsVisible()) {
window->Focus(true);
break;
}
}
}
std::string Browser::GetExecutableFileVersion() const {
return ATOM_VERSION_STRING;
}
std::string Browser::GetExecutableFileProductName() const {
return "Atom-Shell";
}
void Browser::CancelQuit() {
// No way to cancel quit on Linux.
}
} // namespace atom

View File

@@ -1,6 +1,5 @@
var app = require('app');
var dialog = require('dialog');
var delegate = require('atom-delegate');
var ipc = require('ipc');
var Menu = require('menu');
var MenuItem = require('menu-item');
@@ -18,7 +17,7 @@ app.on('open-url', function(event, url) {
dialog.showMessageBox({message: url, buttons: ['OK']});
});
app.on('finish-launching', function() {
app.on('ready', function() {
app.commandLine.appendSwitch('js-flags', '--harmony_collections');
mainWindow = new BrowserWindow({ width: 800, height: 600 });

View File

@@ -1,5 +1,4 @@
var app = require('app');
var dialog = require('dialog');
var path = require('path');
var optimist = require('optimist');
@@ -9,7 +8,7 @@ app.on('window-all-closed', function() {
app.quit();
});
var argv = optimist(process.argv.slice(1)).argv;
var argv = optimist(process.argv.slice(1)).boolean('ci').argv;
// Start the specified app if there is one specified in command line, otherwise
// start the default app.

View File

@@ -0,0 +1,63 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "browser/devtools_delegate.h"
#include "base/values.h"
#include "browser/native_window.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/devtools_client_host.h"
#include "content/public/browser/devtools_http_handler.h"
#include "content/public/browser/devtools_manager.h"
#include "content/public/browser/web_contents.h"
namespace atom {
DevToolsDelegate::DevToolsDelegate(NativeWindow* window,
content::WebContents* target_web_contents)
: content::WebContentsObserver(window->GetWebContents()),
owner_window_(window) {
content::WebContents* web_contents = window->GetWebContents();
// Setup devtools.
devtools_agent_host_ = content::DevToolsAgentHost::GetOrCreateFor(
target_web_contents->GetRenderViewHost());
devtools_client_host_.reset(
content::DevToolsClientHost::CreateDevToolsFrontendHost(web_contents,
this));
content::DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(
devtools_agent_host_.get(), devtools_client_host_.get());
// Go!
base::DictionaryValue options;
options.SetString("title", "DevTools Debugger");
window->InitFromOptions(&options);
web_contents->GetController().LoadURL(
GURL("chrome-devtools://devtools/devtools.html"),
content::Referrer(),
content::PAGE_TRANSITION_AUTO_TOPLEVEL,
std::string());
}
DevToolsDelegate::~DevToolsDelegate() {
}
void DevToolsDelegate::DispatchOnEmbedder(const std::string& message) {
}
void DevToolsDelegate::InspectedContentsClosing() {
delete owner_window_;
}
void DevToolsDelegate::AboutToNavigateRenderView(
content::RenderViewHost* render_view_host) {
content::DevToolsClientHost::SetupDevToolsFrontendClient(
owner_window_->GetWebContents()->GetRenderViewHost());
}
void DevToolsDelegate::OnWindowClosed() {
delete owner_window_;
}
} // namespace atom

View File

@@ -0,0 +1,53 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_DEVTOOLS_DELEGATE_H_
#define ATOM_BROWSER_DEVTOOLS_DELEGATE_H_
#include "base/memory/scoped_ptr.h"
#include "browser/native_window_observer.h"
#include "content/public/browser/devtools_frontend_host_delegate.h"
#include "content/public/browser/web_contents_observer.h"
namespace content {
class DevToolsAgentHost;
class DevToolsClientHost;
}
namespace atom {
class NativeWindow;
class DevToolsDelegate : public content::DevToolsFrontendHostDelegate,
public content::WebContentsObserver,
public NativeWindowObserver {
public:
DevToolsDelegate(NativeWindow* window,
content::WebContents* target_web_contents);
virtual ~DevToolsDelegate();
protected:
// Implementations of content::DevToolsFrontendHostDelegate.
virtual void DispatchOnEmbedder(const std::string& message) OVERRIDE;
virtual void InspectedContentsClosing() OVERRIDE;
// Implementations of content::WebContentsObserver.
virtual void AboutToNavigateRenderView(
content::RenderViewHost* render_view_host) OVERRIDE;
// Implementations of NativeWindowObserver.
virtual void OnWindowClosed() OVERRIDE;
private:
NativeWindow* owner_window_;
scoped_refptr<content::DevToolsAgentHost> devtools_agent_host_;
scoped_ptr<content::DevToolsClientHost> devtools_client_host_;
DISALLOW_COPY_AND_ASSIGN(DevToolsDelegate);
};
} // namespace atom
#endif // ATOM_BROWSER_DEVTOOLS_DELEGATE_H_

80
browser/lib/init.coffee Normal file
View File

@@ -0,0 +1,80 @@
fs = require 'fs'
path = require 'path'
util = require 'util'
# Expose information of current process.
process.__atom_type = 'browser'
process.resourcesPath = path.resolve process.argv[1], '..', '..', '..'
# We modified the original process.argv to let node.js load the atom.js,
# we need to restore it here.
process.argv.splice 1, 1
# Pick out switches appended by atom-shell.
startMark = process.argv.indexOf '--atom-shell-switches-start'
endMark = process.argv.indexOf '--atom-shell-switches-end'
process.execArgv = process.argv.splice startMark, endMark - startMark + 1
# Add browser/api/lib to require's search paths,
# which contains javascript part of Atom's built-in libraries.
globalPaths = require('module').globalPaths
globalPaths.push path.join process.resourcesPath, 'browser', 'api', 'lib'
# Do loading in next tick since we still need some initialize work before
# native bindings can work.
setImmediate ->
# Import common settings.
require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init.js')
if process.platform is 'win32'
# Redirect node's console to use our own implementations, since node can not
# handle console output when running as GUI program.
print = (args...) ->
process.log util.format(args...)
console.log = console.error = console.warn = print
process.stdout.write = process.stderr.write = print
# Always returns EOF for stdin stream.
Readable = require('stream').Readable
stdin = new Readable
stdin.push null
process.__defineGetter__ 'stdin', -> stdin
# Don't quit on fatal error.
process.on 'uncaughtException', (error) ->
# Show error in GUI.
message = error.stack ? "#{error.name}: #{error.message}"
require('dialog').showMessageBox
type: 'warning'
title: 'An javascript error occured in the browser'
message: 'uncaughtException'
detail: message
buttons: ['OK']
# Load the RPC server.
require './rpc-server.js'
# Now we try to load app's package.json.
packageJson = null
packagePath = path.join process.resourcesPath, 'app'
try
# First we try to load process.resourcesPath/app
packageJson = JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json')))
catch error
# If not found then we load browser/default_app
packagePath = path.join process.resourcesPath, 'browser', 'default_app'
packageJson = JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json')))
# Set application's version.
app = require 'app'
app.setVersion packageJson.version if packageJson.version?
# Set application's name.
if packageJson.productName?
app.setName packageJson.productName
else if packageJson.name?
app.setName packageJson.name
# Finally load app's main.js and transfer control to C++.
require path.join(packagePath, packageJson.main)

View File

@@ -1,4 +1,3 @@
BrowserWindow = require 'browser-window'
EventEmitter = require('events').EventEmitter
IDWeakMap = require 'id-weak-map'
v8Util = process.atomBinding 'v8_util'
@@ -41,6 +40,8 @@ class ObjectsStore
class ObjectsRegistry extends EventEmitter
constructor: ->
@setMaxListeners Number.MAX_VALUE
# Objects in weak map will be not referenced (so we won't leak memory), and
# every object created in browser will have a unique id in weak map.
@objectsWeakMap = new IDWeakMap
@@ -49,13 +50,6 @@ class ObjectsRegistry extends EventEmitter
v8Util.setHiddenValue obj, 'atomId', id
id
# Remember all windows in the weak map.
@windowsWeakMap = new IDWeakMap
process.on 'ATOM_BROWSER_INTERNAL_NEW', (obj) =>
if obj.constructor is BrowserWindow
id = @windowsWeakMap.add obj
obj.on 'destroyed', => @windowsWeakMap.remove id
# Register a new object, the object would be kept referenced until you release
# it explicitly.
add: (processId, routingId, obj) ->
@@ -87,9 +81,4 @@ class ObjectsRegistry extends EventEmitter
@emit "release-renderer-view-#{processId}-#{routingId}"
ObjectsStore.releaseForRenderView processId, routingId
# Return an array of all browser windows.
getAllWindows: ->
keys = @windowsWeakMap.keys()
@windowsWeakMap.get key for key in keys
module.exports = new ObjectsRegistry

View File

@@ -7,9 +7,9 @@
#include <string>
#include "base/file_util.h"
#include "base/message_loop.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h"
@@ -18,6 +18,7 @@
#include "browser/atom_browser_main_parts.h"
#include "browser/atom_javascript_dialog_manager.h"
#include "browser/browser.h"
#include "browser/devtools_delegate.h"
#include "browser/window_list.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/invalidate_type.h"
@@ -37,8 +38,8 @@
#include "ui/gfx/point.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
#include "webkit/glue/image_decoder.h"
#include "webkit/user_agent/user_agent_util.h"
#include "vendor/brightray/browser/inspectable_web_contents_impl.h"
#include "webkit/common/user_agent/user_agent_util.h"
using content::NavigationEntry;
@@ -49,16 +50,20 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
: content::WebContentsObserver(web_contents),
has_frame_(true),
is_closed_(false),
node_integration_("all"),
has_dialog_attached_(false),
weak_factory_(this),
inspectable_web_contents_(
brightray::InspectableWebContents::Create(web_contents)) {
options->GetBoolean(switches::kFrame, &has_frame_);
// Read icon before window is created.
std::string icon;
if (options->GetString(switches::kIcon, &icon)) {
if (!SetIcon(icon))
LOG(ERROR) << "Failed to set icon to " << icon;
}
if (options->GetString(switches::kIcon, &icon) && !SetIcon(icon))
LOG(ERROR) << "Failed to set icon to " << icon;
// Read iframe security before any navigation.
options->GetString(switches::kNodeIntegration, &node_integration_);
web_contents->SetDelegate(this);
@@ -156,6 +161,10 @@ void NativeWindow::InitFromOptions(base::DictionaryValue* options) {
Show();
}
bool NativeWindow::HasModalDialog() {
return has_dialog_attached_;
}
void NativeWindow::OpenDevTools() {
inspectable_web_contents()->ShowDevTools();
}
@@ -165,7 +174,7 @@ void NativeWindow::CloseDevTools() {
}
bool NativeWindow::IsDevToolsOpened() {
return inspectable_web_contents()->IsDevToolsOpened();
return inspectable_web_contents()->IsDevToolsViewShowing();
}
void NativeWindow::InspectElement(int x, int y) {
@@ -176,6 +185,16 @@ void NativeWindow::InspectElement(int x, int y) {
agent->InspectElement(x, y);
}
void NativeWindow::DebugDevTools() {
if (!IsDevToolsOpened())
return;
base::DictionaryValue options;
NativeWindow* window = NativeWindow::Create(&options);
window->devtools_delegate_.reset(new DevToolsDelegate(
window, GetDevToolsWebContents()));
}
void NativeWindow::FocusOnWebView() {
GetWebContents()->GetRenderViewHost()->Focus();
}
@@ -193,15 +212,14 @@ bool NativeWindow::SetIcon(const std::string& str_path) {
// Read the file from disk.
std::string file_contents;
if (path.empty() || !file_util::ReadFileToString(path, &file_contents))
if (path.empty() || !base::ReadFileToString(path, &file_contents))
return false;
// Decode the bitmap using WebKit's image decoder.
const unsigned char* data =
reinterpret_cast<const unsigned char*>(file_contents.data());
webkit_glue::ImageDecoder decoder;
scoped_ptr<SkBitmap> decoded(new SkBitmap());
*decoded = decoder.Decode(data, file_contents.length());
gfx::PNGCodec::Decode(data, file_contents.length(), decoded.get());
if (decoded->empty())
return false; // Unable to decode.
@@ -215,8 +233,11 @@ base::ProcessHandle NativeWindow::GetRenderProcessHandle() {
void NativeWindow::CapturePage(const gfx::Rect& rect,
const CapturePageCallback& callback) {
gfx::Rect flipped_y_rect = rect;
flipped_y_rect.set_y(-rect.y());
GetWebContents()->GetRenderViewHost()->CopyFromBackingStore(
rect,
flipped_y_rect,
gfx::Size(),
base::Bind(&NativeWindow::OnCapturePageDone,
weak_factory_.GetWeakPtr(),
@@ -260,6 +281,13 @@ content::WebContents* NativeWindow::GetWebContents() const {
return inspectable_web_contents_->GetWebContents();
}
content::WebContents* NativeWindow::GetDevToolsWebContents() const {
brightray::InspectableWebContentsImpl* inspectable_web_contents_impl =
static_cast<brightray::InspectableWebContentsImpl*>(
inspectable_web_contents());
return inspectable_web_contents_impl->devtools_web_contents();
}
void NativeWindow::NotifyWindowClosed() {
if (is_closed_)
return;
@@ -282,22 +310,28 @@ void NativeWindow::NotifyWindowBlur() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowBlur());
}
// Window opened by window.open.
void NativeWindow::WebContentsCreated(
content::WebContents* source_contents,
int64 source_frame_id,
const string16& frame_name,
const GURL& target_url,
content::WebContents* new_contents) {
LOG(WARNING) << "Please use node-style Window API to create window, "
"using window.open has very strict constrains.";
// In atom-shell all reloads and navigations started by renderer process would
// be redirected to this method, so we can have precise control of how we
// would open the url (in our case, is to restart the renderer process). See
// AtomRendererClient::ShouldFork for how this is done.
content::WebContents* NativeWindow::OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) {
if (params.disposition != CURRENT_TAB)
return NULL;
scoped_ptr<base::DictionaryValue> options(new base::DictionaryValue);
options->SetInteger(switches::kWidth, 800);
options->SetInteger(switches::kHeight, 600);
content::NavigationController::LoadURLParams load_url_params(params.url);
load_url_params.referrer = params.referrer;
load_url_params.transition_type = params.transition;
load_url_params.extra_headers = params.extra_headers;
load_url_params.should_replace_current_entry =
params.should_replace_current_entry;
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
load_url_params.transferred_global_request_id =
params.transferred_global_request_id;
NativeWindow* window = Create(new_contents, options.get());
window->InitFromOptions(options.get());
source->GetController().LoadURLWithParams(load_url_params);
return source;
}
content::JavaScriptDialogManager* NativeWindow::GetJavaScriptDialogManager() {
@@ -383,6 +417,21 @@ void NativeWindow::RendererResponsive(content::WebContents* source) {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnRendererResponsive());
}
void NativeWindow::RenderViewDeleted(content::RenderViewHost* rvh) {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
OnRenderViewDeleted(rvh->GetProcess()->GetID(),
rvh->GetRoutingID()));
}
void NativeWindow::RenderProcessGone(base::TerminationStatus status) {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnRendererCrashed());
}
void NativeWindow::BeforeUnloadFired(const base::TimeTicks& proceed_time) {
// Do nothing, we override this method just to avoid compilation error since
// there are two virtual functions named BeforeUnloadFired.
}
bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(NativeWindow, message)
@@ -397,16 +446,6 @@ bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
return handled;
}
void NativeWindow::RenderViewDeleted(content::RenderViewHost* rvh) {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
OnRenderViewDeleted(rvh->GetProcess()->GetID(),
rvh->GetRoutingID()));
}
void NativeWindow::RenderViewGone(base::TerminationStatus status) {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnRendererCrashed());
}
void NativeWindow::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {

View File

@@ -45,6 +45,7 @@ class Message;
namespace atom {
class AtomJavaScriptDialogManager;
class DevToolsDelegate;
struct DraggableRegion;
class NativeWindow : public brightray::DefaultWebContentsDelegate,
@@ -54,6 +55,25 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
typedef base::Callback<void(const std::vector<unsigned char>& buffer)>
CapturePageCallback;
class DialogScope {
public:
explicit DialogScope(NativeWindow* window)
: window_(window) {
if (window_ != NULL)
window_->set_has_dialog_attached(true);
}
~DialogScope() {
if (window_ != NULL)
window_->set_has_dialog_attached(false);
}
private:
NativeWindow* window_;
DISALLOW_COPY_AND_ASSIGN(DialogScope);
};
virtual ~NativeWindow();
// Create window with existing WebContents.
@@ -100,7 +120,7 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
virtual void FlashFrame(bool flash) = 0;
virtual void SetKiosk(bool kiosk) = 0;
virtual bool IsKiosk() = 0;
virtual bool HasModalDialog() = 0;
virtual bool HasModalDialog();
virtual gfx::NativeWindow GetNativeWindow() = 0;
virtual bool IsClosed() const { return is_closed_; }
@@ -109,6 +129,9 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
virtual bool IsDevToolsOpened();
virtual void InspectElement(int x, int y);
// Creates a new window to debug the devtools.
virtual void DebugDevTools();
virtual void FocusOnWebView();
virtual void BlurWebView();
virtual bool IsWebViewFocused();
@@ -130,6 +153,7 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
virtual void CloseWebContents();
content::WebContents* GetWebContents() const;
content::WebContents* GetDevToolsWebContents() const;
void AddObserver(NativeWindowObserver* obs) {
observers_.AddObserver(obs);
@@ -140,6 +164,11 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
}
bool has_frame() const { return has_frame_; }
std::string node_integration() const { return node_integration_; }
void set_has_dialog_attached(bool has_dialog_attached) {
has_dialog_attached_ = has_dialog_attached;
}
protected:
explicit NativeWindow(content::WebContents* web_contents,
@@ -157,11 +186,9 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
const std::vector<DraggableRegion>& regions) = 0;
// Implementations of content::WebContentsDelegate.
virtual void WebContentsCreated(content::WebContents* source_contents,
int64 source_frame_id,
const string16& frame_name,
const GURL& target_url,
content::WebContents* new_contents) OVERRIDE;
virtual content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) OVERRIDE;
virtual content::JavaScriptDialogManager*
GetJavaScriptDialogManager() OVERRIDE;
virtual void BeforeUnloadFired(content::WebContents* tab,
@@ -184,10 +211,11 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
// Implementations of content::WebContentsObserver.
virtual void RenderViewDeleted(content::RenderViewHost*) OVERRIDE;
virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
virtual void BeforeUnloadFired(const base::TimeTicks& proceed_time) OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
// Implementations of content::NotificationObserver
// Implementations of content::NotificationObserver.
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
@@ -220,12 +248,19 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
// The windows has been closed.
bool is_closed_;
// The security token of iframe.
std::string node_integration_;
// There is a dialog that has been attached to window.
bool has_dialog_attached_;
// Closure that would be called when window is unresponsive when closing,
// it should be cancelled when we can prove that the window is responsive.
base::CancelableClosure window_unresposive_closure_;
base::WeakPtrFactory<NativeWindow> weak_factory_;
scoped_ptr<DevToolsDelegate> devtools_delegate_;
scoped_ptr<AtomJavaScriptDialogManager> dialog_manager_;
scoped_ptr<brightray::InspectableWebContents> inspectable_web_contents_;

View File

@@ -0,0 +1,429 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "browser/native_window_gtk.h"
#include "base/values.h"
#include "browser/ui/gtk/gtk_window_util.h"
#include "common/draggable_region.h"
#include "common/options_switches.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "content/public/common/renderer_preferences.h"
#include "ui/base/x/x11_util.h"
#include "ui/gfx/gtk_util.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/skia_utils_gtk.h"
namespace atom {
namespace {
// Dividing GTK's cursor blink cycle time (in milliseconds) by this value yields
// an appropriate value for content::RendererPreferences::caret_blink_interval.
// This matches the logic in the WebKit GTK port.
const double kGtkCursorBlinkCycleFactor = 2000.0;
} // namespace
NativeWindowGtk::NativeWindowGtk(content::WebContents* web_contents,
base::DictionaryValue* options)
: NativeWindow(web_contents, options),
window_(GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL))),
state_(GDK_WINDOW_STATE_WITHDRAWN),
is_always_on_top_(false) {
gtk_container_add(GTK_CONTAINER(window_),
GetWebContents()->GetView()->GetNativeView());
int width = 800, height = 600;
options->GetInteger(switches::kWidth, &width);
options->GetInteger(switches::kHeight, &height);
gtk_window_set_default_size(window_, width, height);
if (!icon_.IsEmpty())
gtk_window_set_icon(window_, icon_.ToGdkPixbuf());
// In some (older) versions of compiz, raising top-level windows when they
// are partially off-screen causes them to get snapped back on screen, not
// always even on the current virtual desktop. If we are running under
// compiz, suppress such raises, as they are not necessary in compiz anyway.
if (ui::GuessWindowManager() == ui::WM_COMPIZ)
suppress_window_raise_ = true;
g_signal_connect(window_, "delete-event",
G_CALLBACK(OnWindowDeleteEventThunk), this);
g_signal_connect(window_, "focus-out-event",
G_CALLBACK(OnFocusOutThunk), this);
if (!has_frame_) {
gtk_window_set_decorated(window_, false);
g_signal_connect(window_, "motion-notify-event",
G_CALLBACK(OnMouseMoveEventThunk), this);
g_signal_connect(window_, "button-press-event",
G_CALLBACK(OnButtonPressThunk), this);
}
SetWebKitColorStyle();
}
NativeWindowGtk::~NativeWindowGtk() {
if (window_)
gtk_widget_destroy(GTK_WIDGET(window_));
}
void NativeWindowGtk::Close() {
CloseWebContents();
}
void NativeWindowGtk::CloseImmediately() {
gtk_widget_destroy(GTK_WIDGET(window_));
window_ = NULL;
}
void NativeWindowGtk::Move(const gfx::Rect& pos) {
gtk_window_move(window_, pos.x(), pos.y());
gtk_window_resize(window_, pos.width(), pos.height());
}
void NativeWindowGtk::Focus(bool focus) {
if (!IsVisible())
return;
if (focus)
gtk_window_present(window_);
else
gdk_window_lower(gtk_widget_get_window(GTK_WIDGET(window_)));
}
bool NativeWindowGtk::IsFocused() {
return gtk_window_is_active(window_);
}
void NativeWindowGtk::Show() {
gtk_widget_show_all(GTK_WIDGET(window_));
}
void NativeWindowGtk::Hide() {
gtk_widget_hide(GTK_WIDGET(window_));
}
bool NativeWindowGtk::IsVisible() {
return gtk_widget_get_visible(GTK_WIDGET(window_));
}
void NativeWindowGtk::Maximize() {
gtk_window_maximize(window_);
}
void NativeWindowGtk::Unmaximize() {
gtk_window_unmaximize(window_);
}
void NativeWindowGtk::Minimize() {
gtk_window_iconify(window_);
}
void NativeWindowGtk::Restore() {
gtk_window_present(window_);
}
void NativeWindowGtk::SetFullscreen(bool fullscreen) {
if (fullscreen)
gtk_window_fullscreen(window_);
else
gtk_window_unfullscreen(window_);
}
bool NativeWindowGtk::IsFullscreen() {
return state_ & GDK_WINDOW_STATE_FULLSCREEN;
}
void NativeWindowGtk::SetSize(const gfx::Size& size) {
gtk_window_resize(window_, size.width(), size.height());
}
gfx::Size NativeWindowGtk::GetSize() {
GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window_));
GdkRectangle frame_extents;
gdk_window_get_frame_extents(gdk_window, &frame_extents);
return gfx::Size(frame_extents.width, frame_extents.height);
}
void NativeWindowGtk::SetMinimumSize(const gfx::Size& size) {
minimum_size_ = size;
GdkGeometry geometry = { 0 };
geometry.min_width = size.width();
geometry.min_height = size.height();
int hints = GDK_HINT_POS | GDK_HINT_MIN_SIZE;
gtk_window_set_geometry_hints(
window_, GTK_WIDGET(window_), &geometry, (GdkWindowHints)hints);
}
gfx::Size NativeWindowGtk::GetMinimumSize() {
return minimum_size_;
}
void NativeWindowGtk::SetMaximumSize(const gfx::Size& size) {
maximum_size_ = size;
GdkGeometry geometry = { 0 };
geometry.max_width = size.width();
geometry.max_height = size.height();
int hints = GDK_HINT_POS | GDK_HINT_MAX_SIZE;
gtk_window_set_geometry_hints(
window_, GTK_WIDGET(window_), &geometry, (GdkWindowHints)hints);
}
gfx::Size NativeWindowGtk::GetMaximumSize() {
return maximum_size_;
}
void NativeWindowGtk::SetResizable(bool resizable) {
// Should request widget size after setting unresizable, otherwise the
// window will shrink to a very small size.
if (!IsResizable()) {
gint width, height;
gtk_window_get_size(window_, &width, &height);
gtk_widget_set_size_request(GTK_WIDGET(window_), width, height);
}
gtk_window_set_resizable(window_, resizable);
}
bool NativeWindowGtk::IsResizable() {
return gtk_window_get_resizable(window_);
}
void NativeWindowGtk::SetAlwaysOnTop(bool top) {
is_always_on_top_ = top;
gtk_window_set_keep_above(window_, top ? TRUE : FALSE);
}
bool NativeWindowGtk::IsAlwaysOnTop() {
return is_always_on_top_;
}
void NativeWindowGtk::Center() {
gtk_window_set_position(window_, GTK_WIN_POS_CENTER);
}
void NativeWindowGtk::SetPosition(const gfx::Point& position) {
gtk_window_move(window_, position.x(), position.y());
}
gfx::Point NativeWindowGtk::GetPosition() {
GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window_));
GdkRectangle frame_extents;
gdk_window_get_frame_extents(gdk_window, &frame_extents);
return gfx::Point(frame_extents.x, frame_extents.y);
}
void NativeWindowGtk::SetTitle(const std::string& title) {
gtk_window_set_title(window_, title.c_str());
}
std::string NativeWindowGtk::GetTitle() {
return gtk_window_get_title(window_);
}
void NativeWindowGtk::FlashFrame(bool flash) {
gtk_window_set_urgency_hint(window_, flash);
}
void NativeWindowGtk::SetKiosk(bool kiosk) {
SetFullscreen(kiosk);
}
bool NativeWindowGtk::IsKiosk() {
return IsFullscreen();
}
bool NativeWindowGtk::HasModalDialog() {
// FIXME(zcbenz): Implement me.
return false;
}
gfx::NativeWindow NativeWindowGtk::GetNativeWindow() {
return window_;
}
void NativeWindowGtk::UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) {
// Draggable region is not supported for non-frameless window.
if (has_frame_)
return;
SkRegion draggable_region;
// By default, the whole window is non-draggable. We need to explicitly
// include those draggable regions.
for (std::vector<DraggableRegion>::const_iterator iter =
regions.begin();
iter != regions.end(); ++iter) {
const DraggableRegion& region = *iter;
draggable_region.op(
region.bounds.x(),
region.bounds.y(),
region.bounds.right(),
region.bounds.bottom(),
region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
}
draggable_region_ = draggable_region;
}
void NativeWindowGtk::SetWebKitColorStyle() {
content::RendererPreferences* prefs =
GetWebContents()->GetMutableRendererPrefs();
GtkStyle* frame_style = gtk_rc_get_style(GTK_WIDGET(window_));
prefs->focus_ring_color =
gfx::GdkColorToSkColor(frame_style->bg[GTK_STATE_SELECTED]);
prefs->thumb_active_color = SkColorSetRGB(244, 244, 244);
prefs->thumb_inactive_color = SkColorSetRGB(234, 234, 234);
prefs->track_color = SkColorSetRGB(211, 211, 211);
GtkWidget* url_entry = gtk_entry_new();
GtkStyle* entry_style = gtk_rc_get_style(url_entry);
prefs->active_selection_bg_color =
gfx::GdkColorToSkColor(entry_style->base[GTK_STATE_SELECTED]);
prefs->active_selection_fg_color =
gfx::GdkColorToSkColor(entry_style->text[GTK_STATE_SELECTED]);
prefs->inactive_selection_bg_color =
gfx::GdkColorToSkColor(entry_style->base[GTK_STATE_ACTIVE]);
prefs->inactive_selection_fg_color =
gfx::GdkColorToSkColor(entry_style->text[GTK_STATE_ACTIVE]);
gtk_widget_destroy(url_entry);
const base::TimeDelta cursor_blink_time = gfx::GetCursorBlinkCycle();
prefs->caret_blink_interval =
cursor_blink_time.InMilliseconds() ?
cursor_blink_time.InMilliseconds() / kGtkCursorBlinkCycleFactor :
0;
}
bool NativeWindowGtk::IsMaximized() const {
return state_ & GDK_WINDOW_STATE_MAXIMIZED;
}
bool NativeWindowGtk::GetWindowEdge(int x, int y, GdkWindowEdge* edge) {
if (has_frame_)
return false;
if (IsMaximized() || IsFullscreen())
return false;
return gtk_window_util::GetWindowEdge(GetSize(), 0, x, y, edge);
}
gboolean NativeWindowGtk::OnWindowDeleteEvent(GtkWidget* widget,
GdkEvent* event) {
Close();
return TRUE;
}
gboolean NativeWindowGtk::OnFocusOut(GtkWidget* window, GdkEventFocus*) {
NotifyWindowBlur();
return FALSE;
}
gboolean NativeWindowGtk::OnWindowState(GtkWidget* window,
GdkEventWindowState* event) {
state_ = event->new_window_state;
return FALSE;
}
gboolean NativeWindowGtk::OnMouseMoveEvent(GtkWidget* widget,
GdkEventMotion* event) {
if (!IsResizable())
return FALSE;
int win_x, win_y;
GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window_));
gdk_window_get_origin(gdk_window, &win_x, &win_y);
gfx::Point point(static_cast<int>(event->x_root - win_x),
static_cast<int>(event->y_root - win_y));
// Update the cursor if we're on the custom frame border.
GdkWindowEdge edge;
bool has_hit_edge = GetWindowEdge(point.x(), point.y(), &edge);
GdkCursorType new_cursor = GDK_LAST_CURSOR;
if (has_hit_edge)
new_cursor = gtk_window_util::GdkWindowEdgeToGdkCursorType(edge);
GdkCursorType last_cursor = GDK_LAST_CURSOR;
if (frame_cursor_)
last_cursor = frame_cursor_->type;
if (last_cursor != new_cursor) {
frame_cursor_ = has_hit_edge ? gfx::GetCursor(new_cursor) : NULL;
gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(window_)),
frame_cursor_);
}
return FALSE;
}
gboolean NativeWindowGtk::OnButtonPress(GtkWidget* widget,
GdkEventButton* event) {
// Make the button press coordinate relative to the browser window.
int win_x, win_y;
GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window_));
gdk_window_get_origin(gdk_window, &win_x, &win_y);
bool resizable = IsResizable();
GdkWindowEdge edge;
gfx::Point point(static_cast<int>(event->x_root - win_x),
static_cast<int>(event->y_root - win_y));
bool has_hit_edge = resizable && GetWindowEdge(point.x(), point.y(), &edge);
bool has_hit_titlebar = !draggable_region_.isEmpty() &&
draggable_region_.contains(event->x, event->y);
if (event->button == 1) {
if (GDK_BUTTON_PRESS == event->type) {
// Raise the window after a click on either the titlebar or the border to
// match the behavior of most window managers, unless that behavior has
// been suppressed.
if ((has_hit_titlebar || has_hit_edge) && !suppress_window_raise_)
gdk_window_raise(GTK_WIDGET(widget)->window);
if (has_hit_edge) {
gtk_window_begin_resize_drag(window_, edge, event->button,
static_cast<gint>(event->x_root),
static_cast<gint>(event->y_root),
event->time);
return TRUE;
} else if (has_hit_titlebar) {
return gtk_window_util::HandleTitleBarLeftMousePress(
window_, gfx::Rect(GetPosition(), GetSize()), event);
}
} else if (GDK_2BUTTON_PRESS == event->type) {
if (has_hit_titlebar && resizable) {
// Maximize/restore on double click.
if (IsMaximized())
gtk_window_unmaximize(window_);
else
gtk_window_maximize(window_);
return TRUE;
}
}
} else if (event->button == 2) {
if (has_hit_titlebar || has_hit_edge)
gdk_window_lower(gdk_window);
return TRUE;
}
return FALSE;
}
// static
NativeWindow* NativeWindow::Create(content::WebContents* web_contents,
base::DictionaryValue* options) {
return new NativeWindowGtk(web_contents, options);
}
} // namespace atom

109
browser/native_window_gtk.h Normal file
View File

@@ -0,0 +1,109 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_NATIVE_WINDOW_GTK_H_
#define ATOM_BROWSER_NATIVE_WINDOW_GTK_H_
#include <gtk/gtk.h>
#include "browser/native_window.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "ui/base/gtk/gtk_signal.h"
#include "ui/gfx/size.h"
namespace atom {
class NativeWindowGtk : public NativeWindow {
public:
explicit NativeWindowGtk(content::WebContents* web_contents,
base::DictionaryValue* options);
virtual ~NativeWindowGtk();
// NativeWindow implementation.
virtual void Close() OVERRIDE;
virtual void CloseImmediately() OVERRIDE;
virtual void Move(const gfx::Rect& pos) OVERRIDE;
virtual void Focus(bool focus) OVERRIDE;
virtual bool IsFocused() OVERRIDE;
virtual void Show() OVERRIDE;
virtual void Hide() OVERRIDE;
virtual bool IsVisible() OVERRIDE;
virtual void Maximize() OVERRIDE;
virtual void Unmaximize() OVERRIDE;
virtual void Minimize() OVERRIDE;
virtual void Restore() OVERRIDE;
virtual void SetFullscreen(bool fullscreen) OVERRIDE;
virtual bool IsFullscreen() OVERRIDE;
virtual void SetSize(const gfx::Size& size) OVERRIDE;
virtual gfx::Size GetSize() OVERRIDE;
virtual void SetMinimumSize(const gfx::Size& size) OVERRIDE;
virtual gfx::Size GetMinimumSize() OVERRIDE;
virtual void SetMaximumSize(const gfx::Size& size) OVERRIDE;
virtual gfx::Size GetMaximumSize() OVERRIDE;
virtual void SetResizable(bool resizable) OVERRIDE;
virtual bool IsResizable() OVERRIDE;
virtual void SetAlwaysOnTop(bool top) OVERRIDE;
virtual bool IsAlwaysOnTop() OVERRIDE;
virtual void Center() OVERRIDE;
virtual void SetPosition(const gfx::Point& position) OVERRIDE;
virtual gfx::Point GetPosition() OVERRIDE;
virtual void SetTitle(const std::string& title) OVERRIDE;
virtual std::string GetTitle() OVERRIDE;
virtual void FlashFrame(bool flash) OVERRIDE;
virtual void SetKiosk(bool kiosk) OVERRIDE;
virtual bool IsKiosk() OVERRIDE;
virtual bool HasModalDialog() OVERRIDE;
virtual gfx::NativeWindow GetNativeWindow() OVERRIDE;
protected:
virtual void UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) OVERRIDE;
private:
// Set WebKit's style from current theme.
void SetWebKitColorStyle();
// Whether window is maximized.
bool IsMaximized() const;
// If the point (|x|, |y|) is within the resize border area of the window,
// returns true and sets |edge| to the appropriate GdkWindowEdge value.
// Otherwise, returns false.
bool GetWindowEdge(int x, int y, GdkWindowEdge* edge);
CHROMEGTK_CALLBACK_1(NativeWindowGtk, gboolean, OnWindowDeleteEvent,
GdkEvent*);
CHROMEGTK_CALLBACK_1(NativeWindowGtk, gboolean, OnFocusOut, GdkEventFocus*);
CHROMEGTK_CALLBACK_1(NativeWindowGtk, gboolean, OnWindowState,
GdkEventWindowState*);
CHROMEGTK_CALLBACK_1(NativeWindowGtk, gboolean, OnMouseMoveEvent,
GdkEventMotion*);
CHROMEGTK_CALLBACK_1(NativeWindowGtk, gboolean, OnButtonPress,
GdkEventButton*);
GtkWindow* window_;
GdkWindowState state_;
bool is_always_on_top_;
gfx::Size minimum_size_;
gfx::Size maximum_size_;
// The region is treated as title bar, can be dragged to move
// and double clicked to maximize.
SkRegion draggable_region_;
// If true, don't call gdk_window_raise() when we get a click in the title
// bar or window border. This is to work around a compiz bug.
bool suppress_window_raise_;
// The current window cursor. We set it to a resize cursor when over the
// custom frame border. We set it to NULL if we want the default cursor.
GdkCursor* frame_cursor_;
DISALLOW_COPY_AND_ASSIGN(NativeWindowGtk);
};
} // namespace atom
#endif // ATOM_BROWSER_NATIVE_WINDOW_GTK_H_

View File

@@ -11,9 +11,10 @@
#define BASE_MAC_FOUNDATION_UTIL_H_
#include "base/mac/mac_util.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
#include "base/values.h"
#import "browser/ui/atom_event_processing_window.h"
#import "browser/ui/cocoa/event_processing_window.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h"
#include "common/draggable_region.h"
@@ -75,7 +76,7 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
@end
@interface AtomNSWindow : AtomEventProcessingWindow {
@interface AtomNSWindow : EventProcessingWindow {
@protected
atom::NativeWindowMac* shell_;
}
@@ -141,7 +142,7 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
: NativeWindow(web_contents, options),
is_kiosk_(false),
attention_request_id_(0) {
int width, height;
int width = 800, height = 600;
options->GetInteger(switches::kWidth, &width);
options->GetInteger(switches::kHeight, &height);
@@ -439,9 +440,9 @@ void NativeWindowMac::HandleKeyboardEvent(
event.type == content::NativeWebKeyboardEvent::Char)
return;
AtomEventProcessingWindow* event_window =
static_cast<AtomEventProcessingWindow*>(window());
DCHECK([event_window isKindOfClass:[AtomEventProcessingWindow class]]);
EventProcessingWindow* event_window =
static_cast<EventProcessingWindow*>(window());
DCHECK([event_window isKindOfClass:[EventProcessingWindow class]]);
[event_window redispatchKeyEvent:event.os_event];
}
@@ -490,7 +491,7 @@ void NativeWindowMac::InstallDraggableRegionViews() {
// Note that [webView subviews] returns the view's mutable internal array and
// it should be copied to avoid mutating the original array while enumerating
// it.
scoped_nsobject<NSArray> subviews([[webView subviews] copy]);
base::scoped_nsobject<NSArray> subviews([[webView subviews] copy]);
for (NSView* subview in subviews.get())
if ([subview isKindOfClass:[ControlRegionView class]])
[subview removeFromSuperview];
@@ -501,7 +502,7 @@ void NativeWindowMac::InstallDraggableRegionViews() {
system_drag_exclude_areas_.begin();
iter != system_drag_exclude_areas_.end();
++iter) {
scoped_nsobject<NSView> controlRegion(
base::scoped_nsobject<NSView> controlRegion(
[[ControlRegionView alloc] initWithShellWindow:this]);
[controlRegion setFrame:NSMakeRect(iter->x(),
webViewHeight - iter->bottom(),

View File

@@ -194,17 +194,6 @@ class NativeWindowFramelessView : public views::NonClientFrameView {
DISALLOW_COPY_AND_ASSIGN(NativeWindowFramelessView);
};
bool WindowHasModalDialog(HWND parent, HWND except, HWND after = NULL) {
HWND hwnd = ::FindWindowEx(parent, after, NULL, NULL);
if (hwnd != except &&
(::GetWindowLong(hwnd, GWL_STYLE) & (WS_VISIBLE | WS_POPUP)))
return true;
else if (hwnd == NULL)
return false;
else
return WindowHasModalDialog(parent, except, hwnd);
}
} // namespace
NativeWindowWin::NativeWindowWin(content::WebContents* web_contents,
@@ -370,11 +359,6 @@ bool NativeWindowWin::IsKiosk() {
return IsFullscreen();
}
bool NativeWindowWin::HasModalDialog() {
return WindowHasModalDialog(GetNativeWindow(),
GetWebContents()->GetView()->GetNativeView());
}
gfx::NativeWindow NativeWindowWin::GetNativeWindow() {
return window_->GetNativeView();
}
@@ -417,7 +401,7 @@ void NativeWindowWin::UpdateDraggableRegions(
void NativeWindowWin::HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent& event) {
if (event.type == WebKit::WebInputEvent::KeyUp) {
if (event.type == WebKit::WebInputEvent::RawKeyDown) {
ui::Accelerator accelerator(
static_cast<ui::KeyboardCode>(event.windowsKeyCode),
content::GetModifiersFromNativeWebKeyboardEvent(event));
@@ -439,10 +423,9 @@ void NativeWindowWin::Layout() {
OnViewWasResized();
}
void NativeWindowWin::ViewHierarchyChanged(bool is_add,
views::View* parent,
views::View* child) {
if (is_add && child == this)
void NativeWindowWin::ViewHierarchyChanged(
const ViewHierarchyChangedDetails& details) {
if (details.is_add && details.child == this)
AddChildView(web_view_);
}

View File

@@ -5,9 +5,8 @@
#ifndef ATOM_BROWSER_NATIVE_WINDOW_WIN_H_
#define ATOM_BROWSER_NATIVE_WINDOW_WIN_H_
#include "base/string16.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "browser/native_window.h"
#include "ui/gfx/size.h"
#include "ui/views/widget/widget_delegate.h"
@@ -65,7 +64,6 @@ class NativeWindowWin : public NativeWindow,
virtual void FlashFrame(bool flash) OVERRIDE;
virtual void SetKiosk(bool kiosk) OVERRIDE;
virtual bool IsKiosk() OVERRIDE;
virtual bool HasModalDialog() OVERRIDE;
virtual gfx::NativeWindow GetNativeWindow() OVERRIDE;
void OnMenuCommand(int position, HMENU menu);
@@ -87,9 +85,8 @@ class NativeWindowWin : public NativeWindow,
// Overridden from views::View:
virtual void Layout() OVERRIDE;
virtual void ViewHierarchyChanged(bool is_add,
views::View* parent,
views::View* child) OVERRIDE;
virtual void ViewHierarchyChanged(
const ViewHierarchyChangedDetails& details) OVERRIDE;
virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
// Overridden from views::WidgetDelegate:

View File

@@ -4,6 +4,7 @@
#include "browser/net/adapter_request_job.h"
#include "base/threading/sequenced_worker_pool.h"
#include "browser/net/url_request_string_job.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/net_errors.h"
@@ -87,7 +88,13 @@ void AdapterRequestJob::CreateStringJobAndStart(const std::string& mime_type,
void AdapterRequestJob::CreateFileJobAndStart(const base::FilePath& path) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
real_job_ = new net::URLRequestFileJob(request(), network_delegate(), path);
real_job_ = new net::URLRequestFileJob(
request(),
network_delegate(),
path,
content::BrowserThread::GetBlockingPool()->
GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
real_job_->Start();
}

View File

@@ -4,7 +4,8 @@
#include "browser/net/atom_url_request_context_getter.h"
#include "base/string_util.h"
#include "base/strings/string_util.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/worker_pool.h"
#include "browser/net/atom_url_request_job_factory.h"
#include "content/public/browser/browser_thread.h"
@@ -36,15 +37,15 @@ using content::BrowserThread;
AtomURLRequestContextGetter::AtomURLRequestContextGetter(
const base::FilePath& base_path,
MessageLoop* io_loop,
MessageLoop* file_loop,
scoped_ptr<brightray::NetworkDelegate> network_delegate,
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_(network_delegate.Pass()) {
network_delegate_factory_(factory) {
// Must first be created on the UI thread.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -65,8 +66,10 @@ 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()));
@@ -74,6 +77,7 @@ net::URLRequestContext* AtomURLRequestContextGetter::GetURLRequestContext() {
base_path_.Append(FILE_PATH_LITERAL("Cookies")),
false,
nullptr,
nullptr,
nullptr));
storage_->set_server_bound_cert_service(new net::ServerBoundCertService(
new net::DefaultServerBoundCertStore(NULL),
@@ -87,6 +91,7 @@ net::URLRequestContext* AtomURLRequestContextGetter::GetURLRequestContext() {
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(),
@@ -98,7 +103,9 @@ net::URLRequestContext* AtomURLRequestContextGetter::GetURLRequestContext() {
storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults);
storage_->set_http_auth_handler_factory(
net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get()));
storage_->set_http_server_properties(new net::HttpServerPropertiesImpl);
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 =
@@ -112,6 +119,8 @@ net::URLRequestContext* AtomURLRequestContextGetter::GetURLRequestContext() {
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 =
@@ -147,10 +156,15 @@ net::URLRequestContext* AtomURLRequestContextGetter::GetURLRequestContext() {
}
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(chrome::kDataScheme,
new net::DataProtocolHandler);
job_factory_->SetProtocolHandler(chrome::kFileScheme,
new net::FileProtocolHandler);
file_protocol_handler.release());
storage_->set_job_factory(job_factory_);
}

View File

@@ -5,8 +5,10 @@
#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"
@@ -34,7 +36,7 @@ class AtomURLRequestContextGetter : public net::URLRequestContextGetter {
const base::FilePath& base_path,
base::MessageLoop* io_loop,
base::MessageLoop* file_loop,
scoped_ptr<brightray::NetworkDelegate> network_delegate,
base::Callback<scoped_ptr<brightray::NetworkDelegate>(void)>,
content::ProtocolHandlerMap* protocol_handlers);
// net::URLRequestContextGetter implementations:
@@ -53,7 +55,12 @@ class AtomURLRequestContextGetter : public net::URLRequestContextGetter {
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_;

View File

@@ -6,7 +6,6 @@
#include "browser/net/atom_url_request_job_factory.h"
#include "base/stl_util.h"
#include "googleurl/src/gurl.h"
#include "net/base/load_flags.h"
#include "net/url_request/url_request.h"
@@ -102,4 +101,9 @@ bool AtomURLRequestJobFactory::IsHandledURL(const GURL& url) const {
return IsHandledProtocol(url.scheme());
}
bool AtomURLRequestJobFactory::IsSafeRedirectTarget(
const GURL& location) const {
return IsHandledURL(location);
}
} // namespace atom

View File

@@ -45,6 +45,7 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
net::NetworkDelegate* network_delegate) const OVERRIDE;
virtual bool IsHandledProtocol(const std::string& scheme) const OVERRIDE;
virtual bool IsHandledURL(const GURL& url) const OVERRIDE;
virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE;
private:
typedef std::map<std::string, ProtocolHandler*> ProtocolHandlerMap;

View File

@@ -11,7 +11,7 @@
<key>CFBundleIconFile</key>
<string>atom.icns</string>
<key>CFBundleVersion</key>
<string>0.7.6</string>
<string>0.10.1</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>

View File

Before

Width:  |  Height:  |  Size: 345 KiB

After

Width:  |  Height:  |  Size: 345 KiB

View File

@@ -50,8 +50,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,7,6,0
PRODUCTVERSION 0,7,6,0
FILEVERSION 0,10,1,0
PRODUCTVERSION 0,10,1,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -68,12 +68,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Atom-Shell"
VALUE "FileVersion", "0.7.6"
VALUE "FileVersion", "0.10.1"
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.7.6"
VALUE "ProductVersion", "0.10.1"
END
END
BLOCK "VarFileInfo"

View File

@@ -8,7 +8,7 @@
#include <string>
#include "base/string_util.h"
#include "base/strings/string_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "ui/base/accelerators/accelerator.h"

View File

@@ -0,0 +1,20 @@
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "browser/ui/accelerator_util.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/accelerators/platform_accelerator_gtk.h"
namespace accelerator_util {
void SetPlatformAccelerator(ui::Accelerator* accelerator) {
scoped_ptr<ui::PlatformAccelerator> platform_accelerator(
new ui::PlatformAcceleratorGtk(
GetGdkKeyCodeForAccelerator(*accelerator),
GetGdkModifierForAccelerator(*accelerator)));
accelerator->set_platform_accelerator(platform_accelerator.Pass());
}
} // namespace accelerator_util

View File

@@ -6,7 +6,7 @@
#include "ui/base/accelerators/accelerator.h"
#import "ui/base/accelerators/platform_accelerator_cocoa.h"
#import "ui/base/keycodes/keyboard_code_conversion_mac.h"
#import "ui/events/keycodes/keyboard_code_conversion_mac.h"
namespace accelerator_util {

View File

@@ -3,13 +3,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_UI_ATOM_MENU_CONTROLLER_MAC_H_
#define ATOM_BROWSER_UI_ATOM_MENU_CONTROLLER_MAC_H_
#ifndef ATOM_BROWSER_UI_COCOA_ATOM_MENU_CONTROLLER_H_
#define ATOM_BROWSER_UI_COCOA_ATOM_MENU_CONTROLLER_H_
#import <Cocoa/Cocoa.h>
#include "base/memory/scoped_nsobject.h"
#include "base/string16.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/string16.h"
namespace ui {
class MenuModel;
@@ -24,7 +24,7 @@ class MenuModel;
@interface AtomMenuController : NSObject<NSMenuDelegate> {
@protected
ui::MenuModel* model_; // weak
scoped_nsobject<NSMenu> menu_;
base::scoped_nsobject<NSMenu> menu_;
BOOL isMenuOpen_;
}
@@ -69,4 +69,4 @@ class MenuModel;
- (NSMenu*)menuFromModel:(ui::MenuModel*)model;
@end
#endif // ATOM_BROWSER_UI_ATOM_MENU_CONTROLLER_MAC_H_
#endif // ATOM_BROWSER_UI_COCOA_ATOM_MENU_CONTROLLER_H_

View File

@@ -3,7 +3,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "browser/ui/atom_menu_controller_mac.h"
#import "browser/ui/cocoa/atom_menu_controller.h"
#include "base/logging.h"
#include "base/strings/sys_string_conversions.h"
@@ -133,7 +133,7 @@ int EventFlagsFromNSEvent(NSEvent* event) {
fromModel:(ui::MenuModel*)model {
string16 label16 = model->GetLabelAt(index);
NSString* label = l10n_util::FixUpWindowsStyleLabel(label16);
scoped_nsobject<NSMenuItem> item(
base::scoped_nsobject<NSMenuItem> item(
[[NSMenuItem alloc] initWithTitle:label
action:@selector(itemSelected:)
keyEquivalent:@""]);

View File

@@ -2,17 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_UI_ATOM_EVENT_PROCESSING_WINDOW_H_
#define ATOM_BROWSER_UI_ATOM_EVENT_PROCESSING_WINDOW_H_
#ifndef ATOM_BROWSER_UI_COCOA_EVENT_PROCESSING_WINDOW_H_
#define ATOM_BROWSER_UI_COCOA_EVENT_PROCESSING_WINDOW_H_
#import <Cocoa/Cocoa.h>
#include "base/memory/scoped_nsobject.h"
// Override NSWindow to access unhandled keyboard events (for command
// processing); subclassing NSWindow is the only method to do
// this.
@interface AtomEventProcessingWindow : NSWindow {
@interface EventProcessingWindow : NSWindow {
@private
BOOL redispatchingEvent_;
BOOL eventHandled_;
@@ -29,4 +27,4 @@
- (BOOL)performKeyEquivalent:(NSEvent*)theEvent;
@end
#endif // ATOM_BROWSER_UI_ATOM_EVENT_PROCESSING_WINDOW_H_
#endif // ATOM_BROWSER_UI_COCOA_EVENT_PROCESSING_WINDOW_H_

View File

@@ -2,17 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "browser/ui/atom_event_processing_window.h"
#import "browser/ui/cocoa/event_processing_window.h"
#include "base/logging.h"
#import "content/public/browser/render_widget_host_view_mac_base.h"
@interface AtomEventProcessingWindow ()
@interface EventProcessingWindow ()
// Duplicate the given key event, but changing the associated window.
- (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event;
@end
@implementation AtomEventProcessingWindow
@implementation EventProcessingWindow
- (BOOL)redispatchKeyEvent:(NSEvent*)event {
DCHECK(event);
@@ -103,4 +103,4 @@
return NO;
}
@end // AtomEventProcessingWindow
@end // EventProcessingWindow

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "browser/ui/nsalert_synchronous_sheet_mac.h"
#import "browser/ui/cocoa/nsalert_synchronous_sheet.h"
// Private methods -- use prefixes to avoid collisions with Apple's methods
@interface NSAlert (SynchronousSheetPrivate)

View File

@@ -0,0 +1,41 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "browser/ui/file_dialog.h"
#include "base/callback.h"
namespace file_dialog {
bool ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
int properties,
std::vector<base::FilePath>* paths) {
return false;
}
void ShowOpenDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
int properties,
const OpenDialogCallback& callback) {
callback.Run(false, std::vector<base::FilePath>());
}
bool ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
base::FilePath* path) {
return false;
}
void ShowSaveDialog(atom::NativeWindow* parent_window,
const std::string& title,
const base::FilePath& default_path,
const SaveDialogCallback& callback) {
callback.Run(false, base::FilePath());
}
} // namespace file_dialog

View File

@@ -24,7 +24,7 @@ void SetupDialog(NSSavePanel* dialog,
NSString* default_dir = nil;
NSString* default_filename = nil;
if (!default_path.empty()) {
if (file_util::DirectoryExists(default_path)) {
if (base::DirectoryExists(default_path)) {
default_dir = base::SysUTF8ToNSString(default_path.value());
} else {
default_dir = base::SysUTF8ToNSString(default_path.DirName().value());

View File

@@ -11,9 +11,9 @@
#include "base/file_util.h"
#include "base/i18n/case_conversion.h"
#include "base/string_util.h"
#include "base/strings/string_util.h"
#include "base/strings/string_split.h"
#include "base/utf_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/registry.h"
#include "browser/native_window.h"
#include "third_party/wtl/include/atlapp.h"
@@ -163,6 +163,7 @@ class FileDialog {
}
bool Show(atom::NativeWindow* parent_window) {
atom::NativeWindow::DialogScope dialog_scope(parent_window);
HWND window = parent_window ? parent_window->GetNativeWindow() : NULL;
return dialog_->DoModal(window) == IDOK;
}

View File

@@ -0,0 +1,150 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "browser/ui/gtk/gtk_custom_menu.h"
#include "browser/ui/gtk/gtk_custom_menu_item.h"
G_DEFINE_TYPE(GtkCustomMenu, gtk_custom_menu, GTK_TYPE_MENU)
// Stolen directly from gtkmenushell.c. I'd love to call the library version
// instead, but it's static and isn't exported. :(
static gint gtk_menu_shell_is_item(GtkMenuShell* menu_shell,
GtkWidget* child) {
GtkWidget *parent;
g_return_val_if_fail(GTK_IS_MENU_SHELL(menu_shell), FALSE);
g_return_val_if_fail(child != NULL, FALSE);
parent = gtk_widget_get_parent(child);
while (GTK_IS_MENU_SHELL(parent)) {
if (parent == reinterpret_cast<GtkWidget*>(menu_shell))
return TRUE;
parent = GTK_MENU_SHELL(parent)->parent_menu_shell;
}
return FALSE;
}
// Stolen directly from gtkmenushell.c. I'd love to call the library version
// instead, but it's static and isn't exported. :(
static GtkWidget* gtk_menu_shell_get_item(GtkMenuShell* menu_shell,
GdkEvent* event) {
GtkWidget* menu_item = gtk_get_event_widget(event);
while (menu_item && !GTK_IS_MENU_ITEM(menu_item))
menu_item = gtk_widget_get_parent(menu_item);
if (menu_item && gtk_menu_shell_is_item(menu_shell, menu_item))
return menu_item;
else
return NULL;
}
// When processing a button event, abort processing if the cursor isn't in a
// clickable region.
static gboolean gtk_custom_menu_button_press(GtkWidget* widget,
GdkEventButton* event) {
GtkWidget* menu_item = gtk_menu_shell_get_item(
GTK_MENU_SHELL(widget), reinterpret_cast<GdkEvent*>(event));
if (GTK_IS_CUSTOM_MENU_ITEM(menu_item)) {
if (!gtk_custom_menu_item_is_in_clickable_region(
GTK_CUSTOM_MENU_ITEM(menu_item))) {
return TRUE;
}
}
return GTK_WIDGET_CLASS(gtk_custom_menu_parent_class)->
button_press_event(widget, event);
}
// When processing a button event, abort processing if the cursor isn't in a
// clickable region. If it's in a button that doesn't dismiss the menu, fire
// that event and abort having the normal GtkMenu code run.
static gboolean gtk_custom_menu_button_release(GtkWidget* widget,
GdkEventButton* event) {
GtkWidget* menu_item = gtk_menu_shell_get_item(
GTK_MENU_SHELL(widget), reinterpret_cast<GdkEvent*>(event));
if (GTK_IS_CUSTOM_MENU_ITEM(menu_item)) {
if (!gtk_custom_menu_item_is_in_clickable_region(
GTK_CUSTOM_MENU_ITEM(menu_item))) {
// Stop processing this event. This isn't a clickable region.
return TRUE;
}
if (gtk_custom_menu_item_try_no_dismiss_command(
GTK_CUSTOM_MENU_ITEM(menu_item))) {
return TRUE;
}
}
return GTK_WIDGET_CLASS(gtk_custom_menu_parent_class)->
button_release_event(widget, event);
}
// Manually forward button press events to the menu item (and then do what we'd
// do normally).
static gboolean gtk_custom_menu_motion_notify(GtkWidget* widget,
GdkEventMotion* event) {
GtkWidget* menu_item = gtk_menu_shell_get_item(
GTK_MENU_SHELL(widget), (GdkEvent*)event);
if (GTK_IS_CUSTOM_MENU_ITEM(menu_item)) {
gtk_custom_menu_item_receive_motion_event(GTK_CUSTOM_MENU_ITEM(menu_item),
event->x, event->y);
}
return GTK_WIDGET_CLASS(gtk_custom_menu_parent_class)->
motion_notify_event(widget, event);
}
static void gtk_custom_menu_move_current(GtkMenuShell* menu_shell,
GtkMenuDirectionType direction) {
// If the currently selected item is custom, we give it first chance to catch
// up/down events.
// TODO(erg): We are breaking a GSEAL by directly accessing this. We'll need
// to fix this by the time gtk3 comes out.
GtkWidget* menu_item = GTK_MENU_SHELL(menu_shell)->active_menu_item;
if (GTK_IS_CUSTOM_MENU_ITEM(menu_item)) {
switch (direction) {
case GTK_MENU_DIR_PREV:
case GTK_MENU_DIR_NEXT:
if (gtk_custom_menu_item_handle_move(GTK_CUSTOM_MENU_ITEM(menu_item),
direction))
return;
break;
default:
break;
}
}
GTK_MENU_SHELL_CLASS(gtk_custom_menu_parent_class)->
move_current(menu_shell, direction);
// In the case of hitting PREV and transitioning to a custom menu, we want to
// make sure we're selecting the final item in the list, not the first one.
menu_item = GTK_MENU_SHELL(menu_shell)->active_menu_item;
if (GTK_IS_CUSTOM_MENU_ITEM(menu_item)) {
gtk_custom_menu_item_select_item_by_direction(
GTK_CUSTOM_MENU_ITEM(menu_item), direction);
}
}
static void gtk_custom_menu_init(GtkCustomMenu* menu) {
}
static void gtk_custom_menu_class_init(GtkCustomMenuClass* klass) {
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
GtkMenuShellClass* menu_shell_class = GTK_MENU_SHELL_CLASS(klass);
widget_class->button_press_event = gtk_custom_menu_button_press;
widget_class->button_release_event = gtk_custom_menu_button_release;
widget_class->motion_notify_event = gtk_custom_menu_motion_notify;
menu_shell_class->move_current = gtk_custom_menu_move_current;
}
GtkWidget* gtk_custom_menu_new() {
return GTK_WIDGET(g_object_new(GTK_TYPE_CUSTOM_MENU, NULL));
}

View File

@@ -0,0 +1,51 @@
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_GTK_GTK_CUSTOM_MENU_H_
#define CHROME_BROWSER_UI_GTK_GTK_CUSTOM_MENU_H_
// GtkCustomMenu is a GtkMenu subclass that can contain, and collaborates with,
// GtkCustomMenuItem instances. GtkCustomMenuItem is a GtkMenuItem that can
// have buttons and other normal widgets embeded in it. GtkCustomMenu exists
// only to override most of the button/motion/move callback functions so
// that the normal GtkMenu implementation doesn't handle events related to
// GtkCustomMenuItem items.
//
// For a more through overview of this system, see the comments in
// gtk_custom_menu_item.h.
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define GTK_TYPE_CUSTOM_MENU \
(gtk_custom_menu_get_type())
#define GTK_CUSTOM_MENU(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_CUSTOM_MENU, GtkCustomMenu))
#define GTK_CUSTOM_MENU_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_CUSTOM_MENU, GtkCustomMenuClass))
#define GTK_IS_CUSTOM_MENU(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_CUSTOM_MENU))
#define GTK_IS_CUSTOM_MENU_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_CUSTOM_MENU))
#define GTK_CUSTOM_MENU_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_CUSTOM_MENU, GtkCustomMenuClass))
typedef struct _GtkCustomMenu GtkCustomMenu;
typedef struct _GtkCustomMenuClass GtkCustomMenuClass;
struct _GtkCustomMenu {
GtkMenu menu;
};
struct _GtkCustomMenuClass {
GtkMenuClass parent_class;
};
GType gtk_custom_menu_get_type(void) G_GNUC_CONST;
GtkWidget* gtk_custom_menu_new();
G_END_DECLS
#endif // CHROME_BROWSER_UI_GTK_GTK_CUSTOM_MENU_H_

View File

@@ -0,0 +1,493 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "browser/ui/gtk/gtk_custom_menu_item.h"
#include "base/i18n/rtl.h"
#include "browser/ui/gtk/gtk_custom_menu.h"
#include "ui/gfx/gtk_compat.h"
// This method was autogenerated by the program glib-genmarshall, which
// generated it from the line "BOOL:INT". Two different attempts at getting gyp
// to autogenerate this didn't work. If we need more non-standard marshallers,
// this should be deleted, and an actual build step should be added.
void chrome_marshall_BOOLEAN__INT(GClosure* closure,
GValue* return_value G_GNUC_UNUSED,
guint n_param_values,
const GValue* param_values,
gpointer invocation_hint G_GNUC_UNUSED,
gpointer marshal_data) {
typedef gboolean(*GMarshalFunc_BOOLEAN__INT)(gpointer data1,
gint arg_1,
gpointer data2);
register GMarshalFunc_BOOLEAN__INT callback;
register GCClosure *cc = (GCClosure*)closure;
register gpointer data1, data2;
gboolean v_return;
g_return_if_fail(return_value != NULL);
g_return_if_fail(n_param_values == 2);
if (G_CCLOSURE_SWAP_DATA(closure)) {
data1 = closure->data;
// Note: This line (and the line setting data1 in the other if branch)
// were macros in the original autogenerated output. This is with the
// macro resolved for release mode. In debug mode, it uses an accessor
// that asserts saying that the object pointed to by param_values doesn't
// hold a pointer. This appears to be the cause of http://crbug.com/58945.
//
// This is more than a little odd because the gtype on this first param
// isn't set correctly by the time we get here, while I watched it
// explicitly set upstack. I verified that v_pointer is still set
// correctly. I'm not sure what's going on. :(
data2 = (param_values + 0)->data[0].v_pointer;
} else {
data1 = (param_values + 0)->data[0].v_pointer;
data2 = closure->data;
}
callback = (GMarshalFunc_BOOLEAN__INT)(marshal_data ? marshal_data :
cc->callback);
v_return = callback(data1,
g_value_get_int(param_values + 1),
data2);
g_value_set_boolean(return_value, v_return);
}
enum {
BUTTON_PUSHED,
TRY_BUTTON_PUSHED,
LAST_SIGNAL
};
static guint custom_menu_item_signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE(GtkCustomMenuItem, gtk_custom_menu_item, GTK_TYPE_MENU_ITEM)
static void set_selected(GtkCustomMenuItem* item, GtkWidget* selected) {
if (selected != item->currently_selected_button) {
if (item->currently_selected_button) {
gtk_widget_set_state(item->currently_selected_button, GTK_STATE_NORMAL);
gtk_widget_set_state(
gtk_bin_get_child(GTK_BIN(item->currently_selected_button)),
GTK_STATE_NORMAL);
}
item->currently_selected_button = selected;
if (item->currently_selected_button) {
gtk_widget_set_state(item->currently_selected_button, GTK_STATE_SELECTED);
gtk_widget_set_state(
gtk_bin_get_child(GTK_BIN(item->currently_selected_button)),
GTK_STATE_PRELIGHT);
}
}
}
// When GtkButtons set the label text, they rebuild the widget hierarchy each
// and every time. Therefore, we can't just fish out the label from the button
// and set some properties; we have to create this callback function that
// listens on the button's "notify" signal, which is emitted right after the
// label has been (re)created. (Label values can change dynamically.)
static void on_button_label_set(GObject* object) {
GtkButton* button = GTK_BUTTON(object);
GtkWidget* child = gtk_bin_get_child(GTK_BIN(button));
gtk_widget_set_sensitive(child, FALSE);
gtk_misc_set_padding(GTK_MISC(child), 2, 0);
}
static void gtk_custom_menu_item_finalize(GObject *object);
static gint gtk_custom_menu_item_expose(GtkWidget* widget,
GdkEventExpose* event);
static gboolean gtk_custom_menu_item_hbox_expose(GtkWidget* widget,
GdkEventExpose* event,
GtkCustomMenuItem* menu_item);
static void gtk_custom_menu_item_select(GtkItem *item);
static void gtk_custom_menu_item_deselect(GtkItem *item);
static void gtk_custom_menu_item_activate(GtkMenuItem* menu_item);
static void gtk_custom_menu_item_init(GtkCustomMenuItem* item) {
item->all_widgets = NULL;
item->button_widgets = NULL;
item->currently_selected_button = NULL;
item->previously_selected_button = NULL;
GtkWidget* menu_hbox = gtk_hbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(item), menu_hbox);
item->label = gtk_label_new(NULL);
gtk_misc_set_alignment(GTK_MISC(item->label), 0.0, 0.5);
gtk_box_pack_start(GTK_BOX(menu_hbox), item->label, TRUE, TRUE, 0);
item->hbox = gtk_hbox_new(FALSE, 0);
gtk_box_pack_end(GTK_BOX(menu_hbox), item->hbox, FALSE, FALSE, 0);
g_signal_connect(item->hbox, "expose-event",
G_CALLBACK(gtk_custom_menu_item_hbox_expose),
item);
gtk_widget_show_all(menu_hbox);
}
static void gtk_custom_menu_item_class_init(GtkCustomMenuItemClass* klass) {
GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
GtkItemClass* item_class = GTK_ITEM_CLASS(klass);
GtkMenuItemClass* menu_item_class = GTK_MENU_ITEM_CLASS(klass);
gobject_class->finalize = gtk_custom_menu_item_finalize;
widget_class->expose_event = gtk_custom_menu_item_expose;
item_class->select = gtk_custom_menu_item_select;
item_class->deselect = gtk_custom_menu_item_deselect;
menu_item_class->activate = gtk_custom_menu_item_activate;
custom_menu_item_signals[BUTTON_PUSHED] =
g_signal_new("button-pushed",
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__INT,
G_TYPE_NONE, 1, G_TYPE_INT);
custom_menu_item_signals[TRY_BUTTON_PUSHED] =
g_signal_new("try-button-pushed",
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
chrome_marshall_BOOLEAN__INT,
G_TYPE_BOOLEAN, 1, G_TYPE_INT);
}
static void gtk_custom_menu_item_finalize(GObject *object) {
GtkCustomMenuItem* item = GTK_CUSTOM_MENU_ITEM(object);
g_list_free(item->all_widgets);
g_list_free(item->button_widgets);
G_OBJECT_CLASS(gtk_custom_menu_item_parent_class)->finalize(object);
}
static gint gtk_custom_menu_item_expose(GtkWidget* widget,
GdkEventExpose* event) {
if (gtk_widget_get_visible(widget) &&
gtk_widget_get_mapped(widget) &&
gtk_bin_get_child(GTK_BIN(widget))) {
// We skip the drawing in the GtkMenuItem class it draws the highlighted
// background and we don't want that.
gtk_container_propagate_expose(GTK_CONTAINER(widget),
gtk_bin_get_child(GTK_BIN(widget)),
event);
}
return FALSE;
}
static void gtk_custom_menu_item_expose_button(GtkWidget* hbox,
GdkEventExpose* event,
GList* button_item) {
// We search backwards to find the leftmost and rightmost buttons. The
// current button may be that button.
GtkWidget* current_button = GTK_WIDGET(button_item->data);
GtkWidget* first_button = current_button;
for (GList* i = button_item; i && GTK_IS_BUTTON(i->data);
i = g_list_previous(i)) {
first_button = GTK_WIDGET(i->data);
}
GtkWidget* last_button = current_button;
for (GList* i = button_item; i && GTK_IS_BUTTON(i->data);
i = g_list_next(i)) {
last_button = GTK_WIDGET(i->data);
}
if (base::i18n::IsRTL())
std::swap(first_button, last_button);
GtkAllocation first_allocation;
gtk_widget_get_allocation(first_button, &first_allocation);
GtkAllocation current_allocation;
gtk_widget_get_allocation(current_button, &current_allocation);
GtkAllocation last_allocation;
gtk_widget_get_allocation(last_button, &last_allocation);
int x = first_allocation.x;
int y = first_allocation.y;
int width = last_allocation.width + last_allocation.x - first_allocation.x;
int height = last_allocation.height;
gtk_paint_box(gtk_widget_get_style(hbox),
gtk_widget_get_window(hbox),
gtk_widget_get_state(current_button),
GTK_SHADOW_OUT,
&current_allocation, hbox, "button",
x, y, width, height);
// Propagate to the button's children.
gtk_container_propagate_expose(
GTK_CONTAINER(current_button),
gtk_bin_get_child(GTK_BIN(current_button)),
event);
}
static gboolean gtk_custom_menu_item_hbox_expose(GtkWidget* widget,
GdkEventExpose* event,
GtkCustomMenuItem* menu_item) {
// First render all the buttons that aren't the currently selected item.
for (GList* current_item = menu_item->all_widgets;
current_item != NULL; current_item = g_list_next(current_item)) {
if (GTK_IS_BUTTON(current_item->data)) {
if (GTK_WIDGET(current_item->data) !=
menu_item->currently_selected_button) {
gtk_custom_menu_item_expose_button(widget, event, current_item);
}
}
}
// As a separate pass, draw the buton separators above. We need to draw the
// separators in a separate pass because we are drawing on top of the
// buttons. Otherwise, the vlines are overwritten by the next button.
for (GList* current_item = menu_item->all_widgets;
current_item != NULL; current_item = g_list_next(current_item)) {
if (GTK_IS_BUTTON(current_item->data)) {
// Check to see if this is the last button in a run.
GList* next_item = g_list_next(current_item);
if (next_item && GTK_IS_BUTTON(next_item->data)) {
GtkWidget* current_button = GTK_WIDGET(current_item->data);
GtkAllocation button_allocation;
gtk_widget_get_allocation(current_button, &button_allocation);
GtkAllocation child_alloc;
gtk_widget_get_allocation(gtk_bin_get_child(GTK_BIN(current_button)),
&child_alloc);
GtkStyle* style = gtk_widget_get_style(widget);
int half_offset = style->xthickness / 2;
gtk_paint_vline(style,
gtk_widget_get_window(widget),
gtk_widget_get_state(current_button),
&event->area, widget, "button",
child_alloc.y,
child_alloc.y + child_alloc.height,
button_allocation.x +
button_allocation.width - half_offset);
}
}
}
// Finally, draw the selected item on top of the separators so there are no
// artifacts inside the button area.
GList* selected = g_list_find(menu_item->all_widgets,
menu_item->currently_selected_button);
if (selected) {
gtk_custom_menu_item_expose_button(widget, event, selected);
}
return TRUE;
}
static void gtk_custom_menu_item_select(GtkItem* item) {
GtkCustomMenuItem* custom_item = GTK_CUSTOM_MENU_ITEM(item);
// When we are selected, the only thing we do is clear information from
// previous selections. Actual selection of a button is done either in the
// "mouse-motion-event" or is manually set from GtkCustomMenu's overridden
// "move-current" handler.
custom_item->previously_selected_button = NULL;
gtk_widget_queue_draw(GTK_WIDGET(item));
}
static void gtk_custom_menu_item_deselect(GtkItem* item) {
GtkCustomMenuItem* custom_item = GTK_CUSTOM_MENU_ITEM(item);
// When we are deselected, we store the item that was currently selected so
// that it can be acted on. Menu items are first deselected before they are
// activated.
custom_item->previously_selected_button =
custom_item->currently_selected_button;
if (custom_item->currently_selected_button)
set_selected(custom_item, NULL);
gtk_widget_queue_draw(GTK_WIDGET(item));
}
static void gtk_custom_menu_item_activate(GtkMenuItem* menu_item) {
GtkCustomMenuItem* custom_item = GTK_CUSTOM_MENU_ITEM(menu_item);
// We look at |previously_selected_button| because by the time we've been
// activated, we've already gone through our deselect handler.
if (custom_item->previously_selected_button) {
gpointer id_ptr = g_object_get_data(
G_OBJECT(custom_item->previously_selected_button), "command-id");
if (id_ptr != NULL) {
int command_id = GPOINTER_TO_INT(id_ptr);
g_signal_emit(custom_item, custom_menu_item_signals[BUTTON_PUSHED], 0,
command_id);
set_selected(custom_item, NULL);
}
}
}
GtkWidget* gtk_custom_menu_item_new(const char* title) {
GtkCustomMenuItem* item = GTK_CUSTOM_MENU_ITEM(
g_object_new(GTK_TYPE_CUSTOM_MENU_ITEM, NULL));
gtk_label_set_text(GTK_LABEL(item->label), title);
return GTK_WIDGET(item);
}
GtkWidget* gtk_custom_menu_item_add_button(GtkCustomMenuItem* menu_item,
int command_id) {
GtkWidget* button = gtk_button_new();
g_object_set_data(G_OBJECT(button), "command-id",
GINT_TO_POINTER(command_id));
gtk_box_pack_start(GTK_BOX(menu_item->hbox), button, FALSE, FALSE, 0);
gtk_widget_show(button);
menu_item->all_widgets = g_list_append(menu_item->all_widgets, button);
menu_item->button_widgets = g_list_append(menu_item->button_widgets, button);
return button;
}
GtkWidget* gtk_custom_menu_item_add_button_label(GtkCustomMenuItem* menu_item,
int command_id) {
GtkWidget* button = gtk_button_new_with_label("");
g_object_set_data(G_OBJECT(button), "command-id",
GINT_TO_POINTER(command_id));
gtk_box_pack_start(GTK_BOX(menu_item->hbox), button, FALSE, FALSE, 0);
g_signal_connect(button, "notify::label",
G_CALLBACK(on_button_label_set), NULL);
gtk_widget_show(button);
menu_item->all_widgets = g_list_append(menu_item->all_widgets, button);
return button;
}
void gtk_custom_menu_item_add_space(GtkCustomMenuItem* menu_item) {
GtkWidget* fixed = gtk_fixed_new();
gtk_widget_set_size_request(fixed, 5, -1);
gtk_box_pack_start(GTK_BOX(menu_item->hbox), fixed, FALSE, FALSE, 0);
gtk_widget_show(fixed);
menu_item->all_widgets = g_list_append(menu_item->all_widgets, fixed);
}
void gtk_custom_menu_item_receive_motion_event(GtkCustomMenuItem* menu_item,
gdouble x, gdouble y) {
GtkWidget* new_selected_widget = NULL;
GList* current = menu_item->button_widgets;
for (; current != NULL; current = current->next) {
GtkWidget* current_widget = GTK_WIDGET(current->data);
GtkAllocation alloc;
gtk_widget_get_allocation(current_widget, &alloc);
int offset_x, offset_y;
gtk_widget_translate_coordinates(current_widget, GTK_WIDGET(menu_item),
0, 0, &offset_x, &offset_y);
if (x >= offset_x && x < (offset_x + alloc.width) &&
y >= offset_y && y < (offset_y + alloc.height)) {
new_selected_widget = current_widget;
break;
}
}
set_selected(menu_item, new_selected_widget);
}
gboolean gtk_custom_menu_item_handle_move(GtkCustomMenuItem* menu_item,
GtkMenuDirectionType direction) {
GtkWidget* current = menu_item->currently_selected_button;
if (menu_item->button_widgets && current) {
switch (direction) {
case GTK_MENU_DIR_PREV: {
if (g_list_first(menu_item->button_widgets)->data == current)
return FALSE;
set_selected(menu_item, GTK_WIDGET(g_list_previous(g_list_find(
menu_item->button_widgets, current))->data));
break;
}
case GTK_MENU_DIR_NEXT: {
if (g_list_last(menu_item->button_widgets)->data == current)
return FALSE;
set_selected(menu_item, GTK_WIDGET(g_list_next(g_list_find(
menu_item->button_widgets, current))->data));
break;
}
default:
break;
}
}
return TRUE;
}
void gtk_custom_menu_item_select_item_by_direction(
GtkCustomMenuItem* menu_item, GtkMenuDirectionType direction) {
menu_item->previously_selected_button = NULL;
// If we're just told to be selected by the menu system, select the first
// item.
if (menu_item->button_widgets) {
switch (direction) {
case GTK_MENU_DIR_PREV: {
GtkWidget* last_button =
GTK_WIDGET(g_list_last(menu_item->button_widgets)->data);
if (last_button)
set_selected(menu_item, last_button);
break;
}
case GTK_MENU_DIR_NEXT: {
GtkWidget* first_button =
GTK_WIDGET(g_list_first(menu_item->button_widgets)->data);
if (first_button)
set_selected(menu_item, first_button);
break;
}
default:
break;
}
}
gtk_widget_queue_draw(GTK_WIDGET(menu_item));
}
gboolean gtk_custom_menu_item_is_in_clickable_region(
GtkCustomMenuItem* menu_item) {
return menu_item->currently_selected_button != NULL;
}
gboolean gtk_custom_menu_item_try_no_dismiss_command(
GtkCustomMenuItem* menu_item) {
GtkCustomMenuItem* custom_item = GTK_CUSTOM_MENU_ITEM(menu_item);
gboolean activated = TRUE;
// We work with |currently_selected_button| instead of
// |previously_selected_button| since we haven't been "deselect"ed yet.
gpointer id_ptr = g_object_get_data(
G_OBJECT(custom_item->currently_selected_button), "command-id");
if (id_ptr != NULL) {
int command_id = GPOINTER_TO_INT(id_ptr);
g_signal_emit(custom_item, custom_menu_item_signals[TRY_BUTTON_PUSHED], 0,
command_id, &activated);
}
return activated;
}
void gtk_custom_menu_item_foreach_button(GtkCustomMenuItem* menu_item,
GtkCallback callback,
gpointer callback_data) {
// Even though we're filtering |all_widgets| on GTK_IS_BUTTON(), this isn't
// equivalent to |button_widgets| because we also want the button-labels.
for (GList* i = menu_item->all_widgets; i && GTK_IS_BUTTON(i->data);
i = g_list_next(i)) {
if (GTK_IS_BUTTON(i->data)) {
callback(GTK_WIDGET(i->data), callback_data);
}
}
}

View File

@@ -0,0 +1,139 @@
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_GTK_GTK_CUSTOM_MENU_ITEM_H_
#define CHROME_BROWSER_UI_GTK_GTK_CUSTOM_MENU_ITEM_H_
// GtkCustomMenuItem is a GtkMenuItem subclass that has buttons in it and acts
// to support this. GtkCustomMenuItems only render properly when put in a
// GtkCustomMenu; there's a lot of collaboration between these two classes
// necessary to work around how gtk normally does menus.
//
// We can't rely on the normal event infrastructure. While a menu is up, the
// GtkMenu has a grab on all events. Instead of trying to pump events through
// the normal channels, we have the GtkCustomMenu selectively forward mouse
// motion through a back channel. The GtkCustomMenu only listens for button
// press information so it can block the effects of the click if the cursor
// isn't in a button in the menu item.
//
// A GtkCustomMenuItem doesn't try to take these signals and forward them to
// the buttons it owns. The GtkCustomMenu class keeps track of which button is
// selected (due to key events and mouse movement) and otherwise acts like a
// normal GtkItem. The buttons are only for sizing and rendering; they don't
// respond to events. Instead, when the GtkCustomMenuItem is activated by the
// GtkMenu, it uses which button was selected as a signal of what to do.
//
// Users should connect to the "button-pushed" signal to be notified when a
// button was pushed. We don't go through the normal "activate" signal because
// we need to communicate additional information, namely which button was
// activated.
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define GTK_TYPE_CUSTOM_MENU_ITEM \
(gtk_custom_menu_item_get_type())
#define GTK_CUSTOM_MENU_ITEM(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_CUSTOM_MENU_ITEM, \
GtkCustomMenuItem))
#define GTK_CUSTOM_MENU_ITEM_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_CUSTOM_MENU_ITEM, \
GtkCustomMenuItemClass))
#define GTK_IS_CUSTOM_MENU_ITEM(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_CUSTOM_MENU_ITEM))
#define GTK_IS_CUSTOM_MENU_ITEM_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_CUSTOM_MENU_ITEM))
#define GTK_CUSTOM_MENU_ITEM_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_CUSTOM_MENU_ITEM, \
GtkCustomMenuItemClass))
typedef struct _GtkCustomMenuItem GtkCustomMenuItem;
typedef struct _GtkCustomMenuItemClass GtkCustomMenuItemClass;
struct _GtkCustomMenuItem {
GtkMenuItem menu_item;
// Container for button widgets.
GtkWidget* hbox;
// Label on left side of menu item.
GtkWidget* label;
// List of all widgets we added. Used to find the leftmost and rightmost
// continuous buttons.
GList* all_widgets;
// Possible button widgets. Used for keyboard navigation.
GList* button_widgets;
// The widget that currently has highlight.
GtkWidget* currently_selected_button;
// The widget that was selected *before* |currently_selected_button|. Why do
// we hang on to this? Because the menu system sends us a deselect signal
// right before activating us. We need to listen to deselect since that's
// what we receive when the mouse cursor leaves us entirely.
GtkWidget* previously_selected_button;
};
struct _GtkCustomMenuItemClass {
GtkMenuItemClass parent_class;
};
GType gtk_custom_menu_item_get_type(void) G_GNUC_CONST;
GtkWidget* gtk_custom_menu_item_new(const char* title);
// Adds a button to our list of items in the |hbox|.
GtkWidget* gtk_custom_menu_item_add_button(GtkCustomMenuItem* menu_item,
int command_id);
// Adds a button to our list of items in the |hbox|, but that isn't part of
// |button_widgets| to prevent it from being activatable.
GtkWidget* gtk_custom_menu_item_add_button_label(GtkCustomMenuItem* menu_item,
int command_id);
// Adds a vertical space in the |hbox|.
void gtk_custom_menu_item_add_space(GtkCustomMenuItem* menu_item);
// Receives a motion event from the GtkCustomMenu that contains us. We can't
// just subscribe to motion-event or the individual widget enter/leave events
// because the top level GtkMenu has an event grab.
void gtk_custom_menu_item_receive_motion_event(GtkCustomMenuItem* menu_item,
gdouble x, gdouble y);
// Notification that the menu got a cursor key event. Used to move up/down
// within the menu buttons. Returns TRUE to stop the default signal handler
// from running.
gboolean gtk_custom_menu_item_handle_move(GtkCustomMenuItem* menu_item,
GtkMenuDirectionType direction);
// Because we only get a generic "selected" signal when we've changed, we need
// to have a way for the GtkCustomMenu to tell us that we were just
// selected.
void gtk_custom_menu_item_select_item_by_direction(
GtkCustomMenuItem* menu_item, GtkMenuDirectionType direction);
// Whether we are currently hovering over a clickable region on the menu
// item. Used by GtkCustomMenu to determine whether it should discard click
// events.
gboolean gtk_custom_menu_item_is_in_clickable_region(
GtkCustomMenuItem* menu_item);
// If the button is released while the |currently_selected_button| isn't
// supposed to dismiss the menu, this signals to our listeners that we want to
// run this command if it doesn't dismiss the menu. Returns TRUE if we acted
// on this button click (and should prevent the normal GtkMenu machinery from
// firing an "activate" signal).
gboolean gtk_custom_menu_item_try_no_dismiss_command(
GtkCustomMenuItem* menu_item);
// Calls |callback| with every button and button-label in the container.
void gtk_custom_menu_item_foreach_button(GtkCustomMenuItem* menu_item,
GtkCallback callback,
gpointer callback_data);
G_END_DECLS
#endif // CHROME_BROWSER_UI_GTK_GTK_CUSTOM_MENU_ITEM_H_

View File

@@ -0,0 +1,295 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "browser/ui/gtk/gtk_window_util.h"
#include <dlfcn.h>
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
using content::RenderWidgetHost;
using content::WebContents;
namespace gtk_window_util {
const int kFrameBorderThickness = 4;
const int kResizeAreaCornerSize = 16;
// Keep track of the last click time and the last click position so we can
// filter out extra GDK_BUTTON_PRESS events when a double click happens.
static guint32 last_click_time;
static int last_click_x;
static int last_click_y;
// Performs Cut/Copy/Paste operation on the |window|.
// If the current render view is focused, then just call the specified |method|
// against the current render view host, otherwise emit the specified |signal|
// against the focused widget.
// TODO(suzhe): This approach does not work for plugins.
void DoCutCopyPaste(GtkWindow* window,
WebContents* web_contents,
void (RenderWidgetHost::*method)(),
const char* signal) {
GtkWidget* widget = gtk_window_get_focus(window);
if (widget == NULL)
return; // Do nothing if no focused widget.
if (web_contents &&
widget == web_contents->GetView()->GetContentNativeView()) {
(web_contents->GetRenderViewHost()->*method)();
} else {
guint id;
if ((id = g_signal_lookup(signal, G_OBJECT_TYPE(widget))) != 0)
g_signal_emit(widget, id, 0);
}
}
void DoCut(GtkWindow* window, WebContents* web_contents) {
DoCutCopyPaste(window, web_contents,
&RenderWidgetHost::Cut, "cut-clipboard");
}
void DoCopy(GtkWindow* window, WebContents* web_contents) {
DoCutCopyPaste(window, web_contents,
&RenderWidgetHost::Copy, "copy-clipboard");
}
void DoPaste(GtkWindow* window, WebContents* web_contents) {
DoCutCopyPaste(window, web_contents,
&RenderWidgetHost::Paste, "paste-clipboard");
}
// Ubuntu patches their version of GTK+ so that there is always a
// gripper in the bottom right corner of the window. We dynamically
// look up this symbol because it's a non-standard Ubuntu extension to
// GTK+. We always need to disable this feature since we can't
// communicate this to WebKit easily.
typedef void (*gtk_window_set_has_resize_grip_func)(GtkWindow*, gboolean);
gtk_window_set_has_resize_grip_func gtk_window_set_has_resize_grip_sym;
void DisableResizeGrip(GtkWindow* window) {
static bool resize_grip_looked_up = false;
if (!resize_grip_looked_up) {
resize_grip_looked_up = true;
gtk_window_set_has_resize_grip_sym =
reinterpret_cast<gtk_window_set_has_resize_grip_func>(
dlsym(NULL, "gtk_window_set_has_resize_grip"));
}
if (gtk_window_set_has_resize_grip_sym)
gtk_window_set_has_resize_grip_sym(window, FALSE);
}
GdkCursorType GdkWindowEdgeToGdkCursorType(GdkWindowEdge edge) {
switch (edge) {
case GDK_WINDOW_EDGE_NORTH_WEST:
return GDK_TOP_LEFT_CORNER;
case GDK_WINDOW_EDGE_NORTH:
return GDK_TOP_SIDE;
case GDK_WINDOW_EDGE_NORTH_EAST:
return GDK_TOP_RIGHT_CORNER;
case GDK_WINDOW_EDGE_WEST:
return GDK_LEFT_SIDE;
case GDK_WINDOW_EDGE_EAST:
return GDK_RIGHT_SIDE;
case GDK_WINDOW_EDGE_SOUTH_WEST:
return GDK_BOTTOM_LEFT_CORNER;
case GDK_WINDOW_EDGE_SOUTH:
return GDK_BOTTOM_SIDE;
case GDK_WINDOW_EDGE_SOUTH_EAST:
return GDK_BOTTOM_RIGHT_CORNER;
default:
NOTREACHED();
}
return GDK_LAST_CURSOR;
}
bool BoundsMatchMonitorSize(GtkWindow* window, gfx::Rect bounds) {
// A screen can be composed of multiple monitors.
GdkScreen* screen = gtk_window_get_screen(window);
GdkRectangle monitor_size;
if (gtk_widget_get_realized(GTK_WIDGET(window))) {
// |window| has been realized.
gint monitor_num = gdk_screen_get_monitor_at_window(screen,
gtk_widget_get_window(GTK_WIDGET(window)));
gdk_screen_get_monitor_geometry(screen, monitor_num, &monitor_size);
return bounds.size() == gfx::Size(monitor_size.width, monitor_size.height);
}
// Make sure the window doesn't match any monitor size. We compare against
// all monitors because we don't know which monitor the window is going to
// open on before window realized.
gint num_monitors = gdk_screen_get_n_monitors(screen);
for (gint i = 0; i < num_monitors; ++i) {
GdkRectangle monitor_size;
gdk_screen_get_monitor_geometry(screen, i, &monitor_size);
if (bounds.size() == gfx::Size(monitor_size.width, monitor_size.height))
return true;
}
return false;
}
bool HandleTitleBarLeftMousePress(
GtkWindow* window,
const gfx::Rect& bounds,
GdkEventButton* event) {
// We want to start a move when the user single clicks, but not start a
// move when the user double clicks. However, a double click sends the
// following GDK events: GDK_BUTTON_PRESS, GDK_BUTTON_RELEASE,
// GDK_BUTTON_PRESS, GDK_2BUTTON_PRESS, GDK_BUTTON_RELEASE. If we
// start a gtk_window_begin_move_drag on the second GDK_BUTTON_PRESS,
// the call to gtk_window_maximize fails. To work around this, we
// keep track of the last click and if it's going to be a double click,
// we don't call gtk_window_begin_move_drag.
DCHECK_EQ(event->type, GDK_BUTTON_PRESS);
DCHECK_EQ(event->button, 1);
static GtkSettings* settings = gtk_settings_get_default();
gint double_click_time = 250;
gint double_click_distance = 5;
g_object_get(G_OBJECT(settings),
"gtk-double-click-time", &double_click_time,
"gtk-double-click-distance", &double_click_distance,
NULL);
guint32 click_time = event->time - last_click_time;
int click_move_x = abs(event->x - last_click_x);
int click_move_y = abs(event->y - last_click_y);
last_click_time = event->time;
last_click_x = static_cast<int>(event->x);
last_click_y = static_cast<int>(event->y);
if (click_time > static_cast<guint32>(double_click_time) ||
click_move_x > double_click_distance ||
click_move_y > double_click_distance) {
// Ignore drag requests if the window is the size of the screen.
// We do this to avoid triggering fullscreen mode in metacity
// (without the --no-force-fullscreen flag) and in compiz (with
// Legacy Fullscreen Mode enabled).
if (!BoundsMatchMonitorSize(window, bounds)) {
gtk_window_begin_move_drag(window, event->button,
static_cast<gint>(event->x_root),
static_cast<gint>(event->y_root),
event->time);
}
return TRUE;
}
return FALSE;
}
void UnMaximize(GtkWindow* window,
const gfx::Rect& bounds,
const gfx::Rect& restored_bounds) {
gtk_window_unmaximize(window);
// It can happen that you end up with a window whose restore size is the same
// as the size of the screen, so unmaximizing it merely remaximizes it due to
// the same WM feature that SetWindowSize() works around. We try to detect
// this and resize the window to work around the issue.
if (bounds.size() == restored_bounds.size())
gtk_window_resize(window, bounds.width(), bounds.height() - 1);
}
void SetWindowCustomClass(GtkWindow* window, const std::string& wmclass) {
gtk_window_set_wmclass(window,
wmclass.c_str(),
gdk_get_program_class());
// Set WM_WINDOW_ROLE for session management purposes.
// See http://tronche.com/gui/x/icccm/sec-5.html .
gtk_window_set_role(window, wmclass.c_str());
}
void SetWindowSize(GtkWindow* window, const gfx::Size& size) {
gfx::Size new_size = size;
gint current_width = 0;
gint current_height = 0;
gtk_window_get_size(window, &current_width, &current_height);
GdkRectangle size_with_decorations = {0};
GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window));
if (gdk_window) {
gdk_window_get_frame_extents(gdk_window,
&size_with_decorations);
}
if (current_width == size_with_decorations.width &&
current_height == size_with_decorations.height) {
// Make sure the window doesn't match any monitor size. We compare against
// all monitors because we don't know which monitor the window is going to
// open on (the WM decides that).
GdkScreen* screen = gtk_window_get_screen(window);
gint num_monitors = gdk_screen_get_n_monitors(screen);
for (gint i = 0; i < num_monitors; ++i) {
GdkRectangle monitor_size;
gdk_screen_get_monitor_geometry(screen, i, &monitor_size);
if (gfx::Size(monitor_size.width, monitor_size.height) == size) {
gtk_window_resize(window, size.width(), size.height() - 1);
return;
}
}
} else {
// gtk_window_resize is the size of the window not including decorations,
// but we are given the |size| including window decorations.
if (size_with_decorations.width > current_width) {
new_size.set_width(size.width() - size_with_decorations.width +
current_width);
}
if (size_with_decorations.height > current_height) {
new_size.set_height(size.height() - size_with_decorations.height +
current_height);
}
}
gtk_window_resize(window, new_size.width(), new_size.height());
}
bool GetWindowEdge(const gfx::Size& window_size,
int top_edge_inset,
int x,
int y,
GdkWindowEdge* edge) {
gfx::Rect middle(window_size);
middle.Inset(kFrameBorderThickness,
kFrameBorderThickness - top_edge_inset,
kFrameBorderThickness,
kFrameBorderThickness);
if (middle.Contains(x, y))
return false;
gfx::Rect north(0, 0, window_size.width(),
kResizeAreaCornerSize - top_edge_inset);
gfx::Rect west(0, 0, kResizeAreaCornerSize, window_size.height());
gfx::Rect south(0, window_size.height() - kResizeAreaCornerSize,
window_size.width(), kResizeAreaCornerSize);
gfx::Rect east(window_size.width() - kResizeAreaCornerSize, 0,
kResizeAreaCornerSize, window_size.height());
if (north.Contains(x, y)) {
if (west.Contains(x, y))
*edge = GDK_WINDOW_EDGE_NORTH_WEST;
else if (east.Contains(x, y))
*edge = GDK_WINDOW_EDGE_NORTH_EAST;
else
*edge = GDK_WINDOW_EDGE_NORTH;
} else if (south.Contains(x, y)) {
if (west.Contains(x, y))
*edge = GDK_WINDOW_EDGE_SOUTH_WEST;
else if (east.Contains(x, y))
*edge = GDK_WINDOW_EDGE_SOUTH_EAST;
else
*edge = GDK_WINDOW_EDGE_SOUTH;
} else {
if (west.Contains(x, y))
*edge = GDK_WINDOW_EDGE_WEST;
else if (east.Contains(x, y))
*edge = GDK_WINDOW_EDGE_EAST;
else
return false; // The cursor must be outside the window.
}
return true;
}
} // namespace gtk_window_util

View File

@@ -0,0 +1,74 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_UI_GTK_GTK_WINDOW_UTIL_H_
#define ATOM_BROWSER_UI_GTK_GTK_WINDOW_UTIL_H_
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include "ui/gfx/rect.h"
namespace content {
class WebContents;
}
namespace gtk_window_util {
// The frame border is only visible in restored mode and is hardcoded to 4 px
// on each side regardless of the system window border size.
extern const int kFrameBorderThickness;
// In the window corners, the resize areas don't actually expand bigger, but
// the 16 px at the end of each edge triggers diagonal resizing.
extern const int kResizeAreaCornerSize;
// Performs Cut/Copy/Paste operation on the |window|'s |web_contents|.
void DoCut(GtkWindow* window, content::WebContents* web_contents);
void DoCopy(GtkWindow* window, content::WebContents* web_contents);
void DoPaste(GtkWindow* window, content::WebContents* web_contents);
// Ubuntu patches their version of GTK+ to that there is always a
// gripper in the bottom right corner of the window. We always need to
// disable this feature since we can't communicate this to WebKit easily.
void DisableResizeGrip(GtkWindow* window);
// Returns the resize cursor corresponding to the window |edge|.
GdkCursorType GdkWindowEdgeToGdkCursorType(GdkWindowEdge edge);
// Returns |true| if the window bounds match the monitor size.
bool BoundsMatchMonitorSize(GtkWindow* window, gfx::Rect bounds);
bool HandleTitleBarLeftMousePress(GtkWindow* window,
const gfx::Rect& bounds,
GdkEventButton* event);
// Request the underlying window to unmaximize. Also tries to work around
// a window manager "feature" that can prevent this in some edge cases.
void UnMaximize(GtkWindow* window,
const gfx::Rect& bounds,
const gfx::Rect& restored_bounds);
// Set a custom WM_CLASS for a window.
void SetWindowCustomClass(GtkWindow* window, const std::string& wmclass);
// A helper method for setting the GtkWindow size that should be used in place
// of calling gtk_window_resize directly. This is done to avoid a WM "feature"
// where setting the window size to the monitor size causes the WM to set the
// EWMH for full screen mode.
void SetWindowSize(GtkWindow* window, const gfx::Size& size);
// If the point (|x|, |y|) is within the resize border area of the window,
// returns true and sets |edge| to the appropriate GdkWindowEdge value.
// Otherwise, returns false.
// |top_edge_inset| specifies how much smaller (in px) than the default edge
// size the top edge should be, used by browser windows to make it easier to
// move the window since a lot of title bar space is taken by the tabs.
bool GetWindowEdge(const gfx::Size& window_size,
int top_edge_inset,
int x,
int y,
GdkWindowEdge* edge);
} // namespace gtk_window_util
#endif // ATOM_BROWSER_UI_GTK_GTK_WINDOW_UTIL_H_

View File

@@ -0,0 +1,30 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "browser/ui/message_box.h"
#include "base/callback.h"
namespace atom {
int ShowMessageBox(NativeWindow* parent_window,
MessageBoxType type,
const std::vector<std::string>& buttons,
const std::string& title,
const std::string& message,
const std::string& detail) {
return 0;
}
void ShowMessageBox(NativeWindow* parent_window,
MessageBoxType type,
const std::vector<std::string>& buttons,
const std::string& title,
const std::string& message,
const std::string& detail,
const MessageBoxCallback& callback) {
callback.Run(0);
}
} // namespace atom

View File

@@ -9,7 +9,7 @@
#include "base/callback.h"
#include "base/strings/sys_string_conversions.h"
#include "browser/native_window.h"
#include "browser/ui/nsalert_synchronous_sheet_mac.h"
#include "browser/ui/cocoa/nsalert_synchronous_sheet.h"
@interface ModalDelegate : NSObject {
@private

View File

@@ -5,10 +5,10 @@
#include "browser/ui/message_box.h"
#include "base/callback.h"
#include "base/message_loop.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "browser/native_window.h"
#include "skia/ext/skia_utils_win.h"
#include "ui/views/controls/button/label_button.h"
@@ -76,6 +76,7 @@ class MessageDialog : public base::MessageLoop::Dispatcher,
string16 title_;
views::Widget* widget_;
views::MessageBoxView* message_box_view_;
scoped_ptr<NativeWindow::DialogScope> dialog_scope_;
std::vector<views::LabelButton*> buttons_;
MessageBoxCallback callback_;
@@ -96,7 +97,8 @@ MessageDialog::MessageDialog(NativeWindow* parent_window,
result_(-1),
title_(UTF8ToUTF16(title)),
widget_(NULL),
message_box_view_(NULL) {
message_box_view_(NULL),
dialog_scope_(new NativeWindow::DialogScope(parent_window)) {
DCHECK_GT(buttons.size(), 0u);
set_owned_by_client();
@@ -174,6 +176,7 @@ string16 MessageDialog::GetWindowTitle() const {
void MessageDialog::WindowClosing() {
should_close_ = true;
dialog_scope_.reset();
if (delete_on_close_) {
callback_.Run(GetResult());

View File

@@ -8,22 +8,22 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "base/string_util.h"
#include "base/strings/string_util.h"
#include "base/win/wrapped_window_proc.h"
#include "browser/ui/win/menu_2.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/keycodes/keyboard_codes.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_win.h"
#include "ui/base/models/menu_model.h"
#include "ui/base/win/hwnd_util.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/font.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/win/hwnd_util.h"
#include "ui/native_theme/native_theme.h"
#include "ui/native_theme/native_theme_win.h"
#include "ui/views/controls/menu/menu_config.h"
@@ -84,8 +84,8 @@ class NativeMenuWin::MenuHostWindow {
RegisterClass();
hwnd_ = CreateWindowEx(l10n_util::GetExtendedStyles(), kWindowClassName,
L"", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
ui::CheckWindowCreated(hwnd_);
ui::SetWindowUserData(hwnd_, this);
gfx::CheckWindowCreated(hwnd_);
gfx::SetWindowUserData(hwnd_, this);
}
~MenuHostWindow() {
@@ -353,7 +353,7 @@ class NativeMenuWin::MenuHostWindow {
WPARAM w_param,
LPARAM l_param) {
MenuHostWindow* host =
reinterpret_cast<MenuHostWindow*>(ui::GetWindowUserData(window));
reinterpret_cast<MenuHostWindow*>(gfx::GetWindowUserData(window));
// host is null during initial construction.
LRESULT l_result = 0;
if (!host || !host->ProcessWindowMessage(window, message, w_param, l_param,

View File

@@ -13,7 +13,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/string16.h"
#include "base/strings/string16.h"
namespace gfx {
class Point;

View File

@@ -19,14 +19,17 @@ class WindowListObserver;
class WindowList {
public:
typedef std::vector<NativeWindow*> WindowVector;
typedef WindowVector::iterator iterator;
typedef WindowVector::const_iterator const_iterator;
typedef WindowVector::const_reverse_iterator const_reverse_iterator;
// Windows are added to the list before they have constructed windows,
// so the |window()| member function may return NULL.
const_iterator begin() const { return windows_.begin(); }
const_iterator end() const { return windows_.end(); }
iterator begin() { return windows_.begin(); }
iterator end() { return windows_.end(); }
bool empty() const { return windows_.empty(); }
size_t size() const { return windows_.size(); }

View File

@@ -2,7 +2,7 @@
'variables': {
'clang': 0,
'conditions': [
['OS=="mac"', {
['OS=="mac" or OS=="linux"', {
'clang': 1,
}],
['OS=="win" and (MSVS_VERSION=="2012e" or MSVS_VERSION=="2010e")', {
@@ -13,6 +13,7 @@
}],
],
# Reflects node's config.gypi.
'component%': 'static_library',
'python': 'python',
'node_install_npm': 'false',
'node_prefix': '',
@@ -29,11 +30,12 @@
'node_use_openssl': 'true',
'node_use_perfctr': 'false',
'node_use_systemtap': 'false',
'v8_postmortem_support': 'false',
},
# Settings to compile node under Windows.
'target_defaults': {
'target_conditions': [
['_target_name in ["libuv", "http_parser", "cares", "openssl", "node", "zlib"]', {
['_target_name in ["libuv", "http_parser", "cares", "openssl", "openssl-cli", "node_lib", "zlib"]', {
'msvs_disabled_warnings': [
4013, # 'free' undefined; assuming extern returning int
4054, #
@@ -41,17 +43,20 @@
4189, #
4131, # uses old-style declarator
4133, # incompatible types
4146, # unary minus operator applied to unsigned type, result still unsigned
4152, # function/data pointer conversion in expression
4206, # translation unit is empty
4204, # non-constant aggregate initializer
4214, # bit field types other than int
4232, # address of dllimport 'free' is not static, identity not guaranteed
4291, # no matching operator delete found
4295, # array is too small to include a terminating null character
4389, # '==' : signed/unsigned mismatch
4505, # unreferenced local function has been removed
4701, # potentially uninitialized local variable 'sizew' used
4706, # assignment within conditional expression
4996, #
4804, # unsafe use of type 'bool' in operation
4996, # this function or variable may be unsafe.
],
'msvs_settings': {
'VCCLCompilerTool': {
@@ -71,6 +76,26 @@
'-Wno-return-type',
],
},
'conditions': [
['OS=="linux"', {
'cflags': [
'-Wno-parentheses-equality',
'-Wno-unused-function',
'-Wno-sometimes-uninitialized',
'-Wno-pointer-sign',
'-Wno-string-plus-int',
'-Wno-unused-variable',
'-Wno-unused-value',
'-Wno-deprecated-declarations',
'-Wno-return-type',
],
}],
],
}],
['_target_name in ["node_lib", "atom_lib"]', {
'include_dirs': [
'vendor/brightray/vendor/download/libchromiumcontent/src/v8/include',
],
}],
['_target_name=="libuv"', {
'conditions': [
@@ -143,7 +168,9 @@
],
'target_defaults': {
'cflags_cc': [
'-std=c++11',
# Use gnu++11 instead of c++11 here, see:
# https://code.google.com/p/chromium/issues/detail?id=224515
'-std=gnu++11',
],
'xcode_settings': {
'CC': '/usr/bin/clang',
@@ -197,5 +224,14 @@
},
},
}], # OS=="win"
# The breakdpad on Mac assumes Release_Base configuration.
['OS=="mac"', {
'target_defaults': {
'configurations': {
'Release_Base': {
},
},
},
}], # OS=="mac"
],
}

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