mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
228 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93a24ec672 | ||
|
|
11cb777e35 | ||
|
|
27011ad0c8 | ||
|
|
c6fabf8613 | ||
|
|
6e469df90e | ||
|
|
0c0a6bd939 | ||
|
|
3f8ad3bf75 | ||
|
|
afd6f41e08 | ||
|
|
0a393eaa1c | ||
|
|
b1bb7bd8f3 | ||
|
|
45bfbb7cf6 | ||
|
|
5083a7505d | ||
|
|
fd2b2003b4 | ||
|
|
23b5c1f782 | ||
|
|
37d278de34 | ||
|
|
24b5faf8df | ||
|
|
8b712bac8d | ||
|
|
a1f26c4c93 | ||
|
|
13c887d4c9 | ||
|
|
2ed7d58ac4 | ||
|
|
b51e2f6453 | ||
|
|
17c191201c | ||
|
|
4217b70331 | ||
|
|
8947d54cc9 | ||
|
|
f829f2eb0c | ||
|
|
0087f8da27 | ||
|
|
dd606684c7 | ||
|
|
12998399f8 | ||
|
|
c09ba6efdb | ||
|
|
7df1957ac7 | ||
|
|
241e410a07 | ||
|
|
68cfe80369 | ||
|
|
88d7ad95f6 | ||
|
|
02c04cbf68 | ||
|
|
5523938a47 | ||
|
|
fbe1abddf4 | ||
|
|
9a14d2bd0e | ||
|
|
86644543ed | ||
|
|
a9c720969f | ||
|
|
3dd9e4cdf8 | ||
|
|
9a5698807f | ||
|
|
92142ee372 | ||
|
|
715ac35672 | ||
|
|
750db6aed8 | ||
|
|
5c78ecfe40 | ||
|
|
43421aedcf | ||
|
|
13ed038082 | ||
|
|
de151cef8e | ||
|
|
5bfe644c3e | ||
|
|
20431f4f2f | ||
|
|
ad16e9ea49 | ||
|
|
a10782cdea | ||
|
|
c14c6a3521 | ||
|
|
6c62895898 | ||
|
|
134aa32612 | ||
|
|
0a59384003 | ||
|
|
c2b109f7fc | ||
|
|
a755edebfa | ||
|
|
76fc62808c | ||
|
|
54ab6744f1 | ||
|
|
2d262d2dbd | ||
|
|
de99c38fb6 | ||
|
|
91320a9e55 | ||
|
|
0bcc9b7713 | ||
|
|
33b6876cc1 | ||
|
|
81b370ee9f | ||
|
|
fe81e5b32d | ||
|
|
4ba3e101f6 | ||
|
|
7210f6e64d | ||
|
|
ef15b670a9 | ||
|
|
706f547287 | ||
|
|
f142f572c3 | ||
|
|
7e33e26465 | ||
|
|
5e58915bdd | ||
|
|
854c59df5c | ||
|
|
f6db9bc84c | ||
|
|
b8d0c5b3fe | ||
|
|
23760058e9 | ||
|
|
7b621262ea | ||
|
|
62756a79df | ||
|
|
87cd762eb3 | ||
|
|
74566375b5 | ||
|
|
5d9b538513 | ||
|
|
7c0f414881 | ||
|
|
62d2b90e18 | ||
|
|
69092eee15 | ||
|
|
96f24b88ea | ||
|
|
3d858bee95 | ||
|
|
0933a7d1b2 | ||
|
|
fe78c17ea6 | ||
|
|
79a233436b | ||
|
|
3da347a783 | ||
|
|
ff856e679d | ||
|
|
7fbf4246ac | ||
|
|
42077999e9 | ||
|
|
e75950cb89 | ||
|
|
4604c9bb0e | ||
|
|
8aa5b97c61 | ||
|
|
ce52a87477 | ||
|
|
9a04f67c0a | ||
|
|
3d398458a8 | ||
|
|
dec3e37683 | ||
|
|
a988b48016 | ||
|
|
d31df439c3 | ||
|
|
06da5f254a | ||
|
|
2d1afbf51b | ||
|
|
45c26e0e5a | ||
|
|
c6fb645f6b | ||
|
|
e8f1f6819c | ||
|
|
c59bd82f6f | ||
|
|
b2be9373b0 | ||
|
|
f81df9a5d3 | ||
|
|
51c03c3a71 | ||
|
|
4f6ee31a28 | ||
|
|
1746518cdf | ||
|
|
b3c3556286 | ||
|
|
50b96ca7ef | ||
|
|
7749484628 | ||
|
|
b5898d3355 | ||
|
|
809c995c0b | ||
|
|
551c39e241 | ||
|
|
97070246b7 | ||
|
|
029ee9aa1e | ||
|
|
509294b228 | ||
|
|
ab9e1dd650 | ||
|
|
0ac2443eb0 | ||
|
|
136b3da458 | ||
|
|
9f5ed14f24 | ||
|
|
482c740e61 | ||
|
|
1a1cf57097 | ||
|
|
f6f5ff4330 | ||
|
|
6a11eccc3e | ||
|
|
2d6dc9c527 | ||
|
|
65d2540807 | ||
|
|
834d28f528 | ||
|
|
b4ba4a908e | ||
|
|
bda3711815 | ||
|
|
b4cdb546fe | ||
|
|
7ab5db1adb | ||
|
|
1926c2cd01 | ||
|
|
21ba5b867d | ||
|
|
1a80bc786d | ||
|
|
6a532292c4 | ||
|
|
c8ed581e5c | ||
|
|
c0f0f4cdc6 | ||
|
|
b83f042363 | ||
|
|
bce8a3f835 | ||
|
|
2d5b17552a | ||
|
|
19d6d171b1 | ||
|
|
09acb9032a | ||
|
|
3dfc496243 | ||
|
|
506237f5d6 | ||
|
|
609e3ec3ff | ||
|
|
640c8f88ff | ||
|
|
d0ed681643 | ||
|
|
5656714b27 | ||
|
|
ecb9e93394 | ||
|
|
708e738521 | ||
|
|
8457090b18 | ||
|
|
513052de87 | ||
|
|
d65919d896 | ||
|
|
895ccf69a7 | ||
|
|
3063b5189a | ||
|
|
335cd79b37 | ||
|
|
e3bad233e9 | ||
|
|
7abb08cc25 | ||
|
|
31bdfc2281 | ||
|
|
bf14f67cb8 | ||
|
|
ef7a60807b | ||
|
|
f17673be9c | ||
|
|
079f81b304 | ||
|
|
ab83b21fa6 | ||
|
|
3d7da455bc | ||
|
|
ac8a9afada | ||
|
|
8faab22f5e | ||
|
|
40679ae82c | ||
|
|
f972c38bc8 | ||
|
|
e1f0f02da9 | ||
|
|
b4d9c92705 | ||
|
|
44b932f90b | ||
|
|
c5411c3291 | ||
|
|
7dc8ede90f | ||
|
|
b94375c794 | ||
|
|
45c2cda6bb | ||
|
|
5c65f037b0 | ||
|
|
de55d8c292 | ||
|
|
a9d67e9715 | ||
|
|
9bd517e623 | ||
|
|
22d5d40a66 | ||
|
|
3f307ea8a6 | ||
|
|
ded58b8e65 | ||
|
|
6939567cb4 | ||
|
|
1a34e09a45 | ||
|
|
85685feff4 | ||
|
|
4ca0458b37 | ||
|
|
effcf18d56 | ||
|
|
5b312e8f64 | ||
|
|
8506725b54 | ||
|
|
45c41fe880 | ||
|
|
4fc73117c4 | ||
|
|
9593c71f52 | ||
|
|
a23218c51d | ||
|
|
70225009af | ||
|
|
80bea0766e | ||
|
|
54933f992a | ||
|
|
c0bf2facca | ||
|
|
d642fe6075 | ||
|
|
e7dfd48b1c | ||
|
|
90b2d12371 | ||
|
|
f6c66e7ece | ||
|
|
c6a18b1b59 | ||
|
|
6cdc8e4b96 | ||
|
|
598060dfd8 | ||
|
|
b801a93dc5 | ||
|
|
dc9329ff43 | ||
|
|
a61331a083 | ||
|
|
f1fbc5c701 | ||
|
|
896077222d | ||
|
|
47d7a355f2 | ||
|
|
a1ae399d10 | ||
|
|
48b0d85f54 | ||
|
|
423d269187 | ||
|
|
da54ac5f55 | ||
|
|
a26091e485 | ||
|
|
40ab21d9df | ||
|
|
947e6aca9b | ||
|
|
c92d2531b5 | ||
|
|
6d168b89ef |
@@ -10,6 +10,10 @@ editor](https://github.com/atom/atom).
|
||||
Prebuilt binaries of atom-shell for Linux, Windows and Mac can be found on the
|
||||
[releases](https://github.com/atom/atom-shell/releases) page.
|
||||
|
||||
### Mirrors
|
||||
|
||||
- [China Mirror](https://npm.taobao.org/mirrors/atom-shell): Improve download speeds for Chinese user.
|
||||
|
||||
## Documentation
|
||||
|
||||
Guides and the API reference are located in the
|
||||
|
||||
41
atom.gyp
41
atom.gyp
@@ -3,9 +3,8 @@
|
||||
'includes': [
|
||||
'vendor/native_mate/native_mate_files.gypi',
|
||||
],
|
||||
'project_name': 'atom',
|
||||
'product_name': 'Atom',
|
||||
'framework_name': 'Atom Framework',
|
||||
'project_name%': 'atom',
|
||||
'product_name%': 'Atom',
|
||||
'app_sources': [
|
||||
'atom/app/atom_main.cc',
|
||||
'atom/app/atom_main.h',
|
||||
@@ -26,6 +25,7 @@
|
||||
'atom/browser/api/lib/menu-item.coffee',
|
||||
'atom/browser/api/lib/power-monitor.coffee',
|
||||
'atom/browser/api/lib/protocol.coffee',
|
||||
'atom/browser/api/lib/screen.coffee',
|
||||
'atom/browser/api/lib/tray.coffee',
|
||||
'atom/browser/api/lib/web-contents.coffee',
|
||||
'atom/browser/lib/chrome-extension.coffee',
|
||||
@@ -39,7 +39,6 @@
|
||||
'atom/common/api/lib/crash-reporter.coffee',
|
||||
'atom/common/api/lib/id-weak-map.coffee',
|
||||
'atom/common/api/lib/original-fs.coffee',
|
||||
'atom/common/api/lib/screen.coffee',
|
||||
'atom/common/api/lib/shell.coffee',
|
||||
'atom/common/lib/init.coffee',
|
||||
'atom/common/lib/asar.coffee',
|
||||
@@ -53,6 +52,7 @@
|
||||
'atom/renderer/lib/web-view/web-view-constants.coffee',
|
||||
'atom/renderer/api/lib/ipc.coffee',
|
||||
'atom/renderer/api/lib/remote.coffee',
|
||||
'atom/renderer/api/lib/screen.coffee',
|
||||
'atom/renderer/api/lib/web-frame.coffee',
|
||||
],
|
||||
'lib_sources': [
|
||||
@@ -60,6 +60,7 @@
|
||||
'atom/app/atom_content_client.h',
|
||||
'atom/app/atom_main_delegate.cc',
|
||||
'atom/app/atom_main_delegate.h',
|
||||
'atom/app/atom_main_delegate_mac.mm',
|
||||
'atom/browser/api/atom_api_app.cc',
|
||||
'atom/browser/api/atom_api_app.h',
|
||||
'atom/browser/api/atom_api_auto_updater.cc',
|
||||
@@ -78,6 +79,8 @@
|
||||
'atom/browser/api/atom_api_power_monitor.h',
|
||||
'atom/browser/api/atom_api_protocol.cc',
|
||||
'atom/browser/api/atom_api_protocol.h',
|
||||
'atom/browser/api/atom_api_screen.cc',
|
||||
'atom/browser/api/atom_api_screen.h',
|
||||
'atom/browser/api/atom_api_tray.cc',
|
||||
'atom/browser/api/atom_api_tray.h',
|
||||
'atom/browser/api/atom_api_web_contents.cc',
|
||||
@@ -199,8 +202,6 @@
|
||||
'atom/common/api/atom_api_crash_reporter.cc',
|
||||
'atom/common/api/atom_api_id_weak_map.cc',
|
||||
'atom/common/api/atom_api_id_weak_map.h',
|
||||
'atom/common/api/atom_api_screen.cc',
|
||||
'atom/common/api/atom_api_screen.h',
|
||||
'atom/common/api/atom_api_shell.cc',
|
||||
'atom/common/api/atom_api_v8_util.cc',
|
||||
'atom/common/api/atom_bindings.cc',
|
||||
@@ -234,10 +235,12 @@
|
||||
'atom/common/native_mate_converters/accelerator_converter.cc',
|
||||
'atom/common/native_mate_converters/accelerator_converter.h',
|
||||
'atom/common/native_mate_converters/file_path_converter.h',
|
||||
'atom/common/native_mate_converters/gfx_converter.cc',
|
||||
'atom/common/native_mate_converters/gfx_converter.h',
|
||||
'atom/common/native_mate_converters/gurl_converter.h',
|
||||
'atom/common/native_mate_converters/image_converter.cc',
|
||||
'atom/common/native_mate_converters/image_converter.h',
|
||||
'atom/common/native_mate_converters/image_converter_mac.mm',
|
||||
'atom/common/native_mate_converters/string16_converter.h',
|
||||
'atom/common/native_mate_converters/v8_value_converter.cc',
|
||||
'atom/common/native_mate_converters/v8_value_converter.h',
|
||||
@@ -259,8 +262,8 @@
|
||||
'atom/common/platform_util_mac.mm',
|
||||
'atom/common/platform_util_win.cc',
|
||||
'atom/renderer/api/atom_api_renderer_ipc.cc',
|
||||
'atom/renderer/api/atom_renderer_bindings.cc',
|
||||
'atom/renderer/api/atom_renderer_bindings.h',
|
||||
'atom/renderer/api/atom_api_spell_check_client.cc',
|
||||
'atom/renderer/api/atom_api_spell_check_client.h',
|
||||
'atom/renderer/api/atom_api_web_frame.cc',
|
||||
'atom/renderer/api/atom_api_web_frame.h',
|
||||
'atom/renderer/atom_render_view_observer.cc',
|
||||
@@ -321,6 +324,8 @@
|
||||
'chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm',
|
||||
'chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc',
|
||||
'chromium_src/chrome/renderer/printing/print_web_view_helper.h',
|
||||
'chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.cc',
|
||||
'chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.h',
|
||||
'chromium_src/chrome/renderer/tts_dispatcher.cc',
|
||||
'chromium_src/chrome/renderer/tts_dispatcher.h',
|
||||
'chromium_src/library_loaders/libgio_loader.cc',
|
||||
@@ -335,8 +340,8 @@
|
||||
'chromium_src/chrome/browser/ui/views/color_chooser_win.cc',
|
||||
],
|
||||
'framework_sources': [
|
||||
'atom/app/atom_library_main.cc',
|
||||
'atom/app/atom_library_main.h',
|
||||
'atom/app/atom_library_main.mm',
|
||||
],
|
||||
'locales': [
|
||||
'am', 'ar', 'bg', 'bn', 'ca', 'cs', 'da', 'de', 'el', 'en-GB',
|
||||
@@ -415,7 +420,7 @@
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name).app/Contents/Frameworks',
|
||||
'files': [
|
||||
'<(PRODUCT_DIR)/<(product_name) Helper.app',
|
||||
'<(PRODUCT_DIR)/<(framework_name).framework',
|
||||
'<(PRODUCT_DIR)/<(product_name) Framework.framework',
|
||||
'external_binaries/Squirrel.framework',
|
||||
'external_binaries/ReactiveCocoa.framework',
|
||||
'external_binaries/Mantle.framework',
|
||||
@@ -523,6 +528,7 @@
|
||||
'vendor/node/node.gyp:node_lib',
|
||||
],
|
||||
'defines': [
|
||||
'PRODUCT_NAME="<(product_name)"',
|
||||
# This is defined in skia/skia_common.gypi.
|
||||
'SK_SUPPORT_LEGACY_GETTOPDEVICE',
|
||||
# Disable warnings for g_settings_list_schemas.
|
||||
@@ -544,6 +550,8 @@
|
||||
'vendor/brightray/vendor/download/libchromiumcontent/src/v8/include',
|
||||
# The `node.h` is using `#include"ares.h"`.
|
||||
'vendor/node/deps/cares/include',
|
||||
# The `third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h` is using `platform/PlatformExport.h`.
|
||||
'vendor/brightray/vendor/download/libchromiumcontent/src/third_party/WebKit/Source',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
@@ -780,7 +788,7 @@
|
||||
'targets': [
|
||||
{
|
||||
'target_name': '<(project_name)_framework',
|
||||
'product_name': '<(framework_name)',
|
||||
'product_name': '<(product_name) Framework',
|
||||
'type': 'shared_library',
|
||||
'dependencies': [
|
||||
'<(project_name)_lib',
|
||||
@@ -793,6 +801,9 @@
|
||||
'vendor',
|
||||
'<(libchromiumcontent_include_dir)',
|
||||
],
|
||||
'defines': [
|
||||
'PRODUCT_NAME="<(product_name)"',
|
||||
],
|
||||
'export_dependent_settings': [
|
||||
'<(project_name)_lib',
|
||||
],
|
||||
@@ -816,7 +827,7 @@
|
||||
'LIBRARY_SEARCH_PATHS': [
|
||||
'<(libchromiumcontent_library_dir)',
|
||||
],
|
||||
'LD_DYLIB_INSTALL_NAME': '@rpath/<(framework_name).framework/<(framework_name)',
|
||||
'LD_DYLIB_INSTALL_NAME': '@rpath/<(product_name) Framework.framework/<(product_name) Framework',
|
||||
'LD_RUNPATH_SEARCH_PATHS': [
|
||||
'@loader_path/Libraries',
|
||||
],
|
||||
@@ -826,14 +837,14 @@
|
||||
},
|
||||
'copies': [
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/<(framework_name).framework/Versions/A/Libraries',
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name) Framework.framework/Versions/A/Libraries',
|
||||
'files': [
|
||||
'<(libchromiumcontent_library_dir)/ffmpegsumo.so',
|
||||
'<(libchromiumcontent_library_dir)/libchromiumcontent.dylib',
|
||||
],
|
||||
},
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/<(framework_name).framework/Versions/A/Resources',
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name) Framework.framework/Versions/A/Resources',
|
||||
'files': [
|
||||
'<(PRODUCT_DIR)/Inspector',
|
||||
'<(PRODUCT_DIR)/crash_report_sender.app',
|
||||
@@ -845,7 +856,7 @@
|
||||
'postbuild_name': 'Add symlinks for framework subdirectories',
|
||||
'action': [
|
||||
'tools/mac/create-framework-subdir-symlinks.sh',
|
||||
'<(framework_name)',
|
||||
'<(product_name) Framework',
|
||||
'Libraries',
|
||||
'Frameworks',
|
||||
],
|
||||
|
||||
@@ -19,10 +19,10 @@ class AtomContentClient : public brightray::ContentClient {
|
||||
|
||||
protected:
|
||||
// content::ContentClient:
|
||||
virtual std::string GetProduct() const OVERRIDE;
|
||||
virtual void AddAdditionalSchemes(
|
||||
std::string GetProduct() const override;
|
||||
void AddAdditionalSchemes(
|
||||
std::vector<std::string>* standard_schemes,
|
||||
std::vector<std::string>* savable_schemes) OVERRIDE;
|
||||
std::vector<std::string>* savable_schemes) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
extern "C" {
|
||||
__attribute__((visibility("default")))
|
||||
int AtomMain(int argc, const char* argv[]);
|
||||
|
||||
__attribute__((visibility("default")))
|
||||
void AtomInitializeICU();
|
||||
}
|
||||
#endif // OS_MACOSX
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
#include "atom/app/atom_library_main.h"
|
||||
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
#include "base/i18n/icu_util.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "brightray/common/mac/main_application_bundle.h"
|
||||
#include "content/public/app/content_main.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
@@ -15,4 +18,13 @@ int AtomMain(int argc, const char* argv[]) {
|
||||
params.argv = argv;
|
||||
return content::ContentMain(params);
|
||||
}
|
||||
|
||||
void AtomInitializeICU() {
|
||||
base::mac::SetOverrideFrameworkBundlePath(
|
||||
brightray::MainApplicationBundlePath()
|
||||
.Append("Contents")
|
||||
.Append("Frameworks")
|
||||
.Append(PRODUCT_NAME " Framework.framework"));
|
||||
base::i18n::InitializeICU();
|
||||
}
|
||||
#endif // OS_MACOSX
|
||||
@@ -13,11 +13,14 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <shellscalingapi.h>
|
||||
#include <tchar.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
#include "atom/common/crash_reporter/win/crash_service_main.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/win/windows_version.h"
|
||||
#include "content/public/app/startup_helper_win.h"
|
||||
#include "sandbox/win/src/sandbox_types.h"
|
||||
#include "ui/gfx/win/dpi.h"
|
||||
@@ -28,6 +31,8 @@
|
||||
#include "atom/app/atom_library_main.h"
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
#include "base/i18n/icu_util.h"
|
||||
|
||||
// Declaration of node::Start.
|
||||
namespace node {
|
||||
int Start(int argc, char *argv[]);
|
||||
@@ -35,6 +40,48 @@ int Start(int argc, char *argv[]);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
namespace {
|
||||
|
||||
// Win8.1 supports monitor-specific DPI scaling.
|
||||
bool SetProcessDpiAwarenessWrapper(PROCESS_DPI_AWARENESS value) {
|
||||
typedef HRESULT(WINAPI *SetProcessDpiAwarenessPtr)(PROCESS_DPI_AWARENESS);
|
||||
SetProcessDpiAwarenessPtr set_process_dpi_awareness_func =
|
||||
reinterpret_cast<SetProcessDpiAwarenessPtr>(
|
||||
GetProcAddress(GetModuleHandleA("user32.dll"),
|
||||
"SetProcessDpiAwarenessInternal"));
|
||||
if (set_process_dpi_awareness_func) {
|
||||
HRESULT hr = set_process_dpi_awareness_func(value);
|
||||
if (SUCCEEDED(hr)) {
|
||||
VLOG(1) << "SetProcessDpiAwareness succeeded.";
|
||||
return true;
|
||||
} else if (hr == E_ACCESSDENIED) {
|
||||
LOG(ERROR) << "Access denied error from SetProcessDpiAwareness. "
|
||||
"Function called twice, or manifest was used.";
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// This function works for Windows Vista through Win8. Win8.1 must use
|
||||
// SetProcessDpiAwareness[Wrapper].
|
||||
BOOL SetProcessDPIAwareWrapper() {
|
||||
typedef BOOL(WINAPI *SetProcessDPIAwarePtr)(VOID);
|
||||
SetProcessDPIAwarePtr set_process_dpi_aware_func =
|
||||
reinterpret_cast<SetProcessDPIAwarePtr>(
|
||||
GetProcAddress(GetModuleHandleA("user32.dll"),
|
||||
"SetProcessDPIAware"));
|
||||
return set_process_dpi_aware_func &&
|
||||
set_process_dpi_aware_func();
|
||||
}
|
||||
|
||||
void EnableHighDPISupport() {
|
||||
if (!SetProcessDpiAwarenessWrapper(PROCESS_SYSTEM_DPI_AWARE)) {
|
||||
SetProcessDPIAwareWrapper();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
int argc = 0;
|
||||
wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
|
||||
@@ -89,6 +136,7 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
}
|
||||
}
|
||||
// Now that conversion is done, we can finally start.
|
||||
base::i18n::InitializeICU();
|
||||
return node::Start(argc, argv);
|
||||
} else if (env->GetVar("ATOM_SHELL_INTERNAL_CRASH_SERVICE",
|
||||
&crash_service_indicator) &&
|
||||
@@ -100,8 +148,11 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
content::InitializeSandboxInfo(&sandbox_info);
|
||||
atom::AtomMainDelegate delegate;
|
||||
|
||||
// Now chrome relies on a regkey to enable high dpi support.
|
||||
gfx::EnableHighDPISupport();
|
||||
// We don't want to set DPI awareness on pre-Win7 because we don't support
|
||||
// DirectWrite there. GDI fonts are kerned very badly, so better to leave
|
||||
// DPI-unaware and at effective 1.0. See also ShouldUseDirectWrite().
|
||||
if (base::win::GetVersion() >= base::win::VERSION_WIN7)
|
||||
EnableHighDPISupport();
|
||||
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.instance = instance;
|
||||
@@ -113,8 +164,10 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
|
||||
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)
|
||||
if (node_indicator != NULL && strcmp(node_indicator, "1") == 0) {
|
||||
base::i18n::InitializeICU();
|
||||
return node::Start(argc, const_cast<char**>(argv));
|
||||
}
|
||||
|
||||
atom::AtomMainDelegate delegate;
|
||||
content::ContentMainParams params(&delegate);
|
||||
@@ -127,8 +180,10 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
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)
|
||||
if (node_indicator != NULL && strcmp(node_indicator, "1") == 0) {
|
||||
AtomInitializeICU();
|
||||
return node::Start(argc, const_cast<char**>(argv));
|
||||
}
|
||||
|
||||
return AtomMain(argc, argv);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,10 @@ class AtomMainDelegate : public brightray::MainDelegate {
|
||||
scoped_ptr<brightray::ContentClient> CreateContentClient() override;
|
||||
void AddDataPackFromPath(
|
||||
ui::ResourceBundle* bundle, const base::FilePath& pak_dir) override;
|
||||
#if defined(OS_MACOSX)
|
||||
void OverrideChildProcessPath() override;
|
||||
void OverrideFrameworkBundlePath() override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
brightray::ContentClient content_client_;
|
||||
|
||||
38
atom/app/atom_main_delegate_mac.mm
Normal file
38
atom/app/atom_main_delegate_mac.mm
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/path_service.h"
|
||||
#include "brightray/common/mac/main_application_bundle.h"
|
||||
#include "content/public/common/content_paths.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
base::FilePath GetFrameworksPath() {
|
||||
return brightray::MainApplicationBundlePath().Append("Contents")
|
||||
.Append("Frameworks");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void AtomMainDelegate::OverrideFrameworkBundlePath() {
|
||||
base::mac::SetOverrideFrameworkBundlePath(
|
||||
GetFrameworksPath().Append(PRODUCT_NAME " Framework.framework"));
|
||||
}
|
||||
|
||||
void AtomMainDelegate::OverrideChildProcessPath() {
|
||||
base::FilePath helper_path =
|
||||
GetFrameworksPath().Append(PRODUCT_NAME " Helper.app")
|
||||
.Append("Contents")
|
||||
.Append("MacOS")
|
||||
.Append(PRODUCT_NAME " Helper");
|
||||
PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
@@ -12,11 +12,11 @@
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "base/values.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/path_service.h"
|
||||
#include "brightray/browser/brightray_paths.h"
|
||||
#include "native_mate/callback.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
@@ -27,10 +27,6 @@
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#include "base/nix/xdg_util.h"
|
||||
#endif
|
||||
|
||||
using atom::Browser;
|
||||
|
||||
namespace mate {
|
||||
@@ -65,6 +61,30 @@ namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// Return the path constant from string.
|
||||
int GetPathConstant(const std::string& name) {
|
||||
if (name == "appData")
|
||||
return brightray::DIR_APP_DATA;
|
||||
else if (name == "userData")
|
||||
return brightray::DIR_USER_DATA;
|
||||
else if (name == "cache")
|
||||
return brightray::DIR_CACHE;
|
||||
else if (name == "userCache")
|
||||
return brightray::DIR_USER_CACHE;
|
||||
else if (name == "home")
|
||||
return base::DIR_HOME;
|
||||
else if (name == "temp")
|
||||
return base::DIR_TEMP;
|
||||
else if (name == "userDesktop")
|
||||
return base::DIR_USER_DESKTOP;
|
||||
else if (name == "exe")
|
||||
return base::FILE_EXE;
|
||||
else if (name == "module")
|
||||
return base::FILE_MODULE;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
class ResolveProxyHelper {
|
||||
public:
|
||||
ResolveProxyHelper(const GURL& url, App::ResolveProxyCallback callback)
|
||||
@@ -124,15 +144,11 @@ void App::OnQuit() {
|
||||
}
|
||||
|
||||
void App::OnOpenFile(bool* prevent_default, const std::string& file_path) {
|
||||
base::ListValue args;
|
||||
args.AppendString(file_path);
|
||||
*prevent_default = Emit("open-file", args);
|
||||
*prevent_default = Emit("open-file", file_path);
|
||||
}
|
||||
|
||||
void App::OnOpenURL(const std::string& url) {
|
||||
base::ListValue args;
|
||||
args.AppendString(url);
|
||||
Emit("open-url", args);
|
||||
Emit("open-url", url);
|
||||
}
|
||||
|
||||
void App::OnActivateWithNoOpenWindows() {
|
||||
@@ -147,19 +163,26 @@ void App::OnFinishLaunching() {
|
||||
Emit("ready");
|
||||
}
|
||||
|
||||
base::FilePath App::GetDataPath() {
|
||||
base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
|
||||
bool succeed = false;
|
||||
base::FilePath path;
|
||||
#if defined(OS_LINUX)
|
||||
scoped_ptr<base::Environment> env(base::Environment::Create());
|
||||
path = base::nix::GetXDGDirectory(env.get(),
|
||||
base::nix::kXdgConfigHomeEnvVar,
|
||||
base::nix::kDotConfigDir);
|
||||
#else
|
||||
PathService::Get(base::DIR_APP_DATA, &path);
|
||||
#endif
|
||||
int key = GetPathConstant(name);
|
||||
if (key >= 0)
|
||||
succeed = PathService::Get(key, &path);
|
||||
if (!succeed)
|
||||
args->ThrowError("Failed to get path");
|
||||
return path;
|
||||
}
|
||||
|
||||
return path.Append(base::FilePath::FromUTF8Unsafe(
|
||||
Browser::Get()->GetName()));
|
||||
void App::SetPath(mate::Arguments* args,
|
||||
const std::string& name,
|
||||
const base::FilePath& path) {
|
||||
bool succeed = false;
|
||||
int key = GetPathConstant(name);
|
||||
if (key >= 0)
|
||||
succeed = PathService::Override(key, path);
|
||||
if (!succeed)
|
||||
args->ThrowError("Failed to set path");
|
||||
}
|
||||
|
||||
void App::ResolveProxy(const GURL& url, ResolveProxyCallback callback) {
|
||||
@@ -192,7 +215,8 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
|
||||
.SetMethod("setUserTasks",
|
||||
base::Bind(&Browser::SetUserTasks, browser))
|
||||
#endif
|
||||
.SetMethod("getDataPath", &App::GetDataPath)
|
||||
.SetMethod("setPath", &App::SetPath)
|
||||
.SetMethod("getPath", &App::GetPath)
|
||||
.SetMethod("resolveProxy", &App::ResolveProxy)
|
||||
.SetMethod("setDesktopName", &App::SetDesktopName);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,10 @@ namespace base {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -48,7 +52,12 @@ class App : public mate::EventEmitter,
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
private:
|
||||
base::FilePath GetDataPath();
|
||||
// Get/Set the pre-defined path in PathService.
|
||||
base::FilePath GetPath(mate::Arguments* args, const std::string& name);
|
||||
void SetPath(mate::Arguments* args,
|
||||
const std::string& name,
|
||||
const base::FilePath& path);
|
||||
|
||||
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
|
||||
void SetDesktopName(const std::string& desktop_name);
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "atom/browser/api/atom_api_auto_updater.h"
|
||||
|
||||
#include "base/time/time.h"
|
||||
#include "base/values.h"
|
||||
#include "atom/browser/auto_updater.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
@@ -26,9 +25,7 @@ AutoUpdater::~AutoUpdater() {
|
||||
}
|
||||
|
||||
void AutoUpdater::OnError(const std::string& error) {
|
||||
base::ListValue args;
|
||||
args.AppendString(error);
|
||||
Emit("error", args);
|
||||
Emit("error", error);
|
||||
}
|
||||
|
||||
void AutoUpdater::OnCheckingForUpdate() {
|
||||
@@ -49,13 +46,8 @@ void AutoUpdater::OnUpdateDownloaded(const std::string& release_notes,
|
||||
const std::string& update_url,
|
||||
const base::Closure& quit_and_install) {
|
||||
quit_and_install_ = quit_and_install;
|
||||
|
||||
base::ListValue args;
|
||||
args.AppendString(release_notes);
|
||||
args.AppendString(release_name);
|
||||
args.AppendDouble(release_date.ToJsTime());
|
||||
args.AppendString(update_url);
|
||||
Emit("update-downloaded-raw", args);
|
||||
Emit("update-downloaded-raw", release_notes, release_name,
|
||||
release_date.ToJsTime(), update_url);
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder AutoUpdater::GetObjectTemplateBuilder(
|
||||
|
||||
@@ -26,20 +26,20 @@ class AutoUpdater : public mate::EventEmitter,
|
||||
virtual ~AutoUpdater();
|
||||
|
||||
// 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(
|
||||
void OnError(const std::string& error) override;
|
||||
void OnCheckingForUpdate() override;
|
||||
void OnUpdateAvailable() override;
|
||||
void OnUpdateNotAvailable() override;
|
||||
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;
|
||||
const base::Closure& quit_and_install) override;
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate);
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
private:
|
||||
void QuitAndInstall();
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
#include "atom/browser/ui/message_box.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "native_mate/callback.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
@@ -40,21 +41,27 @@ namespace {
|
||||
|
||||
void ShowMessageBox(int type,
|
||||
const std::vector<std::string>& buttons,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::vector<std::string>& texts,
|
||||
const gfx::ImageSkia& icon,
|
||||
atom::NativeWindow* window,
|
||||
mate::Arguments* args) {
|
||||
// FIXME We are exceeding the parameters limit of base::Bind here, so we have
|
||||
// to pass some parameters in an array. We should remove this once we have
|
||||
// variadic template support in base::Bind.
|
||||
const std::string& title = texts[0];
|
||||
const std::string& message = texts[1];
|
||||
const std::string& detail = texts[2];
|
||||
|
||||
v8::Handle<v8::Value> peek = args->PeekNext();
|
||||
atom::MessageBoxCallback callback;
|
||||
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(),
|
||||
peek,
|
||||
&callback)) {
|
||||
atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons, title,
|
||||
message, detail, callback);
|
||||
message, detail, icon, callback);
|
||||
} else {
|
||||
int chosen = atom::ShowMessageBox(window, (atom::MessageBoxType)type,
|
||||
buttons, title, message, detail);
|
||||
buttons, title, message, detail, icon);
|
||||
args->Return(chosen);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
|
||||
virtual ~GlobalShortcut();
|
||||
|
||||
// mate::Wrappable implementations:
|
||||
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) OVERRIDE;
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
private:
|
||||
typedef std::map<ui::Accelerator, base::Closure> AcceleratorCallbackMap;
|
||||
@@ -41,7 +41,7 @@ class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
|
||||
void UnregisterAll();
|
||||
|
||||
// GlobalShortcutListener::Observer implementation.
|
||||
virtual void OnKeyPressed(const ui::Accelerator& accelerator) OVERRIDE;
|
||||
void OnKeyPressed(const ui::Accelerator& accelerator) override;
|
||||
|
||||
AcceleratorCallbackMap accelerator_callback_map_;
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ class MenuMac : public Menu {
|
||||
protected:
|
||||
MenuMac();
|
||||
|
||||
virtual void Popup(Window* window) OVERRIDE;
|
||||
virtual void PopupAt(Window* window, int x, int y) OVERRIDE;
|
||||
void Popup(Window* window) override;
|
||||
void PopupAt(Window* window, int x, int y) override;
|
||||
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller_;
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ class MenuViews : public Menu {
|
||||
MenuViews();
|
||||
|
||||
protected:
|
||||
virtual void Popup(Window* window) OVERRIDE;
|
||||
virtual void PopupAt(Window* window, int x, int y) OVERRIDE;
|
||||
void Popup(Window* window) override;
|
||||
void PopupAt(Window* window, int x, int y) override;
|
||||
|
||||
private:
|
||||
void PopupAtPoint(Window* window, const gfx::Point& point);
|
||||
|
||||
@@ -24,9 +24,9 @@ class PowerMonitor : public mate::EventEmitter,
|
||||
virtual ~PowerMonitor();
|
||||
|
||||
// base::PowerObserver implementations:
|
||||
virtual void OnPowerStateChange(bool on_battery_power) OVERRIDE;
|
||||
virtual void OnSuspend() OVERRIDE;
|
||||
virtual void OnResume() OVERRIDE;
|
||||
void OnPowerStateChange(bool on_battery_power) override;
|
||||
void OnSuspend() override;
|
||||
void OnResume() override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(PowerMonitor);
|
||||
|
||||
@@ -53,7 +53,7 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
|
||||
}
|
||||
|
||||
// AdapterRequestJob:
|
||||
virtual void GetJobTypeInUI() OVERRIDE {
|
||||
void GetJobTypeInUI() override {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
@@ -128,9 +128,9 @@ class CustomProtocolHandler : public ProtocolHandler {
|
||||
: registry_(registry), protocol_handler_(protocol_handler) {
|
||||
}
|
||||
|
||||
virtual net::URLRequestJob* MaybeCreateJob(
|
||||
net::URLRequestJob* MaybeCreateJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const OVERRIDE {
|
||||
net::NetworkDelegate* network_delegate) const override {
|
||||
return new CustomProtocolRequestJob(registry_, protocol_handler_.get(),
|
||||
request, network_delegate);
|
||||
}
|
||||
@@ -305,9 +305,7 @@ void Protocol::UninterceptProtocolInIO(const std::string& scheme) {
|
||||
|
||||
void Protocol::EmitEventInUI(const std::string& event,
|
||||
const std::string& parameter) {
|
||||
base::ListValue args;
|
||||
args.AppendString(parameter);
|
||||
Emit(event, args);
|
||||
Emit(event, parameter);
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
149
atom/browser/api/atom_api_screen.cc
Normal file
149
atom/browser/api/atom_api_screen.cc
Normal file
@@ -0,0 +1,149 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_screen.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "base/bind.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// Find an item in container according to its ID.
|
||||
template<class T>
|
||||
typename T::iterator FindById(T* container, int id) {
|
||||
auto predicate = [id] (const typename T::value_type& item) -> bool {
|
||||
return item.id() == id;
|
||||
};
|
||||
return std::find_if(container->begin(), container->end(), predicate);
|
||||
}
|
||||
|
||||
// Convert the changed_metrics bitmask to string array.
|
||||
std::vector<std::string> MetricsToArray(uint32_t metrics) {
|
||||
std::vector<std::string> array;
|
||||
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS)
|
||||
array.push_back("bounds");
|
||||
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA)
|
||||
array.push_back("workArea");
|
||||
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR)
|
||||
array.push_back("scaleFactor");
|
||||
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_ROTATION)
|
||||
array.push_back("rotaion");
|
||||
return array;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Screen::Screen(gfx::Screen* screen) : screen_(screen) {
|
||||
screen_->AddObserver(this);
|
||||
}
|
||||
|
||||
Screen::~Screen() {
|
||||
screen_->RemoveObserver(this);
|
||||
}
|
||||
|
||||
gfx::Point Screen::GetCursorScreenPoint() {
|
||||
return screen_->GetCursorScreenPoint();
|
||||
}
|
||||
|
||||
gfx::Display Screen::GetPrimaryDisplay() {
|
||||
return screen_->GetPrimaryDisplay();
|
||||
}
|
||||
|
||||
std::vector<gfx::Display> Screen::GetAllDisplays() {
|
||||
// The Screen::GetAllDisplays doesn't update when there is display added or
|
||||
// removed, so we have to manually maintain the displays_ to make it up to
|
||||
// date.
|
||||
if (displays_.size() == 0)
|
||||
displays_ = screen_->GetAllDisplays();
|
||||
return displays_;
|
||||
}
|
||||
|
||||
gfx::Display Screen::GetDisplayNearestPoint(const gfx::Point& point) {
|
||||
return screen_->GetDisplayNearestPoint(point);
|
||||
}
|
||||
|
||||
gfx::Display Screen::GetDisplayMatching(const gfx::Rect& match_rect) {
|
||||
return screen_->GetDisplayMatching(match_rect);
|
||||
}
|
||||
|
||||
void Screen::OnDisplayAdded(const gfx::Display& new_display) {
|
||||
displays_.push_back(new_display);
|
||||
Emit("display-added", new_display);
|
||||
}
|
||||
|
||||
void Screen::OnDisplayRemoved(const gfx::Display& old_display) {
|
||||
auto iter = FindById(&displays_, old_display.id());
|
||||
if (iter == displays_.end())
|
||||
return;
|
||||
|
||||
displays_.erase(iter);
|
||||
Emit("display-removed", old_display);
|
||||
}
|
||||
|
||||
void Screen::OnDisplayMetricsChanged(const gfx::Display& display,
|
||||
uint32_t changed_metrics) {
|
||||
auto iter = FindById(&displays_, display.id());
|
||||
if (iter == displays_.end())
|
||||
return;
|
||||
|
||||
*iter = display;
|
||||
Emit("display-metrics-changed", display, MetricsToArray(changed_metrics));
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder Screen::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint)
|
||||
.SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay)
|
||||
.SetMethod("getAllDisplays", &Screen::GetAllDisplays)
|
||||
.SetMethod("getDisplayNearestPoint", &Screen::GetDisplayNearestPoint)
|
||||
.SetMethod("getDisplayMatching", &Screen::GetDisplayMatching);
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Screen::Create(v8::Isolate* isolate) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate, "Can not initialize \"screen\" module before app is ready")));
|
||||
return v8::Undefined(isolate);
|
||||
}
|
||||
|
||||
gfx::Screen* screen = gfx::Screen::GetNativeScreen();
|
||||
if (!screen) {
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate, "Failed to get screen information")));
|
||||
return v8::Undefined(isolate);
|
||||
}
|
||||
|
||||
return mate::CreateHandle(isolate, new Screen(screen)).ToV8();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
|
||||
v8::Handle<v8::Context> context, void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.Set("screen", atom::api::Screen::Create(context->GetIsolate()));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_screen, Initialize)
|
||||
60
atom/browser/api/atom_api_screen.h
Normal file
60
atom/browser/api/atom_api_screen.h
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_SCREEN_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_SCREEN_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "ui/gfx/display_observer.h"
|
||||
|
||||
namespace gfx {
|
||||
class Point;
|
||||
class Rect;
|
||||
class Screen;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Screen : public mate::EventEmitter,
|
||||
public gfx::DisplayObserver {
|
||||
public:
|
||||
static v8::Handle<v8::Value> Create(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
explicit Screen(gfx::Screen* screen);
|
||||
virtual ~Screen();
|
||||
|
||||
gfx::Point GetCursorScreenPoint();
|
||||
gfx::Display GetPrimaryDisplay();
|
||||
std::vector<gfx::Display> GetAllDisplays();
|
||||
gfx::Display GetDisplayNearestPoint(const gfx::Point& point);
|
||||
gfx::Display GetDisplayMatching(const gfx::Rect& match_rect);
|
||||
|
||||
// gfx::DisplayObserver:
|
||||
void OnDisplayAdded(const gfx::Display& new_display) override;
|
||||
void OnDisplayRemoved(const gfx::Display& old_display) override;
|
||||
void OnDisplayMetricsChanged(const gfx::Display& display,
|
||||
uint32_t changed_metrics) override;
|
||||
|
||||
// mate::Wrappable:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
private:
|
||||
gfx::Screen* screen_;
|
||||
std::vector<gfx::Display> displays_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Screen);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_SCREEN_H_
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
@@ -19,7 +20,7 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
Tray::Tray(const gfx::ImageSkia& image)
|
||||
Tray::Tray(const gfx::Image& image)
|
||||
: tray_icon_(TrayIcon::Create()) {
|
||||
tray_icon_->SetImage(image);
|
||||
tray_icon_->AddObserver(this);
|
||||
@@ -29,7 +30,7 @@ Tray::~Tray() {
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Wrappable* Tray::New(const gfx::ImageSkia& image) {
|
||||
mate::Wrappable* Tray::New(const gfx::Image& image) {
|
||||
return new Tray(image);
|
||||
}
|
||||
|
||||
@@ -57,13 +58,13 @@ void Tray::Destroy() {
|
||||
tray_icon_.reset();
|
||||
}
|
||||
|
||||
void Tray::SetImage(mate::Arguments* args, const gfx::ImageSkia& image) {
|
||||
void Tray::SetImage(mate::Arguments* args, const gfx::Image& image) {
|
||||
if (!CheckTrayLife(args))
|
||||
return;
|
||||
tray_icon_->SetImage(image);
|
||||
}
|
||||
|
||||
void Tray::SetPressedImage(mate::Arguments* args, const gfx::ImageSkia& image) {
|
||||
void Tray::SetPressedImage(mate::Arguments* args, const gfx::Image& image) {
|
||||
if (!CheckTrayLife(args))
|
||||
return;
|
||||
tray_icon_->SetPressedImage(image);
|
||||
@@ -92,7 +93,7 @@ void Tray::DisplayBalloon(mate::Arguments* args,
|
||||
if (!CheckTrayLife(args))
|
||||
return;
|
||||
|
||||
gfx::ImageSkia icon;
|
||||
gfx::Image icon;
|
||||
options.Get("icon", &icon);
|
||||
base::string16 title, content;
|
||||
if (!options.Get("title", &title) ||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
|
||||
namespace gfx {
|
||||
class ImageSkia;
|
||||
class Image;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
@@ -31,13 +31,13 @@ class Menu;
|
||||
class Tray : public mate::EventEmitter,
|
||||
public TrayIconObserver {
|
||||
public:
|
||||
static mate::Wrappable* New(const gfx::ImageSkia& image);
|
||||
static mate::Wrappable* New(const gfx::Image& image);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Handle<v8::ObjectTemplate> prototype);
|
||||
|
||||
protected:
|
||||
explicit Tray(const gfx::ImageSkia& image);
|
||||
explicit Tray(const gfx::Image& image);
|
||||
virtual ~Tray();
|
||||
|
||||
// TrayIconObserver:
|
||||
@@ -48,8 +48,8 @@ class Tray : public mate::EventEmitter,
|
||||
void OnBalloonClosed() override;
|
||||
|
||||
void Destroy();
|
||||
void SetImage(mate::Arguments* args, const gfx::ImageSkia& image);
|
||||
void SetPressedImage(mate::Arguments* args, const gfx::ImageSkia& image);
|
||||
void SetImage(mate::Arguments* args, const gfx::Image& image);
|
||||
void SetPressedImage(mate::Arguments* args, const gfx::Image& image);
|
||||
void SetToolTip(mate::Arguments* args, const std::string& tool_tip);
|
||||
void SetTitle(mate::Arguments* args, const std::string& title);
|
||||
void SetHighlightMode(mate::Arguments* args, bool highlight);
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/web_dialog_helper.h"
|
||||
#include "atom/browser/web_view/web_view_renderer_state.h"
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
@@ -22,6 +25,7 @@
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "vendor/brightray/browser/media/media_stream_devices_controller.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
@@ -33,6 +37,17 @@ namespace {
|
||||
|
||||
v8::Persistent<v8::ObjectTemplate> template_;
|
||||
|
||||
// Get the window that has the |guest| embedded.
|
||||
NativeWindow* GetWindowFromGuest(const content::WebContents* guest) {
|
||||
int guest_process_id = guest->GetRenderProcessHost()->GetID();
|
||||
WebViewRendererState::WebViewInfo info;
|
||||
if (!WebViewRendererState::GetInstance()->GetInfo(guest_process_id, &info))
|
||||
return nullptr;
|
||||
return NativeWindow::FromRenderView(
|
||||
info.embedder->GetRenderProcessHost()->GetID(),
|
||||
info.embedder->GetRoutingID());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
WebContents::WebContents(content::WebContents* web_contents)
|
||||
@@ -73,12 +88,7 @@ bool WebContents::AddMessageToConsole(content::WebContents* source,
|
||||
const base::string16& message,
|
||||
int32 line_no,
|
||||
const base::string16& source_id) {
|
||||
base::ListValue args;
|
||||
args.AppendInteger(level);
|
||||
args.AppendString(message);
|
||||
args.AppendInteger(line_no);
|
||||
args.AppendString(source_id);
|
||||
Emit("console-message", args);
|
||||
Emit("console-message", level, message, line_no, source_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -90,11 +100,10 @@ bool WebContents::ShouldCreateWebContents(
|
||||
const GURL& target_url,
|
||||
const std::string& partition_id,
|
||||
content::SessionStorageNamespace* session_storage_namespace) {
|
||||
base::ListValue args;
|
||||
args.AppendString(target_url.spec());
|
||||
args.AppendString(frame_name);
|
||||
args.AppendInteger(NEW_FOREGROUND_TAB);
|
||||
Emit("-new-window", args);
|
||||
Emit("-new-window",
|
||||
target_url,
|
||||
frame_name,
|
||||
static_cast<int>(NEW_FOREGROUND_TAB));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -106,18 +115,12 @@ content::WebContents* WebContents::OpenURLFromTab(
|
||||
content::WebContents* source,
|
||||
const content::OpenURLParams& params) {
|
||||
if (params.disposition != CURRENT_TAB) {
|
||||
base::ListValue args;
|
||||
args.AppendString(params.url.spec());
|
||||
args.AppendString("");
|
||||
args.AppendInteger(params.disposition);
|
||||
Emit("-new-window", args);
|
||||
Emit("-new-window", params.url, "", static_cast<int>(params.disposition));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Give user a chance to cancel navigation.
|
||||
base::ListValue args;
|
||||
args.AppendString(params.url.spec());
|
||||
if (Emit("will-navigate", args))
|
||||
if (Emit("will-navigate", params.url))
|
||||
return nullptr;
|
||||
|
||||
content::NavigationController::LoadURLParams load_url_params(params.url);
|
||||
@@ -134,6 +137,35 @@ content::WebContents* WebContents::OpenURLFromTab(
|
||||
return web_contents();
|
||||
}
|
||||
|
||||
void WebContents::RunFileChooser(content::WebContents* guest,
|
||||
const content::FileChooserParams& params) {
|
||||
if (!web_dialog_helper_)
|
||||
web_dialog_helper_.reset(new WebDialogHelper(GetWindowFromGuest(guest)));
|
||||
web_dialog_helper_->RunFileChooser(guest, params);
|
||||
}
|
||||
|
||||
void WebContents::EnumerateDirectory(content::WebContents* guest,
|
||||
int request_id,
|
||||
const base::FilePath& path) {
|
||||
if (!web_dialog_helper_)
|
||||
web_dialog_helper_.reset(new WebDialogHelper(GetWindowFromGuest(guest)));
|
||||
web_dialog_helper_->EnumerateDirectory(guest, request_id, path);
|
||||
}
|
||||
|
||||
bool WebContents::CheckMediaAccessPermission(content::WebContents* web_contents,
|
||||
const GURL& security_origin,
|
||||
content::MediaStreamType type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void WebContents::RequestMediaAccessPermission(
|
||||
content::WebContents*,
|
||||
const content::MediaStreamRequest& request,
|
||||
const content::MediaResponseCallback& callback) {
|
||||
brightray::MediaStreamDevicesController controller(request, callback);
|
||||
controller.TakeAction();
|
||||
}
|
||||
|
||||
void WebContents::HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
@@ -146,10 +178,9 @@ void WebContents::HandleKeyboardEvent(
|
||||
}
|
||||
|
||||
void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
|
||||
base::ListValue args;
|
||||
args.AppendInteger(render_view_host->GetProcess()->GetID());
|
||||
args.AppendInteger(render_view_host->GetRoutingID());
|
||||
Emit("render-view-deleted", args);
|
||||
Emit("render-view-deleted",
|
||||
render_view_host->GetProcess()->GetID(),
|
||||
render_view_host->GetRoutingID());
|
||||
}
|
||||
|
||||
void WebContents::RenderProcessGone(base::TerminationStatus status) {
|
||||
@@ -159,10 +190,7 @@ void WebContents::RenderProcessGone(base::TerminationStatus status) {
|
||||
void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host,
|
||||
const GURL& validated_url) {
|
||||
bool is_main_frame = !render_frame_host->GetParent();
|
||||
|
||||
base::ListValue args;
|
||||
args.AppendBoolean(is_main_frame);
|
||||
Emit("did-frame-finish-load", args);
|
||||
Emit("did-frame-finish-load", is_main_frame);
|
||||
|
||||
if (is_main_frame)
|
||||
Emit("did-finish-load");
|
||||
@@ -172,10 +200,7 @@ void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
|
||||
const GURL& validated_url,
|
||||
int error_code,
|
||||
const base::string16& error_description) {
|
||||
base::ListValue args;
|
||||
args.AppendInteger(error_code);
|
||||
args.AppendString(error_description);
|
||||
Emit("did-fail-load", args);
|
||||
Emit("did-fail-load", error_code, error_description);
|
||||
}
|
||||
|
||||
void WebContents::DidStartLoading(content::RenderViewHost* render_view_host) {
|
||||
@@ -189,12 +214,10 @@ void WebContents::DidStopLoading(content::RenderViewHost* render_view_host) {
|
||||
void WebContents::DidGetRedirectForResourceRequest(
|
||||
content::RenderViewHost* render_view_host,
|
||||
const content::ResourceRedirectDetails& details) {
|
||||
base::ListValue args;
|
||||
args.AppendString(details.url.spec());
|
||||
args.AppendString(details.new_url.spec());
|
||||
args.AppendBoolean(
|
||||
details.resource_type == content::RESOURCE_TYPE_MAIN_FRAME);
|
||||
Emit("did-get-redirect-request", args);
|
||||
Emit("did-get-redirect-request",
|
||||
details.url,
|
||||
details.new_url,
|
||||
(details.resource_type == content::RESOURCE_TYPE_MAIN_FRAME));
|
||||
}
|
||||
|
||||
void WebContents::DidNavigateMainFrame(
|
||||
@@ -224,14 +247,14 @@ void WebContents::RenderViewReady() {
|
||||
// WebContents::GetRenderWidgetHostView will return the RWHV of an
|
||||
// interstitial page if one is showing at this time. We only want opacity
|
||||
// to apply to web pages.
|
||||
web_contents()->GetRenderViewHost()->GetView()->
|
||||
SetBackgroundOpaque(guest_opaque_);
|
||||
|
||||
content::RenderViewHost* rvh = web_contents()->GetRenderViewHost();
|
||||
if (auto_size_enabled_) {
|
||||
rvh->EnableAutoResize(min_auto_size_, max_auto_size_);
|
||||
if (guest_opaque_) {
|
||||
web_contents()
|
||||
->GetRenderViewHost()
|
||||
->GetView()
|
||||
->SetBackgroundColorToDefault();
|
||||
} else {
|
||||
rvh->DisableAutoResize(element_size_);
|
||||
web_contents()->GetRenderViewHost()->GetView()->SetBackgroundColor(
|
||||
SK_ColorTRANSPARENT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,6 +297,9 @@ void WebContents::Destroy() {
|
||||
if (!destruction_callback_.is_null())
|
||||
destruction_callback_.Run();
|
||||
|
||||
// When force destroying the "destroyed" event is not emitted.
|
||||
WebContentsDestroyed();
|
||||
|
||||
Observe(nullptr);
|
||||
storage_.reset();
|
||||
}
|
||||
@@ -392,6 +418,46 @@ bool WebContents::IsDevToolsOpened() {
|
||||
return storage_->IsDevToolsViewShowing();
|
||||
}
|
||||
|
||||
void WebContents::Undo() {
|
||||
web_contents()->Undo();
|
||||
}
|
||||
|
||||
void WebContents::Redo() {
|
||||
web_contents()->Redo();
|
||||
}
|
||||
|
||||
void WebContents::Cut() {
|
||||
web_contents()->Cut();
|
||||
}
|
||||
|
||||
void WebContents::Copy() {
|
||||
web_contents()->Copy();
|
||||
}
|
||||
|
||||
void WebContents::Paste() {
|
||||
web_contents()->Paste();
|
||||
}
|
||||
|
||||
void WebContents::Delete() {
|
||||
web_contents()->Delete();
|
||||
}
|
||||
|
||||
void WebContents::SelectAll() {
|
||||
web_contents()->SelectAll();
|
||||
}
|
||||
|
||||
void WebContents::Unselect() {
|
||||
web_contents()->Unselect();
|
||||
}
|
||||
|
||||
void WebContents::Replace(const base::string16& word) {
|
||||
web_contents()->Replace(word);
|
||||
}
|
||||
|
||||
void WebContents::ReplaceMisspelling(const base::string16& word) {
|
||||
web_contents()->ReplaceMisspelling(word);
|
||||
}
|
||||
|
||||
bool WebContents::SendIPCMessage(const base::string16& channel,
|
||||
const base::ListValue& args) {
|
||||
return Send(new AtomViewMsg_Message(routing_id(), channel, args));
|
||||
@@ -432,7 +498,15 @@ void WebContents::SetAllowTransparency(bool allow) {
|
||||
if (!web_contents()->GetRenderViewHost()->GetView())
|
||||
return;
|
||||
|
||||
web_contents()->GetRenderViewHost()->GetView()->SetBackgroundOpaque(!allow);
|
||||
if (guest_opaque_) {
|
||||
web_contents()
|
||||
->GetRenderViewHost()
|
||||
->GetView()
|
||||
->SetBackgroundColorToDefault();
|
||||
} else {
|
||||
web_contents()->GetRenderViewHost()->GetView()->SetBackgroundColor(
|
||||
SK_ColorTRANSPARENT);
|
||||
}
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||
@@ -462,13 +536,23 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||
.SetMethod("setUserAgent", &WebContents::SetUserAgent)
|
||||
.SetMethod("insertCSS", &WebContents::InsertCSS)
|
||||
.SetMethod("_executeJavaScript", &WebContents::ExecuteJavaScript)
|
||||
.SetMethod("openDevTools", &WebContents::OpenDevTools)
|
||||
.SetMethod("closeDevTools", &WebContents::CloseDevTools)
|
||||
.SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened)
|
||||
.SetMethod("undo", &WebContents::Undo)
|
||||
.SetMethod("redo", &WebContents::Redo)
|
||||
.SetMethod("cut", &WebContents::Cut)
|
||||
.SetMethod("copy", &WebContents::Copy)
|
||||
.SetMethod("paste", &WebContents::Paste)
|
||||
.SetMethod("delete", &WebContents::Delete)
|
||||
.SetMethod("selectAll", &WebContents::SelectAll)
|
||||
.SetMethod("unselect", &WebContents::Unselect)
|
||||
.SetMethod("replace", &WebContents::Replace)
|
||||
.SetMethod("replaceMisspelling", &WebContents::ReplaceMisspelling)
|
||||
.SetMethod("_send", &WebContents::SendIPCMessage)
|
||||
.SetMethod("setAutoSize", &WebContents::SetAutoSize)
|
||||
.SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
|
||||
.SetMethod("isGuest", &WebContents::is_guest)
|
||||
.SetMethod("openDevTools", &WebContents::OpenDevTools)
|
||||
.SetMethod("closeDevTools", &WebContents::CloseDevTools)
|
||||
.SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened)
|
||||
.Build());
|
||||
|
||||
return mate::ObjectTemplateBuilder(
|
||||
@@ -485,17 +569,14 @@ void WebContents::OnRendererMessageSync(const base::string16& channel,
|
||||
const base::ListValue& args,
|
||||
IPC::Message* message) {
|
||||
// webContents.emit(channel, new Event(sender, message), args...);
|
||||
Emit(base::UTF16ToUTF8(channel), args, web_contents(), message);
|
||||
EmitWithSender(base::UTF16ToUTF8(channel), web_contents(), message, args);
|
||||
}
|
||||
|
||||
void WebContents::GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
|
||||
const gfx::Size& new_size) {
|
||||
base::ListValue args;
|
||||
args.AppendInteger(old_size.width());
|
||||
args.AppendInteger(old_size.height());
|
||||
args.AppendInteger(new_size.width());
|
||||
args.AppendInteger(new_size.height());
|
||||
Emit("size-changed", args);
|
||||
Emit("size-changed",
|
||||
old_size.width(), old_size.height(),
|
||||
new_size.width(), new_size.height());
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -24,6 +24,8 @@ class Dictionary;
|
||||
|
||||
namespace atom {
|
||||
|
||||
class WebDialogHelper;
|
||||
|
||||
namespace api {
|
||||
|
||||
class WebContents : public mate::EventEmitter,
|
||||
@@ -65,6 +67,20 @@ class WebContents : public mate::EventEmitter,
|
||||
void OpenDevTools();
|
||||
void CloseDevTools();
|
||||
bool IsDevToolsOpened();
|
||||
|
||||
// Editing commands.
|
||||
void Undo();
|
||||
void Redo();
|
||||
void Cut();
|
||||
void Copy();
|
||||
void Paste();
|
||||
void Delete();
|
||||
void SelectAll();
|
||||
void Unselect();
|
||||
void Replace(const base::string16& word);
|
||||
void ReplaceMisspelling(const base::string16& word);
|
||||
|
||||
// Sending messages to browser.
|
||||
bool SendIPCMessage(const base::string16& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
@@ -113,6 +129,18 @@ class WebContents : public mate::EventEmitter,
|
||||
content::WebContents* OpenURLFromTab(
|
||||
content::WebContents* source,
|
||||
const content::OpenURLParams& params) override;
|
||||
void RunFileChooser(content::WebContents* web_contents,
|
||||
const content::FileChooserParams& params) override;
|
||||
void EnumerateDirectory(content::WebContents* web_contents,
|
||||
int request_id,
|
||||
const base::FilePath& path) override;
|
||||
bool CheckMediaAccessPermission(content::WebContents* web_contents,
|
||||
const GURL& security_origin,
|
||||
content::MediaStreamType type) override;
|
||||
void RequestMediaAccessPermission(
|
||||
content::WebContents*,
|
||||
const content::MediaStreamRequest&,
|
||||
const content::MediaResponseCallback&) override;
|
||||
void HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
@@ -161,6 +189,8 @@ class WebContents : public mate::EventEmitter,
|
||||
void GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
|
||||
const gfx::Size& new_size);
|
||||
|
||||
scoped_ptr<WebDialogHelper> web_dialog_helper_;
|
||||
|
||||
// Unique ID for a guest WebContents.
|
||||
int guest_instance_id_;
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "native_mate/callback.h"
|
||||
#include "native_mate/constructor.h"
|
||||
@@ -76,26 +78,18 @@ Window::~Window() {
|
||||
|
||||
void Window::OnPageTitleUpdated(bool* prevent_default,
|
||||
const std::string& title) {
|
||||
base::ListValue args;
|
||||
args.AppendString(title);
|
||||
*prevent_default = Emit("page-title-updated", args);
|
||||
*prevent_default = Emit("page-title-updated", title);
|
||||
}
|
||||
|
||||
void Window::WillCreatePopupWindow(const base::string16& frame_name,
|
||||
const GURL& target_url,
|
||||
const std::string& partition_id,
|
||||
WindowOpenDisposition disposition) {
|
||||
base::ListValue args;
|
||||
args.AppendString(target_url.spec());
|
||||
args.AppendString(frame_name);
|
||||
args.AppendInteger(disposition);
|
||||
Emit("-new-window", args);
|
||||
Emit("-new-window", target_url, frame_name, static_cast<int>(disposition));
|
||||
}
|
||||
|
||||
void Window::WillNavigate(bool* prevent_default, const GURL& url) {
|
||||
base::ListValue args;
|
||||
args.AppendString(url.spec());
|
||||
*prevent_default = Emit("-will-navigate", args);
|
||||
*prevent_default = Emit("-will-navigate", url);
|
||||
}
|
||||
|
||||
void Window::WillCloseWindow(bool* prevent_default) {
|
||||
@@ -422,6 +416,12 @@ bool Window::IsMenuBarVisible() {
|
||||
return window_->IsMenuBarVisible();
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void Window::ShowDefinitionForSelection() {
|
||||
window_->ShowDefinitionForSelection();
|
||||
}
|
||||
#endif
|
||||
|
||||
mate::Handle<WebContents> Window::GetWebContents(v8::Isolate* isolate) const {
|
||||
return WebContents::CreateFrom(isolate, window_->GetWebContents());
|
||||
}
|
||||
@@ -491,6 +491,10 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("isMenuBarAutoHide", &Window::IsMenuBarAutoHide)
|
||||
.SetMethod("setMenuBarVisibility", &Window::SetMenuBarVisibility)
|
||||
.SetMethod("isMenuBarVisible", &Window::IsMenuBarVisible)
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("showDefinitionForSelection",
|
||||
&Window::ShowDefinitionForSelection)
|
||||
#endif
|
||||
.SetMethod("_getWebContents", &Window::GetWebContents)
|
||||
.SetMethod("_getDevToolsWebContents", &Window::GetDevToolsWebContents);
|
||||
}
|
||||
|
||||
@@ -123,6 +123,10 @@ class Window : public mate::EventEmitter,
|
||||
void SetMenuBarVisibility(bool visible);
|
||||
bool IsMenuBarVisible();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void ShowDefinitionForSelection();
|
||||
#endif
|
||||
|
||||
// APIs for WebContents.
|
||||
mate::Handle<WebContents> GetWebContents(v8::Isolate* isolate) const;
|
||||
mate::Handle<WebContents> GetDevToolsWebContents(v8::Isolate* isolate) const;
|
||||
|
||||
@@ -34,10 +34,10 @@ class Event : public Wrappable,
|
||||
virtual ~Event();
|
||||
|
||||
// Wrappable implementations:
|
||||
virtual ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate);
|
||||
ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) override;
|
||||
|
||||
// content::WebContentsObserver implementations:
|
||||
virtual void WebContentsDestroyed() OVERRIDE;
|
||||
void WebContentsDestroyed() override;
|
||||
|
||||
private:
|
||||
// Replyer for the synchronous messages.
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
|
||||
#include "atom/browser/api/event.h"
|
||||
#include "atom/common/native_mate_converters/v8_value_converter.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/values.h"
|
||||
#include "native_mate/arguments.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
@@ -41,43 +38,11 @@ v8::Local<v8::Object> CreateEventObject(v8::Isolate* isolate) {
|
||||
EventEmitter::EventEmitter() {
|
||||
}
|
||||
|
||||
bool EventEmitter::Emit(const base::StringPiece& name) {
|
||||
return Emit(name, base::ListValue());
|
||||
}
|
||||
|
||||
bool EventEmitter::Emit(const base::StringPiece& name,
|
||||
const base::ListValue& args) {
|
||||
return Emit(name, args, NULL, NULL);
|
||||
}
|
||||
|
||||
bool EventEmitter::Emit(const base::StringPiece& name,
|
||||
const base::ListValue& args,
|
||||
content::WebContents* sender,
|
||||
IPC::Message* message) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
v8::Handle<v8::Context> context = isolate->GetCurrentContext();
|
||||
scoped_ptr<atom::V8ValueConverter> converter(new atom::V8ValueConverter);
|
||||
|
||||
// v8_args = [args...];
|
||||
Arguments v8_args;
|
||||
v8_args.reserve(args.GetSize());
|
||||
for (size_t i = 0; i < args.GetSize(); i++) {
|
||||
const base::Value* value(NULL);
|
||||
if (args.Get(i, &value))
|
||||
v8_args.push_back(converter->ToV8Value(value, context));
|
||||
}
|
||||
|
||||
return Emit(isolate, name, v8_args, sender, message);
|
||||
}
|
||||
|
||||
bool EventEmitter::Emit(v8::Isolate* isolate,
|
||||
const base::StringPiece& name,
|
||||
Arguments args,
|
||||
content::WebContents* sender,
|
||||
IPC::Message* message) {
|
||||
bool EventEmitter::CallEmit(v8::Isolate* isolate,
|
||||
const base::StringPiece& name,
|
||||
content::WebContents* sender,
|
||||
IPC::Message* message,
|
||||
ValueArray args) {
|
||||
v8::Handle<v8::Object> event;
|
||||
bool use_native_event = sender && message;
|
||||
|
||||
|
||||
@@ -9,10 +9,6 @@
|
||||
|
||||
#include "native_mate/wrappable.h"
|
||||
|
||||
namespace base {
|
||||
class ListValue;
|
||||
}
|
||||
|
||||
namespace content {
|
||||
class WebContents;
|
||||
}
|
||||
@@ -26,29 +22,39 @@ namespace mate {
|
||||
// Provide helperers to emit event in JavaScript.
|
||||
class EventEmitter : public Wrappable {
|
||||
public:
|
||||
typedef std::vector<v8::Handle<v8::Value>> Arguments;
|
||||
typedef std::vector<v8::Handle<v8::Value>> ValueArray;
|
||||
|
||||
protected:
|
||||
EventEmitter();
|
||||
|
||||
// this.emit(name, new Event());
|
||||
bool Emit(const base::StringPiece& name);
|
||||
|
||||
// this.emit(name, new Event(), args...);
|
||||
bool Emit(const base::StringPiece& name, const base::ListValue& args);
|
||||
template<typename... Args>
|
||||
bool Emit(const base::StringPiece& name, const Args&... args) {
|
||||
return EmitWithSender(name, nullptr, nullptr, args...);
|
||||
}
|
||||
|
||||
// this.emit(name, new Event(sender, message), args...);
|
||||
bool Emit(const base::StringPiece& name, const base::ListValue& args,
|
||||
content::WebContents* sender, IPC::Message* message);
|
||||
template<typename... Args>
|
||||
bool EmitWithSender(const base::StringPiece& name,
|
||||
content::WebContents* sender,
|
||||
IPC::Message* message,
|
||||
const Args&... args) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
// Lower level implementations.
|
||||
bool Emit(v8::Isolate* isolate,
|
||||
const base::StringPiece& name,
|
||||
Arguments args,
|
||||
content::WebContents* sender = nullptr,
|
||||
IPC::Message* message = nullptr);
|
||||
ValueArray converted = { ConvertToV8(isolate, args)... };
|
||||
return CallEmit(isolate, name, sender, message, converted);
|
||||
}
|
||||
|
||||
private:
|
||||
// Lower level implementations.
|
||||
bool CallEmit(v8::Isolate* isolate,
|
||||
const base::StringPiece& name,
|
||||
content::WebContents* sender,
|
||||
IPC::Message* message,
|
||||
ValueArray args);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(EventEmitter);
|
||||
};
|
||||
|
||||
|
||||
@@ -5,9 +5,6 @@ bindings = process.atomBinding 'app'
|
||||
app = bindings.app
|
||||
app.__proto__ = EventEmitter.prototype
|
||||
|
||||
app.getHomeDir = ->
|
||||
process.env[if process.platform is 'win32' then 'USERPROFILE' else 'HOME']
|
||||
|
||||
app.setApplicationMenu = (menu) ->
|
||||
require('menu').setApplicationMenu menu
|
||||
|
||||
@@ -32,6 +29,9 @@ if process.platform is 'darwin'
|
||||
app.once 'ready', -> app.emit 'finish-launching'
|
||||
app.terminate = app.quit
|
||||
app.exit = process.exit
|
||||
app.getHomeDir = -> app.getPath 'home'
|
||||
app.getDataPath = -> app.getPath 'userData'
|
||||
app.setDataPath = (path) -> app.setPath 'userData', path
|
||||
|
||||
# Only one App object pemitted.
|
||||
module.exports = app
|
||||
|
||||
@@ -91,12 +91,12 @@ module.exports =
|
||||
options.title ?= ''
|
||||
options.message ?= ''
|
||||
options.detail ?= ''
|
||||
options.icon ?= null
|
||||
|
||||
binding.showMessageBox options.type,
|
||||
options.buttons,
|
||||
String(options.title),
|
||||
String(options.message),
|
||||
String(options.detail),
|
||||
[options.title, options.message, options.detail],
|
||||
options.icon,
|
||||
window,
|
||||
callback
|
||||
|
||||
|
||||
6
atom/browser/api/lib/screen.coffee
Normal file
6
atom/browser/api/lib/screen.coffee
Normal file
@@ -0,0 +1,6 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
|
||||
screen = process.atomBinding('screen').screen
|
||||
screen.__proto__ = EventEmitter.prototype
|
||||
|
||||
module.exports = screen
|
||||
@@ -9,8 +9,8 @@ module.exports.wrap = (webContents) ->
|
||||
webContents.__proto__ = EventEmitter.prototype
|
||||
|
||||
# WebContents::send(channel, args..)
|
||||
webContents.send = (args...) ->
|
||||
@_send 'ATOM_INTERNAL_MESSAGE', [args...]
|
||||
webContents.send = (channel, args...) ->
|
||||
@_send channel, [args...]
|
||||
|
||||
# Make sure webContents.executeJavaScript would run the code only when the
|
||||
# web contents has been loaded.
|
||||
@@ -48,10 +48,12 @@ module.exports.wrap = (webContents) ->
|
||||
process.emit 'ATOM_BROWSER_RELEASE_RENDER_VIEW', "#{processId}-#{routingId}"
|
||||
|
||||
# Dispatch IPC messages to the ipc module.
|
||||
webContents.on 'ipc-message', (event, channel, args...) ->
|
||||
webContents.on 'ipc-message', (event, packed) ->
|
||||
[channel, args...] = packed
|
||||
Object.defineProperty event, 'sender', value: webContents
|
||||
ipc.emit channel, event, args...
|
||||
webContents.on 'ipc-message-sync', (event, channel, args...) ->
|
||||
webContents.on 'ipc-message-sync', (event, packed) ->
|
||||
[channel, args...] = packed
|
||||
Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value)
|
||||
Object.defineProperty event, 'sender', value: webContents
|
||||
ipc.emit channel, event, args...
|
||||
|
||||
@@ -17,10 +17,10 @@ class AtomAccessTokenStore : public content::AccessTokenStore {
|
||||
virtual ~AtomAccessTokenStore();
|
||||
|
||||
// content::AccessTokenStore:
|
||||
virtual void LoadAccessTokens(
|
||||
const LoadAccessTokensCallbackType& callback) OVERRIDE;
|
||||
virtual void SaveAccessToken(const GURL& server_url,
|
||||
const base::string16& access_token) OVERRIDE;
|
||||
void LoadAccessTokens(
|
||||
const LoadAccessTokensCallbackType& callback) override;
|
||||
void SaveAccessToken(const GURL& server_url,
|
||||
const base::string16& access_token) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomAccessTokenStore);
|
||||
|
||||
@@ -87,8 +87,8 @@ void AtomBrowserClient::OverrideWebkitPrefs(
|
||||
prefs->allow_universal_access_from_file_urls = true;
|
||||
prefs->allow_file_access_from_file_urls = true;
|
||||
prefs->experimental_webgl_enabled = true;
|
||||
prefs->allow_displaying_insecure_content = true;
|
||||
prefs->allow_running_insecure_content = true;
|
||||
prefs->allow_displaying_insecure_content = false;
|
||||
prefs->allow_running_insecure_content = false;
|
||||
|
||||
// Turn off web security for devtools.
|
||||
if (url.SchemeIs("chrome-devtools")) {
|
||||
@@ -96,6 +96,14 @@ void AtomBrowserClient::OverrideWebkitPrefs(
|
||||
return;
|
||||
}
|
||||
|
||||
// Custom preferences of guest page.
|
||||
int guest_process_id = render_view_host->GetProcess()->GetID();
|
||||
WebViewRendererState::WebViewInfo info;
|
||||
if (WebViewRendererState::GetInstance()->GetInfo(guest_process_id, &info)) {
|
||||
prefs->web_security_enabled = !info.disable_web_security;
|
||||
return;
|
||||
}
|
||||
|
||||
NativeWindow* window = NativeWindow::FromRenderView(
|
||||
render_view_host->GetProcess()->GetID(),
|
||||
render_view_host->GetRoutingID());
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
#include "atom/browser/net/atom_url_request_job_factory.h"
|
||||
#include "atom/browser/net/asar/asar_protocol_handler.h"
|
||||
#include "atom/browser/web_view/web_view_manager.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/threading/sequenced_worker_pool.h"
|
||||
#include "base/threading/worker_pool.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/common/url_constants.h"
|
||||
#include "net/url_request/data_protocol_handler.h"
|
||||
#include "net/url_request/file_protocol_handler.h"
|
||||
#include "net/url_request/url_request_intercepting_job_factory.h"
|
||||
#include "url/url_constants.h"
|
||||
|
||||
@@ -24,7 +25,13 @@ namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
const char* kAsarScheme = "asar";
|
||||
class NoCacheBackend : public net::HttpCache::BackendFactory {
|
||||
int CreateBackend(net::NetLog* net_log,
|
||||
scoped_ptr<disk_cache::Backend>* backend,
|
||||
const net::CompletionCallback& callback) override {
|
||||
return net::ERR_FAILED;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -49,17 +56,12 @@ net::URLRequestJobFactory* AtomBrowserContext::CreateURLRequestJobFactory(
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kDataScheme, new net::DataProtocolHandler);
|
||||
job_factory->SetProtocolHandler(
|
||||
url::kFileScheme, new net::FileProtocolHandler(
|
||||
BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
|
||||
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
|
||||
job_factory->SetProtocolHandler(
|
||||
kAsarScheme, new asar::AsarProtocolHandler(
|
||||
url::kFileScheme, new asar::AsarProtocolHandler(
|
||||
BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
|
||||
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
|
||||
|
||||
// Set up interceptors in the reverse order.
|
||||
scoped_ptr<net::URLRequestJobFactory> top_job_factory =
|
||||
job_factory.PassAs<net::URLRequestJobFactory>();
|
||||
scoped_ptr<net::URLRequestJobFactory> top_job_factory = job_factory.Pass();
|
||||
content::URLRequestInterceptorScopedVector::reverse_iterator it;
|
||||
for (it = interceptors->rbegin(); it != interceptors->rend(); ++it)
|
||||
top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
|
||||
@@ -69,6 +71,16 @@ net::URLRequestJobFactory* AtomBrowserContext::CreateURLRequestJobFactory(
|
||||
return top_job_factory.release();
|
||||
}
|
||||
|
||||
net::HttpCache::BackendFactory*
|
||||
AtomBrowserContext::CreateHttpCacheBackendFactory(
|
||||
const base::FilePath& base_path) {
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
if (command_line->HasSwitch(switches::kDisableHttpCache))
|
||||
return new NoCacheBackend;
|
||||
else
|
||||
return brightray::BrowserContext::CreateHttpCacheBackendFactory(base_path);
|
||||
}
|
||||
|
||||
content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() {
|
||||
if (!guest_manager_)
|
||||
guest_manager_.reset(new WebViewManager(this));
|
||||
|
||||
@@ -26,6 +26,8 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
net::URLRequestJobFactory* CreateURLRequestJobFactory(
|
||||
content::ProtocolHandlerMap* handlers,
|
||||
content::URLRequestInterceptorScopedVector* interceptors) override;
|
||||
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
|
||||
const base::FilePath& base_path) override;
|
||||
|
||||
// content::BrowserContext:
|
||||
content::BrowserPluginGuestManager* GetGuestManager() override;
|
||||
|
||||
@@ -72,6 +72,9 @@ void AtomBrowserMainParts::PostEarlyInitialization() {
|
||||
|
||||
// Add atom-shell extended APIs.
|
||||
atom_bindings_->BindTo(js_env_->isolate(), global_env->process_object());
|
||||
|
||||
// Load everything.
|
||||
node_bindings_->LoadEnvironment(global_env);
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::PreMainMessageLoopRun() {
|
||||
|
||||
@@ -27,14 +27,14 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||
|
||||
protected:
|
||||
// Implementations of brightray::BrowserMainParts.
|
||||
virtual brightray::BrowserContext* CreateBrowserContext() OVERRIDE;
|
||||
brightray::BrowserContext* CreateBrowserContext() override;
|
||||
|
||||
// Implementations of content::BrowserMainParts.
|
||||
virtual void PostEarlyInitialization() OVERRIDE;
|
||||
virtual void PreMainMessageLoopRun() OVERRIDE;
|
||||
void PostEarlyInitialization() override;
|
||||
void PreMainMessageLoopRun() override;
|
||||
#if defined(OS_MACOSX)
|
||||
virtual void PreMainMessageLoopStart() OVERRIDE;
|
||||
virtual void PostDestroyThreads() OVERRIDE;
|
||||
void PreMainMessageLoopStart() override;
|
||||
void PostDestroyThreads() override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
@@ -13,11 +13,6 @@
|
||||
|
||||
namespace atom {
|
||||
|
||||
std::string GetApplicationName() {
|
||||
std::string name = brightray::MainApplicationBundlePath().BaseName().AsUTF8Unsafe();
|
||||
return name.substr(0, name.length() - 4/*.app*/);
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::PreMainMessageLoopStart() {
|
||||
// Initialize locale setting.
|
||||
l10n_util::OverrideLocaleWithCocoaLocale();
|
||||
@@ -31,7 +26,7 @@ void AtomBrowserMainParts::PreMainMessageLoopStart() {
|
||||
base::FilePath frameworkPath = brightray::MainApplicationBundlePath()
|
||||
.Append("Contents")
|
||||
.Append("Frameworks")
|
||||
.Append(GetApplicationName() + " Framework.framework");
|
||||
.Append(PRODUCT_NAME " Framework.framework");
|
||||
NSBundle* frameworkBundle = [NSBundle
|
||||
bundleWithPath:base::mac::FilePathToNSString(frameworkPath)];
|
||||
NSNib* mainNib = [[NSNib alloc] initWithNibNamed:@"MainMenu"
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace atom {
|
||||
class AtomJavaScriptDialogManager : public content::JavaScriptDialogManager {
|
||||
public:
|
||||
// content::JavaScriptDialogManager implementations.
|
||||
virtual void RunJavaScriptDialog(
|
||||
void RunJavaScriptDialog(
|
||||
content::WebContents* web_contents,
|
||||
const GURL& origin_url,
|
||||
const std::string& accept_lang,
|
||||
@@ -22,16 +22,15 @@ class AtomJavaScriptDialogManager : public content::JavaScriptDialogManager {
|
||||
const base::string16& message_text,
|
||||
const base::string16& default_prompt_text,
|
||||
const DialogClosedCallback& callback,
|
||||
bool* did_suppress_message) OVERRIDE;
|
||||
virtual void RunBeforeUnloadDialog(
|
||||
bool* did_suppress_message) override;
|
||||
void RunBeforeUnloadDialog(
|
||||
content::WebContents* web_contents,
|
||||
const base::string16& message_text,
|
||||
bool is_reload,
|
||||
const DialogClosedCallback& callback) OVERRIDE;
|
||||
virtual void CancelActiveAndPendingDialogs(
|
||||
content::WebContents* web_contents) OVERRIDE {}
|
||||
virtual void WebContentsDestroyed(
|
||||
content::WebContents* web_contents) OVERRIDE {}
|
||||
const DialogClosedCallback& callback) override;
|
||||
void CancelActiveAndPendingDialogs(
|
||||
content::WebContents* web_contents) override {}
|
||||
void WebContentsDestroyed(content::WebContents* web_contents) override {}
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -41,6 +41,8 @@ if (option.file && !option.webdriver) {
|
||||
app.setName(packageJson.productName);
|
||||
else if (packageJson.name)
|
||||
app.setName(packageJson.name);
|
||||
app.setPath('userData', path.join(app.getPath('appData'), app.getName()));
|
||||
app.setPath('userCache', path.join(app.getPath('cache'), app.getName()));
|
||||
}
|
||||
|
||||
// Run the app.
|
||||
|
||||
@@ -32,17 +32,11 @@ getExtensionInfoFromPath = (srcDirectory) ->
|
||||
startPage: page
|
||||
name: manifest.name
|
||||
srcDirectory: srcDirectory
|
||||
extensionInfoMap[manifest.name]
|
||||
extensionInfoMap[manifest.name]
|
||||
|
||||
# Load persistented extensions.
|
||||
loadedExtensionsPath = path.join app.getDataPath(), 'DevTools Extensions'
|
||||
|
||||
try
|
||||
loadedExtensions = JSON.parse fs.readFileSync(loadedExtensionsPath)
|
||||
loadedExtensions = [] unless Array.isArray loadedExtensions
|
||||
# Preheat the extensionInfo cache.
|
||||
getExtensionInfoFromPath srcDirectory for srcDirectory in loadedExtensions
|
||||
catch e
|
||||
# The loaded extensions cache and its persistent path.
|
||||
loadedExtensions = null
|
||||
loadedExtensionsPath = null
|
||||
|
||||
# Persistent loaded extensions.
|
||||
app.on 'will-quit', ->
|
||||
@@ -59,6 +53,16 @@ app.once 'ready', ->
|
||||
protocol = require 'protocol'
|
||||
BrowserWindow = require 'browser-window'
|
||||
|
||||
# Load persistented extensions.
|
||||
loadedExtensionsPath = path.join app.getDataPath(), 'DevTools Extensions'
|
||||
|
||||
try
|
||||
loadedExtensions = JSON.parse fs.readFileSync(loadedExtensionsPath)
|
||||
loadedExtensions = [] unless Array.isArray loadedExtensions
|
||||
# Preheat the extensionInfo cache.
|
||||
getExtensionInfoFromPath srcDirectory for srcDirectory in loadedExtensions
|
||||
catch e
|
||||
|
||||
# The chrome-extension: can map a extension URL request to real file path.
|
||||
protocol.registerProtocol 'chrome-extension', (request) ->
|
||||
parsed = url.parse request.url
|
||||
@@ -74,8 +78,9 @@ app.once 'ready', ->
|
||||
|
||||
BrowserWindow.addDevToolsExtension = (srcDirectory) ->
|
||||
extensionInfo = getExtensionInfoFromPath srcDirectory
|
||||
window._loadDevToolsExtensions [extensionInfo] for window in BrowserWindow.getAllWindows()
|
||||
extensionInfo.name
|
||||
if extensionInfo
|
||||
window._loadDevToolsExtensions [extensionInfo] for window in BrowserWindow.getAllWindows()
|
||||
extensionInfo.name
|
||||
|
||||
BrowserWindow.removeDevToolsExtension = (name) ->
|
||||
delete extensionInfoMap[name]
|
||||
|
||||
@@ -40,8 +40,9 @@ createGuest = (embedder, params) ->
|
||||
destroyEvents = ['destroyed', 'crashed', 'did-navigate-to-different-page']
|
||||
destroy = ->
|
||||
destroyGuest id if guestInstances[id]?
|
||||
embedder.removeListener event, destroy for event in destroyEvents
|
||||
embedder.once event, destroy for event in destroyEvents
|
||||
guest.once 'destroyed', ->
|
||||
embedder.removeListener event, destroy for event in destroyEvents
|
||||
|
||||
# Init guest web view after attached.
|
||||
guest.once 'did-attach', ->
|
||||
@@ -67,7 +68,8 @@ createGuest = (embedder, params) ->
|
||||
embedder.send "ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-#{guest.viewInstanceId}", event, args...
|
||||
|
||||
# Dispatch guest's IPC messages to embedder.
|
||||
guest.on 'ipc-message-host', (_, channel, args...) ->
|
||||
guest.on 'ipc-message-host', (_, packed) ->
|
||||
[channel, args...] = packed
|
||||
embedder.send "ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-#{guest.viewInstanceId}", channel, args...
|
||||
|
||||
# Autosize.
|
||||
@@ -93,6 +95,7 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) ->
|
||||
webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest,
|
||||
nodeIntegration: params.nodeintegration
|
||||
plugins: params.plugins
|
||||
disableWebSecurity: params.disablewebsecurity
|
||||
preloadUrl: params.preload ? ''
|
||||
|
||||
guest.attachParams = params
|
||||
@@ -113,9 +116,8 @@ destroyGuest = (id) ->
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_CREATE_GUEST', (event, type, params, requestId) ->
|
||||
event.sender.send "ATOM_SHELL_RESPONSE_#{requestId}", createGuest(event.sender, params)
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', (event, elementInstanceId, guestInstanceId, params, requestId) ->
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', (event, elementInstanceId, guestInstanceId, params) ->
|
||||
attachGuest event.sender, elementInstanceId, guestInstanceId, params
|
||||
event.sender.send "ATOM_SHELL_RESPONSE_#{requestId}"
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', (event, id) ->
|
||||
destroyGuest id
|
||||
|
||||
@@ -23,75 +23,81 @@ process.argv.splice startMark, endMark - startMark + 1
|
||||
globalPaths = module.globalPaths
|
||||
globalPaths.push path.join process.resourcesPath, 'atom', 'browser', 'api', 'lib'
|
||||
|
||||
# Following operations need extra bindings by AtomBindings.
|
||||
process.once 'BIND_DONE', ->
|
||||
# Import common settings.
|
||||
require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init.js')
|
||||
# Import common settings.
|
||||
require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init')
|
||||
|
||||
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
|
||||
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
|
||||
# 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.
|
||||
stack = error.stack ? "#{error.name}: #{error.message}"
|
||||
message = "Uncaught Exception:\n#{stack}"
|
||||
require('dialog').showErrorBox 'A JavaScript error occured in the browser process', message
|
||||
# Don't quit on fatal error.
|
||||
process.on 'uncaughtException', (error) ->
|
||||
# Do nothing if the user has a custom uncaught exception handler.
|
||||
if process.listeners('uncaughtException').length > 1
|
||||
return
|
||||
|
||||
# Emit 'exit' event on quit.
|
||||
require('app').on 'quit', ->
|
||||
process.emit 'exit'
|
||||
# Show error in GUI.
|
||||
stack = error.stack ? "#{error.name}: #{error.message}"
|
||||
message = "Uncaught Exception:\n#{stack}"
|
||||
require('dialog').showErrorBox 'A JavaScript error occured in the browser process', message
|
||||
|
||||
# Load the RPC server.
|
||||
require './rpc-server'
|
||||
# Emit 'exit' event on quit.
|
||||
app = require 'app'
|
||||
app.on 'quit', ->
|
||||
process.emit 'exit'
|
||||
|
||||
# Load the guest view manager.
|
||||
require './guest-view-manager'
|
||||
require './guest-window-manager'
|
||||
# Load the RPC server.
|
||||
require './rpc-server'
|
||||
|
||||
# Now we try to load app's package.json.
|
||||
packageJson = null
|
||||
# Load the guest view manager.
|
||||
require './guest-view-manager'
|
||||
require './guest-window-manager'
|
||||
|
||||
searchPaths = [ 'app', 'app.asar', 'default_app' ]
|
||||
for packagePath in searchPaths
|
||||
try
|
||||
packagePath = path.join process.resourcesPath, packagePath
|
||||
packageJson = JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json')))
|
||||
break
|
||||
catch e
|
||||
continue
|
||||
# Now we try to load app's package.json.
|
||||
packageJson = null
|
||||
|
||||
throw new Error("Unable to find a valid app") unless packageJson?
|
||||
searchPaths = [ 'app', 'app.asar', 'default_app' ]
|
||||
for packagePath in searchPaths
|
||||
try
|
||||
packagePath = path.join process.resourcesPath, packagePath
|
||||
packageJson = JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json')))
|
||||
break
|
||||
catch e
|
||||
continue
|
||||
|
||||
# Set application's version.
|
||||
app = require 'app'
|
||||
app.setVersion packageJson.version if packageJson.version?
|
||||
throw new Error("Unable to find a valid app") unless packageJson?
|
||||
|
||||
# Set application's name.
|
||||
if packageJson.productName?
|
||||
app.setName packageJson.productName
|
||||
else if packageJson.name?
|
||||
app.setName packageJson.name
|
||||
# Set application's version.
|
||||
app.setVersion packageJson.version if packageJson.version?
|
||||
|
||||
# Set application's desktop name.
|
||||
if packageJson.desktopName?
|
||||
app.setDesktopName packageJson.desktopName
|
||||
else
|
||||
app.setDesktopName '#{app.getName()}.desktop'
|
||||
# Set application's name.
|
||||
if packageJson.productName?
|
||||
app.setName packageJson.productName
|
||||
else if packageJson.name?
|
||||
app.setName packageJson.name
|
||||
|
||||
# Load the chrome extension support.
|
||||
require './chrome-extension.js'
|
||||
# Set application's desktop name.
|
||||
if packageJson.desktopName?
|
||||
app.setDesktopName packageJson.desktopName
|
||||
else
|
||||
app.setDesktopName "#{app.getName()}.desktop"
|
||||
|
||||
# Finally load app's main.js and transfer control to C++.
|
||||
module._load path.join(packagePath, packageJson.main), module, true
|
||||
# Set the user path according to application's name.
|
||||
app.setPath 'userData', path.join(app.getPath('appData'), app.getName())
|
||||
app.setPath 'userCache', path.join(app.getPath('cache'), app.getName())
|
||||
|
||||
# Load the chrome extension support.
|
||||
require './chrome-extension'
|
||||
|
||||
# Finally load app's main.js and transfer control to C++.
|
||||
module._load path.join(packagePath, packageJson.main), module, true
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/json/json_writer.h"
|
||||
#include "base/prefs/pref_service.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
#include "chrome/browser/printing/print_view_manager_basic.h"
|
||||
#include "chrome/browser/ui/browser_dialogs.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/public/browser/devtools_agent_host.h"
|
||||
#include "content/public/browser/invalidate_type.h"
|
||||
#include "content/public/browser/navigation_entry.h"
|
||||
@@ -56,10 +57,18 @@
|
||||
#include "ui/gfx/screen.h"
|
||||
#include "ui/gfx/size.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "ui/gfx/switches.h"
|
||||
#endif
|
||||
|
||||
using content::NavigationEntry;
|
||||
using content::RenderWidgetHostView;
|
||||
using content::RenderWidgetHost;
|
||||
|
||||
namespace content {
|
||||
CONTENT_EXPORT extern bool g_use_transparent_window;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
@@ -88,6 +97,7 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
|
||||
const mate::Dictionary& options)
|
||||
: content::WebContentsObserver(web_contents),
|
||||
has_frame_(true),
|
||||
transparent_(false),
|
||||
enable_larger_than_screen_(false),
|
||||
is_closed_(false),
|
||||
node_integration_(true),
|
||||
@@ -99,9 +109,14 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
|
||||
printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
|
||||
|
||||
options.Get(switches::kFrame, &has_frame_);
|
||||
options.Get(switches::kTransparent, &transparent_);
|
||||
options.Get(switches::kEnableLargerThanScreen, &enable_larger_than_screen_);
|
||||
options.Get(switches::kNodeIntegration, &node_integration_);
|
||||
|
||||
// Tell the content module to initialize renderer widget with transparent
|
||||
// mode.
|
||||
content::g_use_transparent_window = transparent_;
|
||||
|
||||
// Read icon before window is created.
|
||||
options.Get(switches::kIcon, &icon_);
|
||||
|
||||
@@ -247,6 +262,10 @@ void NativeWindow::Print(bool silent, bool print_background) {
|
||||
PrintNow(silent, print_background);
|
||||
}
|
||||
|
||||
void NativeWindow::ShowDefinitionForSelection() {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void NativeWindow::SetAutoHideMenuBar(bool auto_hide) {
|
||||
}
|
||||
|
||||
@@ -556,6 +575,18 @@ content::JavaScriptDialogManager* NativeWindow::GetJavaScriptDialogManager() {
|
||||
return dialog_manager_.get();
|
||||
}
|
||||
|
||||
void NativeWindow::RenderViewCreated(
|
||||
content::RenderViewHost* render_view_host) {
|
||||
if (!transparent_)
|
||||
return;
|
||||
|
||||
content::RenderWidgetHostImpl* impl = content::RenderWidgetHostImpl::FromID(
|
||||
render_view_host->GetProcess()->GetID(),
|
||||
render_view_host->GetRoutingID());
|
||||
if (impl)
|
||||
impl->SetBackgroundOpaque(false);
|
||||
}
|
||||
|
||||
void NativeWindow::BeforeUnloadFired(content::WebContents* tab,
|
||||
bool proceed,
|
||||
bool* proceed_to_fire_unload) {
|
||||
|
||||
@@ -161,6 +161,9 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||
// Print current page.
|
||||
virtual void Print(bool silent, bool print_background);
|
||||
|
||||
// Show popup dictionary.
|
||||
virtual void ShowDefinitionForSelection();
|
||||
|
||||
// Toggle the menu bar.
|
||||
virtual void SetAutoHideMenuBar(bool auto_hide);
|
||||
virtual bool IsMenuBarAutoHide();
|
||||
@@ -266,6 +269,7 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||
void RendererResponsive(content::WebContents* source) override;
|
||||
|
||||
// Implementations of content::WebContentsObserver.
|
||||
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
|
||||
void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
|
||||
bool OnMessageReceived(const IPC::Message& message) override;
|
||||
|
||||
@@ -284,6 +288,9 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
|
||||
// Whether window has standard frame.
|
||||
bool has_frame_;
|
||||
|
||||
// Whether window is transparent.
|
||||
bool transparent_;
|
||||
|
||||
// Whether window can be resized larger than screen.
|
||||
bool enable_larger_than_screen_;
|
||||
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/mac/scoped_nsobject.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
@@ -23,51 +26,52 @@ class NativeWindowMac : public NativeWindow {
|
||||
virtual ~NativeWindowMac();
|
||||
|
||||
// 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 ShowInactive() OVERRIDE;
|
||||
virtual void Hide() OVERRIDE;
|
||||
virtual bool IsVisible() OVERRIDE;
|
||||
virtual void Maximize() OVERRIDE;
|
||||
virtual void Unmaximize() OVERRIDE;
|
||||
virtual bool IsMaximized() OVERRIDE;
|
||||
virtual void Minimize() OVERRIDE;
|
||||
virtual void Restore() OVERRIDE;
|
||||
virtual bool IsMinimized() 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 SetContentSize(const gfx::Size& size) OVERRIDE;
|
||||
virtual gfx::Size GetContentSize() 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 SetSkipTaskbar(bool skip) OVERRIDE;
|
||||
virtual void SetKiosk(bool kiosk) OVERRIDE;
|
||||
virtual bool IsKiosk() OVERRIDE;
|
||||
virtual void SetRepresentedFilename(const std::string& filename) OVERRIDE;
|
||||
virtual std::string GetRepresentedFilename() OVERRIDE;
|
||||
virtual void SetDocumentEdited(bool edited) OVERRIDE;
|
||||
virtual bool IsDocumentEdited() OVERRIDE;
|
||||
virtual bool HasModalDialog() OVERRIDE;
|
||||
virtual gfx::NativeWindow GetNativeWindow() OVERRIDE;
|
||||
virtual void SetProgressBar(double progress) OVERRIDE;
|
||||
void Close() override;
|
||||
void CloseImmediately() override;
|
||||
void Move(const gfx::Rect& pos) override;
|
||||
void Focus(bool focus) override;
|
||||
bool IsFocused() override;
|
||||
void Show() override;
|
||||
void ShowInactive() override;
|
||||
void Hide() override;
|
||||
bool IsVisible() override;
|
||||
void Maximize() override;
|
||||
void Unmaximize() override;
|
||||
bool IsMaximized() override;
|
||||
void Minimize() override;
|
||||
void Restore() override;
|
||||
bool IsMinimized() override;
|
||||
void SetFullScreen(bool fullscreen) override;
|
||||
bool IsFullscreen() override;
|
||||
void SetSize(const gfx::Size& size) override;
|
||||
gfx::Size GetSize() override;
|
||||
void SetContentSize(const gfx::Size& size) override;
|
||||
gfx::Size GetContentSize() override;
|
||||
void SetMinimumSize(const gfx::Size& size) override;
|
||||
gfx::Size GetMinimumSize() override;
|
||||
void SetMaximumSize(const gfx::Size& size) override;
|
||||
gfx::Size GetMaximumSize() override;
|
||||
void SetResizable(bool resizable) override;
|
||||
bool IsResizable() override;
|
||||
void SetAlwaysOnTop(bool top) override;
|
||||
bool IsAlwaysOnTop() override;
|
||||
void Center() override;
|
||||
void SetPosition(const gfx::Point& position) override;
|
||||
gfx::Point GetPosition() override;
|
||||
void SetTitle(const std::string& title) override;
|
||||
std::string GetTitle() override;
|
||||
void FlashFrame(bool flash) override;
|
||||
void SetSkipTaskbar(bool skip) override;
|
||||
void SetKiosk(bool kiosk) override;
|
||||
bool IsKiosk() override;
|
||||
void SetRepresentedFilename(const std::string& filename) override;
|
||||
std::string GetRepresentedFilename() override;
|
||||
void SetDocumentEdited(bool edited) override;
|
||||
bool IsDocumentEdited() override;
|
||||
bool HasModalDialog() override;
|
||||
gfx::NativeWindow GetNativeWindow() override;
|
||||
void SetProgressBar(double progress) override;
|
||||
void ShowDefinitionForSelection() override;
|
||||
|
||||
// Returns true if |point| in local Cocoa coordinate system falls within
|
||||
// the draggable region.
|
||||
@@ -79,23 +83,22 @@ class NativeWindowMac : public NativeWindow {
|
||||
// Clip web view to rounded corner.
|
||||
void ClipWebView();
|
||||
|
||||
SkRegion* draggable_region() const { return draggable_region_.get(); }
|
||||
|
||||
protected:
|
||||
virtual void UpdateDraggableRegions(
|
||||
const std::vector<DraggableRegion>& regions) OVERRIDE;
|
||||
void UpdateDraggableRegions(
|
||||
const std::vector<DraggableRegion>& regions) override;
|
||||
|
||||
// Implementations of content::WebContentsDelegate.
|
||||
virtual void HandleKeyboardEvent(
|
||||
void HandleKeyboardEvent(
|
||||
content::WebContents*,
|
||||
const content::NativeWebKeyboardEvent&) OVERRIDE;
|
||||
const content::NativeWebKeyboardEvent&) override;
|
||||
|
||||
private:
|
||||
void InstallView();
|
||||
void UninstallView();
|
||||
void InstallDraggableRegionViews();
|
||||
void UpdateDraggableRegionsForCustomDrag(
|
||||
const std::vector<DraggableRegion>& regions);
|
||||
|
||||
// Install the drag view, which will cover the whole window and decides
|
||||
// whehter we can drag.
|
||||
void InstallDraggableRegionView();
|
||||
|
||||
base::scoped_nsobject<NSWindow> window_;
|
||||
|
||||
@@ -109,10 +112,6 @@ class NativeWindowMac : public NativeWindow {
|
||||
// The presentation options before entering kiosk mode.
|
||||
NSApplicationPresentationOptions kiosk_options_;
|
||||
|
||||
// For system drag, the whole window is draggable and the non-draggable areas
|
||||
// have to been explicitly excluded.
|
||||
std::vector<gfx::Rect> system_drag_exclude_areas_;
|
||||
|
||||
// For custom drag, the whole window is non-draggable and the draggable region
|
||||
// has to been explicitly provided.
|
||||
scoped_ptr<SkRegion> draggable_region_; // used in custom drag.
|
||||
|
||||
@@ -101,7 +101,7 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
|
||||
shell_->NotifyWindowBlur();
|
||||
}
|
||||
|
||||
- (void)windowDidResize:(NSNotification*)otification {
|
||||
- (void)windowDidResize:(NSNotification*)notification {
|
||||
if (!shell_->has_frame())
|
||||
shell_->ClipWebView();
|
||||
}
|
||||
@@ -280,6 +280,29 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
// Convert draggable regions in raw format to SkRegion format. Caller is
|
||||
// responsible for deleting the returned SkRegion instance.
|
||||
SkRegion* DraggableRegionsToSkRegion(
|
||||
const std::vector<DraggableRegion>& regions) {
|
||||
SkRegion* sk_region = new SkRegion;
|
||||
for (std::vector<DraggableRegion>::const_iterator iter = regions.begin();
|
||||
iter != regions.end();
|
||||
++iter) {
|
||||
const DraggableRegion& region = *iter;
|
||||
sk_region->op(
|
||||
region.bounds.x(),
|
||||
region.bounds.y(),
|
||||
region.bounds.right(),
|
||||
region.bounds.bottom(),
|
||||
region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
|
||||
}
|
||||
return sk_region;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
|
||||
const mate::Dictionary& options)
|
||||
: NativeWindow(web_contents, options),
|
||||
@@ -296,9 +319,7 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
|
||||
width,
|
||||
height);
|
||||
|
||||
AtomNSWindow* atomWindow;
|
||||
|
||||
atomWindow = [[AtomNSWindow alloc]
|
||||
AtomNSWindow* atomWindow = [[AtomNSWindow alloc]
|
||||
initWithContentRect:cocoa_bounds
|
||||
styleMask:NSTitledWindowMask | NSClosableWindowMask |
|
||||
NSMiniaturizableWindowMask | NSResizableWindowMask |
|
||||
@@ -314,6 +335,13 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
|
||||
[[AtomNSWindowDelegate alloc] initWithShell:this];
|
||||
[window_ setDelegate:delegate];
|
||||
|
||||
if (transparent_) {
|
||||
// Make window has transparent background.
|
||||
[window_ setOpaque:NO];
|
||||
[window_ setHasShadow:NO];
|
||||
[window_ setBackgroundColor:[NSColor clearColor]];
|
||||
}
|
||||
|
||||
// We will manage window's lifetime ourselves.
|
||||
[window_ setReleasedWhenClosed:NO];
|
||||
|
||||
@@ -386,6 +414,10 @@ bool NativeWindowMac::IsFocused() {
|
||||
}
|
||||
|
||||
void NativeWindowMac::Show() {
|
||||
// This method is supposed to put focus on window, however if the app does not
|
||||
// have focus then "makeKeyAndOrderFront" will only show the window.
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
|
||||
[window_ makeKeyAndOrderFront:nil];
|
||||
}
|
||||
|
||||
@@ -538,6 +570,10 @@ gfx::Point NativeWindowMac::GetPosition() {
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetTitle(const std::string& title) {
|
||||
// We don't want the title to show in transparent window.
|
||||
if (transparent_)
|
||||
return;
|
||||
|
||||
[window_ setTitle:base::SysUTF8ToNSString(title)];
|
||||
}
|
||||
|
||||
@@ -642,10 +678,23 @@ void NativeWindowMac::SetProgressBar(double progress) {
|
||||
[dock_tile display];
|
||||
}
|
||||
|
||||
void NativeWindowMac::ShowDefinitionForSelection() {
|
||||
content::WebContents* web_contents = GetWebContents();
|
||||
if (!web_contents)
|
||||
return;
|
||||
content::RenderWidgetHostView* rwhv = web_contents->GetRenderWidgetHostView();
|
||||
if (!rwhv)
|
||||
return;
|
||||
rwhv->ShowDefinitionForSelection();
|
||||
}
|
||||
|
||||
bool NativeWindowMac::IsWithinDraggableRegion(NSPoint point) const {
|
||||
if (!draggable_region_)
|
||||
return false;
|
||||
NSView* webView = GetWebContents()->GetNativeView();
|
||||
content::WebContents* web_contents = GetWebContents();
|
||||
if (!web_contents)
|
||||
return false;
|
||||
NSView* webView = web_contents->GetNativeView();
|
||||
NSInteger webViewHeight = NSHeight([webView bounds]);
|
||||
// |draggable_region_| is stored in local platform-indepdent coordiate system
|
||||
// while |point| is in local Cocoa coordinate system. Do the conversion
|
||||
@@ -658,7 +707,6 @@ void NativeWindowMac::HandleMouseEvent(NSEvent* event) {
|
||||
NSRect mouseRect = [window_ convertRectToScreen:NSMakeRect(eventLoc.x, eventLoc.y, 0, 0)];
|
||||
NSPoint current_mouse_location = mouseRect.origin;
|
||||
|
||||
|
||||
if ([event type] == NSLeftMouseDown) {
|
||||
NSPoint frame_origin = [window_ frame].origin;
|
||||
last_mouse_offset_ = NSMakePoint(
|
||||
@@ -677,8 +725,7 @@ void NativeWindowMac::UpdateDraggableRegions(
|
||||
if (has_frame_)
|
||||
return;
|
||||
|
||||
UpdateDraggableRegionsForCustomDrag(regions);
|
||||
InstallDraggableRegionViews();
|
||||
draggable_region_.reset(DraggableRegionsToSkRegion(regions));
|
||||
}
|
||||
|
||||
void NativeWindowMac::HandleKeyboardEvent(
|
||||
@@ -735,11 +782,16 @@ void NativeWindowMac::InstallView() {
|
||||
}
|
||||
|
||||
ClipWebView();
|
||||
InstallDraggableRegionView();
|
||||
|
||||
[[window_ standardWindowButton:NSWindowZoomButton] setHidden:YES];
|
||||
[[window_ standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
|
||||
[[window_ standardWindowButton:NSWindowCloseButton] setHidden:YES];
|
||||
[[window_ standardWindowButton:NSWindowFullScreenButton] setHidden:YES];
|
||||
|
||||
// Some third-party OS X utilities check the zoom button's enabled state to
|
||||
// determine whether to show custom UI on hover, so we disable it here to
|
||||
// prevent them from doing so in a frameless app window.
|
||||
[[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -749,70 +801,19 @@ void NativeWindowMac::UninstallView() {
|
||||
}
|
||||
|
||||
void NativeWindowMac::ClipWebView() {
|
||||
NSView* view = GetWebContents()->GetNativeView();
|
||||
view.layer.masksToBounds = YES;
|
||||
view.layer.cornerRadius = kAtomWindowCornerRadius;
|
||||
}
|
||||
|
||||
void NativeWindowMac::InstallDraggableRegionViews() {
|
||||
DCHECK(!has_frame_);
|
||||
|
||||
// All ControlRegionViews should be added as children of the WebContentsView,
|
||||
// because WebContentsView will be removed and re-added when entering and
|
||||
// leaving fullscreen mode.
|
||||
NSView* webView = GetWebContents()->GetNativeView();
|
||||
NSInteger webViewHeight = NSHeight([webView bounds]);
|
||||
|
||||
// Remove all ControlRegionViews that are added last time.
|
||||
// Note that [webView subviews] returns the view's mutable internal array and
|
||||
// it should be copied to avoid mutating the original array while enumerating
|
||||
// it.
|
||||
base::scoped_nsobject<NSArray> subviews([[webView subviews] copy]);
|
||||
for (NSView* subview in subviews.get())
|
||||
if ([subview isKindOfClass:[ControlRegionView class]])
|
||||
[subview removeFromSuperview];
|
||||
|
||||
// Create and add ControlRegionView for each region that needs to be excluded
|
||||
// from the dragging.
|
||||
for (std::vector<gfx::Rect>::const_iterator iter =
|
||||
system_drag_exclude_areas_.begin();
|
||||
iter != system_drag_exclude_areas_.end();
|
||||
++iter) {
|
||||
base::scoped_nsobject<NSView> controlRegion(
|
||||
[[ControlRegionView alloc] initWithShellWindow:this]);
|
||||
[controlRegion setFrame:NSMakeRect(iter->x(),
|
||||
webViewHeight - iter->bottom(),
|
||||
iter->width(),
|
||||
iter->height())];
|
||||
[webView addSubview:controlRegion];
|
||||
}
|
||||
webView.layer.masksToBounds = YES;
|
||||
webView.layer.cornerRadius = kAtomWindowCornerRadius;
|
||||
}
|
||||
|
||||
void NativeWindowMac::UpdateDraggableRegionsForCustomDrag(
|
||||
const std::vector<DraggableRegion>& regions) {
|
||||
// We still need one ControlRegionView to cover the whole window such that
|
||||
// mouse events could be captured.
|
||||
NSView* web_view = GetWebContents()->GetNativeView();
|
||||
gfx::Rect window_bounds(
|
||||
0, 0, NSWidth([web_view bounds]), NSHeight([web_view bounds]));
|
||||
system_drag_exclude_areas_.clear();
|
||||
system_drag_exclude_areas_.push_back(window_bounds);
|
||||
|
||||
// Aggregate the draggable areas and non-draggable areas such that hit test
|
||||
// could be performed easily.
|
||||
SkRegion* draggable_region = new SkRegion;
|
||||
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_.reset(draggable_region);
|
||||
void NativeWindowMac::InstallDraggableRegionView() {
|
||||
NSView* webView = GetWebContents()->GetNativeView();
|
||||
base::scoped_nsobject<NSView> controlRegion(
|
||||
[[ControlRegionView alloc] initWithShellWindow:this]);
|
||||
[controlRegion setFrame:NSMakeRect(0, 0,
|
||||
NSWidth([webView bounds]),
|
||||
NSHeight([webView bounds]))];
|
||||
[webView addSubview:controlRegion];
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "ui/views/window/client_view.h"
|
||||
#include "ui/views/widget/native_widget_private.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/wm/core/shadow_types.h"
|
||||
|
||||
#if defined(USE_X11)
|
||||
#include "atom/browser/browser.h"
|
||||
@@ -128,7 +129,7 @@ class NativeWindowClientView : public views::ClientView {
|
||||
}
|
||||
virtual ~NativeWindowClientView() {}
|
||||
|
||||
virtual bool CanClose() OVERRIDE {
|
||||
bool CanClose() override {
|
||||
static_cast<NativeWindowViews*>(contents_view())->CloseWebContents();
|
||||
return false;
|
||||
}
|
||||
@@ -183,6 +184,9 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
|
||||
params.type = views::Widget::InitParams::TYPE_WINDOW;
|
||||
params.remove_standard_frame = !has_frame_;
|
||||
|
||||
if (transparent_)
|
||||
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
|
||||
|
||||
#if defined(USE_X11)
|
||||
std::string name = Browser::Get()->GetName();
|
||||
// Set WM_WINDOW_ROLE.
|
||||
@@ -237,8 +241,18 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
|
||||
// frameless.
|
||||
DWORD frame_style = WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX |
|
||||
WS_CAPTION;
|
||||
// We should not show a frame for transparent window.
|
||||
if (transparent_)
|
||||
frame_style &= ~(WS_THICKFRAME | WS_CAPTION);
|
||||
::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style);
|
||||
}
|
||||
|
||||
if (transparent_) {
|
||||
// Transparent window on Windows has to have WS_EX_COMPOSITED style.
|
||||
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
|
||||
ex_style |= WS_EX_COMPOSITED;
|
||||
::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style);
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO(zcbenz): This was used to force using native frame on Windows 2003, we
|
||||
@@ -248,6 +262,11 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
|
||||
window_->FrameTypeChanged();
|
||||
}
|
||||
|
||||
// The given window is most likely not rectangular since it uses
|
||||
// transparency and has no standard frame, don't show a shadow for it.
|
||||
if (transparent_ && !has_frame_)
|
||||
wm::SetShadowType(GetNativeWindow(), wm::SHADOW_TYPE_NONE);
|
||||
|
||||
window_->UpdateWindowIcon();
|
||||
window_->CenterWindow(bounds.size());
|
||||
Layout();
|
||||
|
||||
@@ -28,16 +28,16 @@ class AdapterRequestJob : public net::URLRequestJob {
|
||||
|
||||
public:
|
||||
// net::URLRequestJob:
|
||||
virtual void Start() OVERRIDE;
|
||||
virtual void Kill() OVERRIDE;
|
||||
virtual bool ReadRawData(net::IOBuffer* buf,
|
||||
int buf_size,
|
||||
int *bytes_read) OVERRIDE;
|
||||
virtual bool IsRedirectResponse(GURL* location,
|
||||
int* http_status_code) OVERRIDE;
|
||||
virtual net::Filter* SetupFilter() const OVERRIDE;
|
||||
virtual bool GetMimeType(std::string* mime_type) const OVERRIDE;
|
||||
virtual bool GetCharset(std::string* charset) OVERRIDE;
|
||||
void Start() override;
|
||||
void Kill() override;
|
||||
bool ReadRawData(net::IOBuffer* buf,
|
||||
int buf_size,
|
||||
int *bytes_read) override;
|
||||
bool IsRedirectResponse(GURL* location,
|
||||
int* http_status_code) override;
|
||||
net::Filter* SetupFilter() const override;
|
||||
bool GetMimeType(std::string* mime_type) const override;
|
||||
bool GetCharset(std::string* charset) override;
|
||||
|
||||
base::WeakPtr<AdapterRequestJob> GetWeakPtr();
|
||||
|
||||
|
||||
@@ -27,10 +27,10 @@ class AsarProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
|
||||
Archive* GetOrCreateAsarArchive(const base::FilePath& path) const;
|
||||
|
||||
// net::URLRequestJobFactory::ProtocolHandler:
|
||||
virtual net::URLRequestJob* MaybeCreateJob(
|
||||
net::URLRequestJob* MaybeCreateJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const OVERRIDE;
|
||||
virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE;
|
||||
net::NetworkDelegate* network_delegate) const override;
|
||||
bool IsSafeRedirectTarget(const GURL& location) const override;
|
||||
|
||||
private:
|
||||
const scoped_refptr<base::TaskRunner> file_task_runner_;
|
||||
|
||||
@@ -32,12 +32,12 @@ class URLRequestAsarJob : public net::URLRequestJob {
|
||||
const scoped_refptr<base::TaskRunner>& file_task_runner);
|
||||
|
||||
// net::URLRequestJob:
|
||||
virtual void Start() OVERRIDE;
|
||||
virtual void Kill() OVERRIDE;
|
||||
virtual bool ReadRawData(net::IOBuffer* buf,
|
||||
int buf_size,
|
||||
int* bytes_read) OVERRIDE;
|
||||
virtual bool GetMimeType(std::string* mime_type) const OVERRIDE;
|
||||
void Start() override;
|
||||
void Kill() override;
|
||||
bool ReadRawData(net::IOBuffer* buf,
|
||||
int buf_size,
|
||||
int* bytes_read) override;
|
||||
bool GetMimeType(std::string* mime_type) const override;
|
||||
|
||||
protected:
|
||||
virtual ~URLRequestAsarJob();
|
||||
|
||||
@@ -50,7 +50,7 @@ ProtocolHandler* AtomURLRequestJobFactory::ReplaceProtocol(
|
||||
|
||||
base::AutoLock locked(lock_);
|
||||
if (!ContainsKey(protocol_handler_map_, scheme))
|
||||
return NULL;
|
||||
return nullptr;
|
||||
ProtocolHandler* original_protocol_handler = protocol_handler_map_[scheme];
|
||||
protocol_handler_map_[scheme] = protocol_handler;
|
||||
return original_protocol_handler;
|
||||
@@ -63,7 +63,7 @@ ProtocolHandler* AtomURLRequestJobFactory::GetProtocolHandler(
|
||||
base::AutoLock locked(lock_);
|
||||
ProtocolHandlerMap::const_iterator it = protocol_handler_map_.find(scheme);
|
||||
if (it == protocol_handler_map_.end())
|
||||
return NULL;
|
||||
return nullptr;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
@@ -82,10 +82,23 @@ net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
|
||||
base::AutoLock locked(lock_);
|
||||
ProtocolHandlerMap::const_iterator it = protocol_handler_map_.find(scheme);
|
||||
if (it == protocol_handler_map_.end())
|
||||
return NULL;
|
||||
return nullptr;
|
||||
return it->second->MaybeCreateJob(request, network_delegate);
|
||||
}
|
||||
|
||||
net::URLRequestJob* AtomURLRequestJobFactory::MaybeInterceptRedirect(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate,
|
||||
const GURL& location) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
net::URLRequestJob* AtomURLRequestJobFactory::MaybeInterceptResponse(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool AtomURLRequestJobFactory::IsHandledProtocol(
|
||||
const std::string& scheme) const {
|
||||
DCHECK(CalledOnValidThread());
|
||||
|
||||
@@ -40,13 +40,20 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
|
||||
bool HasProtocolHandler(const std::string& scheme) const;
|
||||
|
||||
// URLRequestJobFactory implementation
|
||||
virtual net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
|
||||
net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
|
||||
const std::string& scheme,
|
||||
net::URLRequest* request,
|
||||
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;
|
||||
net::NetworkDelegate* network_delegate) const override;
|
||||
net::URLRequestJob* MaybeInterceptRedirect(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate,
|
||||
const GURL& location) const override;
|
||||
net::URLRequestJob* MaybeInterceptResponse(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const override;
|
||||
bool IsHandledProtocol(const std::string& scheme) const override;
|
||||
bool IsHandledURL(const GURL& url) const override;
|
||||
bool IsSafeRedirectTarget(const GURL& location) const override;
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, ProtocolHandler*> ProtocolHandlerMap;
|
||||
|
||||
@@ -20,10 +20,10 @@ class URLRequestStringJob : public net::URLRequestSimpleJob {
|
||||
const std::string& data);
|
||||
|
||||
// URLRequestSimpleJob:
|
||||
virtual int GetData(std::string* mime_type,
|
||||
std::string* charset,
|
||||
std::string* data,
|
||||
const net::CompletionCallback& callback) const OVERRIDE;
|
||||
int GetData(std::string* mime_type,
|
||||
std::string* charset,
|
||||
std::string* data,
|
||||
const net::CompletionCallback& callback) const override;
|
||||
|
||||
private:
|
||||
std::string mime_type_;
|
||||
|
||||
@@ -33,12 +33,12 @@ class NodeDebugger : public net::StreamListenSocket::Delegate {
|
||||
static void DebugMessageHandler(const v8::Debug::Message& message);
|
||||
|
||||
// net::StreamListenSocket::Delegate:
|
||||
virtual void DidAccept(net::StreamListenSocket* server,
|
||||
scoped_ptr<net::StreamListenSocket> socket) OVERRIDE;
|
||||
virtual void DidRead(net::StreamListenSocket* socket,
|
||||
const char* data,
|
||||
int len) OVERRIDE;
|
||||
virtual void DidClose(net::StreamListenSocket* socket) OVERRIDE;
|
||||
void DidAccept(net::StreamListenSocket* server,
|
||||
scoped_ptr<net::StreamListenSocket> socket) override;
|
||||
void DidRead(net::StreamListenSocket* socket,
|
||||
const char* data,
|
||||
int len) override;
|
||||
void DidClose(net::StreamListenSocket* socket) override;
|
||||
|
||||
v8::Isolate* isolate_;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>atom.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.20.1</string>
|
||||
<string>0.21.1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.8.0</string>
|
||||
<key>NSMainNibFile</key>
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,20,1,0
|
||||
PRODUCTVERSION 0,20,1,0
|
||||
FILEVERSION 0,21,1,0
|
||||
PRODUCTVERSION 0,21,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.20.1"
|
||||
VALUE "FileVersion", "0.21.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.20.1"
|
||||
VALUE "ProductVersion", "0.21.1"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -121,6 +121,9 @@ bool StringToAccelerator(const std::string& description,
|
||||
modifiers |= ui::EF_ALT_DOWN;
|
||||
} else if (tokens[i] == "shift") {
|
||||
modifiers |= ui::EF_SHIFT_DOWN;
|
||||
} else if (tokens[i] == "plus") {
|
||||
modifiers |= ui::EF_SHIFT_DOWN;
|
||||
key = ui::VKEY_OEM_PLUS;
|
||||
} else if (tokens[i] == "tab") {
|
||||
key = ui::VKEY_TAB;
|
||||
} else if (tokens[i] == "space") {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "chrome/browser/ui/libgtk2ui/gtk2_signal.h"
|
||||
#include "ui/aura/window.h"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#import <CoreServices/CoreServices.h>
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/mac/mac_util.h"
|
||||
#include "base/mac/scoped_cftyperef.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <shlobj.h>
|
||||
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/i18n/case_conversion.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/string_split.h"
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
#include "base/callback_forward.h"
|
||||
#include "base/strings/string16.h"
|
||||
|
||||
namespace gfx {
|
||||
class ImageSkia;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class NativeWindow;
|
||||
@@ -28,7 +32,8 @@ int ShowMessageBox(NativeWindow* parent_window,
|
||||
const std::vector<std::string>& buttons,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail);
|
||||
const std::string& detail,
|
||||
const gfx::ImageSkia& icon);
|
||||
|
||||
void ShowMessageBox(NativeWindow* parent_window,
|
||||
MessageBoxType type,
|
||||
@@ -36,6 +41,7 @@ void ShowMessageBox(NativeWindow* parent_window,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const gfx::ImageSkia& icon,
|
||||
const MessageBoxCallback& callback);
|
||||
|
||||
// Like ShowMessageBox with simplest settings, but safe to call at very early
|
||||
|
||||
@@ -96,7 +96,8 @@ int ShowMessageBox(NativeWindow* parent_window,
|
||||
const std::vector<std::string>& buttons,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail) {
|
||||
const std::string& detail,
|
||||
const gfx::ImageSkia& icon) {
|
||||
NSAlert* alert = CreateNSAlert(
|
||||
parent_window, type, buttons, title, message, detail);
|
||||
|
||||
@@ -127,6 +128,7 @@ void ShowMessageBox(NativeWindow* parent_window,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const gfx::ImageSkia& icon,
|
||||
const MessageBoxCallback& callback) {
|
||||
NSAlert* alert = CreateNSAlert(
|
||||
parent_window, type, buttons, title, message, detail);
|
||||
|
||||
@@ -60,7 +60,8 @@ class MessageDialog : public views::WidgetDelegate,
|
||||
const std::vector<std::string>& buttons,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail);
|
||||
const std::string& detail,
|
||||
const gfx::ImageSkia& icon);
|
||||
virtual ~MessageDialog();
|
||||
|
||||
void Show(base::RunLoop* run_loop = NULL);
|
||||
@@ -75,24 +76,28 @@ class MessageDialog : public views::WidgetDelegate,
|
||||
|
||||
private:
|
||||
// Overridden from views::WidgetDelegate:
|
||||
virtual base::string16 GetWindowTitle() const;
|
||||
virtual views::Widget* GetWidget() OVERRIDE;
|
||||
virtual const views::Widget* GetWidget() const OVERRIDE;
|
||||
virtual views::View* GetContentsView() OVERRIDE;
|
||||
virtual views::View* GetInitiallyFocusedView() OVERRIDE;
|
||||
virtual ui::ModalType GetModalType() const OVERRIDE;
|
||||
virtual views::NonClientFrameView* CreateNonClientFrameView(
|
||||
views::Widget* widget) OVERRIDE;
|
||||
virtual views::ClientView* CreateClientView(views::Widget* widget) OVERRIDE;
|
||||
base::string16 GetWindowTitle() const override;
|
||||
gfx::ImageSkia GetWindowAppIcon() override;
|
||||
gfx::ImageSkia GetWindowIcon() override;
|
||||
bool ShouldShowWindowIcon() const override;
|
||||
views::Widget* GetWidget() override;
|
||||
const views::Widget* GetWidget() const override;
|
||||
views::View* GetContentsView() override;
|
||||
views::View* GetInitiallyFocusedView() override;
|
||||
ui::ModalType GetModalType() const override;
|
||||
views::NonClientFrameView* CreateNonClientFrameView(
|
||||
views::Widget* widget) override;
|
||||
views::ClientView* CreateClientView(views::Widget* widget) override;
|
||||
|
||||
// Overridden from views::View:
|
||||
virtual gfx::Size GetPreferredSize() const OVERRIDE;
|
||||
virtual void Layout() OVERRIDE;
|
||||
virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
|
||||
gfx::Size GetPreferredSize() const override;
|
||||
void Layout() override;
|
||||
bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
|
||||
|
||||
// Overridden from views::ButtonListener:
|
||||
virtual void ButtonPressed(views::Button* sender,
|
||||
const ui::Event& event) OVERRIDE;
|
||||
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
|
||||
|
||||
gfx::ImageSkia icon_;
|
||||
|
||||
bool delete_on_close_;
|
||||
int result_;
|
||||
@@ -118,7 +123,7 @@ class MessageDialogClientView : public views::ClientView {
|
||||
}
|
||||
|
||||
// views::ClientView:
|
||||
virtual bool CanClose() OVERRIDE {
|
||||
bool CanClose() override {
|
||||
dialog_->Close();
|
||||
return false;
|
||||
}
|
||||
@@ -137,8 +142,10 @@ MessageDialog::MessageDialog(NativeWindow* parent_window,
|
||||
const std::vector<std::string>& buttons,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail)
|
||||
: delete_on_close_(false),
|
||||
const std::string& detail,
|
||||
const gfx::ImageSkia& icon)
|
||||
: icon_(icon),
|
||||
delete_on_close_(false),
|
||||
result_(-1),
|
||||
title_(base::UTF8ToUTF16(title)),
|
||||
parent_(parent_window),
|
||||
@@ -174,6 +181,7 @@ MessageDialog::MessageDialog(NativeWindow* parent_window,
|
||||
|
||||
views::Widget::InitParams params;
|
||||
params.delegate = this;
|
||||
params.type = views::Widget::InitParams::TYPE_WINDOW;
|
||||
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
|
||||
if (parent_) {
|
||||
params.parent = parent_->GetNativeWindow();
|
||||
@@ -184,6 +192,7 @@ MessageDialog::MessageDialog(NativeWindow* parent_window,
|
||||
|
||||
widget_.reset(new views::Widget);
|
||||
widget_->Init(params);
|
||||
widget_->UpdateWindowIcon();
|
||||
|
||||
// Bind to ESC.
|
||||
AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
|
||||
@@ -230,6 +239,18 @@ base::string16 MessageDialog::GetWindowTitle() const {
|
||||
return title_;
|
||||
}
|
||||
|
||||
gfx::ImageSkia MessageDialog::GetWindowAppIcon() {
|
||||
return icon_;
|
||||
}
|
||||
|
||||
gfx::ImageSkia MessageDialog::GetWindowIcon() {
|
||||
return icon_;
|
||||
}
|
||||
|
||||
bool MessageDialog::ShouldShowWindowIcon() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
views::Widget* MessageDialog::GetWidget() {
|
||||
return widget_.get();
|
||||
}
|
||||
@@ -338,8 +359,10 @@ int ShowMessageBox(NativeWindow* parent_window,
|
||||
const std::vector<std::string>& buttons,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail) {
|
||||
MessageDialog dialog(parent_window, type, buttons, title, message, detail);
|
||||
const std::string& detail,
|
||||
const gfx::ImageSkia& icon) {
|
||||
MessageDialog dialog(
|
||||
parent_window, type, buttons, title, message, detail, icon);
|
||||
{
|
||||
base::MessageLoop::ScopedNestableTaskAllower allow(
|
||||
base::MessageLoopForUI::current());
|
||||
@@ -357,10 +380,11 @@ void ShowMessageBox(NativeWindow* parent_window,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const gfx::ImageSkia& icon,
|
||||
const MessageBoxCallback& callback) {
|
||||
// The dialog would be deleted when the dialog is closed.
|
||||
MessageDialog* dialog = new MessageDialog(
|
||||
parent_window, type, buttons, title, message, detail);
|
||||
parent_window, type, buttons, title, message, detail, icon);
|
||||
dialog->set_callback(callback);
|
||||
dialog->Show();
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ TrayIcon::TrayIcon() {
|
||||
TrayIcon::~TrayIcon() {
|
||||
}
|
||||
|
||||
void TrayIcon::SetPressedImage(const gfx::ImageSkia& image) {
|
||||
void TrayIcon::SetPressedImage(const gfx::Image& image) {
|
||||
}
|
||||
|
||||
void TrayIcon::SetTitle(const std::string& title) {
|
||||
@@ -21,7 +21,7 @@ void TrayIcon::SetTitle(const std::string& title) {
|
||||
void TrayIcon::SetHighlightMode(bool highlight) {
|
||||
}
|
||||
|
||||
void TrayIcon::DisplayBalloon(const gfx::ImageSkia& icon,
|
||||
void TrayIcon::DisplayBalloon(const gfx::Image& icon,
|
||||
const base::string16& title,
|
||||
const base::string16& contents) {
|
||||
}
|
||||
|
||||
@@ -20,10 +20,10 @@ class TrayIcon {
|
||||
virtual ~TrayIcon();
|
||||
|
||||
// Sets the image associated with this status icon.
|
||||
virtual void SetImage(const gfx::ImageSkia& image) = 0;
|
||||
virtual void SetImage(const gfx::Image& image) = 0;
|
||||
|
||||
// Sets the image associated with this status icon when pressed.
|
||||
virtual void SetPressedImage(const gfx::ImageSkia& image);
|
||||
virtual void SetPressedImage(const gfx::Image& image);
|
||||
|
||||
// Sets the hover text for this status icon. This is also used as the label
|
||||
// for the menu item which is created as a replacement for the status icon
|
||||
@@ -41,7 +41,7 @@ class TrayIcon {
|
||||
|
||||
// Displays a notification balloon with the specified contents.
|
||||
// Depending on the platform it might not appear by the icon tray.
|
||||
virtual void DisplayBalloon(const gfx::ImageSkia& icon,
|
||||
virtual void DisplayBalloon(const gfx::Image& icon,
|
||||
const base::string16& title,
|
||||
const base::string16& contents);
|
||||
|
||||
|
||||
@@ -22,12 +22,12 @@ class TrayIconCocoa : public TrayIcon {
|
||||
TrayIconCocoa();
|
||||
virtual ~TrayIconCocoa();
|
||||
|
||||
virtual void SetImage(const gfx::ImageSkia& image) OVERRIDE;
|
||||
virtual void SetPressedImage(const gfx::ImageSkia& image) OVERRIDE;
|
||||
virtual void SetToolTip(const std::string& tool_tip) OVERRIDE;
|
||||
virtual void SetTitle(const std::string& title) OVERRIDE;
|
||||
virtual void SetHighlightMode(bool highlight) OVERRIDE;
|
||||
virtual void SetContextMenu(ui::SimpleMenuModel* menu_model) OVERRIDE;
|
||||
void SetImage(const gfx::Image& image) override;
|
||||
void SetPressedImage(const gfx::Image& image) override;
|
||||
void SetToolTip(const std::string& tool_tip) override;
|
||||
void SetTitle(const std::string& title) override;
|
||||
void SetHighlightMode(bool highlight) override;
|
||||
void SetContextMenu(ui::SimpleMenuModel* menu_model) override;
|
||||
|
||||
private:
|
||||
base::scoped_nsobject<NSStatusItem> item_;
|
||||
|
||||
@@ -53,20 +53,14 @@ TrayIconCocoa::~TrayIconCocoa() {
|
||||
[[NSStatusBar systemStatusBar] removeStatusItem:item_];
|
||||
}
|
||||
|
||||
void TrayIconCocoa::SetImage(const gfx::ImageSkia& image) {
|
||||
if (!image.isNull()) {
|
||||
gfx::Image neutral(image);
|
||||
if (!neutral.IsEmpty())
|
||||
[item_ setImage:neutral.ToNSImage()];
|
||||
}
|
||||
void TrayIconCocoa::SetImage(const gfx::Image& image) {
|
||||
if (!image.IsEmpty())
|
||||
[item_ setImage:image.ToNSImage()];
|
||||
}
|
||||
|
||||
void TrayIconCocoa::SetPressedImage(const gfx::ImageSkia& image) {
|
||||
if (!image.isNull()) {
|
||||
gfx::Image neutral(image);
|
||||
if (!neutral.IsEmpty())
|
||||
[item_ setAlternateImage:neutral.ToNSImage()];
|
||||
}
|
||||
void TrayIconCocoa::SetPressedImage(const gfx::Image& image) {
|
||||
if (!image.IsEmpty())
|
||||
[item_ setAlternateImage:image.ToNSImage()];
|
||||
}
|
||||
|
||||
void TrayIconCocoa::SetToolTip(const std::string& tool_tip) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "chrome/browser/ui/libgtk2ui/app_indicator_icon.h"
|
||||
#include "chrome/browser/ui/libgtk2ui/gtk2_status_icon.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -17,18 +18,18 @@ TrayIconGtk::TrayIconGtk() {
|
||||
TrayIconGtk::~TrayIconGtk() {
|
||||
}
|
||||
|
||||
void TrayIconGtk::SetImage(const gfx::ImageSkia& image) {
|
||||
void TrayIconGtk::SetImage(const gfx::Image& image) {
|
||||
if (icon_) {
|
||||
icon_->SetImage(image);
|
||||
icon_->SetImage(image.AsImageSkia());
|
||||
return;
|
||||
}
|
||||
|
||||
base::string16 empty;
|
||||
if (libgtk2ui::AppIndicatorIcon::CouldOpen())
|
||||
icon_.reset(
|
||||
new libgtk2ui::AppIndicatorIcon(base::GenerateGUID(), image, empty));
|
||||
icon_.reset(new libgtk2ui::AppIndicatorIcon(
|
||||
base::GenerateGUID(), image.AsImageSkia(), empty));
|
||||
else
|
||||
icon_.reset(new libgtk2ui::Gtk2StatusIcon(image, empty));
|
||||
icon_.reset(new libgtk2ui::Gtk2StatusIcon(image.AsImageSkia(), empty));
|
||||
icon_->set_delegate(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,14 +23,14 @@ class TrayIconGtk : public TrayIcon,
|
||||
virtual ~TrayIconGtk();
|
||||
|
||||
// TrayIcon:
|
||||
virtual void SetImage(const gfx::ImageSkia& image) OVERRIDE;
|
||||
virtual void SetToolTip(const std::string& tool_tip) OVERRIDE;
|
||||
virtual void SetContextMenu(ui::SimpleMenuModel* menu_model) OVERRIDE;
|
||||
void SetImage(const gfx::Image& image) override;
|
||||
void SetToolTip(const std::string& tool_tip) override;
|
||||
void SetContextMenu(ui::SimpleMenuModel* menu_model) override;
|
||||
|
||||
private:
|
||||
// views::StatusIconLinux::Delegate:
|
||||
virtual void OnClick() OVERRIDE;
|
||||
virtual bool HasClickAction() OVERRIDE;
|
||||
void OnClick() override;
|
||||
bool HasClickAction() override;
|
||||
|
||||
scoped_ptr<views::StatusIconLinux> icon_;
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ SubmenuButton::SubmenuButton(views::ButtonListener* listener,
|
||||
underline_color_(SK_ColorBLACK) {
|
||||
#if defined(OS_LINUX)
|
||||
// Dont' use native style border.
|
||||
SetBorder(CreateDefaultBorder().PassAs<views::Border>());
|
||||
SetBorder(CreateDefaultBorder().Pass());
|
||||
#endif
|
||||
|
||||
if (GetUnderlinePosition(title, &accelerator_, &underline_start_,
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "base/win/windows_version.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/gfx/icon_util.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
#include "ui/gfx/point.h"
|
||||
#include "ui/gfx/rect.h"
|
||||
#include "ui/views/controls/menu/menu_runner.h"
|
||||
@@ -90,19 +91,19 @@ void NotifyIcon::ResetIcon() {
|
||||
LOG(WARNING) << "Unable to re-create status tray icon.";
|
||||
}
|
||||
|
||||
void NotifyIcon::SetImage(const gfx::ImageSkia& image) {
|
||||
void NotifyIcon::SetImage(const gfx::Image& image) {
|
||||
// Create the icon.
|
||||
NOTIFYICONDATA icon_data;
|
||||
InitIconData(&icon_data);
|
||||
icon_data.uFlags = NIF_ICON;
|
||||
icon_.Set(IconUtil::CreateHICONFromSkBitmap(*image.bitmap()));
|
||||
icon_.Set(IconUtil::CreateHICONFromSkBitmap(image.AsBitmap()));
|
||||
icon_data.hIcon = icon_.Get();
|
||||
BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
|
||||
if (!result)
|
||||
LOG(WARNING) << "Error setting status tray icon image";
|
||||
}
|
||||
|
||||
void NotifyIcon::SetPressedImage(const gfx::ImageSkia& image) {
|
||||
void NotifyIcon::SetPressedImage(const gfx::Image& image) {
|
||||
// Ignore pressed images, since the standard on Windows is to not highlight
|
||||
// pressed status icons.
|
||||
}
|
||||
@@ -118,7 +119,7 @@ void NotifyIcon::SetToolTip(const std::string& tool_tip) {
|
||||
LOG(WARNING) << "Unable to set tooltip for status tray icon";
|
||||
}
|
||||
|
||||
void NotifyIcon::DisplayBalloon(const gfx::ImageSkia& icon,
|
||||
void NotifyIcon::DisplayBalloon(const gfx::Image& icon,
|
||||
const base::string16& title,
|
||||
const base::string16& contents) {
|
||||
NOTIFYICONDATA icon_data;
|
||||
@@ -130,8 +131,8 @@ void NotifyIcon::DisplayBalloon(const gfx::ImageSkia& icon,
|
||||
icon_data.uTimeout = 0;
|
||||
|
||||
base::win::Version win_version = base::win::GetVersion();
|
||||
if (!icon.isNull() && win_version != base::win::VERSION_PRE_XP) {
|
||||
balloon_icon_.Set(IconUtil::CreateHICONFromSkBitmap(*icon.bitmap()));
|
||||
if (!icon.IsEmpty() && win_version != base::win::VERSION_PRE_XP) {
|
||||
balloon_icon_.Set(IconUtil::CreateHICONFromSkBitmap(icon.AsBitmap()));
|
||||
icon_data.hBalloonIcon = balloon_icon_.Get();
|
||||
icon_data.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON;
|
||||
}
|
||||
|
||||
@@ -43,10 +43,10 @@ class NotifyIcon : public TrayIcon {
|
||||
UINT message_id() const { return message_id_; }
|
||||
|
||||
// Overridden from TrayIcon:
|
||||
void SetImage(const gfx::ImageSkia& image) override;
|
||||
void SetPressedImage(const gfx::ImageSkia& image) override;
|
||||
void SetImage(const gfx::Image& image) override;
|
||||
void SetPressedImage(const gfx::Image& image) override;
|
||||
void SetToolTip(const std::string& tool_tip) override;
|
||||
void DisplayBalloon(const gfx::ImageSkia& icon,
|
||||
void DisplayBalloon(const gfx::Image& icon,
|
||||
const base::string16& title,
|
||||
const base::string16& contents) override;
|
||||
void SetContextMenu(ui::SimpleMenuModel* menu_model) override;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/common/file_chooser_file_info.h"
|
||||
#include "ui/shell_dialogs/selected_file_info.h"
|
||||
|
||||
namespace atom {
|
||||
@@ -26,15 +27,19 @@ WebDialogHelper::~WebDialogHelper() {
|
||||
|
||||
void WebDialogHelper::RunFileChooser(content::WebContents* web_contents,
|
||||
const content::FileChooserParams& params) {
|
||||
std::vector<ui::SelectedFileInfo> result;
|
||||
std::vector<content::FileChooserFileInfo> result;
|
||||
if (params.mode == content::FileChooserParams::Save) {
|
||||
base::FilePath path;
|
||||
if (file_dialog::ShowSaveDialog(window_,
|
||||
base::UTF16ToUTF8(params.title),
|
||||
params.default_file_name,
|
||||
file_dialog::Filters(),
|
||||
&path))
|
||||
result.push_back(ui::SelectedFileInfo(path, path));
|
||||
&path)) {
|
||||
content::FileChooserFileInfo info;
|
||||
info.file_path = path;
|
||||
info.display_name = path.BaseName().value();
|
||||
result.push_back(info);
|
||||
}
|
||||
} else {
|
||||
int flags = file_dialog::FILE_DIALOG_CREATE_DIRECTORY;
|
||||
switch (params.mode) {
|
||||
@@ -56,9 +61,14 @@ void WebDialogHelper::RunFileChooser(content::WebContents* web_contents,
|
||||
params.default_file_name,
|
||||
file_dialog::Filters(),
|
||||
flags,
|
||||
&paths))
|
||||
for (auto& path : paths)
|
||||
result.push_back(ui::SelectedFileInfo(path, path));
|
||||
&paths)) {
|
||||
for (auto& path : paths) {
|
||||
content::FileChooserFileInfo info;
|
||||
info.file_path = path;
|
||||
info.display_name = path.BaseName().value();
|
||||
result.push_back(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
web_contents->GetRenderViewHost()->FilesSelectedInChooser(
|
||||
|
||||
@@ -41,7 +41,8 @@ struct Converter<atom::WebViewManager::WebViewOptions> {
|
||||
return false;
|
||||
return options.Get("nodeIntegration", &(out->node_integration)) &&
|
||||
options.Get("plugins", &(out->plugins)) &&
|
||||
options.Get("preloadUrl", &(out->preload_url));
|
||||
options.Get("preloadUrl", &(out->preload_url)) &&
|
||||
options.Get("disableWebSecurity", &(out->disable_web_security));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -63,7 +64,11 @@ void WebViewManager::AddGuest(int guest_instance_id,
|
||||
web_contents_map_[guest_instance_id] = { web_contents, embedder };
|
||||
|
||||
WebViewRendererState::WebViewInfo web_view_info = {
|
||||
guest_instance_id, options.node_integration, options.plugins
|
||||
guest_instance_id,
|
||||
embedder,
|
||||
options.node_integration,
|
||||
options.plugins,
|
||||
options.disable_web_security,
|
||||
};
|
||||
net::FileURLToFilePath(options.preload_url, &web_view_info.preload_script);
|
||||
content::BrowserThread::PostTask(
|
||||
|
||||
@@ -24,6 +24,7 @@ class WebViewManager : public content::BrowserPluginGuestManager {
|
||||
struct WebViewOptions {
|
||||
bool node_integration;
|
||||
bool plugins;
|
||||
bool disable_web_security;
|
||||
GURL preload_url;
|
||||
};
|
||||
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/memory/singleton.h"
|
||||
|
||||
namespace content {
|
||||
class WebContents;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class WebViewManager;
|
||||
@@ -22,8 +26,10 @@ class WebViewRendererState {
|
||||
public:
|
||||
struct WebViewInfo {
|
||||
int guest_instance_id;
|
||||
content::WebContents* embedder;
|
||||
bool node_integration;
|
||||
bool plugins;
|
||||
bool disable_web_security;
|
||||
base::FilePath preload_script;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
|
||||
v8::Handle<v8::Context> context, void* priv) {
|
||||
gfx::Screen* screen = gfx::Screen::GetNativeScreen();
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("getCursorScreenPoint",
|
||||
base::Bind(&gfx::Screen::GetCursorScreenPoint,
|
||||
base::Unretained(screen)));
|
||||
dict.SetMethod("getPrimaryDisplay",
|
||||
base::Bind(&gfx::Screen::GetPrimaryDisplay,
|
||||
base::Unretained(screen)));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_screen, Initialize)
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "atom/common/chrome_version.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "base/logging.h"
|
||||
#include "native_mate/callback.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
@@ -20,20 +19,9 @@ namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
// Async handle to execute the stored v8 callback.
|
||||
uv_async_t g_callback_uv_handle;
|
||||
|
||||
// Stored v8 callback, to be called by the async handler.
|
||||
base::Closure g_v8_callback;
|
||||
|
||||
// Dummy class type that used for crashing the program.
|
||||
struct DummyClass { bool crash; };
|
||||
|
||||
// Async handler to execute the stored v8 callback.
|
||||
void UvOnCallback(uv_async_t* handle) {
|
||||
g_v8_callback.Run();
|
||||
}
|
||||
|
||||
void Crash() {
|
||||
static_cast<DummyClass*>(NULL)->crash = true;
|
||||
}
|
||||
@@ -49,19 +37,12 @@ void Log(const base::string16& message) {
|
||||
logging::LogMessage("CONSOLE", 0, 0).stream() << message;
|
||||
}
|
||||
|
||||
void ScheduleCallback(const base::Closure& callback) {
|
||||
g_v8_callback = callback;
|
||||
uv_async_send(&g_callback_uv_handle);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
AtomBindings::AtomBindings() {
|
||||
uv_async_init(uv_default_loop(), &call_next_tick_async_, OnCallNextTick);
|
||||
call_next_tick_async_.data = this;
|
||||
|
||||
uv_async_init(uv_default_loop(), &g_callback_uv_handle, UvOnCallback);
|
||||
}
|
||||
|
||||
AtomBindings::~AtomBindings() {
|
||||
@@ -74,20 +55,17 @@ void AtomBindings::BindTo(v8::Isolate* isolate,
|
||||
mate::Dictionary dict(isolate, process);
|
||||
dict.SetMethod("crash", &Crash);
|
||||
dict.SetMethod("log", &Log);
|
||||
dict.SetMethod("scheduleCallback", &ScheduleCallback);
|
||||
dict.SetMethod("activateUvLoop",
|
||||
base::Bind(&AtomBindings::ActivateUVLoop, base::Unretained(this)));
|
||||
|
||||
v8::Handle<v8::Object> versions;
|
||||
if (dict.Get("versions", &versions)) {
|
||||
versions->Set(mate::StringToV8(isolate, "atom-shell"),
|
||||
mate::StringToV8(isolate, ATOM_VERSION_STRING));
|
||||
versions->Set(mate::StringToV8(isolate, "chrome"),
|
||||
mate::StringToV8(isolate, CHROME_VERSION_STRING));
|
||||
}
|
||||
// Do not warn about deprecated APIs.
|
||||
dict.Set("noDeprecation", true);
|
||||
|
||||
v8::Handle<v8::Value> event = mate::StringToV8(isolate, "BIND_DONE");
|
||||
node::MakeCallback(isolate, process, "emit", 1, &event);
|
||||
mate::Dictionary versions;
|
||||
if (dict.Get("versions", &versions)) {
|
||||
versions.Set("atom-shell", ATOM_VERSION_STRING);
|
||||
versions.Set("chrome", CHROME_VERSION_STRING);
|
||||
}
|
||||
}
|
||||
|
||||
void AtomBindings::ActivateUVLoop(v8::Isolate* isolate) {
|
||||
|
||||
@@ -24,7 +24,7 @@ class AtomBindings {
|
||||
|
||||
// Add process.atomBinding function, which behaves like process.binding but
|
||||
// load native code from atom-shell instead.
|
||||
virtual void BindTo(v8::Isolate* isolate, v8::Handle<v8::Object> process);
|
||||
void BindTo(v8::Isolate* isolate, v8::Handle<v8::Object> process);
|
||||
|
||||
private:
|
||||
void ActivateUVLoop(v8::Isolate* isolate);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
fs = require 'fs'
|
||||
vm = require 'vm'
|
||||
|
||||
copied = {}
|
||||
copied[k] = v for k, v of fs
|
||||
|
||||
module.exports = copied
|
||||
# Execute the 'fs.js' and pass the 'exports' to it.
|
||||
source = '(function (exports, require, module, __filename, __dirname) { ' +
|
||||
process.binding('natives').originalFs +
|
||||
'\n});'
|
||||
fn = vm.runInThisContext source, { filename: 'fs.js' }
|
||||
fn exports, require, module
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
module.exports =
|
||||
if process.platform in ['linux', 'win32'] and process.type is 'renderer'
|
||||
# On Linux we could not access screen in renderer process.
|
||||
require('remote').require 'screen'
|
||||
else
|
||||
process.atomBinding 'screen'
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/file_util.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
|
||||
namespace asar {
|
||||
@@ -17,7 +17,14 @@ ScopedTemporaryFile::ScopedTemporaryFile() {
|
||||
ScopedTemporaryFile::~ScopedTemporaryFile() {
|
||||
if (!path_.empty()) {
|
||||
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
||||
// On Windows it is very likely the file is already in use (because it is
|
||||
// mostly used for Node native modules), so deleting it now will halt the
|
||||
// program.
|
||||
#if defined(OS_WIN)
|
||||
base::DeleteFileAfterReboot(path_);
|
||||
#else
|
||||
base::DeleteFile(path_, false);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#define ATOM_VERSION_H
|
||||
|
||||
#define ATOM_MAJOR_VERSION 0
|
||||
#define ATOM_MINOR_VERSION 20
|
||||
#define ATOM_MINOR_VERSION 21
|
||||
#define ATOM_PATCH_VERSION 1
|
||||
|
||||
#define ATOM_VERSION_IS_RELEASE 1
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef ATOM_COMMON_CHROME_VERSION_H_
|
||||
#define ATOM_COMMON_CHROME_VERSION_H_
|
||||
|
||||
#define CHROME_VERSION_STRING "39.0.2171.65"
|
||||
#define CHROME_VERSION_STRING "40.0.2214.91"
|
||||
#define CHROME_VERSION "v" CHROME_VERSION_STRING
|
||||
|
||||
#endif // ATOM_COMMON_CHROME_VERSION_H_
|
||||
|
||||
@@ -25,13 +25,13 @@ class CrashReporterLinux : public CrashReporter {
|
||||
public:
|
||||
static CrashReporterLinux* GetInstance();
|
||||
|
||||
virtual void InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) OVERRIDE;
|
||||
virtual void SetUploadParameters() OVERRIDE;
|
||||
void InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) override;
|
||||
void SetUploadParameters() override;
|
||||
|
||||
private:
|
||||
friend struct DefaultSingletonTraits<CrashReporterLinux>;
|
||||
|
||||
@@ -19,13 +19,13 @@ class CrashReporterMac : public CrashReporter {
|
||||
public:
|
||||
static CrashReporterMac* GetInstance();
|
||||
|
||||
virtual void InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) OVERRIDE;
|
||||
virtual void SetUploadParameters() OVERRIDE;
|
||||
void InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) override;
|
||||
void SetUploadParameters() override;
|
||||
|
||||
private:
|
||||
friend struct DefaultSingletonTraits<CrashReporterMac>;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/file_util.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/singleton.h"
|
||||
#include "base/strings/string_util.h"
|
||||
|
||||
@@ -21,13 +21,13 @@ class CrashReporterWin : public CrashReporter {
|
||||
public:
|
||||
static CrashReporterWin* GetInstance();
|
||||
|
||||
virtual void InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) OVERRIDE;
|
||||
virtual void SetUploadParameters() OVERRIDE;
|
||||
void InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) override;
|
||||
void SetUploadParameters() override;
|
||||
|
||||
private:
|
||||
friend struct DefaultSingletonTraits<CrashReporterWin>;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <map>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/time/time.h"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "atom/common/crash_reporter/win/crash_service.h"
|
||||
#include "base/at_exit.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/strings/string_util.h"
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
asar = process.atomBinding 'asar'
|
||||
child_process = require 'child_process'
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
util = require 'util'
|
||||
|
||||
@@ -60,203 +59,6 @@ createNotFoundError = (asarPath, filePath) ->
|
||||
error.errno = -2
|
||||
error
|
||||
|
||||
# Override fs APIs.
|
||||
lstatSync = fs.lstatSync
|
||||
fs.lstatSync = (p) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return lstatSync p unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
throw new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
stats = archive.stat filePath
|
||||
throw createNotFoundError(asarPath, filePath) unless stats
|
||||
|
||||
asarStatsToFsStats stats
|
||||
|
||||
lstat = fs.lstat
|
||||
fs.lstat = (p, callback) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return lstat p, callback unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
return callback new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
stats = getOrCreateArchive(asarPath).stat filePath
|
||||
return callback createNotFoundError(asarPath, filePath) unless stats
|
||||
|
||||
process.nextTick -> callback null, asarStatsToFsStats stats
|
||||
|
||||
statSync = fs.statSync
|
||||
fs.statSync = (p) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return statSync p unless isAsar
|
||||
|
||||
# Do not distinguish links for now.
|
||||
fs.lstatSync p
|
||||
|
||||
stat = fs.stat
|
||||
fs.stat = (p, callback) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return stat p, callback unless isAsar
|
||||
|
||||
# Do not distinguish links for now.
|
||||
process.nextTick -> fs.lstat p, callback
|
||||
|
||||
statSyncNoException = fs.statSyncNoException
|
||||
fs.statSyncNoException = (p) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return statSyncNoException p unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
return false unless archive
|
||||
stats = archive.stat filePath
|
||||
return false unless stats
|
||||
asarStatsToFsStats stats
|
||||
|
||||
realpathSync = fs.realpathSync
|
||||
fs.realpathSync = (p) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return realpathSync.apply this, arguments unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
throw new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
real = archive.realpath filePath
|
||||
throw createNotFoundError(asarPath, filePath) if real is false
|
||||
|
||||
path.join realpathSync(asarPath), real
|
||||
|
||||
realpath = fs.realpath
|
||||
fs.realpath = (p, cache, callback) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return realpath.apply this, arguments unless isAsar
|
||||
|
||||
if typeof cache is 'function'
|
||||
callback = cache
|
||||
cache = undefined
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
return callback new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
real = archive.realpath filePath
|
||||
return callback createNotFoundError(asarPath, filePath) if real is false
|
||||
|
||||
realpath asarPath, (err, p) ->
|
||||
return callback err if err
|
||||
callback null, path.join(p, real)
|
||||
|
||||
exists = fs.exists
|
||||
fs.exists = (p, callback) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return exists p, callback unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
return callback new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
process.nextTick -> callback archive.stat(filePath) isnt false
|
||||
|
||||
existsSync = fs.existsSync
|
||||
fs.existsSync = (p) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return existsSync p unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
return false unless archive
|
||||
|
||||
archive.stat(filePath) isnt false
|
||||
|
||||
open = fs.open
|
||||
readFile = fs.readFile
|
||||
fs.readFile = (p, options, callback) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return readFile.apply this, arguments unless isAsar
|
||||
|
||||
if typeof options is 'function'
|
||||
callback = options
|
||||
options = undefined
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
return callback new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
info = archive.getFileInfo filePath
|
||||
return callback createNotFoundError(asarPath, filePath) unless info
|
||||
|
||||
if not options
|
||||
options = encoding: null, flag: 'r'
|
||||
else if util.isString options
|
||||
options = encoding: options, flag: 'r'
|
||||
else if not util.isObject options
|
||||
throw new TypeError('Bad arguments')
|
||||
|
||||
flag = options.flag || 'r'
|
||||
encoding = options.encoding
|
||||
|
||||
buffer = new Buffer(info.size)
|
||||
open archive.path, flag, (error, fd) ->
|
||||
return callback error if error
|
||||
fs.read fd, buffer, 0, info.size, info.offset, (error) ->
|
||||
fs.close fd, ->
|
||||
callback error, if encoding then buffer.toString encoding else buffer
|
||||
|
||||
openSync = fs.openSync
|
||||
readFileSync = fs.readFileSync
|
||||
fs.readFileSync = (p, options) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return readFileSync.apply this, arguments unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
throw new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
info = archive.getFileInfo filePath
|
||||
throw createNotFoundError(asarPath, filePath) unless info
|
||||
|
||||
if not options
|
||||
options = encoding: null, flag: 'r'
|
||||
else if util.isString options
|
||||
options = encoding: options, flag: 'r'
|
||||
else if not util.isObject options
|
||||
throw new TypeError('Bad arguments')
|
||||
|
||||
flag = options.flag || 'r'
|
||||
encoding = options.encoding
|
||||
|
||||
buffer = new Buffer(info.size)
|
||||
fd = openSync archive.path, flag
|
||||
try
|
||||
fs.readSync fd, buffer, 0, info.size, info.offset
|
||||
catch e
|
||||
throw e
|
||||
finally
|
||||
fs.closeSync fd
|
||||
if encoding then buffer.toString encoding else buffer
|
||||
|
||||
readdir = fs.readdir
|
||||
fs.readdir = (p, callback) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return readdir.apply this, arguments unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
return callback new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
files = archive.readdir filePath
|
||||
return callback createNotFoundError(asarPath, filePath) unless files
|
||||
|
||||
process.nextTick -> callback null, files
|
||||
|
||||
readdirSync = fs.readdirSync
|
||||
fs.readdirSync = (p) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return readdirSync.apply this, arguments unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
throw new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
files = archive.readdir filePath
|
||||
throw createNotFoundError(asarPath, filePath) unless files
|
||||
|
||||
files
|
||||
|
||||
# Override APIs that rely on passing file path instead of content to C++.
|
||||
overrideAPISync = (module, name, arg = 0) ->
|
||||
old = module[name]
|
||||
@@ -293,9 +95,207 @@ overrideAPI = (module, name, arg = 0) ->
|
||||
arguments[arg] = newPath
|
||||
old.apply this, arguments
|
||||
|
||||
overrideAPI fs, 'open'
|
||||
overrideAPI child_process, 'execFile'
|
||||
overrideAPISync process, 'dlopen', 1
|
||||
overrideAPISync require('module')._extensions, '.node', 1
|
||||
overrideAPISync fs, 'openSync'
|
||||
overrideAPISync child_process, 'fork'
|
||||
# Override fs APIs.
|
||||
exports.wrapFsWithAsar = (fs) ->
|
||||
lstatSync = fs.lstatSync
|
||||
fs.lstatSync = (p) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return lstatSync p unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
throw new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
stats = archive.stat filePath
|
||||
throw createNotFoundError(asarPath, filePath) unless stats
|
||||
|
||||
asarStatsToFsStats stats
|
||||
|
||||
lstat = fs.lstat
|
||||
fs.lstat = (p, callback) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return lstat p, callback unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
return callback new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
stats = getOrCreateArchive(asarPath).stat filePath
|
||||
return callback createNotFoundError(asarPath, filePath) unless stats
|
||||
|
||||
process.nextTick -> callback null, asarStatsToFsStats stats
|
||||
|
||||
statSync = fs.statSync
|
||||
fs.statSync = (p) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return statSync p unless isAsar
|
||||
|
||||
# Do not distinguish links for now.
|
||||
fs.lstatSync p
|
||||
|
||||
stat = fs.stat
|
||||
fs.stat = (p, callback) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return stat p, callback unless isAsar
|
||||
|
||||
# Do not distinguish links for now.
|
||||
process.nextTick -> fs.lstat p, callback
|
||||
|
||||
statSyncNoException = fs.statSyncNoException
|
||||
fs.statSyncNoException = (p) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return statSyncNoException p unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
return false unless archive
|
||||
stats = archive.stat filePath
|
||||
return false unless stats
|
||||
asarStatsToFsStats stats
|
||||
|
||||
realpathSync = fs.realpathSync
|
||||
fs.realpathSync = (p) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return realpathSync.apply this, arguments unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
throw new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
real = archive.realpath filePath
|
||||
throw createNotFoundError(asarPath, filePath) if real is false
|
||||
|
||||
path.join realpathSync(asarPath), real
|
||||
|
||||
realpath = fs.realpath
|
||||
fs.realpath = (p, cache, callback) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return realpath.apply this, arguments unless isAsar
|
||||
|
||||
if typeof cache is 'function'
|
||||
callback = cache
|
||||
cache = undefined
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
return callback new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
real = archive.realpath filePath
|
||||
return callback createNotFoundError(asarPath, filePath) if real is false
|
||||
|
||||
realpath asarPath, (err, p) ->
|
||||
return callback err if err
|
||||
callback null, path.join(p, real)
|
||||
|
||||
exists = fs.exists
|
||||
fs.exists = (p, callback) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return exists p, callback unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
return callback new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
process.nextTick -> callback archive.stat(filePath) isnt false
|
||||
|
||||
existsSync = fs.existsSync
|
||||
fs.existsSync = (p) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return existsSync p unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
return false unless archive
|
||||
|
||||
archive.stat(filePath) isnt false
|
||||
|
||||
open = fs.open
|
||||
readFile = fs.readFile
|
||||
fs.readFile = (p, options, callback) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return readFile.apply this, arguments unless isAsar
|
||||
|
||||
if typeof options is 'function'
|
||||
callback = options
|
||||
options = undefined
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
return callback new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
info = archive.getFileInfo filePath
|
||||
return callback createNotFoundError(asarPath, filePath) unless info
|
||||
|
||||
if not options
|
||||
options = encoding: null, flag: 'r'
|
||||
else if util.isString options
|
||||
options = encoding: options, flag: 'r'
|
||||
else if not util.isObject options
|
||||
throw new TypeError('Bad arguments')
|
||||
|
||||
flag = options.flag || 'r'
|
||||
encoding = options.encoding
|
||||
|
||||
buffer = new Buffer(info.size)
|
||||
open archive.path, flag, (error, fd) ->
|
||||
return callback error if error
|
||||
fs.read fd, buffer, 0, info.size, info.offset, (error) ->
|
||||
fs.close fd, ->
|
||||
callback error, if encoding then buffer.toString encoding else buffer
|
||||
|
||||
openSync = fs.openSync
|
||||
readFileSync = fs.readFileSync
|
||||
fs.readFileSync = (p, options) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return readFileSync.apply this, arguments unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
throw new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
info = archive.getFileInfo filePath
|
||||
throw createNotFoundError(asarPath, filePath) unless info
|
||||
|
||||
if not options
|
||||
options = encoding: null, flag: 'r'
|
||||
else if util.isString options
|
||||
options = encoding: options, flag: 'r'
|
||||
else if not util.isObject options
|
||||
throw new TypeError('Bad arguments')
|
||||
|
||||
flag = options.flag || 'r'
|
||||
encoding = options.encoding
|
||||
|
||||
buffer = new Buffer(info.size)
|
||||
fd = openSync archive.path, flag
|
||||
try
|
||||
fs.readSync fd, buffer, 0, info.size, info.offset
|
||||
catch e
|
||||
throw e
|
||||
finally
|
||||
fs.closeSync fd
|
||||
if encoding then buffer.toString encoding else buffer
|
||||
|
||||
readdir = fs.readdir
|
||||
fs.readdir = (p, callback) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return readdir.apply this, arguments unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
return callback new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
files = archive.readdir filePath
|
||||
return callback createNotFoundError(asarPath, filePath) unless files
|
||||
|
||||
process.nextTick -> callback null, files
|
||||
|
||||
readdirSync = fs.readdirSync
|
||||
fs.readdirSync = (p) ->
|
||||
[isAsar, asarPath, filePath] = splitPath p
|
||||
return readdirSync.apply this, arguments unless isAsar
|
||||
|
||||
archive = getOrCreateArchive asarPath
|
||||
throw new Error("Invalid package #{asarPath}") unless archive
|
||||
|
||||
files = archive.readdir filePath
|
||||
throw createNotFoundError(asarPath, filePath) unless files
|
||||
|
||||
files
|
||||
|
||||
overrideAPI fs, 'open'
|
||||
overrideAPI child_process, 'execFile'
|
||||
overrideAPISync process, 'dlopen', 1
|
||||
overrideAPISync require('module')._extensions, '.node', 1
|
||||
overrideAPISync fs, 'openSync'
|
||||
overrideAPISync child_process, 'fork'
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
process = global.process
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
timers = require 'timers'
|
||||
Module = require 'module'
|
||||
@@ -35,8 +36,20 @@ if process.type is 'browser'
|
||||
global.setTimeout = wrapWithActivateUvLoop timers.setTimeout
|
||||
global.setInterval = wrapWithActivateUvLoop timers.setInterval
|
||||
|
||||
# Initialize the "original-fs" module before asar support is loaded.
|
||||
require 'original-fs'
|
||||
|
||||
# Add support for asar packages.
|
||||
require './asar'
|
||||
asar = require './asar'
|
||||
asar.wrapFsWithAsar fs
|
||||
|
||||
# Make graceful-fs work with asar.
|
||||
source = process.binding 'natives'
|
||||
source.originalFs = source.fs
|
||||
source.fs = """
|
||||
var src = '(function (exports, require, module, __filename, __dirname) { ' +
|
||||
process.binding('natives').originalFs +
|
||||
' });';
|
||||
var vm = require('vm');
|
||||
var fn = vm.runInThisContext(src, { filename: 'fs.js' });
|
||||
fn(exports, require, module);
|
||||
var asar = require(#{JSON.stringify(__dirname)} + '/asar');
|
||||
asar.wrapFsWithAsar(exports);
|
||||
"""
|
||||
|
||||
110
atom/common/native_mate_converters/gfx_converter.cc
Normal file
110
atom/common/native_mate_converters/gfx_converter.cc
Normal file
@@ -0,0 +1,110 @@
|
||||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gfx/point.h"
|
||||
#include "ui/gfx/rect.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
#include "ui/gfx/size.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
v8::Handle<v8::Value> Converter<gfx::Point>::ToV8(v8::Isolate* isolate,
|
||||
const gfx::Point& val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
dict.Set("x", val.x());
|
||||
dict.Set("y", val.y());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
bool Converter<gfx::Point>::FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::Point* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
int x, y;
|
||||
if (!dict.Get("x", &x) || !dict.Get("y", &y))
|
||||
return false;
|
||||
*out = gfx::Point(x, y);
|
||||
return true;
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Converter<gfx::Size>::ToV8(v8::Isolate* isolate,
|
||||
const gfx::Size& val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
dict.Set("width", val.width());
|
||||
dict.Set("height", val.height());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
bool Converter<gfx::Size>::FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::Size* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
int width, height;
|
||||
if (!dict.Get("width", &width) || !dict.Get("height", &height))
|
||||
return false;
|
||||
*out = gfx::Size(width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Converter<gfx::Rect>::ToV8(v8::Isolate* isolate,
|
||||
const gfx::Rect& val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
dict.Set("x", val.x());
|
||||
dict.Set("y", val.y());
|
||||
dict.Set("width", val.width());
|
||||
dict.Set("height", val.height());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
bool Converter<gfx::Rect>::FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::Rect* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
int x, y, width, height;
|
||||
if (!dict.Get("x", &x) || !dict.Get("y", &y) ||
|
||||
!dict.Get("width", &width) || !dict.Get("height", &height))
|
||||
return false;
|
||||
*out = gfx::Rect(x, y, width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
struct Converter<gfx::Display::TouchSupport> {
|
||||
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const gfx::Display::TouchSupport& val) {
|
||||
switch (val) {
|
||||
case gfx::Display::TOUCH_SUPPORT_AVAILABLE:
|
||||
return StringToV8(isolate, "available");
|
||||
case gfx::Display::TOUCH_SUPPORT_UNAVAILABLE:
|
||||
return StringToV8(isolate, "unavailable");
|
||||
default:
|
||||
return StringToV8(isolate, "unknown");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
v8::Handle<v8::Value> Converter<gfx::Display>::ToV8(v8::Isolate* isolate,
|
||||
const gfx::Display& val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
dict.Set("id", val.id());
|
||||
dict.Set("bounds", val.bounds());
|
||||
dict.Set("workArea", val.work_area());
|
||||
dict.Set("size", val.size());
|
||||
dict.Set("workAreaSize", val.work_area_size());
|
||||
dict.Set("scaleFactor", val.device_scale_factor());
|
||||
dict.Set("rotation", val.RotationAsDegree());
|
||||
dict.Set("touchSupport", val.touch_support());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
|
||||
} // namespace mate
|
||||
@@ -5,95 +5,51 @@
|
||||
#ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_GFX_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_GFX_CONVERTER_H_
|
||||
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gfx/point.h"
|
||||
#include "ui/gfx/rect.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
#include "ui/gfx/size.h"
|
||||
#include "native_mate/converter.h"
|
||||
|
||||
namespace gfx {
|
||||
class Point;
|
||||
class Size;
|
||||
class Rect;
|
||||
class Display;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<gfx::Point> {
|
||||
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const gfx::Point& val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
dict.Set("x", val.x());
|
||||
dict.Set("y", val.y());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||
gfx::Point* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
int x, y;
|
||||
if (!dict.Get("x", &x) || !dict.Get("y", &y))
|
||||
return false;
|
||||
*out = gfx::Point(x, y);
|
||||
return true;
|
||||
}
|
||||
const gfx::Point& val);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::Point* out);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<gfx::Size> {
|
||||
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const gfx::Size& val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
dict.Set("width", val.width());
|
||||
dict.Set("height", val.height());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||
gfx::Size* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
int width, height;
|
||||
if (!dict.Get("width", &width) || !dict.Get("height", &height))
|
||||
return false;
|
||||
*out = gfx::Size(width, height);
|
||||
return true;
|
||||
}
|
||||
const gfx::Size& val);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::Size* out);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<gfx::Rect> {
|
||||
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const gfx::Rect& val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
dict.Set("x", val.x());
|
||||
dict.Set("y", val.y());
|
||||
dict.Set("width", val.width());
|
||||
dict.Set("height", val.height());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||
gfx::Rect* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
int x, y, width, height;
|
||||
if (!dict.Get("x", &x) || !dict.Get("y", &y) ||
|
||||
!dict.Get("width", &width) || !dict.Get("height", &height))
|
||||
return false;
|
||||
*out = gfx::Rect(x, y, width, height);
|
||||
return true;
|
||||
}
|
||||
const gfx::Rect& val);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::Rect* out);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<gfx::Display> {
|
||||
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const gfx::Display& display) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
dict.Set("bounds", display.bounds());
|
||||
dict.Set("workArea", display.work_area());
|
||||
dict.Set("size", display.size());
|
||||
dict.Set("workAreaSize", display.work_area_size());
|
||||
dict.Set("scaleFactor", display.device_scale_factor());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
const gfx::Display& val);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::Display* out);
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
@@ -8,13 +8,16 @@
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "ui/gfx/codec/jpeg_codec.h"
|
||||
#include "ui/gfx/codec/png_codec.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
#include "ui/base/layout.h"
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace {
|
||||
@@ -29,6 +32,8 @@ ScaleFactorPair kScaleFactorPairs[] = {
|
||||
{ "@2x" , 2.0f },
|
||||
{ "@3x" , 3.0f },
|
||||
{ "@1x" , 1.0f },
|
||||
{ "@4x" , 4.0f },
|
||||
{ "@5x" , 5.0f },
|
||||
{ "@1.25x" , 1.25f },
|
||||
{ "@1.33x" , 1.33f },
|
||||
{ "@1.4x" , 1.4f },
|
||||
@@ -40,10 +45,6 @@ ScaleFactorPair kScaleFactorPairs[] = {
|
||||
float GetScaleFactorFromPath(const base::FilePath& path) {
|
||||
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
|
||||
|
||||
// There is no scale info in the file path.
|
||||
if (!EndsWith(filename, "x", true))
|
||||
return 1.0f;
|
||||
|
||||
// We don't try to convert string to float here because it is very very
|
||||
// expensive.
|
||||
for (unsigned i = 0; i < arraysize(kScaleFactorPairs); ++i) {
|
||||
@@ -54,27 +55,9 @@ float GetScaleFactorFromPath(const base::FilePath& path) {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
void AppendIfExists(std::vector<base::FilePath>* paths,
|
||||
const base::FilePath& path) {
|
||||
if (base::PathExists(path))
|
||||
paths->push_back(path);
|
||||
}
|
||||
|
||||
void PopulatePossibleFilePaths(std::vector<base::FilePath>* paths,
|
||||
const base::FilePath& path) {
|
||||
AppendIfExists(paths, path);
|
||||
|
||||
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
|
||||
if (MatchPattern(filename, "*@*x"))
|
||||
return;
|
||||
|
||||
for (unsigned i = 0; i < arraysize(kScaleFactorPairs); ++i)
|
||||
AppendIfExists(paths,
|
||||
path.InsertBeforeExtensionASCII(kScaleFactorPairs[i].name));
|
||||
}
|
||||
|
||||
bool AddImageSkiaRepFromPath(gfx::ImageSkia* image,
|
||||
const base::FilePath& path) {
|
||||
bool AddImageSkiaRep(gfx::ImageSkia* image,
|
||||
const base::FilePath& path,
|
||||
double scale_factor) {
|
||||
std::string file_contents;
|
||||
if (!base::ReadFileToString(path, &file_contents))
|
||||
return false;
|
||||
@@ -89,13 +72,28 @@ bool AddImageSkiaRepFromPath(gfx::ImageSkia* image,
|
||||
// Try JPEG.
|
||||
decoded.reset(gfx::JPEGCodec::Decode(data, size));
|
||||
|
||||
if (decoded) {
|
||||
image->AddRepresentation(gfx::ImageSkiaRep(
|
||||
*decoded.release(), GetScaleFactorFromPath(path)));
|
||||
return true;
|
||||
}
|
||||
if (!decoded)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
image->AddRepresentation(gfx::ImageSkiaRep(*decoded.release(), scale_factor));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image,
|
||||
const base::FilePath& path) {
|
||||
bool succeed = false;
|
||||
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
|
||||
if (MatchPattern(filename, "*@*x"))
|
||||
// Don't search for other representations if the DPI has been specified.
|
||||
return AddImageSkiaRep(image, path, GetScaleFactorFromPath(path));
|
||||
else
|
||||
succeed |= AddImageSkiaRep(image, path, 1.0f);
|
||||
|
||||
for (const ScaleFactorPair& pair : kScaleFactorPairs)
|
||||
succeed |= AddImageSkiaRep(image,
|
||||
path.InsertBeforeExtensionASCII(pair.name),
|
||||
pair.scale);
|
||||
return succeed;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -103,21 +101,27 @@ bool AddImageSkiaRepFromPath(gfx::ImageSkia* image,
|
||||
bool Converter<gfx::ImageSkia>::FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::ImageSkia* out) {
|
||||
base::FilePath path;
|
||||
if (Converter<base::FilePath>::FromV8(isolate, val, &path)) {
|
||||
std::vector<base::FilePath> paths;
|
||||
PopulatePossibleFilePaths(&paths, path);
|
||||
if (paths.empty())
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < paths.size(); ++i) {
|
||||
if (!AddImageSkiaRepFromPath(out, paths[i]))
|
||||
return false;
|
||||
}
|
||||
if (val->IsNull())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
base::FilePath path;
|
||||
if (!Converter<base::FilePath>::FromV8(isolate, val, &path))
|
||||
return false;
|
||||
|
||||
return PopulateImageSkiaRepsFromPath(out, path);
|
||||
}
|
||||
|
||||
bool Converter<gfx::Image>::FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::Image* out) {
|
||||
gfx::ImageSkia image;
|
||||
if (!ConvertFromV8(isolate, val, &image))
|
||||
return false;
|
||||
|
||||
*out = gfx::Image(image);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // !defined(OS_MACOSX)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "native_mate/converter.h"
|
||||
|
||||
namespace gfx {
|
||||
class Image;
|
||||
class ImageSkia;
|
||||
}
|
||||
|
||||
@@ -20,6 +21,13 @@ struct Converter<gfx::ImageSkia> {
|
||||
gfx::ImageSkia* out);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<gfx::Image> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::Image* out);
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_IMAGE_CONVERTER_H_
|
||||
|
||||
60
atom/common/native_mate_converters/image_converter_mac.mm
Normal file
60
atom/common/native_mate_converters/image_converter_mac.mm
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "base/mac/foundation_util.h"
|
||||
#include "base/mac/scoped_nsobject.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsTemplateImage(const std::string& path) {
|
||||
return (MatchPattern(path, "*Template.*") ||
|
||||
MatchPattern(path, "*Template@*x.*"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
||||
bool Converter<gfx::ImageSkia>::FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::ImageSkia* out) {
|
||||
gfx::Image image;
|
||||
if (!ConvertFromV8(isolate, val, &image))
|
||||
return false;
|
||||
|
||||
*out = image.AsImageSkia();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Converter<gfx::Image>::FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::Image* out) {
|
||||
if (val->IsNull())
|
||||
return true;
|
||||
|
||||
std::string path;
|
||||
if (!ConvertFromV8(isolate, val, &path))
|
||||
return false;
|
||||
|
||||
base::scoped_nsobject<NSImage> image([[NSImage alloc]
|
||||
initByReferencingFile:base::SysUTF8ToNSString(path)]);
|
||||
if (![image isValid])
|
||||
return false;
|
||||
|
||||
if (IsTemplateImage(path))
|
||||
[image setTemplate:YES];
|
||||
|
||||
*out = gfx::Image(image.release());
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mate
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user