commit
c571776da6
281 changed files with 9187 additions and 1920 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
/.idea/
|
||||||
/build/
|
/build/
|
||||||
/dist/
|
/dist/
|
||||||
/external_binaries/
|
/external_binaries/
|
||||||
|
|
|
@ -10,6 +10,7 @@ os:
|
||||||
- osx
|
- osx
|
||||||
env:
|
env:
|
||||||
- TARGET_ARCH=x64
|
- TARGET_ARCH=x64
|
||||||
|
osx_image: xcode7
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
:zap: *프레임워크 이름이 Atom Shell에서 Electron으로 변경되었습니다* :zap:
|
:zap: *프레임워크 이름이 Atom Shell에서 Electron으로 변경되었습니다* :zap:
|
||||||
|
|
||||||
Electron 프레임워크는 JavaScript, HTML 그리고 CSS를 사용하여 Cross-Platform 데스크톱 어플리케이션을 개발할 수 있도록 해주는 프레임워크입니다. 이 프레임워크는 [io.js](http://iojs.org) 와
|
Electron 프레임워크는 JavaScript, HTML 그리고 CSS를 사용하여 Cross-Platform 데스크톱 어플리케이션을 개발할 수 있도록 해주는 프레임워크입니다. 이 프레임워크는 [Node.js](https://nodejs.org) 와
|
||||||
[Chromium](http://www.chromium.org)을 기반으로 만들어 졌으며 [Atom Editor](https://github.com/atom/atom)에 사용되고 있습니다.
|
[Chromium](http://www.chromium.org)을 기반으로 만들어 졌으며 [Atom Editor](https://github.com/atom/atom)에 사용되고 있습니다.
|
||||||
|
|
||||||
Electron에 대한 중요한 알림을 받고 싶다면 Twitter에서 [@ElectronJS](https://twitter.com/electronjs)를 팔로우 하세요.
|
Electron에 대한 중요한 알림을 받고 싶다면 Twitter에서 [@ElectronJS](https://twitter.com/electronjs)를 팔로우 하세요.
|
||||||
|
@ -47,9 +47,13 @@ Electron을 빌드 하는 방법과 프로젝트에 기여하는 방법도 문
|
||||||
- [중국어 간체](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
|
- [중국어 간체](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
|
||||||
- [중국어 번체](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
|
- [중국어 번체](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
|
||||||
|
|
||||||
|
## 시작하기
|
||||||
|
|
||||||
|
[`atom/electron-quick-start`](https://github.com/atom/electron-quick-start) 저장소를 클론하여 Electron을 간단히 접해볼 수 있습니다.
|
||||||
|
|
||||||
## 커뮤니티
|
## 커뮤니티
|
||||||
|
|
||||||
다음 링크를 통해 커뮤니티에 질문을 올리거나 토론을 나누실 수 있습니다:
|
다음 링크를 통해 커뮤니티에 질문을 올리거나 토론을 나눌 수 있습니다:
|
||||||
|
|
||||||
- Atom 포럼의 [`electron`](http://discuss.atom.io/category/electron) 카테고리
|
- Atom 포럼의 [`electron`](http://discuss.atom.io/category/electron) 카테고리
|
||||||
- Freenode 채팅의 `#atom-shell` 채널
|
- Freenode 채팅의 `#atom-shell` 채널
|
||||||
|
|
13
README.md
13
README.md
|
@ -7,20 +7,20 @@
|
||||||
:zap: *Formerly known as Atom Shell* :zap:
|
:zap: *Formerly known as Atom Shell* :zap:
|
||||||
|
|
||||||
The Electron framework lets you write cross-platform desktop applications
|
The Electron framework lets you write cross-platform desktop applications
|
||||||
using JavaScript, HTML and CSS. It is based on [io.js](http://iojs.org) and
|
using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) and
|
||||||
[Chromium](http://www.chromium.org) and is used in the [Atom
|
[Chromium](http://www.chromium.org) and is used in the [Atom
|
||||||
editor](https://github.com/atom/atom).
|
editor](https://github.com/atom/atom).
|
||||||
|
|
||||||
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
|
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
|
||||||
announcements.
|
announcements.
|
||||||
|
|
||||||
This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0).
|
This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0/).
|
||||||
By participating, you are expected to uphold this code. Please report
|
By participating, you are expected to uphold this code. Please report
|
||||||
unacceptable behavior to atom@github.com.
|
unacceptable behavior to atom@github.com.
|
||||||
|
|
||||||
## Downloads
|
## Downloads
|
||||||
|
|
||||||
Prebuilt binaries and debug symbols of Electron for Linux, Windows and Mac can
|
Prebuilt binaries and debug symbols of Electron for Linux, Windows and OS X can
|
||||||
be found on the [releases](https://github.com/atom/electron/releases) page.
|
be found on the [releases](https://github.com/atom/electron/releases) page.
|
||||||
|
|
||||||
You can also use [`npm`](https://docs.npmjs.com/) to install prebuilt electron
|
You can also use [`npm`](https://docs.npmjs.com/) to install prebuilt electron
|
||||||
|
@ -53,11 +53,16 @@ contains documents describing how to build and contribute to Electron.
|
||||||
- [Simplified Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
|
- [Simplified Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
|
||||||
- [Traditional Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
|
- [Traditional Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
Clone and run the [`atom/electron-quick-start`](https://github.com/atom/electron-quick-start)
|
||||||
|
repository to see a minimal Electron app in action.
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
You can ask questions and interact with the community in the following
|
You can ask questions and interact with the community in the following
|
||||||
locations:
|
locations:
|
||||||
- [`electron`](http://discuss.atom.io/category/electron) category on the Atom
|
- [`electron`](http://discuss.atom.io/c/electron) category on the Atom
|
||||||
forums
|
forums
|
||||||
- `#atom-shell` channel on Freenode
|
- `#atom-shell` channel on Freenode
|
||||||
- [`Atom`](http://atom-slack.herokuapp.com/) channel on Slack
|
- [`Atom`](http://atom-slack.herokuapp.com/) channel on Slack
|
||||||
|
|
69
atom.gyp
69
atom.gyp
|
@ -4,7 +4,7 @@
|
||||||
'product_name%': 'Electron',
|
'product_name%': 'Electron',
|
||||||
'company_name%': 'GitHub, Inc',
|
'company_name%': 'GitHub, Inc',
|
||||||
'company_abbr%': 'github',
|
'company_abbr%': 'github',
|
||||||
'version%': '0.33.6',
|
'version%': '0.34.3',
|
||||||
},
|
},
|
||||||
'includes': [
|
'includes': [
|
||||||
'filenames.gypi',
|
'filenames.gypi',
|
||||||
|
@ -64,9 +64,6 @@
|
||||||
'files': [
|
'files': [
|
||||||
'<(PRODUCT_DIR)/<(product_name) Helper.app',
|
'<(PRODUCT_DIR)/<(product_name) Helper.app',
|
||||||
'<(PRODUCT_DIR)/<(product_name) Framework.framework',
|
'<(PRODUCT_DIR)/<(product_name) Framework.framework',
|
||||||
'external_binaries/Squirrel.framework',
|
|
||||||
'external_binaries/ReactiveCocoa.framework',
|
|
||||||
'external_binaries/Mantle.framework',
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -109,7 +106,21 @@
|
||||||
'<@(locale_dirs)',
|
'<@(locale_dirs)',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
|
'conditions': [
|
||||||
|
['mas_build==0', {
|
||||||
|
'copies': [
|
||||||
|
{
|
||||||
|
'destination': '<(PRODUCT_DIR)/<(product_name).app/Contents/Frameworks',
|
||||||
|
'files': [
|
||||||
|
'external_binaries/Squirrel.framework',
|
||||||
|
'external_binaries/ReactiveCocoa.framework',
|
||||||
|
'external_binaries/Mantle.framework',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}],
|
||||||
|
],
|
||||||
}, { # OS=="mac"
|
}, { # OS=="mac"
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'make_locale_paks',
|
'make_locale_paks',
|
||||||
|
@ -285,12 +296,28 @@
|
||||||
'vendor/breakpad/breakpad.gyp:breakpad_sender',
|
'vendor/breakpad/breakpad.gyp:breakpad_sender',
|
||||||
],
|
],
|
||||||
}], # OS=="win"
|
}], # OS=="win"
|
||||||
['OS=="mac"', {
|
['OS=="mac" and mas_build==0', {
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'vendor/crashpad/client/client.gyp:crashpad_client',
|
'vendor/crashpad/client/client.gyp:crashpad_client',
|
||||||
'vendor/crashpad/handler/handler.gyp:crashpad_handler',
|
'vendor/crashpad/handler/handler.gyp:crashpad_handler',
|
||||||
],
|
],
|
||||||
}], # OS=="mac"
|
'link_settings': {
|
||||||
|
# Do not link with QTKit for mas build.
|
||||||
|
'libraries': [
|
||||||
|
'$(SDKROOT)/System/Library/Frameworks/QTKit.framework',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}], # OS=="mac" and mas_build==0
|
||||||
|
['OS=="mac" and mas_build==1', {
|
||||||
|
'defines': [
|
||||||
|
'MAS_BUILD',
|
||||||
|
],
|
||||||
|
'sources!': [
|
||||||
|
'atom/browser/auto_updater_mac.mm',
|
||||||
|
'atom/common/crash_reporter/crash_reporter_mac.h',
|
||||||
|
'atom/common/crash_reporter/crash_reporter_mac.mm',
|
||||||
|
],
|
||||||
|
}], # OS=="mac" and mas_build==1
|
||||||
['OS=="linux"', {
|
['OS=="linux"', {
|
||||||
'link_settings': {
|
'link_settings': {
|
||||||
'ldflags': [
|
'ldflags': [
|
||||||
|
@ -393,9 +420,6 @@
|
||||||
'libraries': [
|
'libraries': [
|
||||||
'$(SDKROOT)/System/Library/Frameworks/Carbon.framework',
|
'$(SDKROOT)/System/Library/Frameworks/Carbon.framework',
|
||||||
'$(SDKROOT)/System/Library/Frameworks/QuartzCore.framework',
|
'$(SDKROOT)/System/Library/Frameworks/QuartzCore.framework',
|
||||||
'external_binaries/Squirrel.framework',
|
|
||||||
'external_binaries/ReactiveCocoa.framework',
|
|
||||||
'external_binaries/Mantle.framework',
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
'mac_bundle': 1,
|
'mac_bundle': 1,
|
||||||
|
@ -439,12 +463,6 @@
|
||||||
'<@(copied_libraries)',
|
'<@(copied_libraries)',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
'destination': '<(PRODUCT_DIR)/<(product_name) Framework.framework/Versions/A/Resources',
|
|
||||||
'files': [
|
|
||||||
'<(PRODUCT_DIR)/crashpad_handler',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
'postbuilds': [
|
'postbuilds': [
|
||||||
{
|
{
|
||||||
|
@ -476,6 +494,25 @@
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
'conditions': [
|
||||||
|
['mas_build==0', {
|
||||||
|
'link_settings': {
|
||||||
|
'libraries': [
|
||||||
|
'external_binaries/Squirrel.framework',
|
||||||
|
'external_binaries/ReactiveCocoa.framework',
|
||||||
|
'external_binaries/Mantle.framework',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'copies': [
|
||||||
|
{
|
||||||
|
'destination': '<(PRODUCT_DIR)/<(product_name) Framework.framework/Versions/A/Resources',
|
||||||
|
'files': [
|
||||||
|
'<(PRODUCT_DIR)/crashpad_handler',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}],
|
||||||
|
],
|
||||||
}, # target framework
|
}, # target framework
|
||||||
{
|
{
|
||||||
'target_name': '<(project_name)_helper',
|
'target_name': '<(project_name)_helper',
|
||||||
|
|
|
@ -99,7 +99,7 @@ void AtomContentClient::AddAdditionalSchemes(
|
||||||
void AtomContentClient::AddPepperPlugins(
|
void AtomContentClient::AddPepperPlugins(
|
||||||
std::vector<content::PepperPluginInfo>* plugins) {
|
std::vector<content::PepperPluginInfo>* plugins) {
|
||||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||||
auto flash_path = command_line->GetSwitchValueNative(
|
auto flash_path = command_line->GetSwitchValuePath(
|
||||||
switches::kPpapiFlashPath);
|
switches::kPpapiFlashPath);
|
||||||
if (flash_path.empty())
|
if (flash_path.empty())
|
||||||
return;
|
return;
|
||||||
|
@ -108,7 +108,7 @@ void AtomContentClient::AddPepperPlugins(
|
||||||
switches::kPpapiFlashVersion);
|
switches::kPpapiFlashVersion);
|
||||||
|
|
||||||
plugins->push_back(
|
plugins->push_back(
|
||||||
CreatePepperFlashInfo(base::FilePath(flash_path), flash_version));
|
CreatePepperFlashInfo(flash_path, flash_version));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "base/at_exit.h"
|
#include "base/at_exit.h"
|
||||||
#include "base/i18n/icu_util.h"
|
#include "base/i18n/icu_util.h"
|
||||||
#include "base/mac/bundle_locations.h"
|
#include "base/mac/bundle_locations.h"
|
||||||
|
#include "base/mac/scoped_nsautorelease_pool.h"
|
||||||
#include "brightray/common/mac/main_application_bundle.h"
|
#include "brightray/common/mac/main_application_bundle.h"
|
||||||
#include "content/public/app/content_main.h"
|
#include "content/public/app/content_main.h"
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ int AtomMain(int argc, const char* argv[]) {
|
||||||
|
|
||||||
int AtomInitializeICUandStartNode(int argc, char *argv[]) {
|
int AtomInitializeICUandStartNode(int argc, char *argv[]) {
|
||||||
base::AtExitManager atexit_manager;
|
base::AtExitManager atexit_manager;
|
||||||
|
base::mac::ScopedNSAutoreleasePool pool;
|
||||||
base::mac::SetOverrideFrameworkBundlePath(
|
base::mac::SetOverrideFrameworkBundlePath(
|
||||||
brightray::MainApplicationBundlePath()
|
brightray::MainApplicationBundlePath()
|
||||||
.Append("Contents")
|
.Append("Contents")
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "atom/app/atom_main_delegate.h"
|
#include "atom/app/atom_main_delegate.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "atom/app/atom_content_client.h"
|
#include "atom/app/atom_content_client.h"
|
||||||
#include "atom/browser/atom_browser_client.h"
|
#include "atom/browser/atom_browser_client.h"
|
||||||
|
@ -20,6 +21,15 @@
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool IsBrowserProcess(base::CommandLine* cmd) {
|
||||||
|
std::string process_type = cmd->GetSwitchValueASCII(switches::kProcessType);
|
||||||
|
return process_type.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
AtomMainDelegate::AtomMainDelegate() {
|
AtomMainDelegate::AtomMainDelegate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,8 +37,14 @@ AtomMainDelegate::~AtomMainDelegate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||||
|
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||||
|
|
||||||
logging::LoggingSettings settings;
|
logging::LoggingSettings settings;
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
|
// On Windows the terminal returns immediately, so we add a new line to
|
||||||
|
// prevent output in the same line as the prompt.
|
||||||
|
if (IsBrowserProcess(command_line))
|
||||||
|
std::wcout << std::endl;
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
// Print logging to debug.log on Windows
|
// Print logging to debug.log on Windows
|
||||||
settings.logging_dest = logging::LOG_TO_ALL;
|
settings.logging_dest = logging::LOG_TO_ALL;
|
||||||
|
@ -43,19 +59,25 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||||
#endif // !defined(OS_WIN)
|
#endif // !defined(OS_WIN)
|
||||||
|
|
||||||
// Only enable logging when --enable-logging is specified.
|
// Only enable logging when --enable-logging is specified.
|
||||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
scoped_ptr<base::Environment> env(base::Environment::Create());
|
||||||
if (!command_line->HasSwitch(switches::kEnableLogging))
|
if (!command_line->HasSwitch(switches::kEnableLogging) &&
|
||||||
|
!env->HasVar("ELECTRON_ENABLE_LOGGING")) {
|
||||||
settings.logging_dest = logging::LOG_NONE;
|
settings.logging_dest = logging::LOG_NONE;
|
||||||
|
logging::SetMinLogLevel(logging::LOG_NUM_SEVERITIES);
|
||||||
|
}
|
||||||
|
|
||||||
logging::InitLogging(settings);
|
logging::InitLogging(settings);
|
||||||
|
|
||||||
// Logging with pid and timestamp.
|
// Logging with pid and timestamp.
|
||||||
logging::SetLogItems(true, false, true, false);
|
logging::SetLogItems(true, false, true, false);
|
||||||
|
|
||||||
#if defined(DEBUG) && defined(OS_LINUX)
|
|
||||||
// Enable convient stack printing.
|
// Enable convient stack printing.
|
||||||
base::debug::EnableInProcessStackDumping();
|
bool enable_stack_dumping = env->HasVar("ELECTRON_ENABLE_STACK_DUMPING");
|
||||||
|
#if defined(DEBUG) && defined(OS_LINUX)
|
||||||
|
enable_stack_dumping = true;
|
||||||
#endif
|
#endif
|
||||||
|
if (enable_stack_dumping)
|
||||||
|
base::debug::EnableInProcessStackDumping();
|
||||||
|
|
||||||
return brightray::MainDelegate::BasicStartupComplete(exit_code);
|
return brightray::MainDelegate::BasicStartupComplete(exit_code);
|
||||||
}
|
}
|
||||||
|
@ -77,16 +99,9 @@ void AtomMainDelegate::PreSandboxStartup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only append arguments for browser process.
|
// Only append arguments for browser process.
|
||||||
if (!process_type.empty())
|
if (!IsBrowserProcess(command_line))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
// Disable the LegacyRenderWidgetHostHWND, it made frameless windows unable
|
|
||||||
// to move and resize. We may consider enabling it again after upgraded to
|
|
||||||
// Chrome 38, which should have fixed the problem.
|
|
||||||
command_line->AppendSwitch(switches::kDisableLegacyIntermediateWindow);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Disable renderer sandbox for most of node's functions.
|
// Disable renderer sandbox for most of node's functions.
|
||||||
command_line->AppendSwitch(switches::kNoSandbox);
|
command_line->AppendSwitch(switches::kNoSandbox);
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
#include "atom/app/uv_task_runner.h"
|
#include "atom/app/uv_task_runner.h"
|
||||||
#include "atom/browser/javascript_environment.h"
|
#include "atom/browser/javascript_environment.h"
|
||||||
#include "atom/browser/node_debugger.h"
|
#include "atom/browser/node_debugger.h"
|
||||||
#include "atom/common/node_includes.h"
|
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
|
#include "atom/common/node_includes.h"
|
||||||
#include "base/thread_task_runner_handle.h"
|
#include "base/thread_task_runner_handle.h"
|
||||||
#include "gin/array_buffer.h"
|
#include "gin/array_buffer.h"
|
||||||
#include "gin/public/isolate_holder.h"
|
#include "gin/public/isolate_holder.h"
|
||||||
|
@ -19,25 +19,22 @@ namespace atom {
|
||||||
int NodeMain(int argc, char *argv[]) {
|
int NodeMain(int argc, char *argv[]) {
|
||||||
base::CommandLine::Init(argc, argv);
|
base::CommandLine::Init(argc, argv);
|
||||||
|
|
||||||
argv = uv_setup_args(argc, argv);
|
|
||||||
int exec_argc;
|
|
||||||
const char** exec_argv;
|
|
||||||
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
|
|
||||||
|
|
||||||
int exit_code = 1;
|
int exit_code = 1;
|
||||||
{
|
{
|
||||||
// Feed gin::PerIsolateData with a task runner.
|
// Feed gin::PerIsolateData with a task runner.
|
||||||
|
argv = uv_setup_args(argc, argv);
|
||||||
uv_loop_t* loop = uv_default_loop();
|
uv_loop_t* loop = uv_default_loop();
|
||||||
scoped_refptr<UvTaskRunner> uv_task_runner(new UvTaskRunner(loop));
|
scoped_refptr<UvTaskRunner> uv_task_runner(new UvTaskRunner(loop));
|
||||||
base::ThreadTaskRunnerHandle handle(uv_task_runner);
|
base::ThreadTaskRunnerHandle handle(uv_task_runner);
|
||||||
|
|
||||||
gin::V8Initializer::LoadV8Snapshot();
|
gin::V8Initializer::LoadV8Snapshot();
|
||||||
gin::V8Initializer::LoadV8Natives();
|
gin::V8Initializer::LoadV8Natives();
|
||||||
gin::IsolateHolder::Initialize(
|
|
||||||
gin::IsolateHolder::kNonStrictMode,
|
|
||||||
gin::ArrayBufferAllocator::SharedInstance());
|
|
||||||
|
|
||||||
JavascriptEnvironment gin_env;
|
JavascriptEnvironment gin_env;
|
||||||
|
|
||||||
|
int exec_argc;
|
||||||
|
const char** exec_argv;
|
||||||
|
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
|
||||||
|
|
||||||
node::Environment* env = node::CreateEnvironment(
|
node::Environment* env = node::CreateEnvironment(
|
||||||
gin_env.isolate(), loop, gin_env.context(), argc, argv,
|
gin_env.isolate(), loop, gin_env.context(), argc, argv,
|
||||||
exec_argc, exec_argv);
|
exec_argc, exec_argv);
|
||||||
|
|
|
@ -48,8 +48,13 @@ void UvTaskRunner::OnTimeout(uv_timer_t* timer) {
|
||||||
|
|
||||||
self->tasks_[timer].Run();
|
self->tasks_[timer].Run();
|
||||||
self->tasks_.erase(timer);
|
self->tasks_.erase(timer);
|
||||||
uv_unref(reinterpret_cast<uv_handle_t*>(timer));
|
uv_timer_stop(timer);
|
||||||
delete timer;
|
uv_close(reinterpret_cast<uv_handle_t*>(timer), UvTaskRunner::OnClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void UvTaskRunner::OnClose(uv_handle_t* handle) {
|
||||||
|
delete reinterpret_cast<uv_timer_t*>(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
|
@ -31,6 +31,7 @@ class UvTaskRunner : public base::SingleThreadTaskRunner {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void OnTimeout(uv_timer_t* timer);
|
static void OnTimeout(uv_timer_t* timer);
|
||||||
|
static void OnClose(uv_handle_t* handle);
|
||||||
|
|
||||||
uv_loop_t* loop_;
|
uv_loop_t* loop_;
|
||||||
|
|
||||||
|
|
|
@ -7,19 +7,18 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
#include <shlobj.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "atom/browser/api/atom_api_menu.h"
|
#include "atom/browser/api/atom_api_menu.h"
|
||||||
#include "atom/browser/api/atom_api_session.h"
|
#include "atom/browser/api/atom_api_session.h"
|
||||||
|
#include "atom/browser/api/atom_api_web_contents.h"
|
||||||
#include "atom/browser/atom_browser_context.h"
|
#include "atom/browser/atom_browser_context.h"
|
||||||
#include "atom/browser/atom_browser_main_parts.h"
|
#include "atom/browser/atom_browser_main_parts.h"
|
||||||
#include "atom/browser/browser.h"
|
#include "atom/browser/browser.h"
|
||||||
#include "atom/browser/api/atom_api_web_contents.h"
|
#include "atom/browser/login_handler.h"
|
||||||
#include "atom/common/native_mate_converters/callback.h"
|
#include "atom/common/native_mate_converters/callback.h"
|
||||||
|
#include "atom/common/native_mate_converters/net_converter.h"
|
||||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
|
#include "atom/common/options_switches.h"
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
#include "base/environment.h"
|
#include "base/environment.h"
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
|
@ -27,6 +26,7 @@
|
||||||
#include "brightray/browser/brightray_paths.h"
|
#include "brightray/browser/brightray_paths.h"
|
||||||
#include "content/public/browser/client_certificate_delegate.h"
|
#include "content/public/browser/client_certificate_delegate.h"
|
||||||
#include "content/public/browser/gpu_data_manager.h"
|
#include "content/public/browser/gpu_data_manager.h"
|
||||||
|
#include "content/public/common/content_switches.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "native_mate/object_template_builder.h"
|
#include "native_mate/object_template_builder.h"
|
||||||
#include "net/ssl/ssl_cert_request_info.h"
|
#include "net/ssl/ssl_cert_request_info.h"
|
||||||
|
@ -109,12 +109,27 @@ int GetPathConstant(const std::string& name) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NotificationCallbackWrapper(
|
||||||
|
const ProcessSingleton::NotificationCallback& callback,
|
||||||
|
const base::CommandLine::StringVector& cmd,
|
||||||
|
const base::FilePath& cwd) {
|
||||||
|
// Make sure the callback is called after app gets ready.
|
||||||
|
if (Browser::Get()->is_ready()) {
|
||||||
|
callback.Run(cmd, cwd);
|
||||||
|
} else {
|
||||||
|
scoped_refptr<base::SingleThreadTaskRunner> task_runner(
|
||||||
|
base::ThreadTaskRunnerHandle::Get());
|
||||||
|
task_runner->PostTask(
|
||||||
|
FROM_HERE, base::Bind(base::IgnoreResult(callback), cmd, cwd));
|
||||||
|
}
|
||||||
|
// ProcessSingleton needs to know whether current process is quiting.
|
||||||
|
return !Browser::Get()->is_shutting_down();
|
||||||
|
}
|
||||||
|
|
||||||
void OnClientCertificateSelected(
|
void OnClientCertificateSelected(
|
||||||
v8::Isolate* isolate,
|
v8::Isolate* isolate,
|
||||||
std::shared_ptr<content::ClientCertificateDelegate> delegate,
|
std::shared_ptr<content::ClientCertificateDelegate> delegate,
|
||||||
mate::Arguments* args) {
|
mate::Arguments* args) {
|
||||||
v8::Locker locker(isolate);
|
|
||||||
v8::HandleScope handle_scope(isolate);
|
|
||||||
mate::Dictionary cert_data;
|
mate::Dictionary cert_data;
|
||||||
if (!(args->Length() == 1 && args->GetNext(&cert_data))) {
|
if (!(args->Length() == 1 && args->GetNext(&cert_data))) {
|
||||||
args->ThrowError();
|
args->ThrowError();
|
||||||
|
@ -128,10 +143,18 @@ void OnClientCertificateSelected(
|
||||||
net::X509Certificate::CreateCertificateListFromBytes(
|
net::X509Certificate::CreateCertificateListFromBytes(
|
||||||
encoded_data.data(), encoded_data.size(),
|
encoded_data.data(), encoded_data.size(),
|
||||||
net::X509Certificate::FORMAT_AUTO);
|
net::X509Certificate::FORMAT_AUTO);
|
||||||
|
|
||||||
delegate->ContinueWithCertificate(certs[0].get());
|
delegate->ContinueWithCertificate(certs[0].get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PassLoginInformation(scoped_refptr<LoginHandler> login_handler,
|
||||||
|
mate::Arguments* args) {
|
||||||
|
base::string16 username, password;
|
||||||
|
if (args->GetNext(&username) && args->GetNext(&password))
|
||||||
|
login_handler->Login(username, password);
|
||||||
|
else
|
||||||
|
login_handler->CancelAuth();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
App::App() {
|
App::App() {
|
||||||
|
@ -158,6 +181,11 @@ void App::OnWindowAllClosed() {
|
||||||
|
|
||||||
void App::OnQuit() {
|
void App::OnQuit() {
|
||||||
Emit("quit");
|
Emit("quit");
|
||||||
|
|
||||||
|
if (process_singleton_.get()) {
|
||||||
|
process_singleton_->Cleanup();
|
||||||
|
process_singleton_.reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::OnOpenFile(bool* prevent_default, const std::string& file_path) {
|
void App::OnOpenFile(bool* prevent_default, const std::string& file_path) {
|
||||||
|
@ -209,6 +237,31 @@ void App::OnSelectCertificate(
|
||||||
cert_request_info->client_certs[0].get());
|
cert_request_info->client_certs[0].get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void App::OnLogin(LoginHandler* login_handler) {
|
||||||
|
// Convert the args explicitly since they will be passed for twice.
|
||||||
|
v8::Locker locker(isolate());
|
||||||
|
v8::HandleScope handle_scope(isolate());
|
||||||
|
auto web_contents =
|
||||||
|
WebContents::CreateFrom(isolate(), login_handler->GetWebContents());
|
||||||
|
auto request = mate::ConvertToV8(isolate(), login_handler->request());
|
||||||
|
auto auth_info = mate::ConvertToV8(isolate(), login_handler->auth_info());
|
||||||
|
auto callback = mate::ConvertToV8(
|
||||||
|
isolate(),
|
||||||
|
base::Bind(&PassLoginInformation, make_scoped_refptr(login_handler)));
|
||||||
|
|
||||||
|
bool prevent_default =
|
||||||
|
Emit("login", web_contents, request, auth_info, callback);
|
||||||
|
|
||||||
|
// Also pass it to WebContents.
|
||||||
|
if (!prevent_default)
|
||||||
|
prevent_default =
|
||||||
|
web_contents->Emit("login", request, auth_info, callback);
|
||||||
|
|
||||||
|
// Default behavior is to always cancel the auth.
|
||||||
|
if (!prevent_default)
|
||||||
|
login_handler->CancelAuth();
|
||||||
|
}
|
||||||
|
|
||||||
void App::OnGpuProcessCrashed(base::TerminationStatus exit_code) {
|
void App::OnGpuProcessCrashed(base::TerminationStatus exit_code) {
|
||||||
Emit("gpu-process-crashed");
|
Emit("gpu-process-crashed");
|
||||||
}
|
}
|
||||||
|
@ -242,11 +295,10 @@ void App::SetDesktopName(const std::string& desktop_name) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::SetAppUserModelId(const std::string& app_id) {
|
void App::AllowNTLMCredentialsForAllDomains(bool should_allow) {
|
||||||
#if defined(OS_WIN)
|
auto browser_context = static_cast<AtomBrowserContext*>(
|
||||||
base::string16 app_id_utf16 = base::UTF8ToUTF16(app_id);
|
AtomBrowserMainParts::Get()->browser_context());
|
||||||
SetCurrentProcessExplicitAppUserModelID(app_id_utf16.c_str());
|
browser_context->AllowNTLMCredentialsForAllDomains(should_allow);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string App::GetLocale() {
|
std::string App::GetLocale() {
|
||||||
|
@ -260,11 +312,34 @@ v8::Local<v8::Value> App::DefaultSession(v8::Isolate* isolate) {
|
||||||
return v8::Local<v8::Value>::New(isolate, default_session_);
|
return v8::Local<v8::Value>::New(isolate, default_session_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool App::MakeSingleInstance(
|
||||||
|
const ProcessSingleton::NotificationCallback& callback) {
|
||||||
|
if (process_singleton_.get())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
base::FilePath user_dir;
|
||||||
|
PathService::Get(brightray::DIR_USER_DATA, &user_dir);
|
||||||
|
process_singleton_.reset(new ProcessSingleton(
|
||||||
|
user_dir, base::Bind(NotificationCallbackWrapper, callback)));
|
||||||
|
|
||||||
|
switch (process_singleton_->NotifyOtherProcessOrCreate()) {
|
||||||
|
case ProcessSingleton::NotifyResult::LOCK_ERROR:
|
||||||
|
case ProcessSingleton::NotifyResult::PROFILE_IN_USE:
|
||||||
|
case ProcessSingleton::NotifyResult::PROCESS_NOTIFIED:
|
||||||
|
process_singleton_.reset();
|
||||||
|
return true;
|
||||||
|
case ProcessSingleton::NotifyResult::PROCESS_NONE:
|
||||||
|
default: // Shouldn't be needed, but VS warns if it is not there.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
|
mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
|
||||||
v8::Isolate* isolate) {
|
v8::Isolate* isolate) {
|
||||||
auto browser = base::Unretained(Browser::Get());
|
auto browser = base::Unretained(Browser::Get());
|
||||||
return mate::ObjectTemplateBuilder(isolate)
|
return mate::ObjectTemplateBuilder(isolate)
|
||||||
.SetMethod("quit", base::Bind(&Browser::Quit, browser))
|
.SetMethod("quit", base::Bind(&Browser::Quit, browser))
|
||||||
|
.SetMethod("exit", base::Bind(&Browser::Exit, browser))
|
||||||
.SetMethod("focus", base::Bind(&Browser::Focus, browser))
|
.SetMethod("focus", base::Bind(&Browser::Focus, browser))
|
||||||
.SetMethod("getVersion", base::Bind(&Browser::GetVersion, browser))
|
.SetMethod("getVersion", base::Bind(&Browser::GetVersion, browser))
|
||||||
.SetMethod("setVersion", base::Bind(&Browser::SetVersion, browser))
|
.SetMethod("setVersion", base::Bind(&Browser::SetVersion, browser))
|
||||||
|
@ -275,6 +350,8 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
|
||||||
base::Bind(&Browser::AddRecentDocument, browser))
|
base::Bind(&Browser::AddRecentDocument, browser))
|
||||||
.SetMethod("clearRecentDocuments",
|
.SetMethod("clearRecentDocuments",
|
||||||
base::Bind(&Browser::ClearRecentDocuments, browser))
|
base::Bind(&Browser::ClearRecentDocuments, browser))
|
||||||
|
.SetMethod("setAppUserModelId",
|
||||||
|
base::Bind(&Browser::SetAppUserModelID, browser))
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
.SetMethod("setUserTasks",
|
.SetMethod("setUserTasks",
|
||||||
base::Bind(&Browser::SetUserTasks, browser))
|
base::Bind(&Browser::SetUserTasks, browser))
|
||||||
|
@ -282,8 +359,10 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder(
|
||||||
.SetMethod("setPath", &App::SetPath)
|
.SetMethod("setPath", &App::SetPath)
|
||||||
.SetMethod("getPath", &App::GetPath)
|
.SetMethod("getPath", &App::GetPath)
|
||||||
.SetMethod("setDesktopName", &App::SetDesktopName)
|
.SetMethod("setDesktopName", &App::SetDesktopName)
|
||||||
.SetMethod("setAppUserModelId", &App::SetAppUserModelId)
|
.SetMethod("allowNTLMCredentialsForAllDomains",
|
||||||
|
&App::AllowNTLMCredentialsForAllDomains)
|
||||||
.SetMethod("getLocale", &App::GetLocale)
|
.SetMethod("getLocale", &App::GetLocale)
|
||||||
|
.SetMethod("makeSingleInstance", &App::MakeSingleInstance)
|
||||||
.SetProperty("defaultSession", &App::DefaultSession);
|
.SetProperty("defaultSession", &App::DefaultSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,6 +380,16 @@ namespace {
|
||||||
|
|
||||||
void AppendSwitch(const std::string& switch_string, mate::Arguments* args) {
|
void AppendSwitch(const std::string& switch_string, mate::Arguments* args) {
|
||||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||||
|
|
||||||
|
if (switch_string == atom::switches::kPpapiFlashPath ||
|
||||||
|
switch_string == atom::switches::kClientCertificate ||
|
||||||
|
switch_string == switches::kLogNetLog) {
|
||||||
|
base::FilePath path;
|
||||||
|
args->GetNext(&path);
|
||||||
|
command_line->AppendSwitchPath(switch_string, path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::string value;
|
std::string value;
|
||||||
if (args->GetNext(&value))
|
if (args->GetNext(&value))
|
||||||
command_line->AppendSwitchASCII(switch_string, value);
|
command_line->AppendSwitchASCII(switch_string, value);
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#include "atom/browser/api/event_emitter.h"
|
#include "atom/browser/api/event_emitter.h"
|
||||||
#include "atom/browser/browser_observer.h"
|
#include "atom/browser/browser_observer.h"
|
||||||
|
#include "atom/common/native_mate_converters/callback.h"
|
||||||
|
#include "chrome/browser/process_singleton.h"
|
||||||
#include "content/public/browser/gpu_data_manager_observer.h"
|
#include "content/public/browser/gpu_data_manager_observer.h"
|
||||||
#include "native_mate/handle.h"
|
#include "native_mate/handle.h"
|
||||||
|
|
||||||
|
@ -48,6 +50,7 @@ class App : public mate::EventEmitter,
|
||||||
content::WebContents* web_contents,
|
content::WebContents* web_contents,
|
||||||
net::SSLCertRequestInfo* cert_request_info,
|
net::SSLCertRequestInfo* cert_request_info,
|
||||||
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
|
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
|
||||||
|
void OnLogin(LoginHandler* login_handler) override;
|
||||||
|
|
||||||
// content::GpuDataManagerObserver:
|
// content::GpuDataManagerObserver:
|
||||||
void OnGpuProcessCrashed(base::TerminationStatus exit_code) override;
|
void OnGpuProcessCrashed(base::TerminationStatus exit_code) override;
|
||||||
|
@ -64,12 +67,16 @@ class App : public mate::EventEmitter,
|
||||||
const base::FilePath& path);
|
const base::FilePath& path);
|
||||||
|
|
||||||
void SetDesktopName(const std::string& desktop_name);
|
void SetDesktopName(const std::string& desktop_name);
|
||||||
void SetAppUserModelId(const std::string& app_id);
|
void AllowNTLMCredentialsForAllDomains(bool should_allow);
|
||||||
|
bool MakeSingleInstance(
|
||||||
|
const ProcessSingleton::NotificationCallback& callback);
|
||||||
std::string GetLocale();
|
std::string GetLocale();
|
||||||
v8::Local<v8::Value> DefaultSession(v8::Isolate* isolate);
|
v8::Local<v8::Value> DefaultSession(v8::Isolate* isolate);
|
||||||
|
|
||||||
v8::Global<v8::Value> default_session_;
|
v8::Global<v8::Value> default_session_;
|
||||||
|
|
||||||
|
scoped_ptr<ProcessSingleton> process_singleton_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(App);
|
DISALLOW_COPY_AND_ASSIGN(App);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,31 @@
|
||||||
#include "atom/browser/api/atom_api_auto_updater.h"
|
#include "atom/browser/api/atom_api_auto_updater.h"
|
||||||
|
|
||||||
#include "base/time/time.h"
|
#include "base/time/time.h"
|
||||||
#include "atom/browser/auto_updater.h"
|
|
||||||
#include "atom/browser/browser.h"
|
#include "atom/browser/browser.h"
|
||||||
|
#include "atom/browser/native_window.h"
|
||||||
|
#include "atom/browser/window_list.h"
|
||||||
|
#include "atom/common/native_mate_converters/callback.h"
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "native_mate/object_template_builder.h"
|
#include "native_mate/object_template_builder.h"
|
||||||
|
|
||||||
|
namespace mate {
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<base::Time> {
|
||||||
|
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||||
|
const base::Time& val) {
|
||||||
|
v8::MaybeLocal<v8::Value> date = v8::Date::New(
|
||||||
|
isolate->GetCurrentContext(), val.ToJsTime());
|
||||||
|
if (date.IsEmpty())
|
||||||
|
return v8::Null(isolate);
|
||||||
|
else
|
||||||
|
return date.ToLocalChecked();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mate
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
@ -20,11 +39,18 @@ AutoUpdater::AutoUpdater() {
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoUpdater::~AutoUpdater() {
|
AutoUpdater::~AutoUpdater() {
|
||||||
auto_updater::AutoUpdater::SetDelegate(NULL);
|
auto_updater::AutoUpdater::SetDelegate(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoUpdater::OnError(const std::string& error) {
|
void AutoUpdater::OnError(const std::string& message) {
|
||||||
Emit("error", error);
|
v8::Locker locker(isolate());
|
||||||
|
v8::HandleScope handle_scope(isolate());
|
||||||
|
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
|
||||||
|
EmitCustomEvent(
|
||||||
|
"error",
|
||||||
|
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked(),
|
||||||
|
// Message is also emitted to keep compatibility with old code.
|
||||||
|
message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoUpdater::OnCheckingForUpdate() {
|
void AutoUpdater::OnCheckingForUpdate() {
|
||||||
|
@ -42,11 +68,14 @@ void AutoUpdater::OnUpdateNotAvailable() {
|
||||||
void AutoUpdater::OnUpdateDownloaded(const std::string& release_notes,
|
void AutoUpdater::OnUpdateDownloaded(const std::string& release_notes,
|
||||||
const std::string& release_name,
|
const std::string& release_name,
|
||||||
const base::Time& release_date,
|
const base::Time& release_date,
|
||||||
const std::string& update_url,
|
const std::string& url) {
|
||||||
const base::Closure& quit_and_install) {
|
Emit("update-downloaded", release_notes, release_name, release_date, url,
|
||||||
quit_and_install_ = quit_and_install;
|
// Keep compatibility with old APIs.
|
||||||
Emit("update-downloaded-raw", release_notes, release_name,
|
base::Bind(&AutoUpdater::QuitAndInstall, base::Unretained(this)));
|
||||||
release_date.ToJsTime(), update_url);
|
}
|
||||||
|
|
||||||
|
void AutoUpdater::OnWindowAllClosed() {
|
||||||
|
QuitAndInstall();
|
||||||
}
|
}
|
||||||
|
|
||||||
mate::ObjectTemplateBuilder AutoUpdater::GetObjectTemplateBuilder(
|
mate::ObjectTemplateBuilder AutoUpdater::GetObjectTemplateBuilder(
|
||||||
|
@ -54,14 +83,21 @@ mate::ObjectTemplateBuilder AutoUpdater::GetObjectTemplateBuilder(
|
||||||
return mate::ObjectTemplateBuilder(isolate)
|
return mate::ObjectTemplateBuilder(isolate)
|
||||||
.SetMethod("setFeedUrl", &auto_updater::AutoUpdater::SetFeedURL)
|
.SetMethod("setFeedUrl", &auto_updater::AutoUpdater::SetFeedURL)
|
||||||
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
|
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
|
||||||
.SetMethod("_quitAndInstall", &AutoUpdater::QuitAndInstall);
|
.SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoUpdater::QuitAndInstall() {
|
void AutoUpdater::QuitAndInstall() {
|
||||||
if (quit_and_install_.is_null())
|
// If we don't have any window then quitAndInstall immediately.
|
||||||
Browser::Get()->Shutdown();
|
WindowList* window_list = WindowList::GetInstance();
|
||||||
else
|
if (window_list->size() == 0) {
|
||||||
quit_and_install_.Run();
|
auto_updater::AutoUpdater::QuitAndInstall();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise do the restart after all windows have been closed.
|
||||||
|
window_list->AddObserver(this);
|
||||||
|
for (NativeWindow* window : *window_list)
|
||||||
|
window->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "base/callback.h"
|
|
||||||
#include "atom/browser/api/event_emitter.h"
|
#include "atom/browser/api/event_emitter.h"
|
||||||
#include "atom/browser/auto_updater_delegate.h"
|
#include "atom/browser/auto_updater.h"
|
||||||
|
#include "atom/browser/window_list_observer.h"
|
||||||
#include "native_mate/handle.h"
|
#include "native_mate/handle.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
@ -17,7 +17,8 @@ namespace atom {
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
class AutoUpdater : public mate::EventEmitter,
|
class AutoUpdater : public mate::EventEmitter,
|
||||||
public auto_updater::AutoUpdaterDelegate {
|
public auto_updater::Delegate,
|
||||||
|
public WindowListObserver {
|
||||||
public:
|
public:
|
||||||
static mate::Handle<AutoUpdater> Create(v8::Isolate* isolate);
|
static mate::Handle<AutoUpdater> Create(v8::Isolate* isolate);
|
||||||
|
|
||||||
|
@ -25,17 +26,18 @@ class AutoUpdater : public mate::EventEmitter,
|
||||||
AutoUpdater();
|
AutoUpdater();
|
||||||
virtual ~AutoUpdater();
|
virtual ~AutoUpdater();
|
||||||
|
|
||||||
// AutoUpdaterDelegate implementations.
|
// Delegate implementations.
|
||||||
void OnError(const std::string& error) override;
|
void OnError(const std::string& error) override;
|
||||||
void OnCheckingForUpdate() override;
|
void OnCheckingForUpdate() override;
|
||||||
void OnUpdateAvailable() override;
|
void OnUpdateAvailable() override;
|
||||||
void OnUpdateNotAvailable() override;
|
void OnUpdateNotAvailable() override;
|
||||||
void OnUpdateDownloaded(
|
void OnUpdateDownloaded(const std::string& release_notes,
|
||||||
const std::string& release_notes,
|
const std::string& release_name,
|
||||||
const std::string& release_name,
|
const base::Time& release_date,
|
||||||
const base::Time& release_date,
|
const std::string& update_url) override;
|
||||||
const std::string& update_url,
|
|
||||||
const base::Closure& quit_and_install) override;
|
// WindowListObserver:
|
||||||
|
void OnWindowAllClosed() override;
|
||||||
|
|
||||||
// mate::Wrappable implementations:
|
// mate::Wrappable implementations:
|
||||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||||
|
@ -44,8 +46,6 @@ class AutoUpdater : public mate::EventEmitter,
|
||||||
private:
|
private:
|
||||||
void QuitAndInstall();
|
void QuitAndInstall();
|
||||||
|
|
||||||
base::Closure quit_and_install_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AutoUpdater);
|
DISALLOW_COPY_AND_ASSIGN(AutoUpdater);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include "atom/browser/atom_browser_main_parts.h"
|
||||||
#include "atom/common/native_mate_converters/callback.h"
|
#include "atom/common/native_mate_converters/callback.h"
|
||||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||||
|
@ -159,14 +160,6 @@ mate::ObjectTemplateBuilder DownloadItem::GetObjectTemplateBuilder(
|
||||||
.SetMethod("setSavePath", &DownloadItem::SetSavePath);
|
.SetMethod("setSavePath", &DownloadItem::SetSavePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetWrapDownloadItem(const WrapDownloadItemCallback& callback) {
|
|
||||||
g_wrap_download_item = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearWrapDownloadItem() {
|
|
||||||
g_wrap_download_item.Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
mate::Handle<DownloadItem> DownloadItem::Create(
|
mate::Handle<DownloadItem> DownloadItem::Create(
|
||||||
v8::Isolate* isolate, content::DownloadItem* item) {
|
v8::Isolate* isolate, content::DownloadItem* item) {
|
||||||
|
@ -182,6 +175,18 @@ void* DownloadItem::UserDataKey() {
|
||||||
return &kDownloadItemSavePathKey;
|
return &kDownloadItemSavePathKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClearWrapDownloadItem() {
|
||||||
|
g_wrap_download_item.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetWrapDownloadItem(const WrapDownloadItemCallback& callback) {
|
||||||
|
g_wrap_download_item = callback;
|
||||||
|
|
||||||
|
// Cleanup the wrapper on exit.
|
||||||
|
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
|
||||||
|
base::Bind(ClearWrapDownloadItem));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
@ -193,7 +198,6 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
mate::Dictionary dict(isolate, exports);
|
mate::Dictionary dict(isolate, exports);
|
||||||
dict.SetMethod("_setWrapDownloadItem", &atom::api::SetWrapDownloadItem);
|
dict.SetMethod("_setWrapDownloadItem", &atom::api::SetWrapDownloadItem);
|
||||||
dict.SetMethod("_clearWrapDownloadItem", &atom::api::ClearWrapDownloadItem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -23,6 +23,9 @@ GlobalShortcut::GlobalShortcut() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalShortcut::~GlobalShortcut() {
|
GlobalShortcut::~GlobalShortcut() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalShortcut::Destroy() {
|
||||||
UnregisterAll();
|
UnregisterAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "atom/browser/api/trackable_object.h"
|
||||||
#include "base/callback.h"
|
#include "base/callback.h"
|
||||||
#include "chrome/browser/extensions/global_shortcut_listener.h"
|
#include "chrome/browser/extensions/global_shortcut_listener.h"
|
||||||
#include "native_mate/wrappable.h"
|
|
||||||
#include "native_mate/handle.h"
|
#include "native_mate/handle.h"
|
||||||
#include "ui/base/accelerators/accelerator.h"
|
#include "ui/base/accelerators/accelerator.h"
|
||||||
|
|
||||||
|
@ -19,13 +19,16 @@ namespace atom {
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
|
class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
|
||||||
public mate::Wrappable {
|
public mate::TrackableObject<GlobalShortcut> {
|
||||||
public:
|
public:
|
||||||
static mate::Handle<GlobalShortcut> Create(v8::Isolate* isolate);
|
static mate::Handle<GlobalShortcut> Create(v8::Isolate* isolate);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GlobalShortcut();
|
GlobalShortcut();
|
||||||
virtual ~GlobalShortcut();
|
~GlobalShortcut() override;
|
||||||
|
|
||||||
|
// mate::TrackableObject:
|
||||||
|
void Destroy() override;
|
||||||
|
|
||||||
// mate::Wrappable implementations:
|
// mate::Wrappable implementations:
|
||||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||||
|
|
|
@ -27,6 +27,14 @@ Menu::Menu()
|
||||||
Menu::~Menu() {
|
Menu::~Menu() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Menu::Destroy() {
|
||||||
|
model_.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Menu::IsDestroyed() const {
|
||||||
|
return !model_;
|
||||||
|
}
|
||||||
|
|
||||||
void Menu::AfterInit(v8::Isolate* isolate) {
|
void Menu::AfterInit(v8::Isolate* isolate) {
|
||||||
mate::Dictionary wrappable(isolate, GetWrapper(isolate));
|
mate::Dictionary wrappable(isolate, GetWrapper(isolate));
|
||||||
mate::Dictionary delegate;
|
mate::Dictionary delegate;
|
||||||
|
|
|
@ -8,16 +8,16 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "atom/browser/api/atom_api_window.h"
|
#include "atom/browser/api/atom_api_window.h"
|
||||||
|
#include "atom/browser/api/trackable_object.h"
|
||||||
#include "atom/browser/ui/atom_menu_model.h"
|
#include "atom/browser/ui/atom_menu_model.h"
|
||||||
#include "base/callback.h"
|
#include "base/callback.h"
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
#include "native_mate/wrappable.h"
|
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
class Menu : public mate::Wrappable,
|
class Menu : public mate::TrackableObject<Menu>,
|
||||||
public AtomMenuModel::Delegate {
|
public AtomMenuModel::Delegate {
|
||||||
public:
|
public:
|
||||||
static mate::Wrappable* Create();
|
static mate::Wrappable* Create();
|
||||||
|
@ -37,9 +37,13 @@ class Menu : public mate::Wrappable,
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Menu();
|
Menu();
|
||||||
virtual ~Menu();
|
~Menu() override;
|
||||||
|
|
||||||
|
// mate::TrackableObject:
|
||||||
|
void Destroy() override;
|
||||||
|
|
||||||
// mate::Wrappable:
|
// mate::Wrappable:
|
||||||
|
bool IsDestroyed() const override;
|
||||||
void AfterInit(v8::Isolate* isolate) override;
|
void AfterInit(v8::Isolate* isolate) override;
|
||||||
|
|
||||||
// ui::SimpleMenuModel::Delegate:
|
// ui::SimpleMenuModel::Delegate:
|
||||||
|
|
|
@ -19,6 +19,7 @@ class MenuMac : public Menu {
|
||||||
protected:
|
protected:
|
||||||
MenuMac();
|
MenuMac();
|
||||||
|
|
||||||
|
void Destroy() override;
|
||||||
void Popup(Window* window) override;
|
void Popup(Window* window) override;
|
||||||
void PopupAt(Window* window, int x, int y) override;
|
void PopupAt(Window* window, int x, int y) override;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,11 @@ namespace api {
|
||||||
MenuMac::MenuMac() {
|
MenuMac::MenuMac() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MenuMac::Destroy() {
|
||||||
|
menu_controller_.reset();
|
||||||
|
Menu::Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
void MenuMac::Popup(Window* window) {
|
void MenuMac::Popup(Window* window) {
|
||||||
NativeWindow* native_window = window->window();
|
NativeWindow* native_window = window->window();
|
||||||
if (!native_window)
|
if (!native_window)
|
||||||
|
|
|
@ -19,6 +19,9 @@ PowerMonitor::PowerMonitor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
PowerMonitor::~PowerMonitor() {
|
PowerMonitor::~PowerMonitor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerMonitor::Destroy() {
|
||||||
base::PowerMonitor::Get()->RemoveObserver(this);
|
base::PowerMonitor::Get()->RemoveObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#ifndef ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
#ifndef ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||||
#define ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
#define ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||||
|
|
||||||
#include "atom/browser/api/event_emitter.h"
|
#include "atom/browser/api/trackable_object.h"
|
||||||
#include "base/compiler_specific.h"
|
#include "base/compiler_specific.h"
|
||||||
#include "base/power_monitor/power_observer.h"
|
#include "base/power_monitor/power_observer.h"
|
||||||
#include "native_mate/handle.h"
|
#include "native_mate/handle.h"
|
||||||
|
@ -14,14 +14,17 @@ namespace atom {
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
class PowerMonitor : public mate::EventEmitter,
|
class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
|
||||||
public base::PowerObserver {
|
public base::PowerObserver {
|
||||||
public:
|
public:
|
||||||
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PowerMonitor();
|
PowerMonitor();
|
||||||
virtual ~PowerMonitor();
|
~PowerMonitor() override;
|
||||||
|
|
||||||
|
// mate::TrackableObject:
|
||||||
|
void Destroy() override;
|
||||||
|
|
||||||
// base::PowerObserver implementations:
|
// base::PowerObserver implementations:
|
||||||
void OnPowerStateChange(bool on_battery_power) override;
|
void OnPowerStateChange(bool on_battery_power) override;
|
||||||
|
|
|
@ -45,6 +45,11 @@ PowerSaveBlocker::PowerSaveBlocker()
|
||||||
PowerSaveBlocker::~PowerSaveBlocker() {
|
PowerSaveBlocker::~PowerSaveBlocker() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PowerSaveBlocker::Destroy() {
|
||||||
|
power_save_blocker_types_.clear();
|
||||||
|
power_save_blocker_.reset();
|
||||||
|
}
|
||||||
|
|
||||||
void PowerSaveBlocker::UpdatePowerSaveBlocker() {
|
void PowerSaveBlocker::UpdatePowerSaveBlocker() {
|
||||||
if (power_save_blocker_types_.empty()) {
|
if (power_save_blocker_types_.empty()) {
|
||||||
power_save_blocker_.reset();
|
power_save_blocker_.reset();
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include "atom/browser/api/trackable_object.h"
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
#include "content/public/browser/power_save_blocker.h"
|
#include "content/public/browser/power_save_blocker.h"
|
||||||
#include "native_mate/handle.h"
|
#include "native_mate/handle.h"
|
||||||
#include "native_mate/wrappable.h"
|
|
||||||
|
|
||||||
namespace mate {
|
namespace mate {
|
||||||
class Dictionary;
|
class Dictionary;
|
||||||
|
@ -20,13 +20,16 @@ namespace atom {
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
class PowerSaveBlocker : public mate::Wrappable {
|
class PowerSaveBlocker : public mate::TrackableObject<PowerSaveBlocker> {
|
||||||
public:
|
public:
|
||||||
static mate::Handle<PowerSaveBlocker> Create(v8::Isolate* isolate);
|
static mate::Handle<PowerSaveBlocker> Create(v8::Isolate* isolate);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PowerSaveBlocker();
|
PowerSaveBlocker();
|
||||||
virtual ~PowerSaveBlocker();
|
~PowerSaveBlocker() override;
|
||||||
|
|
||||||
|
// mate::TrackableObject:
|
||||||
|
void Destroy() override;
|
||||||
|
|
||||||
// mate::Wrappable implementations:
|
// mate::Wrappable implementations:
|
||||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||||
|
@ -48,7 +51,6 @@ class PowerSaveBlocker : public mate::Wrappable {
|
||||||
std::map<int, content::PowerSaveBlocker::PowerSaveBlockerType>;
|
std::map<int, content::PowerSaveBlocker::PowerSaveBlockerType>;
|
||||||
PowerSaveBlockerTypeMap power_save_blocker_types_;
|
PowerSaveBlockerTypeMap power_save_blocker_types_;
|
||||||
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker);
|
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,27 +12,12 @@
|
||||||
#include "atom/browser/net/url_request_fetch_job.h"
|
#include "atom/browser/net/url_request_fetch_job.h"
|
||||||
#include "atom/browser/net/url_request_string_job.h"
|
#include "atom/browser/net/url_request_string_job.h"
|
||||||
#include "atom/common/native_mate_converters/callback.h"
|
#include "atom/common/native_mate_converters/callback.h"
|
||||||
|
#include "atom/common/native_mate_converters/net_converter.h"
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
|
|
||||||
using content::BrowserThread;
|
using content::BrowserThread;
|
||||||
|
|
||||||
namespace mate {
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct Converter<const net::URLRequest*> {
|
|
||||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
|
||||||
const net::URLRequest* val) {
|
|
||||||
return mate::ObjectTemplateBuilder(isolate)
|
|
||||||
.SetValue("method", val->method())
|
|
||||||
.SetValue("url", val->url().spec())
|
|
||||||
.SetValue("referrer", val->referrer())
|
|
||||||
.Build()->NewInstance();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace mate
|
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
|
@ -9,8 +9,10 @@
|
||||||
|
|
||||||
#include "atom/browser/api/atom_api_cookies.h"
|
#include "atom/browser/api/atom_api_cookies.h"
|
||||||
#include "atom/browser/api/atom_api_download_item.h"
|
#include "atom/browser/api/atom_api_download_item.h"
|
||||||
#include "atom/browser/atom_browser_context.h"
|
|
||||||
#include "atom/browser/api/atom_api_web_contents.h"
|
#include "atom/browser/api/atom_api_web_contents.h"
|
||||||
|
#include "atom/browser/api/save_page_handler.h"
|
||||||
|
#include "atom/browser/atom_browser_context.h"
|
||||||
|
#include "atom/browser/atom_browser_main_parts.h"
|
||||||
#include "atom/common/native_mate_converters/callback.h"
|
#include "atom/common/native_mate_converters/callback.h"
|
||||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||||
|
@ -104,6 +106,24 @@ struct Converter<ClearStorageDataOptions> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<net::ProxyConfig> {
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::Value> val,
|
||||||
|
net::ProxyConfig* out) {
|
||||||
|
std::string proxy;
|
||||||
|
if (!ConvertFromV8(isolate, val, &proxy))
|
||||||
|
return false;
|
||||||
|
auto pac_url = GURL(proxy);
|
||||||
|
if (pac_url.is_valid()) {
|
||||||
|
out->set_pac_url(pac_url);
|
||||||
|
} else {
|
||||||
|
out->proxy_rules().ParseFromString(proxy);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace mate
|
} // namespace mate
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
@ -208,12 +228,12 @@ void ClearHttpCacheInIO(
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetProxyInIO(net::URLRequestContextGetter* getter,
|
void SetProxyInIO(net::URLRequestContextGetter* getter,
|
||||||
const std::string& proxy,
|
const net::ProxyConfig& config,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
net::ProxyConfig config;
|
|
||||||
config.proxy_rules().ParseFromString(proxy);
|
|
||||||
auto proxy_service = getter->GetURLRequestContext()->proxy_service();
|
auto proxy_service = getter->GetURLRequestContext()->proxy_service();
|
||||||
proxy_service->ResetConfigService(new net::ProxyConfigServiceFixed(config));
|
proxy_service->ResetConfigService(new net::ProxyConfigServiceFixed(config));
|
||||||
|
// Refetches and applies the new pac script if provided.
|
||||||
|
proxy_service->ForceReloadProxyConfig();
|
||||||
RunCallbackInUI(callback);
|
RunCallbackInUI(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,6 +257,8 @@ Session::~Session() {
|
||||||
void Session::OnDownloadCreated(content::DownloadManager* manager,
|
void Session::OnDownloadCreated(content::DownloadManager* manager,
|
||||||
content::DownloadItem* item) {
|
content::DownloadItem* item) {
|
||||||
auto web_contents = item->GetWebContents();
|
auto web_contents = item->GetWebContents();
|
||||||
|
if (SavePageHandler::IsSavePageTypes(item->GetMimeType()))
|
||||||
|
return;
|
||||||
bool prevent_default = Emit(
|
bool prevent_default = Emit(
|
||||||
"will-download",
|
"will-download",
|
||||||
DownloadItem::Create(isolate(), item),
|
DownloadItem::Create(isolate(), item),
|
||||||
|
@ -284,11 +306,11 @@ void Session::ClearStorageData(mate::Arguments* args) {
|
||||||
base::Time(), base::Time::Max(), callback);
|
base::Time(), base::Time::Max(), callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::SetProxy(const std::string& proxy,
|
void Session::SetProxy(const net::ProxyConfig& config,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
auto getter = browser_context_->GetRequestContext();
|
auto getter = browser_context_->GetRequestContext();
|
||||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(&SetProxyInIO, base::Unretained(getter), proxy, callback));
|
base::Bind(&SetProxyInIO, base::Unretained(getter), config, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::SetDownloadPath(const base::FilePath& path) {
|
void Session::SetDownloadPath(const base::FilePath& path) {
|
||||||
|
@ -374,14 +396,18 @@ mate::Handle<Session> Session::FromPartition(
|
||||||
static_cast<AtomBrowserContext*>(browser_context.get()));
|
static_cast<AtomBrowserContext*>(browser_context.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetWrapSession(const WrapSessionCallback& callback) {
|
|
||||||
g_wrap_session = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearWrapSession() {
|
void ClearWrapSession() {
|
||||||
g_wrap_session.Reset();
|
g_wrap_session.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetWrapSession(const WrapSessionCallback& callback) {
|
||||||
|
g_wrap_session = callback;
|
||||||
|
|
||||||
|
// Cleanup the wrapper on exit.
|
||||||
|
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
|
||||||
|
base::Bind(ClearWrapSession));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
@ -394,7 +420,6 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||||
mate::Dictionary dict(isolate, exports);
|
mate::Dictionary dict(isolate, exports);
|
||||||
dict.SetMethod("fromPartition", &atom::api::Session::FromPartition);
|
dict.SetMethod("fromPartition", &atom::api::Session::FromPartition);
|
||||||
dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession);
|
dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession);
|
||||||
dict.SetMethod("_clearWrapSession", &atom::api::ClearWrapSession);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -23,6 +23,10 @@ class Arguments;
|
||||||
class Dictionary;
|
class Dictionary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace net {
|
||||||
|
class ProxyConfig;
|
||||||
|
}
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
class AtomBrowserContext;
|
class AtomBrowserContext;
|
||||||
|
@ -64,7 +68,7 @@ class Session: public mate::TrackableObject<Session>,
|
||||||
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
|
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
|
||||||
void ClearCache(const net::CompletionCallback& callback);
|
void ClearCache(const net::CompletionCallback& callback);
|
||||||
void ClearStorageData(mate::Arguments* args);
|
void ClearStorageData(mate::Arguments* args);
|
||||||
void SetProxy(const std::string& proxy, const base::Closure& callback);
|
void SetProxy(const net::ProxyConfig& config, const base::Closure& callback);
|
||||||
void SetDownloadPath(const base::FilePath& path);
|
void SetDownloadPath(const base::FilePath& path);
|
||||||
void EnableNetworkEmulation(const mate::Dictionary& options);
|
void EnableNetworkEmulation(const mate::Dictionary& options);
|
||||||
void DisableNetworkEmulation();
|
void DisableNetworkEmulation();
|
||||||
|
|
|
@ -74,10 +74,26 @@ void Tray::OnBalloonClosed() {
|
||||||
Emit("balloon-closed");
|
Emit("balloon-closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Tray::OnDrop() {
|
||||||
|
Emit("drop");
|
||||||
|
}
|
||||||
|
|
||||||
void Tray::OnDropFiles(const std::vector<std::string>& files) {
|
void Tray::OnDropFiles(const std::vector<std::string>& files) {
|
||||||
Emit("drop-files", files);
|
Emit("drop-files", files);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Tray::OnDragEntered() {
|
||||||
|
Emit("drag-enter");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tray::OnDragExited() {
|
||||||
|
Emit("drag-leave");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tray::OnDragEnded() {
|
||||||
|
Emit("drag-end");
|
||||||
|
}
|
||||||
|
|
||||||
bool Tray::IsDestroyed() const {
|
bool Tray::IsDestroyed() const {
|
||||||
return !tray_icon_;
|
return !tray_icon_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "atom/browser/api/event_emitter.h"
|
#include "atom/browser/api/trackable_object.h"
|
||||||
#include "atom/browser/ui/tray_icon_observer.h"
|
#include "atom/browser/ui/tray_icon_observer.h"
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ namespace api {
|
||||||
|
|
||||||
class Menu;
|
class Menu;
|
||||||
|
|
||||||
class Tray : public mate::EventEmitter,
|
class Tray : public mate::TrackableObject<Tray>,
|
||||||
public TrayIconObserver {
|
public TrayIconObserver {
|
||||||
public:
|
public:
|
||||||
static mate::Wrappable* New(v8::Isolate* isolate, const gfx::Image& image);
|
static mate::Wrappable* New(v8::Isolate* isolate, const gfx::Image& image);
|
||||||
|
@ -39,7 +39,7 @@ class Tray : public mate::EventEmitter,
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit Tray(const gfx::Image& image);
|
explicit Tray(const gfx::Image& image);
|
||||||
virtual ~Tray();
|
~Tray() override;
|
||||||
|
|
||||||
// TrayIconObserver:
|
// TrayIconObserver:
|
||||||
void OnClicked(const gfx::Rect& bounds, int modifiers) override;
|
void OnClicked(const gfx::Rect& bounds, int modifiers) override;
|
||||||
|
@ -48,12 +48,18 @@ class Tray : public mate::EventEmitter,
|
||||||
void OnBalloonShow() override;
|
void OnBalloonShow() override;
|
||||||
void OnBalloonClicked() override;
|
void OnBalloonClicked() override;
|
||||||
void OnBalloonClosed() override;
|
void OnBalloonClosed() override;
|
||||||
|
void OnDrop() override;
|
||||||
void OnDropFiles(const std::vector<std::string>& files) override;
|
void OnDropFiles(const std::vector<std::string>& files) override;
|
||||||
|
void OnDragEntered() override;
|
||||||
|
void OnDragExited() override;
|
||||||
|
void OnDragEnded() override;
|
||||||
|
|
||||||
// mate::Wrappable:
|
// mate::Wrappable:
|
||||||
bool IsDestroyed() const override;
|
bool IsDestroyed() const override;
|
||||||
|
|
||||||
void Destroy();
|
// mate::TrackableObject:
|
||||||
|
void Destroy() override;
|
||||||
|
|
||||||
void SetImage(mate::Arguments* args, const gfx::Image& image);
|
void SetImage(mate::Arguments* args, const gfx::Image& image);
|
||||||
void SetPressedImage(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 SetToolTip(mate::Arguments* args, const std::string& tool_tip);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "atom/common/api/event_emitter_caller.h"
|
#include "atom/common/api/event_emitter_caller.h"
|
||||||
#include "atom/common/native_mate_converters/blink_converter.h"
|
#include "atom/common/native_mate_converters/blink_converter.h"
|
||||||
#include "atom/common/native_mate_converters/callback.h"
|
#include "atom/common/native_mate_converters/callback.h"
|
||||||
|
#include "atom/common/native_mate_converters/content_converter.h"
|
||||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||||
#include "atom/common/native_mate_converters/gfx_converter.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/gurl_converter.h"
|
||||||
|
@ -31,6 +32,7 @@
|
||||||
#include "chrome/browser/printing/print_view_manager_basic.h"
|
#include "chrome/browser/printing/print_view_manager_basic.h"
|
||||||
#include "chrome/browser/printing/print_preview_message_handler.h"
|
#include "chrome/browser/printing/print_preview_message_handler.h"
|
||||||
#include "content/common/view_messages.h"
|
#include "content/common/view_messages.h"
|
||||||
|
#include "content/public/browser/browser_plugin_guest_manager.h"
|
||||||
#include "content/public/browser/favicon_status.h"
|
#include "content/public/browser/favicon_status.h"
|
||||||
#include "content/public/browser/native_web_keyboard_event.h"
|
#include "content/public/browser/native_web_keyboard_event.h"
|
||||||
#include "content/public/browser/navigation_details.h"
|
#include "content/public/browser/navigation_details.h"
|
||||||
|
@ -45,12 +47,14 @@
|
||||||
#include "content/public/browser/storage_partition.h"
|
#include "content/public/browser/storage_partition.h"
|
||||||
#include "content/public/browser/site_instance.h"
|
#include "content/public/browser/site_instance.h"
|
||||||
#include "content/public/browser/web_contents.h"
|
#include "content/public/browser/web_contents.h"
|
||||||
|
#include "content/public/common/context_menu_params.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "native_mate/object_template_builder.h"
|
#include "native_mate/object_template_builder.h"
|
||||||
#include "net/http/http_response_headers.h"
|
#include "net/http/http_response_headers.h"
|
||||||
#include "net/url_request/static_http_user_agent_settings.h"
|
#include "net/url_request/static_http_user_agent_settings.h"
|
||||||
#include "net/url_request/url_request_context.h"
|
#include "net/url_request/url_request_context.h"
|
||||||
#include "third_party/WebKit/public/web/WebInputEvent.h"
|
#include "third_party/WebKit/public/web/WebInputEvent.h"
|
||||||
|
#include "ui/base/l10n/l10n_util.h"
|
||||||
|
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
|
@ -62,9 +66,21 @@ struct PrintSettings {
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetUserAgentInIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
void SetUserAgentInIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||||
|
std::string accept_lang,
|
||||||
std::string user_agent) {
|
std::string user_agent) {
|
||||||
getter->GetURLRequestContext()->set_http_user_agent_settings(
|
getter->GetURLRequestContext()->set_http_user_agent_settings(
|
||||||
new net::StaticHttpUserAgentSettings("en-us,en", user_agent));
|
new net::StaticHttpUserAgentSettings(
|
||||||
|
net::HttpUtil::GenerateAcceptLanguageHeader(accept_lang),
|
||||||
|
user_agent));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotifyZoomLevelChanged(
|
||||||
|
double level, content::WebContents* guest_web_contents) {
|
||||||
|
guest_web_contents->SendToAllFrames(
|
||||||
|
new AtomViewMsg_SetZoomLevel(MSG_ROUTING_NONE, level));
|
||||||
|
|
||||||
|
// Return false to iterate over all guests.
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -133,7 +149,6 @@ struct Converter<net::HttpResponseHeaders*> {
|
||||||
std::string value;
|
std::string value;
|
||||||
while (headers->EnumerateHeaderLines(&iter, &key, &value)) {
|
while (headers->EnumerateHeaderLines(&iter, &key, &value)) {
|
||||||
key = base::StringToLowerASCII(key);
|
key = base::StringToLowerASCII(key);
|
||||||
value = base::StringToLowerASCII(value);
|
|
||||||
if (response_headers.HasKey(key)) {
|
if (response_headers.HasKey(key)) {
|
||||||
base::ListValue* values = nullptr;
|
base::ListValue* values = nullptr;
|
||||||
if (response_headers.GetList(key, &values))
|
if (response_headers.GetList(key, &values))
|
||||||
|
@ -149,6 +164,27 @@ struct Converter<net::HttpResponseHeaders*> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Converter<content::SavePageType> {
|
||||||
|
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||||
|
content::SavePageType* out) {
|
||||||
|
std::string save_type;
|
||||||
|
if (!ConvertFromV8(isolate, val, &save_type))
|
||||||
|
return false;
|
||||||
|
save_type = base::StringToLowerASCII(save_type);
|
||||||
|
if (save_type == "htmlonly") {
|
||||||
|
*out = content::SAVE_PAGE_TYPE_AS_ONLY_HTML;
|
||||||
|
} else if (save_type == "htmlcomplete") {
|
||||||
|
*out = content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML;
|
||||||
|
} else if (save_type == "mhtml") {
|
||||||
|
*out = content::SAVE_PAGE_TYPE_AS_MHTML;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace mate
|
} // namespace mate
|
||||||
|
|
||||||
|
|
||||||
|
@ -233,9 +269,7 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||||
managed_web_contents()->GetView()->SetDelegate(this);
|
managed_web_contents()->GetView()->SetDelegate(this);
|
||||||
|
|
||||||
// Save the preferences in C++.
|
// Save the preferences in C++.
|
||||||
base::DictionaryValue web_preferences;
|
new WebContentsPreferences(web_contents, options);
|
||||||
mate::ConvertFromV8(isolate, options.GetHandle(), &web_preferences);
|
|
||||||
new WebContentsPreferences(web_contents, &web_preferences);
|
|
||||||
|
|
||||||
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
|
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
|
||||||
|
|
||||||
|
@ -371,6 +405,15 @@ void WebContents::RendererResponsive(content::WebContents* source) {
|
||||||
owner_window()->RendererResponsive(source);
|
owner_window()->RendererResponsive(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WebContents::HandleContextMenu(const content::ContextMenuParams& params) {
|
||||||
|
if (!params.custom_context.is_pepper_menu)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Emit("pepper-context-menu", std::make_pair(params, web_contents()));
|
||||||
|
web_contents()->NotifyContextMenuClosed(params.custom_context);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) {
|
void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) {
|
||||||
// Do nothing, we override this method just to avoid compilation error since
|
// Do nothing, we override this method just to avoid compilation error since
|
||||||
// there are two virtual functions named BeforeUnloadFired.
|
// there are two virtual functions named BeforeUnloadFired.
|
||||||
|
@ -528,6 +571,7 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
|
||||||
IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage)
|
IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage)
|
||||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync,
|
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync,
|
||||||
OnRendererMessageSync)
|
OnRendererMessageSync)
|
||||||
|
IPC_MESSAGE_HANDLER(AtomViewHostMsg_ZoomLevelChanged, OnZoomLevelChanged)
|
||||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||||
IPC_END_MESSAGE_MAP()
|
IPC_END_MESSAGE_MAP()
|
||||||
|
|
||||||
|
@ -584,6 +628,10 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
|
||||||
if (options.Get("userAgent", &user_agent))
|
if (options.Get("userAgent", &user_agent))
|
||||||
SetUserAgent(user_agent);
|
SetUserAgent(user_agent);
|
||||||
|
|
||||||
|
std::string extra_headers;
|
||||||
|
if (options.Get("extraHeaders", &extra_headers))
|
||||||
|
params.extra_headers = extra_headers;
|
||||||
|
|
||||||
params.transition_type = ui::PAGE_TRANSITION_TYPED;
|
params.transition_type = ui::PAGE_TRANSITION_TYPED;
|
||||||
params.should_clear_history_list = true;
|
params.should_clear_history_list = true;
|
||||||
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
|
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
|
||||||
|
@ -637,8 +685,10 @@ void WebContents::SetUserAgent(const std::string& user_agent) {
|
||||||
web_contents()->SetUserAgentOverride(user_agent);
|
web_contents()->SetUserAgentOverride(user_agent);
|
||||||
scoped_refptr<net::URLRequestContextGetter> getter =
|
scoped_refptr<net::URLRequestContextGetter> getter =
|
||||||
web_contents()->GetBrowserContext()->GetRequestContext();
|
web_contents()->GetBrowserContext()->GetRequestContext();
|
||||||
|
|
||||||
|
auto accept_lang = l10n_util::GetApplicationLocale("");
|
||||||
getter->GetNetworkTaskRunner()->PostTask(FROM_HERE,
|
getter->GetNetworkTaskRunner()->PostTask(FROM_HERE,
|
||||||
base::Bind(&SetUserAgentInIO, getter, user_agent));
|
base::Bind(&SetUserAgentInIO, getter, accept_lang, user_agent));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string WebContents::GetUserAgent() {
|
std::string WebContents::GetUserAgent() {
|
||||||
|
@ -649,6 +699,13 @@ void WebContents::InsertCSS(const std::string& css) {
|
||||||
web_contents()->InsertCSS(css);
|
web_contents()->InsertCSS(css);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WebContents::SavePage(const base::FilePath& full_file_path,
|
||||||
|
const content::SavePageType& save_type,
|
||||||
|
const SavePageHandler::SavePageCallback& callback) {
|
||||||
|
auto handler = new SavePageHandler(web_contents(), callback);
|
||||||
|
return handler->Handle(full_file_path, save_type);
|
||||||
|
}
|
||||||
|
|
||||||
void WebContents::ExecuteJavaScript(const base::string16& code,
|
void WebContents::ExecuteJavaScript(const base::string16& code,
|
||||||
bool has_user_gesture) {
|
bool has_user_gesture) {
|
||||||
Send(new AtomViewMsg_ExecuteJavaScript(routing_id(), code, has_user_gesture));
|
Send(new AtomViewMsg_ExecuteJavaScript(routing_id(), code, has_user_gesture));
|
||||||
|
@ -960,6 +1017,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
|
||||||
.SetMethod("setUserAgent", &WebContents::SetUserAgent)
|
.SetMethod("setUserAgent", &WebContents::SetUserAgent)
|
||||||
.SetMethod("getUserAgent", &WebContents::GetUserAgent)
|
.SetMethod("getUserAgent", &WebContents::GetUserAgent)
|
||||||
.SetMethod("insertCSS", &WebContents::InsertCSS)
|
.SetMethod("insertCSS", &WebContents::InsertCSS)
|
||||||
|
.SetMethod("savePage", &WebContents::SavePage)
|
||||||
.SetMethod("_executeJavaScript", &WebContents::ExecuteJavaScript)
|
.SetMethod("_executeJavaScript", &WebContents::ExecuteJavaScript)
|
||||||
.SetMethod("openDevTools", &WebContents::OpenDevTools)
|
.SetMethod("openDevTools", &WebContents::OpenDevTools)
|
||||||
.SetMethod("closeDevTools", &WebContents::CloseDevTools)
|
.SetMethod("closeDevTools", &WebContents::CloseDevTools)
|
||||||
|
@ -1033,6 +1091,15 @@ void WebContents::OnRendererMessageSync(const base::string16& channel,
|
||||||
EmitWithSender(base::UTF16ToUTF8(channel), web_contents(), message, args);
|
EmitWithSender(base::UTF16ToUTF8(channel), web_contents(), message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebContents::OnZoomLevelChanged(double level) {
|
||||||
|
auto manager = web_contents()->GetBrowserContext()->GetGuestManager();
|
||||||
|
if (!manager)
|
||||||
|
return;
|
||||||
|
manager->ForEachGuest(web_contents(),
|
||||||
|
base::Bind(&NotifyZoomLevelChanged,
|
||||||
|
level));
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
mate::Handle<WebContents> WebContents::CreateFrom(
|
mate::Handle<WebContents> WebContents::CreateFrom(
|
||||||
v8::Isolate* isolate, content::WebContents* web_contents) {
|
v8::Isolate* isolate, content::WebContents* web_contents) {
|
||||||
|
@ -1055,14 +1122,18 @@ mate::Handle<WebContents> WebContents::Create(
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetWrapWebContents(const WrapWebContentsCallback& callback) {
|
|
||||||
g_wrap_web_contents = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearWrapWebContents() {
|
void ClearWrapWebContents() {
|
||||||
g_wrap_web_contents.Reset();
|
g_wrap_web_contents.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetWrapWebContents(const WrapWebContentsCallback& callback) {
|
||||||
|
g_wrap_web_contents = callback;
|
||||||
|
|
||||||
|
// Cleanup the wrapper on exit.
|
||||||
|
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
|
||||||
|
base::Bind(ClearWrapWebContents));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
@ -1076,7 +1147,6 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||||
mate::Dictionary dict(isolate, exports);
|
mate::Dictionary dict(isolate, exports);
|
||||||
dict.SetMethod("create", &atom::api::WebContents::Create);
|
dict.SetMethod("create", &atom::api::WebContents::Create);
|
||||||
dict.SetMethod("_setWrapWebContents", &atom::api::SetWrapWebContents);
|
dict.SetMethod("_setWrapWebContents", &atom::api::SetWrapWebContents);
|
||||||
dict.SetMethod("_clearWrapWebContents", &atom::api::ClearWrapWebContents);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "atom/browser/api/frame_subscriber.h"
|
#include "atom/browser/api/frame_subscriber.h"
|
||||||
|
#include "atom/browser/api/save_page_handler.h"
|
||||||
#include "atom/browser/api/trackable_object.h"
|
#include "atom/browser/api/trackable_object.h"
|
||||||
#include "atom/browser/common_web_contents_delegate.h"
|
#include "atom/browser/common_web_contents_delegate.h"
|
||||||
#include "content/public/browser/web_contents_observer.h"
|
#include "content/public/browser/web_contents_observer.h"
|
||||||
|
@ -73,6 +74,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||||
void SetUserAgent(const std::string& user_agent);
|
void SetUserAgent(const std::string& user_agent);
|
||||||
std::string GetUserAgent();
|
std::string GetUserAgent();
|
||||||
void InsertCSS(const std::string& css);
|
void InsertCSS(const std::string& css);
|
||||||
|
bool SavePage(const base::FilePath& full_file_path,
|
||||||
|
const content::SavePageType& save_type,
|
||||||
|
const SavePageHandler::SavePageCallback& callback);
|
||||||
void ExecuteJavaScript(const base::string16& code,
|
void ExecuteJavaScript(const base::string16& code,
|
||||||
bool has_user_gesture);
|
bool has_user_gesture);
|
||||||
void OpenDevTools(mate::Arguments* args);
|
void OpenDevTools(mate::Arguments* args);
|
||||||
|
@ -185,6 +189,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||||
void ExitFullscreenModeForTab(content::WebContents* source) override;
|
void ExitFullscreenModeForTab(content::WebContents* source) override;
|
||||||
void RendererUnresponsive(content::WebContents* source) override;
|
void RendererUnresponsive(content::WebContents* source) override;
|
||||||
void RendererResponsive(content::WebContents* source) override;
|
void RendererResponsive(content::WebContents* source) override;
|
||||||
|
bool HandleContextMenu(const content::ContextMenuParams& params) override;
|
||||||
|
|
||||||
// content::WebContentsObserver:
|
// content::WebContentsObserver:
|
||||||
void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
|
void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
|
||||||
|
@ -247,6 +252,10 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||||
const base::ListValue& args,
|
const base::ListValue& args,
|
||||||
IPC::Message* message);
|
IPC::Message* message);
|
||||||
|
|
||||||
|
// Called when guests need to be notified of
|
||||||
|
// embedders' zoom level change.
|
||||||
|
void OnZoomLevelChanged(double level);
|
||||||
|
|
||||||
v8::Global<v8::Value> session_;
|
v8::Global<v8::Value> session_;
|
||||||
v8::Global<v8::Value> devtools_web_contents_;
|
v8::Global<v8::Value> devtools_web_contents_;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
#include "atom/browser/api/atom_api_window.h"
|
#include "atom/browser/api/atom_api_window.h"
|
||||||
|
#include "atom/common/native_mate_converters/value_converter.h"
|
||||||
|
|
||||||
#include "atom/browser/api/atom_api_menu.h"
|
#include "atom/browser/api/atom_api_menu.h"
|
||||||
#include "atom/browser/api/atom_api_web_contents.h"
|
#include "atom/browser/api/atom_api_web_contents.h"
|
||||||
|
@ -60,11 +61,71 @@ void OnCapturePageDone(
|
||||||
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
|
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Converts min-width to minWidth, returns false if no conversion is needed.
|
||||||
|
bool TranslateOldKey(const std::string& key, std::string* new_key) {
|
||||||
|
if (key.find('-') == std::string::npos)
|
||||||
|
return false;
|
||||||
|
new_key->reserve(key.size());
|
||||||
|
bool next_upper_case = false;
|
||||||
|
for (char c : key) {
|
||||||
|
if (c == '-') {
|
||||||
|
next_upper_case = true;
|
||||||
|
} else if (next_upper_case) {
|
||||||
|
new_key->push_back(base::ToUpperASCII(c));
|
||||||
|
next_upper_case = false;
|
||||||
|
} else {
|
||||||
|
new_key->push_back(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts min-width to minWidth recursively in the dictionary.
|
||||||
|
void TranslateOldOptions(v8::Isolate* isolate, v8::Local<v8::Object> options) {
|
||||||
|
auto context = isolate->GetCurrentContext();
|
||||||
|
auto maybe_keys = options->GetOwnPropertyNames(context);
|
||||||
|
if (maybe_keys.IsEmpty())
|
||||||
|
return;
|
||||||
|
std::vector<std::string> keys;
|
||||||
|
if (!mate::ConvertFromV8(isolate, maybe_keys.ToLocalChecked(), &keys))
|
||||||
|
return;
|
||||||
|
mate::Dictionary dict(isolate, options);
|
||||||
|
for (const auto& key : keys) {
|
||||||
|
v8::Local<v8::Value> value;
|
||||||
|
if (!dict.Get(key, &value)) // Shouldn't happen, but guard it anyway.
|
||||||
|
continue;
|
||||||
|
// Go recursively.
|
||||||
|
v8::Local<v8::Object> sub_options;
|
||||||
|
if (mate::ConvertFromV8(isolate, value, &sub_options))
|
||||||
|
TranslateOldOptions(isolate, sub_options);
|
||||||
|
// Translate key.
|
||||||
|
std::string new_key;
|
||||||
|
if (TranslateOldKey(key, &new_key)) {
|
||||||
|
dict.Set(new_key, value);
|
||||||
|
dict.Delete(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
// Converts binary data to Buffer.
|
||||||
|
v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) {
|
||||||
|
auto buffer = node::Buffer::New(isolate, static_cast<char*>(val), size);
|
||||||
|
if (buffer.IsEmpty())
|
||||||
|
return v8::Null(isolate);
|
||||||
|
else
|
||||||
|
return buffer.ToLocalChecked();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
|
Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
|
||||||
// Use options['web-preferences'] to create WebContents.
|
// Be compatible with old style field names like min-width.
|
||||||
|
TranslateOldOptions(isolate, options.GetHandle());
|
||||||
|
|
||||||
|
// Use options.webPreferences to create WebContents.
|
||||||
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
|
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
|
||||||
options.Get(switches::kWebPreferences, &web_preferences);
|
options.Get(switches::kWebPreferences, &web_preferences);
|
||||||
|
|
||||||
|
@ -189,6 +250,16 @@ void Window::OnExecuteWindowsCommand(const std::string& command_name) {
|
||||||
Emit("app-command", command_name);
|
Emit("app-command", command_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
void Window::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) {
|
||||||
|
if (IsWindowMessageHooked(message)) {
|
||||||
|
messages_callback_map_[message].Run(
|
||||||
|
ToBuffer(isolate(), static_cast<void*>(&w_param), sizeof(WPARAM)),
|
||||||
|
ToBuffer(isolate(), static_cast<void*>(&l_param), sizeof(LPARAM)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// static
|
// static
|
||||||
mate::Wrappable* Window::New(v8::Isolate* isolate,
|
mate::Wrappable* Window::New(v8::Isolate* isolate,
|
||||||
const mate::Dictionary& options) {
|
const mate::Dictionary& options) {
|
||||||
|
@ -385,6 +456,10 @@ bool Window::IsKiosk() {
|
||||||
return window_->IsKiosk();
|
return window_->IsKiosk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::SetBackgroundColor(const std::string& color_name) {
|
||||||
|
window_->SetBackgroundColor(color_name);
|
||||||
|
}
|
||||||
|
|
||||||
void Window::FocusOnWebView() {
|
void Window::FocusOnWebView() {
|
||||||
window_->FocusOnWebView();
|
window_->FocusOnWebView();
|
||||||
}
|
}
|
||||||
|
@ -488,6 +563,29 @@ bool Window::IsMenuBarVisible() {
|
||||||
return window_->IsMenuBarVisible();
|
return window_->IsMenuBarVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
bool Window::HookWindowMessage(UINT message,
|
||||||
|
const MessageCallback& callback) {
|
||||||
|
messages_callback_map_[message] = callback;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::UnhookWindowMessage(UINT message) {
|
||||||
|
if (!ContainsKey(messages_callback_map_, message))
|
||||||
|
return;
|
||||||
|
|
||||||
|
messages_callback_map_.erase(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::IsWindowMessageHooked(UINT message) {
|
||||||
|
return ContainsKey(messages_callback_map_, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::UnhookAllWindowMessages() {
|
||||||
|
messages_callback_map_.clear();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
void Window::ShowDefinitionForSelection() {
|
void Window::ShowDefinitionForSelection() {
|
||||||
window_->ShowDefinitionForSelection();
|
window_->ShowDefinitionForSelection();
|
||||||
|
@ -564,6 +662,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||||
.SetMethod("setSkipTaskbar", &Window::SetSkipTaskbar)
|
.SetMethod("setSkipTaskbar", &Window::SetSkipTaskbar)
|
||||||
.SetMethod("setKiosk", &Window::SetKiosk)
|
.SetMethod("setKiosk", &Window::SetKiosk)
|
||||||
.SetMethod("isKiosk", &Window::IsKiosk)
|
.SetMethod("isKiosk", &Window::IsKiosk)
|
||||||
|
.SetMethod("setBackgroundColor", &Window::SetBackgroundColor)
|
||||||
.SetMethod("setRepresentedFilename", &Window::SetRepresentedFilename)
|
.SetMethod("setRepresentedFilename", &Window::SetRepresentedFilename)
|
||||||
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
|
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
|
||||||
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
|
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
|
||||||
|
@ -585,6 +684,12 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||||
&Window::SetVisibleOnAllWorkspaces)
|
&Window::SetVisibleOnAllWorkspaces)
|
||||||
.SetMethod("isVisibleOnAllWorkspaces",
|
.SetMethod("isVisibleOnAllWorkspaces",
|
||||||
&Window::IsVisibleOnAllWorkspaces)
|
&Window::IsVisibleOnAllWorkspaces)
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
.SetMethod("hookWindowMessage", &Window::HookWindowMessage)
|
||||||
|
.SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked)
|
||||||
|
.SetMethod("unhookWindowMessage", &Window::UnhookWindowMessage)
|
||||||
|
.SetMethod("unhookAllWindowMessages", &Window::UnhookAllWindowMessages)
|
||||||
|
#endif
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
.SetMethod("showDefinitionForSelection",
|
.SetMethod("showDefinitionForSelection",
|
||||||
&Window::ShowDefinitionForSelection)
|
&Window::ShowDefinitionForSelection)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#ifndef ATOM_BROWSER_API_ATOM_API_WINDOW_H_
|
#ifndef ATOM_BROWSER_API_ATOM_API_WINDOW_H_
|
||||||
#define ATOM_BROWSER_API_ATOM_API_WINDOW_H_
|
#define ATOM_BROWSER_API_ATOM_API_WINDOW_H_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -75,6 +76,10 @@ class Window : public mate::TrackableObject<Window>,
|
||||||
void OnRendererResponsive() override;
|
void OnRendererResponsive() override;
|
||||||
void OnExecuteWindowsCommand(const std::string& command_name) override;
|
void OnExecuteWindowsCommand(const std::string& command_name) override;
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
void OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) override;
|
||||||
|
#endif
|
||||||
|
|
||||||
// mate::Wrappable:
|
// mate::Wrappable:
|
||||||
bool IsDestroyed() const override;
|
bool IsDestroyed() const override;
|
||||||
|
|
||||||
|
@ -122,6 +127,7 @@ class Window : public mate::TrackableObject<Window>,
|
||||||
void SetSkipTaskbar(bool skip);
|
void SetSkipTaskbar(bool skip);
|
||||||
void SetKiosk(bool kiosk);
|
void SetKiosk(bool kiosk);
|
||||||
bool IsKiosk();
|
bool IsKiosk();
|
||||||
|
void SetBackgroundColor(const std::string& color_name);
|
||||||
void FocusOnWebView();
|
void FocusOnWebView();
|
||||||
void BlurWebView();
|
void BlurWebView();
|
||||||
bool IsWebViewFocused();
|
bool IsWebViewFocused();
|
||||||
|
@ -142,6 +148,16 @@ class Window : public mate::TrackableObject<Window>,
|
||||||
bool IsMenuBarVisible();
|
bool IsMenuBarVisible();
|
||||||
void SetAspectRatio(double aspect_ratio, mate::Arguments* args);
|
void SetAspectRatio(double aspect_ratio, mate::Arguments* args);
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
typedef base::Callback<void(v8::Local<v8::Value>,
|
||||||
|
v8::Local<v8::Value>)> MessageCallback;
|
||||||
|
|
||||||
|
bool HookWindowMessage(UINT message, const MessageCallback& callback);
|
||||||
|
bool IsWindowMessageHooked(UINT message);
|
||||||
|
void UnhookWindowMessage(UINT message);
|
||||||
|
void UnhookAllWindowMessages();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
void ShowDefinitionForSelection();
|
void ShowDefinitionForSelection();
|
||||||
#endif
|
#endif
|
||||||
|
@ -152,6 +168,11 @@ class Window : public mate::TrackableObject<Window>,
|
||||||
int32_t ID() const;
|
int32_t ID() const;
|
||||||
v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
|
v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
typedef std::map<UINT, MessageCallback> MessageCallbackMap;
|
||||||
|
MessageCallbackMap messages_callback_map_;
|
||||||
|
#endif
|
||||||
|
|
||||||
v8::Global<v8::Value> web_contents_;
|
v8::Global<v8::Value> web_contents_;
|
||||||
v8::Global<v8::Value> menu_;
|
v8::Global<v8::Value> menu_;
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
deprecate = require 'deprecate'
|
||||||
EventEmitter = require('events').EventEmitter
|
EventEmitter = require('events').EventEmitter
|
||||||
|
|
||||||
bindings = process.atomBinding 'app'
|
bindings = process.atomBinding 'app'
|
||||||
|
@ -7,19 +8,6 @@ downloadItemBindings = process.atomBinding 'download_item'
|
||||||
app = bindings.app
|
app = bindings.app
|
||||||
app.__proto__ = EventEmitter.prototype
|
app.__proto__ = EventEmitter.prototype
|
||||||
|
|
||||||
wrapSession = (session) ->
|
|
||||||
# session is an Event Emitter.
|
|
||||||
session.__proto__ = EventEmitter.prototype
|
|
||||||
|
|
||||||
wrapDownloadItem = (download_item) ->
|
|
||||||
# download_item is an Event Emitter.
|
|
||||||
download_item.__proto__ = EventEmitter.prototype
|
|
||||||
# Be compatible with old APIs.
|
|
||||||
download_item.url = download_item.getUrl()
|
|
||||||
download_item.filename = download_item.getFilename()
|
|
||||||
download_item.mimeType = download_item.getMimeType()
|
|
||||||
download_item.hasUserGesture = download_item.hasUserGesture()
|
|
||||||
|
|
||||||
app.setApplicationMenu = (menu) ->
|
app.setApplicationMenu = (menu) ->
|
||||||
require('menu').setApplicationMenu menu
|
require('menu').setApplicationMenu menu
|
||||||
|
|
||||||
|
@ -47,22 +35,38 @@ app.setAppPath = (path) ->
|
||||||
app.getAppPath = ->
|
app.getAppPath = ->
|
||||||
appPath
|
appPath
|
||||||
|
|
||||||
# Be compatible with old API.
|
# Helpers.
|
||||||
app.once 'ready', -> @emit 'finish-launching'
|
app.resolveProxy = (url, callback) -> @defaultSession.resolveProxy url, callback
|
||||||
app.terminate = app.quit
|
|
||||||
app.exit = process.exit
|
|
||||||
app.getHomeDir = -> @getPath 'home'
|
|
||||||
app.getDataPath = -> @getPath 'userData'
|
|
||||||
app.setDataPath = (path) -> @setPath 'userData', path
|
|
||||||
app.resolveProxy = -> @defaultSession.resolveProxy.apply @defaultSession, arguments
|
|
||||||
app.on 'activate', (event, hasVisibleWindows) -> @emit 'activate-with-no-open-windows' if not hasVisibleWindows
|
|
||||||
|
|
||||||
# Session wrapper.
|
# Deprecated.
|
||||||
|
app.getHomeDir = deprecate 'app.getHomeDir', 'app.getPath', ->
|
||||||
|
@getPath 'home'
|
||||||
|
app.getDataPath = deprecate 'app.getDataPath', 'app.getPath', ->
|
||||||
|
@getPath 'userData'
|
||||||
|
app.setDataPath = deprecate 'app.setDataPath', 'app.setPath', (path) ->
|
||||||
|
@setPath 'userData', path
|
||||||
|
deprecate.rename app, 'terminate', 'quit'
|
||||||
|
deprecate.event app, 'finish-launching', 'ready', ->
|
||||||
|
setImmediate => # give default app a chance to setup default menu.
|
||||||
|
@emit 'finish-launching'
|
||||||
|
deprecate.event app, 'activate-with-no-open-windows', 'activate', (event, hasVisibleWindows) ->
|
||||||
|
@emit 'activate-with-no-open-windows' if not hasVisibleWindows
|
||||||
|
|
||||||
|
# Wrappers for native classes.
|
||||||
|
wrapSession = (session) ->
|
||||||
|
# session is an EventEmitter.
|
||||||
|
session.__proto__ = EventEmitter.prototype
|
||||||
sessionBindings._setWrapSession wrapSession
|
sessionBindings._setWrapSession wrapSession
|
||||||
process.once 'exit', sessionBindings._clearWrapSession
|
|
||||||
|
|
||||||
|
wrapDownloadItem = (downloadItem) ->
|
||||||
|
# downloadItem is an EventEmitter.
|
||||||
|
downloadItem.__proto__ = EventEmitter.prototype
|
||||||
|
# Deprecated.
|
||||||
|
deprecate.property downloadItem, 'url', 'getUrl'
|
||||||
|
deprecate.property downloadItem, 'filename', 'getFilename'
|
||||||
|
deprecate.property downloadItem, 'mimeType', 'getMimeType'
|
||||||
|
deprecate.property downloadItem, 'hasUserGesture', 'hasUserGesture'
|
||||||
downloadItemBindings._setWrapDownloadItem wrapDownloadItem
|
downloadItemBindings._setWrapDownloadItem wrapDownloadItem
|
||||||
process.once 'exit', downloadItemBindings._clearWrapDownloadItem
|
|
||||||
|
|
||||||
# Only one App object pemitted.
|
# Only one App object pemitted.
|
||||||
module.exports = app
|
module.exports = app
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
module.exports =
|
|
||||||
browserMainParts:
|
|
||||||
preMainMessageLoopRun: ->
|
|
||||||
|
|
||||||
setImmediate ->
|
|
||||||
module.exports.browserMainParts.preMainMessageLoopRun()
|
|
|
@ -1,24 +1,7 @@
|
||||||
autoUpdater = process.atomBinding('auto_updater').autoUpdater
|
switch process.platform
|
||||||
EventEmitter = require('events').EventEmitter
|
when 'win32'
|
||||||
|
module.exports = require './auto-updater/auto-updater-win'
|
||||||
autoUpdater.__proto__ = EventEmitter.prototype
|
when 'darwin'
|
||||||
|
module.exports = require './auto-updater/auto-updater-mac'
|
||||||
autoUpdater.on 'update-downloaded-raw', (args...) ->
|
else
|
||||||
args[3] = new Date(args[3]) # releaseDate
|
throw new Error('auto-updater is not implemented on this platform')
|
||||||
@emit 'update-downloaded', args..., => @quitAndInstall()
|
|
||||||
|
|
||||||
autoUpdater.quitAndInstall = ->
|
|
||||||
# If we don't have any window then quitAndInstall immediately.
|
|
||||||
BrowserWindow = require 'browser-window'
|
|
||||||
windows = BrowserWindow.getAllWindows()
|
|
||||||
if windows.length is 0
|
|
||||||
@_quitAndInstall()
|
|
||||||
return
|
|
||||||
|
|
||||||
# Do the restart after all windows have been closed.
|
|
||||||
app = require 'app'
|
|
||||||
app.removeAllListeners 'window-all-closed'
|
|
||||||
app.once 'window-all-closed', @_quitAndInstall.bind(this)
|
|
||||||
win.close() for win in windows
|
|
||||||
|
|
||||||
module.exports = autoUpdater
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
{EventEmitter} = require 'events'
|
||||||
|
{autoUpdater} = process.atomBinding 'auto_updater'
|
||||||
|
|
||||||
|
autoUpdater.__proto__ = EventEmitter.prototype
|
||||||
|
|
||||||
|
module.exports = autoUpdater
|
42
atom/browser/api/lib/auto-updater/auto-updater-win.coffee
Normal file
42
atom/browser/api/lib/auto-updater/auto-updater-win.coffee
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
app = require 'app'
|
||||||
|
url = require 'url'
|
||||||
|
{EventEmitter} = require 'events'
|
||||||
|
|
||||||
|
squirrelUpdate = require './squirrel-update-win'
|
||||||
|
|
||||||
|
class AutoUpdater extends EventEmitter
|
||||||
|
quitAndInstall: ->
|
||||||
|
squirrelUpdate.processStart()
|
||||||
|
app.quit()
|
||||||
|
|
||||||
|
setFeedUrl: (updateUrl) ->
|
||||||
|
@updateUrl = updateUrl
|
||||||
|
|
||||||
|
checkForUpdates: ->
|
||||||
|
return @emitError 'Update URL is not set' unless @updateUrl
|
||||||
|
return @emitError 'Can not find Squirrel' unless squirrelUpdate.supported()
|
||||||
|
|
||||||
|
@emit 'checking-for-update'
|
||||||
|
|
||||||
|
squirrelUpdate.download @updateUrl, (error, update) =>
|
||||||
|
return @emitError error if error?
|
||||||
|
return @emit 'update-not-available' unless update?
|
||||||
|
|
||||||
|
@emit 'update-available'
|
||||||
|
|
||||||
|
squirrelUpdate.update @updateUrl, (error) =>
|
||||||
|
return @emitError error if error?
|
||||||
|
|
||||||
|
{releaseNotes, version} = update
|
||||||
|
# Following information is not available on Windows, so fake them.
|
||||||
|
date = new Date
|
||||||
|
url = @updateUrl
|
||||||
|
|
||||||
|
@emit 'update-downloaded', {}, releaseNotes, version, date, url, => @quitAndInstall()
|
||||||
|
|
||||||
|
# Private: Emit both error object and message, this is to keep compatibility
|
||||||
|
# with Old APIs.
|
||||||
|
emitError: (message) ->
|
||||||
|
@emit 'error', new Error(message), message
|
||||||
|
|
||||||
|
module.exports = new AutoUpdater
|
67
atom/browser/api/lib/auto-updater/squirrel-update-win.coffee
Normal file
67
atom/browser/api/lib/auto-updater/squirrel-update-win.coffee
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
fs = require 'fs'
|
||||||
|
path = require 'path'
|
||||||
|
{spawn} = require 'child_process'
|
||||||
|
|
||||||
|
appFolder = path.dirname process.execPath # i.e. my-app/app-0.1.13/
|
||||||
|
updateExe = path.resolve appFolder, '..', 'Update.exe' # i.e. my-app/Update.exe
|
||||||
|
exeName = path.basename process.execPath
|
||||||
|
|
||||||
|
# Spawn a command and invoke the callback when it completes with an error
|
||||||
|
# and the output from standard out.
|
||||||
|
spawnUpdate = (args, detached, callback) ->
|
||||||
|
try
|
||||||
|
spawnedProcess = spawn updateExe, args, {detached}
|
||||||
|
catch error
|
||||||
|
# Shouldn't happen, but still guard it.
|
||||||
|
process.nextTick -> callback error
|
||||||
|
return
|
||||||
|
|
||||||
|
stdout = ''
|
||||||
|
stderr = ''
|
||||||
|
spawnedProcess.stdout.on 'data', (data) -> stdout += data
|
||||||
|
spawnedProcess.stderr.on 'data', (data) -> stderr += data
|
||||||
|
|
||||||
|
errorEmitted = false
|
||||||
|
spawnedProcess.on 'error', (error) ->
|
||||||
|
errorEmitted = true
|
||||||
|
callback error
|
||||||
|
spawnedProcess.on 'exit', (code, signal) ->
|
||||||
|
# We may have already emitted an error.
|
||||||
|
return if errorEmitted
|
||||||
|
|
||||||
|
# Process terminated with error.
|
||||||
|
if code isnt 0
|
||||||
|
return callback "Command failed: #{signal ? code}\n#{stderr}"
|
||||||
|
|
||||||
|
# Success.
|
||||||
|
callback null, stdout
|
||||||
|
|
||||||
|
# Start an instance of the installed app.
|
||||||
|
exports.processStart = (callback) ->
|
||||||
|
spawnUpdate ['--processStart', exeName], true, ->
|
||||||
|
|
||||||
|
# Download the releases specified by the URL and write new results to stdout.
|
||||||
|
exports.download = (updateUrl, callback) ->
|
||||||
|
spawnUpdate ['--download', updateUrl], false, (error, stdout) ->
|
||||||
|
return callback(error) if error?
|
||||||
|
|
||||||
|
try
|
||||||
|
# Last line of output is the JSON details about the releases
|
||||||
|
json = stdout.trim().split('\n').pop()
|
||||||
|
update = JSON.parse(json)?.releasesToApply?.pop?()
|
||||||
|
catch
|
||||||
|
return callback "Invalid result:\n#{stdout}"
|
||||||
|
|
||||||
|
callback null, update
|
||||||
|
|
||||||
|
# Update the application to the latest remote version specified by URL.
|
||||||
|
exports.update = (updateUrl, callback) ->
|
||||||
|
spawnUpdate ['--update', updateUrl], false, callback
|
||||||
|
|
||||||
|
# Is the Update.exe installed with the current application?
|
||||||
|
exports.supported = ->
|
||||||
|
try
|
||||||
|
fs.accessSync updateExe, fs.R_OK
|
||||||
|
return true
|
||||||
|
catch
|
||||||
|
return false
|
|
@ -1,6 +1,7 @@
|
||||||
EventEmitter = require('events').EventEmitter
|
EventEmitter = require('events').EventEmitter
|
||||||
app = require 'app'
|
app = require 'app'
|
||||||
ipc = require 'ipc'
|
ipc = require 'ipc-main'
|
||||||
|
deprecate = require 'deprecate'
|
||||||
|
|
||||||
BrowserWindow = process.atomBinding('window').BrowserWindow
|
BrowserWindow = process.atomBinding('window').BrowserWindow
|
||||||
BrowserWindow::__proto__ = EventEmitter.prototype
|
BrowserWindow::__proto__ = EventEmitter.prototype
|
||||||
|
@ -71,32 +72,32 @@ BrowserWindow.fromDevToolsWebContents = (webContents) ->
|
||||||
|
|
||||||
# Helpers.
|
# Helpers.
|
||||||
BrowserWindow::loadUrl = -> @webContents.loadUrl.apply @webContents, arguments
|
BrowserWindow::loadUrl = -> @webContents.loadUrl.apply @webContents, arguments
|
||||||
BrowserWindow::send = -> @webContents.send.apply @webContents, arguments
|
|
||||||
|
|
||||||
# Be compatible with old API.
|
|
||||||
BrowserWindow::undo = -> @webContents.undo()
|
|
||||||
BrowserWindow::redo = -> @webContents.redo()
|
|
||||||
BrowserWindow::cut = -> @webContents.cut()
|
|
||||||
BrowserWindow::copy = -> @webContents.copy()
|
|
||||||
BrowserWindow::paste = -> @webContents.paste()
|
|
||||||
BrowserWindow::selectAll = -> @webContents.selectAll()
|
|
||||||
BrowserWindow::restart = -> @webContents.reload()
|
|
||||||
BrowserWindow::getUrl = -> @webContents.getUrl()
|
|
||||||
BrowserWindow::reload = -> @webContents.reload.apply @webContents, arguments
|
BrowserWindow::reload = -> @webContents.reload.apply @webContents, arguments
|
||||||
BrowserWindow::reloadIgnoringCache = -> @webContents.reloadIgnoringCache.apply @webContents, arguments
|
BrowserWindow::send = -> @webContents.send.apply @webContents, arguments
|
||||||
BrowserWindow::getPageTitle = -> @webContents.getTitle()
|
|
||||||
BrowserWindow::isLoading = -> @webContents.isLoading()
|
|
||||||
BrowserWindow::isWaitingForResponse = -> @webContents.isWaitingForResponse()
|
|
||||||
BrowserWindow::stop = -> @webContents.stop()
|
|
||||||
BrowserWindow::isCrashed = -> @webContents.isCrashed()
|
|
||||||
BrowserWindow::executeJavaScriptInDevTools = (code) -> @devToolsWebContents?.executeJavaScript code
|
|
||||||
BrowserWindow::openDevTools = -> @webContents.openDevTools.apply @webContents, arguments
|
BrowserWindow::openDevTools = -> @webContents.openDevTools.apply @webContents, arguments
|
||||||
BrowserWindow::closeDevTools = -> @webContents.closeDevTools()
|
BrowserWindow::closeDevTools = -> @webContents.closeDevTools()
|
||||||
BrowserWindow::isDevToolsOpened = -> @webContents.isDevToolsOpened()
|
BrowserWindow::isDevToolsOpened = -> @webContents.isDevToolsOpened()
|
||||||
BrowserWindow::toggleDevTools = -> @webContents.toggleDevTools()
|
BrowserWindow::toggleDevTools = -> @webContents.toggleDevTools()
|
||||||
BrowserWindow::inspectElement = -> @webContents.inspectElement.apply @webContents, arguments
|
BrowserWindow::inspectElement = -> @webContents.inspectElement.apply @webContents, arguments
|
||||||
BrowserWindow::inspectServiceWorker = -> @webContents.inspectServiceWorker()
|
BrowserWindow::inspectServiceWorker = -> @webContents.inspectServiceWorker()
|
||||||
BrowserWindow::print = -> @webContents.print.apply @webContents, arguments
|
|
||||||
BrowserWindow::printToPDF = -> @webContents.printToPDF.apply @webContents, arguments
|
# Deprecated.
|
||||||
|
deprecate.rename BrowserWindow, 'restart', 'reload'
|
||||||
|
deprecate.member BrowserWindow, 'undo', 'webContents'
|
||||||
|
deprecate.member BrowserWindow, 'redo', 'webContents'
|
||||||
|
deprecate.member BrowserWindow, 'cut', 'webContents'
|
||||||
|
deprecate.member BrowserWindow, 'copy', 'webContents'
|
||||||
|
deprecate.member BrowserWindow, 'paste', 'webContents'
|
||||||
|
deprecate.member BrowserWindow, 'selectAll', 'webContents'
|
||||||
|
deprecate.member BrowserWindow, 'getUrl', 'webContents'
|
||||||
|
deprecate.member BrowserWindow, 'reloadIgnoringCache', 'webContents'
|
||||||
|
deprecate.member BrowserWindow, 'getPageTitle', 'webContents'
|
||||||
|
deprecate.member BrowserWindow, 'isLoading', 'webContents'
|
||||||
|
deprecate.member BrowserWindow, 'isWaitingForResponse', 'webContents'
|
||||||
|
deprecate.member BrowserWindow, 'stop', 'webContents'
|
||||||
|
deprecate.member BrowserWindow, 'isCrashed', 'webContents'
|
||||||
|
deprecate.member BrowserWindow, 'executeJavaScriptInDevTools', 'webContents'
|
||||||
|
deprecate.member BrowserWindow, 'print', 'webContents'
|
||||||
|
deprecate.member BrowserWindow, 'printToPDF', 'webContents'
|
||||||
|
|
||||||
module.exports = BrowserWindow
|
module.exports = BrowserWindow
|
||||||
|
|
3
atom/browser/api/lib/ipc-main.coffee
Normal file
3
atom/browser/api/lib/ipc-main.coffee
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{EventEmitter} = require 'events'
|
||||||
|
|
||||||
|
module.exports = new EventEmitter
|
|
@ -1,3 +1,6 @@
|
||||||
EventEmitter = require('events').EventEmitter
|
deprecate = require 'deprecate'
|
||||||
|
|
||||||
module.exports = new EventEmitter
|
# This module is deprecated, we mirror everything from ipcMain.
|
||||||
|
deprecate.warn 'ipc module', 'ipcMain module'
|
||||||
|
|
||||||
|
module.exports = require 'ipc-main'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ipc = require 'ipc'
|
ipc = require 'ipc-main'
|
||||||
|
|
||||||
# The history operation in renderer is redirected to browser.
|
# The history operation in renderer is redirected to browser.
|
||||||
ipc.on 'ATOM_SHELL_NAVIGATION_CONTROLLER', (event, method, args...) ->
|
ipc.on 'ATOM_SHELL_NAVIGATION_CONTROLLER', (event, method, args...) ->
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
EventEmitter = require('events').EventEmitter
|
EventEmitter = require('events').EventEmitter
|
||||||
|
Menu = require './menu'
|
||||||
NavigationController = require './navigation-controller'
|
NavigationController = require './navigation-controller'
|
||||||
binding = process.atomBinding 'web_contents'
|
binding = process.atomBinding 'web_contents'
|
||||||
ipc = require 'ipc'
|
ipc = require 'ipc-main'
|
||||||
|
|
||||||
nextId = 0
|
nextId = 0
|
||||||
getNextId = -> ++nextId
|
getNextId = -> ++nextId
|
||||||
|
@ -65,6 +66,11 @@ wrapWebContents = (webContents) ->
|
||||||
Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value)
|
Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value)
|
||||||
ipc.emit channel, event, args...
|
ipc.emit channel, event, args...
|
||||||
|
|
||||||
|
# Handle context menu action request from pepper plugin.
|
||||||
|
webContents.on 'pepper-context-menu', (event, params) ->
|
||||||
|
menu = Menu.buildFromTemplate params.menu
|
||||||
|
menu.popup params.x, params.y
|
||||||
|
|
||||||
webContents.printToPDF = (options, callback) ->
|
webContents.printToPDF = (options, callback) ->
|
||||||
printingSetting =
|
printingSetting =
|
||||||
pageRage: []
|
pageRage: []
|
||||||
|
@ -106,7 +112,6 @@ wrapWebContents = (webContents) ->
|
||||||
@_printToPDF printingSetting, callback
|
@_printToPDF printingSetting, callback
|
||||||
|
|
||||||
binding._setWrapWebContents wrapWebContents
|
binding._setWrapWebContents wrapWebContents
|
||||||
process.once 'exit', binding._clearWrapWebContents
|
|
||||||
|
|
||||||
module.exports.create = (options={}) ->
|
module.exports.create = (options={}) ->
|
||||||
binding.create(options)
|
binding.create(options)
|
||||||
|
|
83
atom/browser/api/save_page_handler.cc
Normal file
83
atom/browser/api/save_page_handler.cc
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
// 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/browser/api/save_page_handler.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "atom/browser/atom_browser_context.h"
|
||||||
|
#include "base/callback.h"
|
||||||
|
#include "base/files/file_path.h"
|
||||||
|
#include "content/public/browser/web_contents.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
SavePageHandler::SavePageHandler(content::WebContents* web_contents,
|
||||||
|
const SavePageCallback& callback)
|
||||||
|
: web_contents_(web_contents),
|
||||||
|
callback_(callback) {
|
||||||
|
}
|
||||||
|
|
||||||
|
SavePageHandler::~SavePageHandler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavePageHandler::OnDownloadCreated(content::DownloadManager* manager,
|
||||||
|
content::DownloadItem* item) {
|
||||||
|
// OnDownloadCreated is invoked during WebContents::SavePage, so the |item|
|
||||||
|
// here is the one stated by WebContents::SavePage.
|
||||||
|
item->AddObserver(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SavePageHandler::Handle(const base::FilePath& full_path,
|
||||||
|
const content::SavePageType& save_type) {
|
||||||
|
auto download_manager = content::BrowserContext::GetDownloadManager(
|
||||||
|
web_contents_->GetBrowserContext());
|
||||||
|
download_manager->AddObserver(this);
|
||||||
|
// Chromium will create a 'foo_files' directory under the directory of saving
|
||||||
|
// page 'foo.html' for holding other resource files of 'foo.html'.
|
||||||
|
base::FilePath saved_main_directory_path = full_path.DirName().Append(
|
||||||
|
full_path.RemoveExtension().BaseName().value() +
|
||||||
|
FILE_PATH_LITERAL("_files"));
|
||||||
|
bool result = web_contents_->SavePage(full_path,
|
||||||
|
saved_main_directory_path,
|
||||||
|
save_type);
|
||||||
|
download_manager->RemoveObserver(this);
|
||||||
|
// If initialization fails which means fail to create |DownloadItem|, we need
|
||||||
|
// to delete the |SavePageHandler| instance to avoid memory-leak.
|
||||||
|
if (!result)
|
||||||
|
delete this;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavePageHandler::OnDownloadUpdated(content::DownloadItem* item) {
|
||||||
|
if (item->IsDone()) {
|
||||||
|
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||||
|
v8::Locker locker(isolate);
|
||||||
|
v8::HandleScope handle_scope(isolate);
|
||||||
|
if (item->GetState() == content::DownloadItem::COMPLETE) {
|
||||||
|
callback_.Run(v8::Null(isolate));
|
||||||
|
} else {
|
||||||
|
v8::Local<v8::String> error_message = v8::String::NewFromUtf8(
|
||||||
|
isolate, "Fail to save page");
|
||||||
|
callback_.Run(v8::Exception::Error(error_message));
|
||||||
|
}
|
||||||
|
Destroy(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavePageHandler::Destroy(content::DownloadItem* item) {
|
||||||
|
item->RemoveObserver(this);
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool SavePageHandler::IsSavePageTypes(const std::string& type) {
|
||||||
|
return type == "multipart/related" || type == "text/html";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
60
atom/browser/api/save_page_handler.h
Normal file
60
atom/browser/api/save_page_handler.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_SAVE_PAGE_HANDLER_H_
|
||||||
|
#define ATOM_BROWSER_API_SAVE_PAGE_HANDLER_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "content/public/browser/download_item.h"
|
||||||
|
#include "content/public/browser/download_manager.h"
|
||||||
|
#include "content/public/browser/save_page_type.h"
|
||||||
|
#include "v8/include/v8.h"
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
class FilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace content {
|
||||||
|
class WebContents;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
|
||||||
|
// A self-destroyed class for handling save page request.
|
||||||
|
class SavePageHandler : public content::DownloadManager::Observer,
|
||||||
|
public content::DownloadItem::Observer {
|
||||||
|
public:
|
||||||
|
using SavePageCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||||
|
|
||||||
|
SavePageHandler(content::WebContents* web_contents,
|
||||||
|
const SavePageCallback& callback);
|
||||||
|
~SavePageHandler();
|
||||||
|
|
||||||
|
bool Handle(const base::FilePath& full_path,
|
||||||
|
const content::SavePageType& save_type);
|
||||||
|
|
||||||
|
static bool IsSavePageTypes(const std::string& type);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Destroy(content::DownloadItem* item);
|
||||||
|
|
||||||
|
// content::DownloadManager::Observer:
|
||||||
|
void OnDownloadCreated(content::DownloadManager* manager,
|
||||||
|
content::DownloadItem* item) override;
|
||||||
|
|
||||||
|
// content::DownloadItem::Observer:
|
||||||
|
void OnDownloadUpdated(content::DownloadItem* item) override;
|
||||||
|
|
||||||
|
content::WebContents* web_contents_; // weak
|
||||||
|
SavePageCallback callback_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace api
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
#endif // ATOM_BROWSER_API_SAVE_PAGE_HANDLER_H_
|
|
@ -60,7 +60,8 @@ std::string RemoveWhitespace(const std::string& str) {
|
||||||
AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
||||||
bool in_memory)
|
bool in_memory)
|
||||||
: brightray::BrowserContext(partition, in_memory),
|
: brightray::BrowserContext(partition, in_memory),
|
||||||
job_factory_(new AtomURLRequestJobFactory) {
|
job_factory_(new AtomURLRequestJobFactory),
|
||||||
|
allow_ntlm_everywhere_(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AtomBrowserContext::~AtomBrowserContext() {
|
AtomBrowserContext::~AtomBrowserContext() {
|
||||||
|
@ -168,6 +169,16 @@ void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
|
||||||
base::FilePath());
|
base::FilePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AtomBrowserContext::AllowNTLMCredentialsForDomain(const GURL& origin) {
|
||||||
|
if (allow_ntlm_everywhere_)
|
||||||
|
return true;
|
||||||
|
return Delegate::AllowNTLMCredentialsForDomain(origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AtomBrowserContext::AllowNTLMCredentialsForAllDomains(bool should_allow) {
|
||||||
|
allow_ntlm_everywhere_ = should_allow;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
||||||
namespace brightray {
|
namespace brightray {
|
||||||
|
|
|
@ -28,6 +28,7 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||||
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
|
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
|
||||||
const base::FilePath& base_path) override;
|
const base::FilePath& base_path) override;
|
||||||
net::SSLConfigService* CreateSSLConfigService() override;
|
net::SSLConfigService* CreateSSLConfigService() override;
|
||||||
|
bool AllowNTLMCredentialsForDomain(const GURL& auth_origin) override;
|
||||||
|
|
||||||
// content::BrowserContext:
|
// content::BrowserContext:
|
||||||
content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
|
content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
|
||||||
|
@ -36,6 +37,8 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||||
// brightray::BrowserContext:
|
// brightray::BrowserContext:
|
||||||
void RegisterPrefs(PrefRegistrySimple* pref_registry) override;
|
void RegisterPrefs(PrefRegistrySimple* pref_registry) override;
|
||||||
|
|
||||||
|
void AllowNTLMCredentialsForAllDomains(bool should_allow);
|
||||||
|
|
||||||
AtomURLRequestJobFactory* job_factory() const { return job_factory_; }
|
AtomURLRequestJobFactory* job_factory() const { return job_factory_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -45,6 +48,8 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||||
// Managed by brightray::BrowserContext.
|
// Managed by brightray::BrowserContext.
|
||||||
AtomURLRequestJobFactory* job_factory_;
|
AtomURLRequestJobFactory* job_factory_;
|
||||||
|
|
||||||
|
bool allow_ntlm_everywhere_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
|
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL;
|
||||||
|
|
||||||
AtomBrowserMainParts::AtomBrowserMainParts()
|
AtomBrowserMainParts::AtomBrowserMainParts()
|
||||||
: fake_browser_process_(new BrowserProcess),
|
: fake_browser_process_(new BrowserProcess),
|
||||||
|
exit_code_(nullptr),
|
||||||
browser_(new Browser),
|
browser_(new Browser),
|
||||||
node_bindings_(NodeBindings::Create(true)),
|
node_bindings_(NodeBindings::Create(true)),
|
||||||
atom_bindings_(new AtomBindings),
|
atom_bindings_(new AtomBindings),
|
||||||
|
@ -47,6 +48,14 @@ AtomBrowserMainParts* AtomBrowserMainParts::Get() {
|
||||||
return self_;
|
return self_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AtomBrowserMainParts::SetExitCode(int code) {
|
||||||
|
if (!exit_code_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*exit_code_ = code;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void AtomBrowserMainParts::RegisterDestructionCallback(
|
void AtomBrowserMainParts::RegisterDestructionCallback(
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
destruction_callbacks_.push_back(callback);
|
destruction_callbacks_.push_back(callback);
|
||||||
|
@ -62,17 +71,15 @@ void AtomBrowserMainParts::PreEarlyInitialization() {
|
||||||
void AtomBrowserMainParts::PostEarlyInitialization() {
|
void AtomBrowserMainParts::PostEarlyInitialization() {
|
||||||
brightray::BrowserMainParts::PostEarlyInitialization();
|
brightray::BrowserMainParts::PostEarlyInitialization();
|
||||||
|
|
||||||
{
|
// Temporary set the bridge_task_runner_ as current thread's task runner,
|
||||||
// Temporary set the bridge_task_runner_ as current thread's task runner,
|
// so we can fool gin::PerIsolateData to use it as its task runner, instead
|
||||||
// so we can fool gin::PerIsolateData to use it as its task runner, instead
|
// of getting current message loop's task runner, which is null for now.
|
||||||
// of getting current message loop's task runner, which is null for now.
|
bridge_task_runner_ = new BridgeTaskRunner;
|
||||||
bridge_task_runner_ = new BridgeTaskRunner;
|
base::ThreadTaskRunnerHandle handle(bridge_task_runner_);
|
||||||
base::ThreadTaskRunnerHandle handle(bridge_task_runner_);
|
|
||||||
|
|
||||||
// The ProxyResolverV8 has setup a complete V8 environment, in order to
|
// The ProxyResolverV8 has setup a complete V8 environment, in order to
|
||||||
// avoid conflicts we only initialize our V8 environment after that.
|
// avoid conflicts we only initialize our V8 environment after that.
|
||||||
js_env_.reset(new JavascriptEnvironment);
|
js_env_.reset(new JavascriptEnvironment);
|
||||||
}
|
|
||||||
|
|
||||||
node_bindings_->Initialize();
|
node_bindings_->Initialize();
|
||||||
|
|
||||||
|
@ -107,6 +114,7 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
|
||||||
1000));
|
1000));
|
||||||
|
|
||||||
brightray::BrowserMainParts::PreMainMessageLoopRun();
|
brightray::BrowserMainParts::PreMainMessageLoopRun();
|
||||||
|
BridgeTaskRunner::MessageLoopIsReady();
|
||||||
|
|
||||||
#if defined(USE_X11)
|
#if defined(USE_X11)
|
||||||
libgtk2ui::GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess());
|
libgtk2ui::GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess());
|
||||||
|
@ -119,6 +127,11 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AtomBrowserMainParts::MainMessageLoopRun(int* result_code) {
|
||||||
|
exit_code_ = result_code;
|
||||||
|
return brightray::BrowserMainParts::MainMessageLoopRun(result_code);
|
||||||
|
}
|
||||||
|
|
||||||
void AtomBrowserMainParts::PostMainMessageLoopStart() {
|
void AtomBrowserMainParts::PostMainMessageLoopStart() {
|
||||||
brightray::BrowserMainParts::PostMainMessageLoopStart();
|
brightray::BrowserMainParts::PostMainMessageLoopStart();
|
||||||
#if defined(OS_POSIX)
|
#if defined(OS_POSIX)
|
||||||
|
@ -129,11 +142,23 @@ void AtomBrowserMainParts::PostMainMessageLoopStart() {
|
||||||
void AtomBrowserMainParts::PostMainMessageLoopRun() {
|
void AtomBrowserMainParts::PostMainMessageLoopRun() {
|
||||||
brightray::BrowserMainParts::PostMainMessageLoopRun();
|
brightray::BrowserMainParts::PostMainMessageLoopRun();
|
||||||
|
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
FreeAppDelegate();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Make sure destruction callbacks are called before message loop is
|
// Make sure destruction callbacks are called before message loop is
|
||||||
// destroyed, otherwise some objects that need to be deleted on IO thread
|
// destroyed, otherwise some objects that need to be deleted on IO thread
|
||||||
// won't be freed.
|
// won't be freed.
|
||||||
for (const auto& callback : destruction_callbacks_)
|
for (const auto& callback : destruction_callbacks_)
|
||||||
callback.Run();
|
callback.Run();
|
||||||
|
|
||||||
|
// Destroy JavaScript environment immediately after running destruction
|
||||||
|
// callbacks.
|
||||||
|
gc_timer_.Stop();
|
||||||
|
node_debugger_.reset();
|
||||||
|
atom_bindings_.reset();
|
||||||
|
node_bindings_.reset();
|
||||||
|
js_env_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
|
@ -31,6 +31,9 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||||
|
|
||||||
static AtomBrowserMainParts* Get();
|
static AtomBrowserMainParts* Get();
|
||||||
|
|
||||||
|
// Sets the exit code, will fail if the the message loop is not ready.
|
||||||
|
bool SetExitCode(int code);
|
||||||
|
|
||||||
// Register a callback that should be destroyed before JavaScript environment
|
// Register a callback that should be destroyed before JavaScript environment
|
||||||
// gets destroyed.
|
// gets destroyed.
|
||||||
void RegisterDestructionCallback(const base::Closure& callback);
|
void RegisterDestructionCallback(const base::Closure& callback);
|
||||||
|
@ -42,11 +45,11 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||||
void PreEarlyInitialization() override;
|
void PreEarlyInitialization() override;
|
||||||
void PostEarlyInitialization() override;
|
void PostEarlyInitialization() override;
|
||||||
void PreMainMessageLoopRun() override;
|
void PreMainMessageLoopRun() override;
|
||||||
|
bool MainMessageLoopRun(int* result_code) override;
|
||||||
void PostMainMessageLoopStart() override;
|
void PostMainMessageLoopStart() override;
|
||||||
void PostMainMessageLoopRun() override;
|
void PostMainMessageLoopRun() override;
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
void PreMainMessageLoopStart() override;
|
void PreMainMessageLoopStart() override;
|
||||||
void PostDestroyThreads() override;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -56,6 +59,10 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||||
void HandleShutdownSignals();
|
void HandleShutdownSignals();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
void FreeAppDelegate();
|
||||||
|
#endif
|
||||||
|
|
||||||
// A fake BrowserProcess object that used to feed the source code from chrome.
|
// A fake BrowserProcess object that used to feed the source code from chrome.
|
||||||
scoped_ptr<BrowserProcess> fake_browser_process_;
|
scoped_ptr<BrowserProcess> fake_browser_process_;
|
||||||
|
|
||||||
|
@ -63,6 +70,9 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||||
// with a task runner that will post all work to main loop.
|
// with a task runner that will post all work to main loop.
|
||||||
scoped_refptr<BridgeTaskRunner> bridge_task_runner_;
|
scoped_refptr<BridgeTaskRunner> bridge_task_runner_;
|
||||||
|
|
||||||
|
// Pointer to exit code.
|
||||||
|
int* exit_code_;
|
||||||
|
|
||||||
scoped_ptr<Browser> browser_;
|
scoped_ptr<Browser> browser_;
|
||||||
scoped_ptr<JavascriptEnvironment> js_env_;
|
scoped_ptr<JavascriptEnvironment> js_env_;
|
||||||
scoped_ptr<NodeBindings> node_bindings_;
|
scoped_ptr<NodeBindings> node_bindings_;
|
||||||
|
|
|
@ -34,7 +34,7 @@ void AtomBrowserMainParts::PreMainMessageLoopStart() {
|
||||||
setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
|
setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomBrowserMainParts::PostDestroyThreads() {
|
void AtomBrowserMainParts::FreeAppDelegate() {
|
||||||
[[NSApp delegate] release];
|
[[NSApp delegate] release];
|
||||||
[NSApp setDelegate:nil];
|
[NSApp setDelegate:nil];
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
|
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
|
||||||
|
|
||||||
|
#include "atom/browser/login_handler.h"
|
||||||
#include "atom/common/platform_util.h"
|
#include "atom/common/platform_util.h"
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
#include "net/base/escape.h"
|
#include "net/base/escape.h"
|
||||||
|
@ -29,4 +30,11 @@ bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
content::ResourceDispatcherHostLoginDelegate*
|
||||||
|
AtomResourceDispatcherHostDelegate::CreateLoginDelegate(
|
||||||
|
net::AuthChallengeInfo* auth_info,
|
||||||
|
net::URLRequest* request) {
|
||||||
|
return new LoginHandler(auth_info, request);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
|
@ -21,6 +21,9 @@ class AtomResourceDispatcherHostDelegate
|
||||||
bool is_main_frame,
|
bool is_main_frame,
|
||||||
ui::PageTransition transition,
|
ui::PageTransition transition,
|
||||||
bool has_user_gesture) override;
|
bool has_user_gesture) override;
|
||||||
|
content::ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
|
||||||
|
net::AuthChallengeInfo* auth_info,
|
||||||
|
net::URLRequest* request) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
|
@ -5,11 +5,14 @@
|
||||||
#include "atom/browser/atom_ssl_config_service.h"
|
#include "atom/browser/atom_ssl_config_service.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
|
#include "base/strings/string_split.h"
|
||||||
#include "atom/common/options_switches.h"
|
#include "atom/common/options_switches.h"
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
#include "net/socket/ssl_client_socket.h"
|
#include "net/socket/ssl_client_socket.h"
|
||||||
|
#include "net/ssl/ssl_cipher_suite_names.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
@ -26,6 +29,23 @@ uint16 GetSSLProtocolVersion(const std::string& version_string) {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<uint16> ParseCipherSuites(
|
||||||
|
const std::vector<std::string>& cipher_strings) {
|
||||||
|
std::vector<uint16> cipher_suites;
|
||||||
|
cipher_suites.reserve(cipher_strings.size());
|
||||||
|
|
||||||
|
for (auto& cipher_string : cipher_strings) {
|
||||||
|
uint16 cipher_suite = 0;
|
||||||
|
if (!net::ParseSSLCipherString(cipher_string, &cipher_suite)) {
|
||||||
|
LOG(ERROR) << "Ignoring unrecognised cipher suite : "
|
||||||
|
<< cipher_string;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cipher_suites.push_back(cipher_suite);
|
||||||
|
}
|
||||||
|
return cipher_suites;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
AtomSSLConfigService::AtomSSLConfigService() {
|
AtomSSLConfigService::AtomSSLConfigService() {
|
||||||
|
@ -35,6 +55,13 @@ AtomSSLConfigService::AtomSSLConfigService() {
|
||||||
cmd_line->GetSwitchValueASCII(switches::kSSLVersionFallbackMin);
|
cmd_line->GetSwitchValueASCII(switches::kSSLVersionFallbackMin);
|
||||||
config_.version_fallback_min = GetSSLProtocolVersion(version_string);
|
config_.version_fallback_min = GetSSLProtocolVersion(version_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cmd_line->HasSwitch(switches::kCipherSuiteBlacklist)) {
|
||||||
|
auto cipher_strings = base::SplitString(
|
||||||
|
cmd_line->GetSwitchValueASCII(switches::kCipherSuiteBlacklist),
|
||||||
|
",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||||
|
config_.disabled_cipher_suites = ParseCipherSuites(cipher_strings);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AtomSSLConfigService::~AtomSSLConfigService() {
|
AtomSSLConfigService::~AtomSSLConfigService() {
|
||||||
|
|
|
@ -6,14 +6,25 @@
|
||||||
|
|
||||||
namespace auto_updater {
|
namespace auto_updater {
|
||||||
|
|
||||||
AutoUpdaterDelegate* AutoUpdater::delegate_ = NULL;
|
Delegate* AutoUpdater::delegate_ = nullptr;
|
||||||
|
|
||||||
AutoUpdaterDelegate* AutoUpdater::GetDelegate() {
|
Delegate* AutoUpdater::GetDelegate() {
|
||||||
return delegate_;
|
return delegate_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoUpdater::SetDelegate(AutoUpdaterDelegate* delegate) {
|
void AutoUpdater::SetDelegate(Delegate* delegate) {
|
||||||
delegate_ = delegate;
|
delegate_ = delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(OS_MACOSX) || defined(MAS_BUILD)
|
||||||
|
void AutoUpdater::SetFeedURL(const std::string& url) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoUpdater::CheckForUpdates() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoUpdater::QuitAndInstall() {
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace auto_updater
|
} // namespace auto_updater
|
||||||
|
|
|
@ -9,21 +9,48 @@
|
||||||
|
|
||||||
#include "base/basictypes.h"
|
#include "base/basictypes.h"
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
class Time;
|
||||||
|
}
|
||||||
|
|
||||||
namespace auto_updater {
|
namespace auto_updater {
|
||||||
|
|
||||||
class AutoUpdaterDelegate;
|
class Delegate {
|
||||||
|
public:
|
||||||
|
// An error happened.
|
||||||
|
virtual void OnError(const std::string& error) {}
|
||||||
|
|
||||||
|
// Checking to see if there is an update
|
||||||
|
virtual void OnCheckingForUpdate() {}
|
||||||
|
|
||||||
|
// There is an update available and it is being downloaded
|
||||||
|
virtual void OnUpdateAvailable() {}
|
||||||
|
|
||||||
|
// There is no available update.
|
||||||
|
virtual void OnUpdateNotAvailable() {}
|
||||||
|
|
||||||
|
// There is a new update which has been downloaded.
|
||||||
|
virtual void OnUpdateDownloaded(const std::string& release_notes,
|
||||||
|
const std::string& release_name,
|
||||||
|
const base::Time& release_date,
|
||||||
|
const std::string& update_url) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~Delegate() {}
|
||||||
|
};
|
||||||
|
|
||||||
class AutoUpdater {
|
class AutoUpdater {
|
||||||
public:
|
public:
|
||||||
// Gets/Sets the delegate.
|
// Gets/Sets the delegate.
|
||||||
static AutoUpdaterDelegate* GetDelegate();
|
static Delegate* GetDelegate();
|
||||||
static void SetDelegate(AutoUpdaterDelegate* delegate);
|
static void SetDelegate(Delegate* delegate);
|
||||||
|
|
||||||
static void SetFeedURL(const std::string& url);
|
static void SetFeedURL(const std::string& url);
|
||||||
static void CheckForUpdates();
|
static void CheckForUpdates();
|
||||||
|
static void QuitAndInstall();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static AutoUpdaterDelegate* delegate_;
|
static Delegate* delegate_;
|
||||||
|
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(AutoUpdater);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(AutoUpdater);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,45 +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.
|
|
||||||
|
|
||||||
#ifndef ATOM_BROWSER_AUTO_UPDATER_DELEGATE_H_
|
|
||||||
#define ATOM_BROWSER_AUTO_UPDATER_DELEGATE_H_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "base/callback_forward.h"
|
|
||||||
|
|
||||||
namespace base {
|
|
||||||
class Time;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace auto_updater {
|
|
||||||
|
|
||||||
class AutoUpdaterDelegate {
|
|
||||||
public:
|
|
||||||
// An error happened.
|
|
||||||
virtual void OnError(const std::string& error) {}
|
|
||||||
|
|
||||||
// Checking to see if there is an update
|
|
||||||
virtual void OnCheckingForUpdate() {}
|
|
||||||
|
|
||||||
// There is an update available and it is being downloaded
|
|
||||||
virtual void OnUpdateAvailable() {}
|
|
||||||
|
|
||||||
// There is no available update.
|
|
||||||
virtual void OnUpdateNotAvailable() {}
|
|
||||||
|
|
||||||
// There is a new update which has been downloaded.
|
|
||||||
virtual void OnUpdateDownloaded(const std::string& release_notes,
|
|
||||||
const std::string& release_name,
|
|
||||||
const base::Time& release_date,
|
|
||||||
const std::string& update_url,
|
|
||||||
const base::Closure& quit_and_install) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual ~AutoUpdaterDelegate() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace auto_updater
|
|
||||||
|
|
||||||
#endif // ATOM_BROWSER_AUTO_UPDATER_DELEGATE_H_
|
|
|
@ -1,17 +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/browser/auto_updater.h"
|
|
||||||
|
|
||||||
namespace auto_updater {
|
|
||||||
|
|
||||||
// static
|
|
||||||
void AutoUpdater::SetFeedURL(const std::string& url) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
void AutoUpdater::CheckForUpdates() {
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace auto_updater
|
|
|
@ -12,9 +12,6 @@
|
||||||
#include "base/bind.h"
|
#include "base/bind.h"
|
||||||
#include "base/time/time.h"
|
#include "base/time/time.h"
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
#include "atom/browser/auto_updater_delegate.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace auto_updater {
|
namespace auto_updater {
|
||||||
|
|
||||||
|
@ -23,20 +20,12 @@ namespace {
|
||||||
// The gloal SQRLUpdater object.
|
// The gloal SQRLUpdater object.
|
||||||
SQRLUpdater* g_updater = nil;
|
SQRLUpdater* g_updater = nil;
|
||||||
|
|
||||||
void RelaunchToInstallUpdate() {
|
|
||||||
[[g_updater relaunchToInstallUpdate] subscribeError:^(NSError* error) {
|
|
||||||
AutoUpdaterDelegate* delegate = AutoUpdater::GetDelegate();
|
|
||||||
if (delegate)
|
|
||||||
delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription));
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void AutoUpdater::SetFeedURL(const std::string& feed) {
|
void AutoUpdater::SetFeedURL(const std::string& feed) {
|
||||||
if (g_updater == nil) {
|
if (g_updater == nil) {
|
||||||
AutoUpdaterDelegate* delegate = GetDelegate();
|
Delegate* delegate = GetDelegate();
|
||||||
if (!delegate)
|
if (!delegate)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -67,7 +56,7 @@ void AutoUpdater::SetFeedURL(const std::string& feed) {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void AutoUpdater::CheckForUpdates() {
|
void AutoUpdater::CheckForUpdates() {
|
||||||
AutoUpdaterDelegate* delegate = GetDelegate();
|
Delegate* delegate = GetDelegate();
|
||||||
if (!delegate)
|
if (!delegate)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -86,8 +75,7 @@ void AutoUpdater::CheckForUpdates() {
|
||||||
base::SysNSStringToUTF8(update.releaseNotes),
|
base::SysNSStringToUTF8(update.releaseNotes),
|
||||||
base::SysNSStringToUTF8(update.releaseName),
|
base::SysNSStringToUTF8(update.releaseName),
|
||||||
base::Time::FromDoubleT(update.releaseDate.timeIntervalSince1970),
|
base::Time::FromDoubleT(update.releaseDate.timeIntervalSince1970),
|
||||||
base::SysNSStringToUTF8(update.updateURL.absoluteString),
|
base::SysNSStringToUTF8(update.updateURL.absoluteString));
|
||||||
base::Bind(RelaunchToInstallUpdate));
|
|
||||||
} else {
|
} else {
|
||||||
// When the completed event is sent with no update, then we know there
|
// When the completed event is sent with no update, then we know there
|
||||||
// is no update available.
|
// is no update available.
|
||||||
|
@ -100,4 +88,12 @@ void AutoUpdater::CheckForUpdates() {
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AutoUpdater::QuitAndInstall() {
|
||||||
|
[[g_updater relaunchToInstallUpdate] subscribeError:^(NSError* error) {
|
||||||
|
Delegate* delegate = AutoUpdater::GetDelegate();
|
||||||
|
if (delegate)
|
||||||
|
delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription));
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace auto_updater
|
} // namespace auto_updater
|
||||||
|
|
|
@ -1,17 +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/browser/auto_updater.h"
|
|
||||||
|
|
||||||
namespace auto_updater {
|
|
||||||
|
|
||||||
// static
|
|
||||||
void AutoUpdater::SetFeedURL(const std::string& url) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
void AutoUpdater::CheckForUpdates() {
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace auto_updater
|
|
|
@ -8,13 +8,33 @@
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
// static
|
||||||
|
std::vector<BridgeTaskRunner::TaskPair> BridgeTaskRunner::tasks_;
|
||||||
|
std::vector<BridgeTaskRunner::TaskPair> BridgeTaskRunner::non_nestable_tasks_;
|
||||||
|
|
||||||
|
// static
|
||||||
|
void BridgeTaskRunner::MessageLoopIsReady() {
|
||||||
|
auto message_loop = base::MessageLoop::current();
|
||||||
|
CHECK(message_loop);
|
||||||
|
for (const TaskPair& task : tasks_) {
|
||||||
|
message_loop->task_runner()->PostDelayedTask(
|
||||||
|
base::get<0>(task), base::get<1>(task), base::get<2>(task));
|
||||||
|
}
|
||||||
|
for (const TaskPair& task : non_nestable_tasks_) {
|
||||||
|
message_loop->task_runner()->PostNonNestableDelayedTask(
|
||||||
|
base::get<0>(task), base::get<1>(task), base::get<2>(task));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool BridgeTaskRunner::PostDelayedTask(
|
bool BridgeTaskRunner::PostDelayedTask(
|
||||||
const tracked_objects::Location& from_here,
|
const tracked_objects::Location& from_here,
|
||||||
const base::Closure& task,
|
const base::Closure& task,
|
||||||
base::TimeDelta delay) {
|
base::TimeDelta delay) {
|
||||||
auto message_loop = base::MessageLoop::current();
|
auto message_loop = base::MessageLoop::current();
|
||||||
if (!message_loop)
|
if (!message_loop) {
|
||||||
return false;
|
tasks_.push_back(base::MakeTuple(from_here, task, delay));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return message_loop->task_runner()->PostDelayedTask(from_here, task, delay);
|
return message_loop->task_runner()->PostDelayedTask(from_here, task, delay);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +42,7 @@ bool BridgeTaskRunner::PostDelayedTask(
|
||||||
bool BridgeTaskRunner::RunsTasksOnCurrentThread() const {
|
bool BridgeTaskRunner::RunsTasksOnCurrentThread() const {
|
||||||
auto message_loop = base::MessageLoop::current();
|
auto message_loop = base::MessageLoop::current();
|
||||||
if (!message_loop)
|
if (!message_loop)
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
return message_loop->task_runner()->RunsTasksOnCurrentThread();
|
return message_loop->task_runner()->RunsTasksOnCurrentThread();
|
||||||
}
|
}
|
||||||
|
@ -32,8 +52,10 @@ bool BridgeTaskRunner::PostNonNestableDelayedTask(
|
||||||
const base::Closure& task,
|
const base::Closure& task,
|
||||||
base::TimeDelta delay) {
|
base::TimeDelta delay) {
|
||||||
auto message_loop = base::MessageLoop::current();
|
auto message_loop = base::MessageLoop::current();
|
||||||
if (!message_loop)
|
if (!message_loop) {
|
||||||
return false;
|
non_nestable_tasks_.push_back(base::MakeTuple(from_here, task, delay));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return message_loop->task_runner()->PostNonNestableDelayedTask(
|
return message_loop->task_runner()->PostNonNestableDelayedTask(
|
||||||
from_here, task, delay);
|
from_here, task, delay);
|
||||||
|
|
|
@ -5,17 +5,23 @@
|
||||||
#ifndef ATOM_BROWSER_BRIDGE_TASK_RUNNER_H_
|
#ifndef ATOM_BROWSER_BRIDGE_TASK_RUNNER_H_
|
||||||
#define ATOM_BROWSER_BRIDGE_TASK_RUNNER_H_
|
#define ATOM_BROWSER_BRIDGE_TASK_RUNNER_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "base/single_thread_task_runner.h"
|
#include "base/single_thread_task_runner.h"
|
||||||
|
#include "base/tuple.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
// Post all tasks to the current message loop's task runner if available,
|
// Post all tasks to the current message loop's task runner if available,
|
||||||
// otherwise fail silently.
|
// otherwise delay the work until message loop is ready.
|
||||||
class BridgeTaskRunner : public base::SingleThreadTaskRunner {
|
class BridgeTaskRunner : public base::SingleThreadTaskRunner {
|
||||||
public:
|
public:
|
||||||
BridgeTaskRunner() {}
|
BridgeTaskRunner() {}
|
||||||
~BridgeTaskRunner() override {}
|
~BridgeTaskRunner() override {}
|
||||||
|
|
||||||
|
// Called when message loop is ready.
|
||||||
|
static void MessageLoopIsReady();
|
||||||
|
|
||||||
// base::SingleThreadTaskRunner:
|
// base::SingleThreadTaskRunner:
|
||||||
bool PostDelayedTask(const tracked_objects::Location& from_here,
|
bool PostDelayedTask(const tracked_objects::Location& from_here,
|
||||||
const base::Closure& task,
|
const base::Closure& task,
|
||||||
|
@ -27,6 +33,11 @@ class BridgeTaskRunner : public base::SingleThreadTaskRunner {
|
||||||
base::TimeDelta delay) override;
|
base::TimeDelta delay) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using TaskPair = base::Tuple<
|
||||||
|
tracked_objects::Location, base::Closure, base::TimeDelta>;
|
||||||
|
static std::vector<TaskPair> tasks_;
|
||||||
|
static std::vector<TaskPair> non_nestable_tasks_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(BridgeTaskRunner);
|
DISALLOW_COPY_AND_ASSIGN(BridgeTaskRunner);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "atom/browser/atom_browser_main_parts.h"
|
#include "atom/browser/atom_browser_main_parts.h"
|
||||||
|
#include "atom/browser/native_window.h"
|
||||||
#include "atom/browser/window_list.h"
|
#include "atom/browser/window_list.h"
|
||||||
#include "base/message_loop/message_loop.h"
|
#include "base/message_loop/message_loop.h"
|
||||||
#include "content/public/browser/client_certificate_delegate.h"
|
#include "content/public/browser/client_certificate_delegate.h"
|
||||||
|
@ -45,6 +46,27 @@ void Browser::Quit() {
|
||||||
window_list->CloseAllWindows();
|
window_list->CloseAllWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Browser::Exit(int code) {
|
||||||
|
if (!AtomBrowserMainParts::Get()->SetExitCode(code)) {
|
||||||
|
// Message loop is not ready, quit directly.
|
||||||
|
exit(code);
|
||||||
|
} else {
|
||||||
|
// Prepare to quit when all windows have been closed..
|
||||||
|
is_quiting_ = true;
|
||||||
|
|
||||||
|
// Must destroy windows before quitting, otherwise bad things can happen.
|
||||||
|
atom::WindowList* window_list = atom::WindowList::GetInstance();
|
||||||
|
if (window_list->size() == 0) {
|
||||||
|
NotifyAndShutdown();
|
||||||
|
} else {
|
||||||
|
// Unlike Quit(), we do not ask to close window, but destroy the window
|
||||||
|
// without asking.
|
||||||
|
for (NativeWindow* window : *window_list)
|
||||||
|
window->CloseContents(nullptr); // e.g. Destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Browser::Shutdown() {
|
void Browser::Shutdown() {
|
||||||
if (is_shutdown_)
|
if (is_shutdown_)
|
||||||
return;
|
return;
|
||||||
|
@ -53,8 +75,14 @@ void Browser::Shutdown() {
|
||||||
is_quiting_ = true;
|
is_quiting_ = true;
|
||||||
|
|
||||||
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnQuit());
|
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnQuit());
|
||||||
base::MessageLoop::current()->PostTask(
|
|
||||||
FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
|
if (base::MessageLoop::current()) {
|
||||||
|
base::MessageLoop::current()->PostTask(
|
||||||
|
FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
|
||||||
|
} else {
|
||||||
|
// There is no message loop available so we are in early stage.
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Browser::GetVersion() const {
|
std::string Browser::GetVersion() const {
|
||||||
|
@ -83,10 +111,6 @@ std::string Browser::GetName() const {
|
||||||
|
|
||||||
void Browser::SetName(const std::string& name) {
|
void Browser::SetName(const std::string& name) {
|
||||||
name_override_ = name;
|
name_override_ = name;
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
SetAppUserModelID(name);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Browser::OpenFile(const std::string& file_path) {
|
bool Browser::OpenFile(const std::string& file_path) {
|
||||||
|
@ -128,6 +152,10 @@ void Browser::ClientCertificateSelector(
|
||||||
delegate.Pass()));
|
delegate.Pass()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Browser::RequestLogin(LoginHandler* login_handler) {
|
||||||
|
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnLogin(login_handler));
|
||||||
|
}
|
||||||
|
|
||||||
void Browser::NotifyAndShutdown() {
|
void Browser::NotifyAndShutdown() {
|
||||||
if (is_shutdown_)
|
if (is_shutdown_)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -11,12 +11,12 @@
|
||||||
#include "base/basictypes.h"
|
#include "base/basictypes.h"
|
||||||
#include "base/compiler_specific.h"
|
#include "base/compiler_specific.h"
|
||||||
#include "base/observer_list.h"
|
#include "base/observer_list.h"
|
||||||
|
#include "base/strings/string16.h"
|
||||||
#include "atom/browser/browser_observer.h"
|
#include "atom/browser/browser_observer.h"
|
||||||
#include "atom/browser/window_list_observer.h"
|
#include "atom/browser/window_list_observer.h"
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/strings/string16.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
@ -29,6 +29,8 @@ class MenuModel;
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
class LoginHandler;
|
||||||
|
|
||||||
// This class is used for control application-wide operations.
|
// This class is used for control application-wide operations.
|
||||||
class Browser : public WindowListObserver {
|
class Browser : public WindowListObserver {
|
||||||
public:
|
public:
|
||||||
|
@ -40,6 +42,9 @@ class Browser : public WindowListObserver {
|
||||||
// Try to close all windows and quit the application.
|
// Try to close all windows and quit the application.
|
||||||
void Quit();
|
void Quit();
|
||||||
|
|
||||||
|
// Exit the application immediately and set exit code.
|
||||||
|
void Exit(int code);
|
||||||
|
|
||||||
// Cleanup everything and shutdown the application gracefully.
|
// Cleanup everything and shutdown the application gracefully.
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
|
@ -64,6 +69,9 @@ class Browser : public WindowListObserver {
|
||||||
// Clear the recent documents list.
|
// Clear the recent documents list.
|
||||||
void ClearRecentDocuments();
|
void ClearRecentDocuments();
|
||||||
|
|
||||||
|
// Set the application user model ID.
|
||||||
|
void SetAppUserModelID(const base::string16& name);
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
// Bounce the dock icon.
|
// Bounce the dock icon.
|
||||||
enum BounceType {
|
enum BounceType {
|
||||||
|
@ -98,8 +106,10 @@ class Browser : public WindowListObserver {
|
||||||
// Add a custom task to jump list.
|
// Add a custom task to jump list.
|
||||||
void SetUserTasks(const std::vector<UserTask>& tasks);
|
void SetUserTasks(const std::vector<UserTask>& tasks);
|
||||||
|
|
||||||
// Set the application user model ID, called when "SetName" is called.
|
// Returns the application user model ID, if there isn't one, then create
|
||||||
void SetAppUserModelID(const std::string& name);
|
// one from app's name.
|
||||||
|
// The returned string managed by Browser, and should not be modified.
|
||||||
|
PCWSTR GetAppUserModelID();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Tell the application to open a file.
|
// Tell the application to open a file.
|
||||||
|
@ -122,6 +132,9 @@ class Browser : public WindowListObserver {
|
||||||
net::SSLCertRequestInfo* cert_request_info,
|
net::SSLCertRequestInfo* cert_request_info,
|
||||||
scoped_ptr<content::ClientCertificateDelegate> delegate);
|
scoped_ptr<content::ClientCertificateDelegate> delegate);
|
||||||
|
|
||||||
|
// Request basic auth login.
|
||||||
|
void RequestLogin(LoginHandler* login_handler);
|
||||||
|
|
||||||
void AddObserver(BrowserObserver* obs) {
|
void AddObserver(BrowserObserver* obs) {
|
||||||
observers_.AddObserver(obs);
|
observers_.AddObserver(obs);
|
||||||
}
|
}
|
||||||
|
@ -130,6 +143,7 @@ class Browser : public WindowListObserver {
|
||||||
observers_.RemoveObserver(obs);
|
observers_.RemoveObserver(obs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_shutting_down() const { return is_shutdown_; }
|
||||||
bool is_quiting() const { return is_quiting_; }
|
bool is_quiting() const { return is_quiting_; }
|
||||||
bool is_ready() const { return is_ready_; }
|
bool is_ready() const { return is_ready_; }
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,9 @@ void Browser::AddRecentDocument(const base::FilePath& path) {
|
||||||
void Browser::ClearRecentDocuments() {
|
void Browser::ClearRecentDocuments() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Browser::SetAppUserModelID(const base::string16& name) {
|
||||||
|
}
|
||||||
|
|
||||||
std::string Browser::GetExecutableFileVersion() const {
|
std::string Browser::GetExecutableFileVersion() const {
|
||||||
return brightray::GetApplicationVersion();
|
return brightray::GetApplicationVersion();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,9 @@ void Browser::AddRecentDocument(const base::FilePath& path) {
|
||||||
void Browser::ClearRecentDocuments() {
|
void Browser::ClearRecentDocuments() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Browser::SetAppUserModelID(const base::string16& name) {
|
||||||
|
}
|
||||||
|
|
||||||
std::string Browser::GetExecutableFileVersion() const {
|
std::string Browser::GetExecutableFileVersion() const {
|
||||||
return brightray::GetApplicationVersion();
|
return brightray::GetApplicationVersion();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ class SSLCertRequestInfo;
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
class LoginHandler;
|
||||||
|
|
||||||
class BrowserObserver {
|
class BrowserObserver {
|
||||||
public:
|
public:
|
||||||
// The browser is about to close all windows.
|
// The browser is about to close all windows.
|
||||||
|
@ -57,6 +59,9 @@ class BrowserObserver {
|
||||||
net::SSLCertRequestInfo* cert_request_info,
|
net::SSLCertRequestInfo* cert_request_info,
|
||||||
scoped_ptr<content::ClientCertificateDelegate> delegate) {}
|
scoped_ptr<content::ClientCertificateDelegate> delegate) {}
|
||||||
|
|
||||||
|
// The browser requests HTTP login.
|
||||||
|
virtual void OnLogin(LoginHandler* login_handler) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~BrowserObserver() {}
|
virtual ~BrowserObserver() {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
|
#include "base/strings/string_util.h"
|
||||||
#include "base/strings/stringprintf.h"
|
#include "base/strings/stringprintf.h"
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
#include "base/win/win_util.h"
|
#include "base/win/win_util.h"
|
||||||
|
@ -25,6 +26,8 @@ namespace atom {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
const wchar_t kAppUserModelIDFormat[] = L"electron.app.$1";
|
||||||
|
|
||||||
BOOL CALLBACK WindowsEnumerationHandler(HWND hwnd, LPARAM param) {
|
BOOL CALLBACK WindowsEnumerationHandler(HWND hwnd, LPARAM param) {
|
||||||
DWORD target_process_id = *reinterpret_cast<DWORD*>(param);
|
DWORD target_process_id = *reinterpret_cast<DWORD*>(param);
|
||||||
DWORD process_id = 0;
|
DWORD process_id = 0;
|
||||||
|
@ -56,7 +59,7 @@ void Browser::AddRecentDocument(const base::FilePath& path) {
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
SHARDAPPIDINFO info;
|
SHARDAPPIDINFO info;
|
||||||
info.psi = item;
|
info.psi = item;
|
||||||
info.pszAppID = app_user_model_id_.c_str();
|
info.pszAppID = GetAppUserModelID();
|
||||||
SHAddToRecentDocs(SHARD_APPIDINFO, &info);
|
SHAddToRecentDocs(SHARD_APPIDINFO, &info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,16 +69,21 @@ void Browser::ClearRecentDocuments() {
|
||||||
if (FAILED(destinations.CoCreateInstance(CLSID_ApplicationDestinations,
|
if (FAILED(destinations.CoCreateInstance(CLSID_ApplicationDestinations,
|
||||||
NULL, CLSCTX_INPROC_SERVER)))
|
NULL, CLSCTX_INPROC_SERVER)))
|
||||||
return;
|
return;
|
||||||
if (FAILED(destinations->SetAppID(app_user_model_id_.c_str())))
|
if (FAILED(destinations->SetAppID(GetAppUserModelID())))
|
||||||
return;
|
return;
|
||||||
destinations->RemoveAllDestinations();
|
destinations->RemoveAllDestinations();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Browser::SetAppUserModelID(const base::string16& name) {
|
||||||
|
app_user_model_id_ = name;
|
||||||
|
SetCurrentProcessExplicitAppUserModelID(app_user_model_id_.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
void Browser::SetUserTasks(const std::vector<UserTask>& tasks) {
|
void Browser::SetUserTasks(const std::vector<UserTask>& tasks) {
|
||||||
CComPtr<ICustomDestinationList> destinations;
|
CComPtr<ICustomDestinationList> destinations;
|
||||||
if (FAILED(destinations.CoCreateInstance(CLSID_DestinationList)))
|
if (FAILED(destinations.CoCreateInstance(CLSID_DestinationList)))
|
||||||
return;
|
return;
|
||||||
if (FAILED(destinations->SetAppID(app_user_model_id_.c_str())))
|
if (FAILED(destinations->SetAppID(GetAppUserModelID())))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Start a transaction that updates the JumpList of this application.
|
// Start a transaction that updates the JumpList of this application.
|
||||||
|
@ -117,10 +125,13 @@ void Browser::SetUserTasks(const std::vector<UserTask>& tasks) {
|
||||||
destinations->CommitList();
|
destinations->CommitList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Browser::SetAppUserModelID(const std::string& name) {
|
PCWSTR Browser::GetAppUserModelID() {
|
||||||
app_user_model_id_ = base::string16(L"electron.app.");
|
if (app_user_model_id_.empty()) {
|
||||||
app_user_model_id_ += base::UTF8ToUTF16(name);
|
SetAppUserModelID(ReplaceStringPlaceholders(
|
||||||
SetCurrentProcessExplicitAppUserModelID(app_user_model_id_.c_str());
|
kAppUserModelIDFormat, base::UTF8ToUTF16(GetName()), nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
return app_user_model_id_.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Browser::GetExecutableFileVersion() const {
|
std::string Browser::GetExecutableFileVersion() const {
|
||||||
|
|
|
@ -12,8 +12,8 @@ app.on('ready', function() {
|
||||||
mainWindow = new BrowserWindow({
|
mainWindow = new BrowserWindow({
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
'auto-hide-menu-bar': true,
|
autoHideMenuBar: true,
|
||||||
'use-content-size': true,
|
useContentSize: true,
|
||||||
});
|
});
|
||||||
mainWindow.loadUrl('file://' + __dirname + '/index.html');
|
mainWindow.loadUrl('file://' + __dirname + '/index.html');
|
||||||
mainWindow.focus();
|
mainWindow.focus();
|
||||||
|
|
|
@ -18,6 +18,9 @@ for (var i = 0; i < argv.length; i++) {
|
||||||
if (argv[i] == '--version' || argv[i] == '-v') {
|
if (argv[i] == '--version' || argv[i] == '-v') {
|
||||||
option.version = true;
|
option.version = true;
|
||||||
break;
|
break;
|
||||||
|
} else if (argv[i].match(/^--app=/)) {
|
||||||
|
option.file = argv[i].split('=')[1];
|
||||||
|
break;
|
||||||
} else if (argv[i] == '--help' || argv[i] == '-h') {
|
} else if (argv[i] == '--help' || argv[i] == '-h') {
|
||||||
option.help = true;
|
option.help = true;
|
||||||
break;
|
break;
|
||||||
|
@ -260,7 +263,7 @@ if (option.file && !option.webdriver) {
|
||||||
helpMessage += "A path to an Electron application may be specified. The path must be to \n";
|
helpMessage += "A path to an Electron application may be specified. The path must be to \n";
|
||||||
helpMessage += "an index.js file or to a folder containing a package.json or index.js file.\n\n";
|
helpMessage += "an index.js file or to a folder containing a package.json or index.js file.\n\n";
|
||||||
helpMessage += "Options:\n";
|
helpMessage += "Options:\n";
|
||||||
helpMessage += " -r, --require Module to preload (option can be repeated)";
|
helpMessage += " -r, --require Module to preload (option can be repeated)\n";
|
||||||
helpMessage += " -h, --help Print this usage message.\n";
|
helpMessage += " -h, --help Print this usage message.\n";
|
||||||
helpMessage += " -v, --version Print the version.";
|
helpMessage += " -v, --version Print the version.";
|
||||||
console.log(helpMessage);
|
console.log(helpMessage);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "atom/browser/javascript_environment.h"
|
#include "atom/browser/javascript_environment.h"
|
||||||
|
|
||||||
|
#include "base/command_line.h"
|
||||||
#include "gin/array_buffer.h"
|
#include "gin/array_buffer.h"
|
||||||
#include "gin/v8_initializer.h"
|
#include "gin/v8_initializer.h"
|
||||||
|
|
||||||
|
@ -20,7 +21,12 @@ JavascriptEnvironment::JavascriptEnvironment()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JavascriptEnvironment::Initialize() {
|
bool JavascriptEnvironment::Initialize() {
|
||||||
gin::V8Initializer::LoadV8Snapshot();
|
auto cmd = base::CommandLine::ForCurrentProcess();
|
||||||
|
if (cmd->HasSwitch("debug-brk")) {
|
||||||
|
// Need to be called before v8::Initialize().
|
||||||
|
const char expose_debug_as[] = "--expose_debug_as=v8debug";
|
||||||
|
v8::V8::SetFlagsFromString(expose_debug_as, sizeof(expose_debug_as) - 1);
|
||||||
|
}
|
||||||
gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode,
|
gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode,
|
||||||
gin::ArrayBufferAllocator::SharedInstance());
|
gin::ArrayBufferAllocator::SharedInstance());
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -55,7 +55,7 @@ app.once 'ready', ->
|
||||||
BrowserWindow = require 'browser-window'
|
BrowserWindow = require 'browser-window'
|
||||||
|
|
||||||
# Load persistented extensions.
|
# Load persistented extensions.
|
||||||
loadedExtensionsPath = path.join app.getDataPath(), 'DevTools Extensions'
|
loadedExtensionsPath = path.join app.getPath('userData'), 'DevTools Extensions'
|
||||||
|
|
||||||
try
|
try
|
||||||
loadedExtensions = JSON.parse fs.readFileSync(loadedExtensionsPath)
|
loadedExtensions = JSON.parse fs.readFileSync(loadedExtensionsPath)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ipc = require 'ipc'
|
ipc = require 'ipc-main'
|
||||||
webContents = require 'web-contents'
|
webContents = require 'web-contents'
|
||||||
webViewManager = null # Doesn't exist in early initialization.
|
webViewManager = null # Doesn't exist in early initialization.
|
||||||
|
|
||||||
|
@ -118,11 +118,11 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) ->
|
||||||
destroyGuest embedder, oldGuestInstanceId
|
destroyGuest embedder, oldGuestInstanceId
|
||||||
|
|
||||||
webPreferences =
|
webPreferences =
|
||||||
'guest-instance-id': guestInstanceId
|
guestInstanceId: guestInstanceId
|
||||||
'node-integration': params.nodeintegration ? false
|
nodeIntegration: params.nodeintegration ? false
|
||||||
'plugins': params.plugins
|
plugins: params.plugins
|
||||||
'web-security': !params.disablewebsecurity
|
webSecurity: !params.disablewebsecurity
|
||||||
webPreferences['preload-url'] = params.preload if params.preload
|
webPreferences.preloadUrl = params.preload if params.preload
|
||||||
webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest, webPreferences
|
webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest, webPreferences
|
||||||
|
|
||||||
guest.attachParams = params
|
guest.attachParams = params
|
||||||
|
|
|
@ -1,18 +1,27 @@
|
||||||
ipc = require 'ipc'
|
ipc = require 'ipc-main'
|
||||||
v8Util = process.atomBinding 'v8_util'
|
v8Util = process.atomBinding 'v8_util'
|
||||||
BrowserWindow = require 'browser-window'
|
BrowserWindow = require 'browser-window'
|
||||||
|
|
||||||
frameToGuest = {}
|
frameToGuest = {}
|
||||||
|
|
||||||
|
# Copy attribute of |parent| to |child| if it is not defined in |child|.
|
||||||
|
mergeOptions = (child, parent) ->
|
||||||
|
for own key, value of parent when key not in child
|
||||||
|
if typeof value is 'object'
|
||||||
|
child[key] = mergeOptions {}, value
|
||||||
|
else
|
||||||
|
child[key] = value
|
||||||
|
child
|
||||||
|
|
||||||
# Merge |options| with the |embedder|'s window's options.
|
# Merge |options| with the |embedder|'s window's options.
|
||||||
mergeBrowserWindowOptions = (embedder, options) ->
|
mergeBrowserWindowOptions = (embedder, options) ->
|
||||||
if embedder.browserWindowOptions?
|
if embedder.browserWindowOptions?
|
||||||
# Inherit the original options if it is a BrowserWindow.
|
# Inherit the original options if it is a BrowserWindow.
|
||||||
options.__proto__ = embedder.browserWindowOptions
|
mergeOptions options, embedder.browserWindowOptions
|
||||||
else
|
else
|
||||||
# Or only inherit web-preferences if it is a webview.
|
# Or only inherit web-preferences if it is a webview.
|
||||||
options['web-preferences'] ?= {}
|
options.webPreferences ?= {}
|
||||||
options['web-preferences'].__proto__ = embedder.getWebPreferences()
|
mergeOptions options.webPreferences, embedder.getWebPreferences()
|
||||||
options
|
options
|
||||||
|
|
||||||
# Create a new guest created by |embedder| with |options|.
|
# Create a new guest created by |embedder| with |options|.
|
||||||
|
@ -67,7 +76,7 @@ ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestId, method,
|
||||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestId, message, targetOrigin) ->
|
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestId, message, targetOrigin) ->
|
||||||
guestContents = BrowserWindow.fromId(guestId)?.webContents
|
guestContents = BrowserWindow.fromId(guestId)?.webContents
|
||||||
if guestContents?.getUrl().indexOf(targetOrigin) is 0 or targetOrigin is '*'
|
if guestContents?.getUrl().indexOf(targetOrigin) is 0 or targetOrigin is '*'
|
||||||
guestContents.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', message, targetOrigin
|
guestContents.send 'ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', guestId, message, targetOrigin
|
||||||
|
|
||||||
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', (event, guestId, message, targetOrigin, sourceOrigin) ->
|
ipc.on 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPENER_POSTMESSAGE', (event, guestId, message, targetOrigin, sourceOrigin) ->
|
||||||
embedder = v8Util.getHiddenValue event.sender, 'embedder'
|
embedder = v8Util.getHiddenValue event.sender, 'embedder'
|
||||||
|
|
|
@ -21,10 +21,15 @@ globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')
|
||||||
if process.platform is 'win32'
|
if process.platform is 'win32'
|
||||||
# Redirect node's console to use our own implementations, since node can not
|
# Redirect node's console to use our own implementations, since node can not
|
||||||
# handle console output when running as GUI program.
|
# handle console output when running as GUI program.
|
||||||
print = (args...) ->
|
consoleLog = (args...) ->
|
||||||
process.log util.format(args...)
|
process.log util.format(args...) + "\n"
|
||||||
console.log = console.error = console.warn = print
|
streamWrite = (chunk, encoding, callback) ->
|
||||||
process.stdout.write = process.stderr.write = print
|
chunk = chunk.toString(encoding) if Buffer.isBuffer chunk
|
||||||
|
process.log chunk
|
||||||
|
callback() if callback
|
||||||
|
true
|
||||||
|
console.log = console.error = console.warn = consoleLog
|
||||||
|
process.stdout.write = process.stderr.write = streamWrite
|
||||||
|
|
||||||
# Always returns EOF for stdin stream.
|
# Always returns EOF for stdin stream.
|
||||||
Readable = require('stream').Readable
|
Readable = require('stream').Readable
|
||||||
|
@ -48,6 +53,9 @@ app = require 'app'
|
||||||
app.on 'quit', ->
|
app.on 'quit', ->
|
||||||
process.emit 'exit'
|
process.emit 'exit'
|
||||||
|
|
||||||
|
# Map process.exit to app.exit, which quits gracefully.
|
||||||
|
process.exit = app.exit
|
||||||
|
|
||||||
# Load the RPC server.
|
# Load the RPC server.
|
||||||
require './rpc-server'
|
require './rpc-server'
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ class ObjectsRegistry extends EventEmitter
|
||||||
@dereference id, 1
|
@dereference id, 1
|
||||||
# Also reduce the count in owner.
|
# Also reduce the count in owner.
|
||||||
pointer = @owners[webContentsId]
|
pointer = @owners[webContentsId]
|
||||||
|
return unless pointer?
|
||||||
--pointer[id]
|
--pointer[id]
|
||||||
delete pointer[id] if pointer[id] is 0
|
delete pointer[id] if pointer[id] is 0
|
||||||
|
|
||||||
|
@ -57,6 +58,7 @@ class ObjectsRegistry extends EventEmitter
|
||||||
# Private: Dereference the object from store.
|
# Private: Dereference the object from store.
|
||||||
dereference: (id, count) ->
|
dereference: (id, count) ->
|
||||||
pointer = @storage[id]
|
pointer = @storage[id]
|
||||||
|
return unless pointer?
|
||||||
pointer.count -= count
|
pointer.count -= count
|
||||||
if pointer.count is 0
|
if pointer.count is 0
|
||||||
v8Util.deleteHiddenValue pointer.object, 'atomId'
|
v8Util.deleteHiddenValue pointer.object, 'atomId'
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
ipc = require 'ipc'
|
ipc = require 'ipc-main'
|
||||||
path = require 'path'
|
path = require 'path'
|
||||||
objectsRegistry = require './objects-registry.js'
|
objectsRegistry = require './objects-registry.js'
|
||||||
v8Util = process.atomBinding 'v8_util'
|
v8Util = process.atomBinding 'v8_util'
|
||||||
|
IDWeakMap = process.atomBinding('id_weak_map').IDWeakMap
|
||||||
|
|
||||||
# Convert a real value into meta data.
|
# Convert a real value into meta data.
|
||||||
valueToMeta = (sender, value, optimizeSimpleObject=false) ->
|
valueToMeta = (sender, value, optimizeSimpleObject=false) ->
|
||||||
|
@ -10,6 +11,8 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) ->
|
||||||
meta.type = 'buffer' if Buffer.isBuffer value
|
meta.type = 'buffer' if Buffer.isBuffer value
|
||||||
meta.type = 'value' if value is null
|
meta.type = 'value' if value is null
|
||||||
meta.type = 'array' if Array.isArray value
|
meta.type = 'array' if Array.isArray value
|
||||||
|
meta.type = 'error' if value instanceof Error
|
||||||
|
meta.type = 'date' if value instanceof Date
|
||||||
meta.type = 'promise' if value? and value.constructor.name is 'Promise'
|
meta.type = 'promise' if value? and value.constructor.name is 'Promise'
|
||||||
|
|
||||||
# Treat simple objects as value.
|
# Treat simple objects as value.
|
||||||
|
@ -30,21 +33,28 @@ valueToMeta = (sender, value, optimizeSimpleObject=false) ->
|
||||||
# it.
|
# it.
|
||||||
meta.id = objectsRegistry.add sender.getId(), value
|
meta.id = objectsRegistry.add sender.getId(), value
|
||||||
|
|
||||||
meta.members = []
|
meta.members = ({name, type: typeof field} for name, field of value)
|
||||||
meta.members.push {name: prop, type: typeof field} for prop, field of value
|
|
||||||
else if meta.type is 'buffer'
|
else if meta.type is 'buffer'
|
||||||
meta.value = Array::slice.call value, 0
|
meta.value = Array::slice.call value, 0
|
||||||
else if meta.type is 'promise'
|
else if meta.type is 'promise'
|
||||||
meta.then = valueToMeta(sender, value.then.bind(value))
|
meta.then = valueToMeta sender, value.then.bind(value)
|
||||||
|
else if meta.type is 'error'
|
||||||
|
meta.members = plainObjectToMeta value
|
||||||
|
else if meta.type is 'date'
|
||||||
|
meta.value = value.getTime()
|
||||||
else
|
else
|
||||||
meta.type = 'value'
|
meta.type = 'value'
|
||||||
meta.value = value
|
meta.value = value
|
||||||
|
|
||||||
meta
|
meta
|
||||||
|
|
||||||
|
# Convert object to meta by value.
|
||||||
|
plainObjectToMeta = (obj) ->
|
||||||
|
Object.getOwnPropertyNames(obj).map (name) -> {name, value: obj[name]}
|
||||||
|
|
||||||
# Convert Error into meta data.
|
# Convert Error into meta data.
|
||||||
errorToMeta = (error) ->
|
exceptionToMeta = (error) ->
|
||||||
type: 'error', message: error.message, stack: (error.stack || error)
|
type: 'exception', message: error.message, stack: (error.stack || error)
|
||||||
|
|
||||||
# Convert array of meta data from renderer into array of real values.
|
# Convert array of meta data from renderer into array of real values.
|
||||||
unwrapArgs = (sender, args) ->
|
unwrapArgs = (sender, args) ->
|
||||||
|
@ -64,16 +74,27 @@ unwrapArgs = (sender, args) ->
|
||||||
returnValue = metaToValue meta.value
|
returnValue = metaToValue meta.value
|
||||||
-> returnValue
|
-> returnValue
|
||||||
when 'function'
|
when 'function'
|
||||||
|
# Cache the callbacks in renderer.
|
||||||
|
unless sender.callbacks
|
||||||
|
sender.callbacks = new IDWeakMap
|
||||||
|
sender.on 'render-view-deleted', ->
|
||||||
|
sender.callbacks.clear()
|
||||||
|
return sender.callbacks.get meta.id if sender.callbacks.has meta.id
|
||||||
|
|
||||||
rendererReleased = false
|
rendererReleased = false
|
||||||
objectsRegistry.once "clear-#{sender.getId()}", ->
|
objectsRegistry.once "clear-#{sender.getId()}", ->
|
||||||
rendererReleased = true
|
rendererReleased = true
|
||||||
|
|
||||||
ret = ->
|
ret = ->
|
||||||
throw new Error('Calling a callback of released renderer view') if rendererReleased
|
if rendererReleased
|
||||||
|
throw new Error("Attempting to call a function in a renderer window
|
||||||
|
that has been closed or released. Function provided here: #{meta.location}.")
|
||||||
sender.send 'ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(sender, arguments)
|
sender.send 'ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(sender, arguments)
|
||||||
v8Util.setDestructor ret, ->
|
v8Util.setDestructor ret, ->
|
||||||
return if rendererReleased
|
return if rendererReleased
|
||||||
|
sender.callbacks.remove meta.id
|
||||||
sender.send 'ATOM_RENDERER_RELEASE_CALLBACK', meta.id
|
sender.send 'ATOM_RENDERER_RELEASE_CALLBACK', meta.id
|
||||||
|
sender.callbacks.set meta.id, ret
|
||||||
ret
|
ret
|
||||||
else throw new TypeError("Unknown type: #{meta.type}")
|
else throw new TypeError("Unknown type: #{meta.type}")
|
||||||
|
|
||||||
|
@ -98,19 +119,19 @@ ipc.on 'ATOM_BROWSER_REQUIRE', (event, module) ->
|
||||||
try
|
try
|
||||||
event.returnValue = valueToMeta event.sender, process.mainModule.require(module)
|
event.returnValue = valueToMeta event.sender, process.mainModule.require(module)
|
||||||
catch e
|
catch e
|
||||||
event.returnValue = errorToMeta e
|
event.returnValue = exceptionToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_GLOBAL', (event, name) ->
|
ipc.on 'ATOM_BROWSER_GLOBAL', (event, name) ->
|
||||||
try
|
try
|
||||||
event.returnValue = valueToMeta event.sender, global[name]
|
event.returnValue = valueToMeta event.sender, global[name]
|
||||||
catch e
|
catch e
|
||||||
event.returnValue = errorToMeta e
|
event.returnValue = exceptionToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_CURRENT_WINDOW', (event) ->
|
ipc.on 'ATOM_BROWSER_CURRENT_WINDOW', (event) ->
|
||||||
try
|
try
|
||||||
event.returnValue = valueToMeta event.sender, event.sender.getOwnerBrowserWindow()
|
event.returnValue = valueToMeta event.sender, event.sender.getOwnerBrowserWindow()
|
||||||
catch e
|
catch e
|
||||||
event.returnValue = errorToMeta e
|
event.returnValue = exceptionToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_CURRENT_WEB_CONTENTS', (event) ->
|
ipc.on 'ATOM_BROWSER_CURRENT_WEB_CONTENTS', (event) ->
|
||||||
event.returnValue = valueToMeta event.sender, event.sender
|
event.returnValue = valueToMeta event.sender, event.sender
|
||||||
|
@ -124,7 +145,7 @@ ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, id, args) ->
|
||||||
obj = new (Function::bind.apply(constructor, [null].concat(args)))
|
obj = new (Function::bind.apply(constructor, [null].concat(args)))
|
||||||
event.returnValue = valueToMeta event.sender, obj
|
event.returnValue = valueToMeta event.sender, obj
|
||||||
catch e
|
catch e
|
||||||
event.returnValue = errorToMeta e
|
event.returnValue = exceptionToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_FUNCTION_CALL', (event, id, args) ->
|
ipc.on 'ATOM_BROWSER_FUNCTION_CALL', (event, id, args) ->
|
||||||
try
|
try
|
||||||
|
@ -132,7 +153,7 @@ ipc.on 'ATOM_BROWSER_FUNCTION_CALL', (event, id, args) ->
|
||||||
func = objectsRegistry.get id
|
func = objectsRegistry.get id
|
||||||
callFunction event, func, global, args
|
callFunction event, func, global, args
|
||||||
catch e
|
catch e
|
||||||
event.returnValue = errorToMeta e
|
event.returnValue = exceptionToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', (event, id, method, args) ->
|
ipc.on 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', (event, id, method, args) ->
|
||||||
try
|
try
|
||||||
|
@ -142,7 +163,7 @@ ipc.on 'ATOM_BROWSER_MEMBER_CONSTRUCTOR', (event, id, method, args) ->
|
||||||
obj = new (Function::bind.apply(constructor, [null].concat(args)))
|
obj = new (Function::bind.apply(constructor, [null].concat(args)))
|
||||||
event.returnValue = valueToMeta event.sender, obj
|
event.returnValue = valueToMeta event.sender, obj
|
||||||
catch e
|
catch e
|
||||||
event.returnValue = errorToMeta e
|
event.returnValue = exceptionToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_MEMBER_CALL', (event, id, method, args) ->
|
ipc.on 'ATOM_BROWSER_MEMBER_CALL', (event, id, method, args) ->
|
||||||
try
|
try
|
||||||
|
@ -150,7 +171,7 @@ ipc.on 'ATOM_BROWSER_MEMBER_CALL', (event, id, method, args) ->
|
||||||
obj = objectsRegistry.get id
|
obj = objectsRegistry.get id
|
||||||
callFunction event, obj[method], obj, args
|
callFunction event, obj[method], obj, args
|
||||||
catch e
|
catch e
|
||||||
event.returnValue = errorToMeta e
|
event.returnValue = exceptionToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_MEMBER_SET', (event, id, name, value) ->
|
ipc.on 'ATOM_BROWSER_MEMBER_SET', (event, id, name, value) ->
|
||||||
try
|
try
|
||||||
|
@ -158,14 +179,14 @@ ipc.on 'ATOM_BROWSER_MEMBER_SET', (event, id, name, value) ->
|
||||||
obj[name] = value
|
obj[name] = value
|
||||||
event.returnValue = null
|
event.returnValue = null
|
||||||
catch e
|
catch e
|
||||||
event.returnValue = errorToMeta e
|
event.returnValue = exceptionToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_MEMBER_GET', (event, id, name) ->
|
ipc.on 'ATOM_BROWSER_MEMBER_GET', (event, id, name) ->
|
||||||
try
|
try
|
||||||
obj = objectsRegistry.get id
|
obj = objectsRegistry.get id
|
||||||
event.returnValue = valueToMeta event.sender, obj[name]
|
event.returnValue = valueToMeta event.sender, obj[name]
|
||||||
catch e
|
catch e
|
||||||
event.returnValue = errorToMeta e
|
event.returnValue = exceptionToMeta e
|
||||||
|
|
||||||
ipc.on 'ATOM_BROWSER_DEREFERENCE', (event, id) ->
|
ipc.on 'ATOM_BROWSER_DEREFERENCE', (event, id) ->
|
||||||
objectsRegistry.remove event.sender.getId(), id
|
objectsRegistry.remove event.sender.getId(), id
|
||||||
|
@ -175,4 +196,4 @@ ipc.on 'ATOM_BROWSER_GUEST_WEB_CONTENTS', (event, guestInstanceId) ->
|
||||||
guestViewManager = require './guest-view-manager'
|
guestViewManager = require './guest-view-manager'
|
||||||
event.returnValue = valueToMeta event.sender, guestViewManager.getGuest(guestInstanceId)
|
event.returnValue = valueToMeta event.sender, guestViewManager.getGuest(guestInstanceId)
|
||||||
catch e
|
catch e
|
||||||
event.returnValue = errorToMeta e
|
event.returnValue = exceptionToMeta e
|
||||||
|
|
109
atom/browser/login_handler.cc
Normal file
109
atom/browser/login_handler.cc
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
// 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/browser/login_handler.h"
|
||||||
|
|
||||||
|
#include "atom/browser/browser.h"
|
||||||
|
#include "content/public/browser/browser_thread.h"
|
||||||
|
#include "content/public/browser/render_frame_host.h"
|
||||||
|
#include "content/public/browser/resource_dispatcher_host.h"
|
||||||
|
#include "content/public/browser/resource_request_info.h"
|
||||||
|
#include "content/public/browser/web_contents.h"
|
||||||
|
#include "net/base/auth.h"
|
||||||
|
#include "net/url_request/url_request.h"
|
||||||
|
|
||||||
|
using content::BrowserThread;
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Helper to remove the ref from an net::URLRequest to the LoginHandler.
|
||||||
|
// Should only be called from the IO thread, since it accesses an
|
||||||
|
// net::URLRequest.
|
||||||
|
void ResetLoginHandlerForRequest(net::URLRequest* request) {
|
||||||
|
content::ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
LoginHandler::LoginHandler(net::AuthChallengeInfo* auth_info,
|
||||||
|
net::URLRequest* request)
|
||||||
|
: handled_auth_(false),
|
||||||
|
auth_info_(auth_info),
|
||||||
|
request_(request),
|
||||||
|
render_process_host_id_(0),
|
||||||
|
render_frame_id_(0) {
|
||||||
|
content::ResourceRequestInfo::ForRequest(request_)->GetAssociatedRenderFrame(
|
||||||
|
&render_process_host_id_, &render_frame_id_);
|
||||||
|
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||||
|
base::Bind(&Browser::RequestLogin,
|
||||||
|
base::Unretained(Browser::Get()),
|
||||||
|
make_scoped_refptr(this)));
|
||||||
|
}
|
||||||
|
|
||||||
|
LoginHandler::~LoginHandler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
content::WebContents* LoginHandler::GetWebContents() const {
|
||||||
|
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||||
|
|
||||||
|
content::RenderFrameHost* rfh = content::RenderFrameHost::FromID(
|
||||||
|
render_process_host_id_, render_frame_id_);
|
||||||
|
return content::WebContents::FromRenderFrameHost(rfh);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoginHandler::Login(const base::string16& username,
|
||||||
|
const base::string16& password) {
|
||||||
|
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||||
|
if (TestAndSetAuthHandled())
|
||||||
|
return;
|
||||||
|
BrowserThread::PostTask(
|
||||||
|
BrowserThread::IO, FROM_HERE,
|
||||||
|
base::Bind(&LoginHandler::DoLogin, this, username, password));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoginHandler::CancelAuth() {
|
||||||
|
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||||
|
if (TestAndSetAuthHandled())
|
||||||
|
return;
|
||||||
|
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||||
|
base::Bind(&LoginHandler::DoCancelAuth, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoginHandler::OnRequestCancelled() {
|
||||||
|
TestAndSetAuthHandled();
|
||||||
|
request_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marks authentication as handled and returns the previous handled state.
|
||||||
|
bool LoginHandler::TestAndSetAuthHandled() {
|
||||||
|
base::AutoLock lock(handled_auth_lock_);
|
||||||
|
bool was_handled = handled_auth_;
|
||||||
|
handled_auth_ = true;
|
||||||
|
return was_handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoginHandler::DoCancelAuth() {
|
||||||
|
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||||
|
|
||||||
|
if (request_) {
|
||||||
|
request_->CancelAuth();
|
||||||
|
// Verify that CancelAuth doesn't destroy the request via our delegate.
|
||||||
|
DCHECK(request_ != nullptr);
|
||||||
|
ResetLoginHandlerForRequest(request_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoginHandler::DoLogin(const base::string16& username,
|
||||||
|
const base::string16& password) {
|
||||||
|
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||||
|
|
||||||
|
if (request_) {
|
||||||
|
request_->SetAuth(net::AuthCredentials(username, password));
|
||||||
|
ResetLoginHandlerForRequest(request_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace atom
|
76
atom/browser/login_handler.h
Normal file
76
atom/browser/login_handler.h
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// 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_LOGIN_HANDLER_H_
|
||||||
|
#define ATOM_BROWSER_LOGIN_HANDLER_H_
|
||||||
|
|
||||||
|
#include "base/strings/string16.h"
|
||||||
|
#include "base/synchronization/lock.h"
|
||||||
|
#include "content/public/browser/resource_dispatcher_host_login_delegate.h"
|
||||||
|
|
||||||
|
namespace content {
|
||||||
|
class WebContents;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace net {
|
||||||
|
class AuthChallengeInfo;
|
||||||
|
class URLRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
// Handles the HTTP basic auth, must be created on IO thread.
|
||||||
|
class LoginHandler : public content::ResourceDispatcherHostLoginDelegate {
|
||||||
|
public:
|
||||||
|
LoginHandler(net::AuthChallengeInfo* auth_info, net::URLRequest* request);
|
||||||
|
|
||||||
|
// Returns the WebContents associated with the request, must be called on UI
|
||||||
|
// thread.
|
||||||
|
content::WebContents* GetWebContents() const;
|
||||||
|
|
||||||
|
// The auth is cancelled, must be called on UI thread.
|
||||||
|
void CancelAuth();
|
||||||
|
|
||||||
|
// Login with |username| and |password|, must be called on UI thread.
|
||||||
|
void Login(const base::string16& username, const base::string16& password);
|
||||||
|
|
||||||
|
const net::AuthChallengeInfo* auth_info() const { return auth_info_.get(); }
|
||||||
|
const net::URLRequest* request() const { return request_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
~LoginHandler() override;
|
||||||
|
|
||||||
|
// content::ResourceDispatcherHostLoginDelegate:
|
||||||
|
void OnRequestCancelled() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Must be called on IO thread.
|
||||||
|
void DoCancelAuth();
|
||||||
|
void DoLogin(const base::string16& username, const base::string16& password);
|
||||||
|
|
||||||
|
// Marks authentication as handled and returns the previous handled
|
||||||
|
// state.
|
||||||
|
bool TestAndSetAuthHandled();
|
||||||
|
|
||||||
|
// True if we've handled auth (Login or CancelAuth has been called).
|
||||||
|
bool handled_auth_;
|
||||||
|
mutable base::Lock handled_auth_lock_;
|
||||||
|
|
||||||
|
// Who/where/what asked for the authentication.
|
||||||
|
scoped_refptr<net::AuthChallengeInfo> auth_info_;
|
||||||
|
|
||||||
|
// The request that wants login data.
|
||||||
|
// This should only be accessed on the IO loop.
|
||||||
|
net::URLRequest* request_;
|
||||||
|
|
||||||
|
// Cached from the net::URLRequest, in case it goes NULL on us.
|
||||||
|
int render_process_host_id_;
|
||||||
|
int render_frame_id_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(LoginHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
#endif // ATOM_BROWSER_LOGIN_HANDLER_H_
|
|
@ -43,11 +43,20 @@
|
||||||
atom::Browser::Get()->OpenURL(base::SysNSStringToUTF8(url));
|
atom::Browser::Get()->OpenURL(base::SysNSStringToUTF8(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (bool)voiceOverEnabled {
|
||||||
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||||
|
[defaults addSuiteNamed:@"com.apple.universalaccess"];
|
||||||
|
[defaults synchronize];
|
||||||
|
|
||||||
|
return [defaults boolForKey:@"voiceOverOnOffKey"];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute {
|
- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute {
|
||||||
// Undocumented attribute that VoiceOver happens to set while running.
|
// Undocumented attribute that VoiceOver happens to set while running.
|
||||||
// Chromium uses this too, even though it's not exactly right.
|
// Chromium uses this too, even though it's not exactly right.
|
||||||
if ([attribute isEqualToString:@"AXEnhancedUserInterface"]) {
|
if ([attribute isEqualToString:@"AXEnhancedUserInterface"]) {
|
||||||
[self updateAccessibilityEnabled:[value boolValue]];
|
bool enableAccessibility = ([self voiceOverEnabled] && [value boolValue]);
|
||||||
|
[self updateAccessibilityEnabled:enableAccessibility];
|
||||||
}
|
}
|
||||||
return [super accessibilitySetValue:value forAttribute:attribute];
|
return [super accessibilitySetValue:value forAttribute:attribute];
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,26 +43,6 @@ DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay);
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
// Convert draggable regions in raw format to SkRegion format. Caller is
|
|
||||||
// responsible for deleting the returned SkRegion instance.
|
|
||||||
scoped_ptr<SkRegion> DraggableRegionsToSkRegion(
|
|
||||||
const std::vector<DraggableRegion>& regions) {
|
|
||||||
scoped_ptr<SkRegion> sk_region(new SkRegion);
|
|
||||||
for (const DraggableRegion& region : regions) {
|
|
||||||
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.Pass();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
NativeWindow::NativeWindow(
|
NativeWindow::NativeWindow(
|
||||||
brightray::InspectableWebContents* inspectable_web_contents,
|
brightray::InspectableWebContents* inspectable_web_contents,
|
||||||
const mate::Dictionary& options)
|
const mate::Dictionary& options)
|
||||||
|
@ -112,27 +92,35 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
|
||||||
int x = -1, y = -1;
|
int x = -1, y = -1;
|
||||||
bool center;
|
bool center;
|
||||||
if (options.Get(switches::kX, &x) && options.Get(switches::kY, &y)) {
|
if (options.Get(switches::kX, &x) && options.Get(switches::kY, &y)) {
|
||||||
int width = -1, height = -1;
|
SetPosition(gfx::Point(x, y));
|
||||||
options.Get(switches::kWidth, &width);
|
|
||||||
options.Get(switches::kHeight, &height);
|
|
||||||
SetBounds(gfx::Rect(x, y, width, height));
|
|
||||||
} else if (options.Get(switches::kCenter, ¢er) && center) {
|
} else if (options.Get(switches::kCenter, ¢er) && center) {
|
||||||
Center();
|
Center();
|
||||||
}
|
}
|
||||||
|
// On Linux and Window we may already have maximum size defined.
|
||||||
|
extensions::SizeConstraints size_constraints(GetContentSizeConstraints());
|
||||||
int min_height = 0, min_width = 0;
|
int min_height = 0, min_width = 0;
|
||||||
if (options.Get(switches::kMinHeight, &min_height) |
|
if (options.Get(switches::kMinHeight, &min_height) |
|
||||||
options.Get(switches::kMinWidth, &min_width)) {
|
options.Get(switches::kMinWidth, &min_width)) {
|
||||||
SetMinimumSize(gfx::Size(min_width, min_height));
|
size_constraints.set_minimum_size(gfx::Size(min_width, min_height));
|
||||||
}
|
}
|
||||||
int max_height = INT_MAX, max_width = INT_MAX;
|
int max_height = INT_MAX, max_width = INT_MAX;
|
||||||
if (options.Get(switches::kMaxHeight, &max_height) |
|
if (options.Get(switches::kMaxHeight, &max_height) |
|
||||||
options.Get(switches::kMaxWidth, &max_width)) {
|
options.Get(switches::kMaxWidth, &max_width)) {
|
||||||
SetMaximumSize(gfx::Size(max_width, max_height));
|
size_constraints.set_maximum_size(gfx::Size(max_width, max_height));
|
||||||
}
|
}
|
||||||
|
bool use_content_size = false;
|
||||||
|
options.Get(switches::kUseContentSize, &use_content_size);
|
||||||
|
if (use_content_size) {
|
||||||
|
SetContentSizeConstraints(size_constraints);
|
||||||
|
} else {
|
||||||
|
SetSizeConstraints(size_constraints);
|
||||||
|
}
|
||||||
|
#if defined(OS_WIN) || defined(USE_X11)
|
||||||
bool resizable;
|
bool resizable;
|
||||||
if (options.Get(switches::kResizable, &resizable)) {
|
if (options.Get(switches::kResizable, &resizable)) {
|
||||||
SetResizable(resizable);
|
SetResizable(resizable);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
bool top;
|
bool top;
|
||||||
if (options.Get(switches::kAlwaysOnTop, &top) && top) {
|
if (options.Get(switches::kAlwaysOnTop, &top) && top) {
|
||||||
SetAlwaysOnTop(true);
|
SetAlwaysOnTop(true);
|
||||||
|
@ -151,6 +139,10 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
|
||||||
if (options.Get(switches::kKiosk, &kiosk) && kiosk) {
|
if (options.Get(switches::kKiosk, &kiosk) && kiosk) {
|
||||||
SetKiosk(kiosk);
|
SetKiosk(kiosk);
|
||||||
}
|
}
|
||||||
|
std::string color;
|
||||||
|
if (options.Get(switches::kBackgroundColor, &color)) {
|
||||||
|
SetBackgroundColor(color);
|
||||||
|
}
|
||||||
std::string title("Electron");
|
std::string title("Electron");
|
||||||
options.Get(switches::kTitle, &title);
|
options.Get(switches::kTitle, &title);
|
||||||
SetTitle(title);
|
SetTitle(title);
|
||||||
|
@ -178,6 +170,67 @@ gfx::Point NativeWindow::GetPosition() {
|
||||||
return GetBounds().origin();
|
return GetBounds().origin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeWindow::SetContentSize(const gfx::Size& size) {
|
||||||
|
SetSize(ContentSizeToWindowSize(size));
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::Size NativeWindow::GetContentSize() {
|
||||||
|
return WindowSizeToContentSize(GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeWindow::SetSizeConstraints(
|
||||||
|
const extensions::SizeConstraints& window_constraints) {
|
||||||
|
extensions::SizeConstraints content_constraints;
|
||||||
|
if (window_constraints.HasMaximumSize())
|
||||||
|
content_constraints.set_maximum_size(
|
||||||
|
WindowSizeToContentSize(window_constraints.GetMaximumSize()));
|
||||||
|
if (window_constraints.HasMinimumSize())
|
||||||
|
content_constraints.set_minimum_size(
|
||||||
|
WindowSizeToContentSize(window_constraints.GetMinimumSize()));
|
||||||
|
SetContentSizeConstraints(content_constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
extensions::SizeConstraints NativeWindow::GetSizeConstraints() {
|
||||||
|
extensions::SizeConstraints content_constraints = GetContentSizeConstraints();
|
||||||
|
extensions::SizeConstraints window_constraints;
|
||||||
|
if (content_constraints.HasMaximumSize())
|
||||||
|
window_constraints.set_maximum_size(
|
||||||
|
ContentSizeToWindowSize(content_constraints.GetMaximumSize()));
|
||||||
|
if (content_constraints.HasMinimumSize())
|
||||||
|
window_constraints.set_minimum_size(
|
||||||
|
ContentSizeToWindowSize(content_constraints.GetMinimumSize()));
|
||||||
|
return window_constraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeWindow::SetContentSizeConstraints(
|
||||||
|
const extensions::SizeConstraints& size_constraints) {
|
||||||
|
size_constraints_ = size_constraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
extensions::SizeConstraints NativeWindow::GetContentSizeConstraints() {
|
||||||
|
return size_constraints_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeWindow::SetMinimumSize(const gfx::Size& size) {
|
||||||
|
extensions::SizeConstraints size_constraints;
|
||||||
|
size_constraints.set_minimum_size(size);
|
||||||
|
SetSizeConstraints(size_constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::Size NativeWindow::GetMinimumSize() {
|
||||||
|
return GetSizeConstraints().GetMinimumSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeWindow::SetMaximumSize(const gfx::Size& size) {
|
||||||
|
extensions::SizeConstraints size_constraints;
|
||||||
|
size_constraints.set_maximum_size(size);
|
||||||
|
SetSizeConstraints(size_constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::Size NativeWindow::GetMaximumSize() {
|
||||||
|
return GetSizeConstraints().GetMaximumSize();
|
||||||
|
}
|
||||||
|
|
||||||
void NativeWindow::SetRepresentedFilename(const std::string& filename) {
|
void NativeWindow::SetRepresentedFilename(const std::string& filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,6 +464,28 @@ void NativeWindow::NotifyWindowExecuteWindowsCommand(
|
||||||
OnExecuteWindowsCommand(command));
|
OnExecuteWindowsCommand(command));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
void NativeWindow::NotifyWindowMessage(
|
||||||
|
UINT message, WPARAM w_param, LPARAM l_param) {
|
||||||
|
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
|
||||||
|
OnWindowMessage(message, w_param, l_param));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
scoped_ptr<SkRegion> NativeWindow::DraggableRegionsToSkRegion(
|
||||||
|
const std::vector<DraggableRegion>& regions) {
|
||||||
|
scoped_ptr<SkRegion> sk_region(new SkRegion);
|
||||||
|
for (const DraggableRegion& region : regions) {
|
||||||
|
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.Pass();
|
||||||
|
}
|
||||||
|
|
||||||
void NativeWindow::RenderViewCreated(
|
void NativeWindow::RenderViewCreated(
|
||||||
content::RenderViewHost* render_view_host) {
|
content::RenderViewHost* render_view_host) {
|
||||||
if (!transparent_)
|
if (!transparent_)
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "content/public/browser/readback_types.h"
|
#include "content/public/browser/readback_types.h"
|
||||||
#include "content/public/browser/web_contents_observer.h"
|
#include "content/public/browser/web_contents_observer.h"
|
||||||
#include "content/public/browser/web_contents_user_data.h"
|
#include "content/public/browser/web_contents_user_data.h"
|
||||||
|
#include "extensions/browser/app_window/size_constraints.h"
|
||||||
#include "ui/gfx/image/image.h"
|
#include "ui/gfx/image/image.h"
|
||||||
#include "ui/gfx/image/image_skia.h"
|
#include "ui/gfx/image/image_skia.h"
|
||||||
|
|
||||||
|
@ -110,12 +111,18 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
virtual gfx::Size GetSize();
|
virtual gfx::Size GetSize();
|
||||||
virtual void SetPosition(const gfx::Point& position);
|
virtual void SetPosition(const gfx::Point& position);
|
||||||
virtual gfx::Point GetPosition();
|
virtual gfx::Point GetPosition();
|
||||||
virtual void SetContentSize(const gfx::Size& size) = 0;
|
virtual void SetContentSize(const gfx::Size& size);
|
||||||
virtual gfx::Size GetContentSize() = 0;
|
virtual gfx::Size GetContentSize();
|
||||||
virtual void SetMinimumSize(const gfx::Size& size) = 0;
|
virtual void SetSizeConstraints(
|
||||||
virtual gfx::Size GetMinimumSize() = 0;
|
const extensions::SizeConstraints& size_constraints);
|
||||||
virtual void SetMaximumSize(const gfx::Size& size) = 0;
|
virtual extensions::SizeConstraints GetSizeConstraints();
|
||||||
virtual gfx::Size GetMaximumSize() = 0;
|
virtual void SetContentSizeConstraints(
|
||||||
|
const extensions::SizeConstraints& size_constraints);
|
||||||
|
virtual extensions::SizeConstraints GetContentSizeConstraints();
|
||||||
|
virtual void SetMinimumSize(const gfx::Size& size);
|
||||||
|
virtual gfx::Size GetMinimumSize();
|
||||||
|
virtual void SetMaximumSize(const gfx::Size& size);
|
||||||
|
virtual gfx::Size GetMaximumSize();
|
||||||
virtual void SetResizable(bool resizable) = 0;
|
virtual void SetResizable(bool resizable) = 0;
|
||||||
virtual bool IsResizable() = 0;
|
virtual bool IsResizable() = 0;
|
||||||
virtual void SetAlwaysOnTop(bool top) = 0;
|
virtual void SetAlwaysOnTop(bool top) = 0;
|
||||||
|
@ -127,6 +134,7 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
virtual void SetSkipTaskbar(bool skip) = 0;
|
virtual void SetSkipTaskbar(bool skip) = 0;
|
||||||
virtual void SetKiosk(bool kiosk) = 0;
|
virtual void SetKiosk(bool kiosk) = 0;
|
||||||
virtual bool IsKiosk() = 0;
|
virtual bool IsKiosk() = 0;
|
||||||
|
virtual void SetBackgroundColor(const std::string& color_name) = 0;
|
||||||
virtual void SetRepresentedFilename(const std::string& filename);
|
virtual void SetRepresentedFilename(const std::string& filename);
|
||||||
virtual std::string GetRepresentedFilename();
|
virtual std::string GetRepresentedFilename();
|
||||||
virtual void SetDocumentEdited(bool edited);
|
virtual void SetDocumentEdited(bool edited);
|
||||||
|
@ -202,6 +210,10 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
void NotifyWindowLeaveHtmlFullScreen();
|
void NotifyWindowLeaveHtmlFullScreen();
|
||||||
void NotifyWindowExecuteWindowsCommand(const std::string& command);
|
void NotifyWindowExecuteWindowsCommand(const std::string& command);
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
void NotifyWindowMessage(UINT message, WPARAM w_param, LPARAM l_param);
|
||||||
|
#endif
|
||||||
|
|
||||||
void AddObserver(NativeWindowObserver* obs) {
|
void AddObserver(NativeWindowObserver* obs) {
|
||||||
observers_.AddObserver(obs);
|
observers_.AddObserver(obs);
|
||||||
}
|
}
|
||||||
|
@ -234,6 +246,19 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
NativeWindow(brightray::InspectableWebContents* inspectable_web_contents,
|
NativeWindow(brightray::InspectableWebContents* inspectable_web_contents,
|
||||||
const mate::Dictionary& options);
|
const mate::Dictionary& options);
|
||||||
|
|
||||||
|
// Convert draggable regions in raw format to SkRegion format. Caller is
|
||||||
|
// responsible for deleting the returned SkRegion instance.
|
||||||
|
scoped_ptr<SkRegion> DraggableRegionsToSkRegion(
|
||||||
|
const std::vector<DraggableRegion>& regions);
|
||||||
|
|
||||||
|
// Converts between content size to window size.
|
||||||
|
virtual gfx::Size ContentSizeToWindowSize(const gfx::Size& size) = 0;
|
||||||
|
virtual gfx::Size WindowSizeToContentSize(const gfx::Size& size) = 0;
|
||||||
|
|
||||||
|
// Called when the window needs to update its draggable region.
|
||||||
|
virtual void UpdateDraggableRegions(
|
||||||
|
const std::vector<DraggableRegion>& regions);
|
||||||
|
|
||||||
// content::WebContentsObserver:
|
// content::WebContentsObserver:
|
||||||
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
|
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
|
||||||
void BeforeUnloadDialogCancelled() override;
|
void BeforeUnloadDialogCancelled() override;
|
||||||
|
@ -241,10 +266,6 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
bool OnMessageReceived(const IPC::Message& message) override;
|
bool OnMessageReceived(const IPC::Message& message) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Called when the window needs to update its draggable region.
|
|
||||||
void UpdateDraggableRegions(
|
|
||||||
const std::vector<DraggableRegion>& regions);
|
|
||||||
|
|
||||||
// Schedule a notification unresponsive event.
|
// Schedule a notification unresponsive event.
|
||||||
void ScheduleUnresponsiveEvent(int ms);
|
void ScheduleUnresponsiveEvent(int ms);
|
||||||
|
|
||||||
|
@ -269,6 +290,9 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
// has to been explicitly provided.
|
// has to been explicitly provided.
|
||||||
scoped_ptr<SkRegion> draggable_region_; // used in custom drag.
|
scoped_ptr<SkRegion> draggable_region_; // used in custom drag.
|
||||||
|
|
||||||
|
// Minimum and maximum size, stored as content size.
|
||||||
|
extensions::SizeConstraints size_constraints_;
|
||||||
|
|
||||||
// Whether window can be resized larger than screen.
|
// Whether window can be resized larger than screen.
|
||||||
bool enable_larger_than_screen_;
|
bool enable_larger_than_screen_;
|
||||||
|
|
||||||
|
|
|
@ -44,12 +44,8 @@ class NativeWindowMac : public NativeWindow {
|
||||||
bool IsFullscreen() const override;
|
bool IsFullscreen() const override;
|
||||||
void SetBounds(const gfx::Rect& bounds) override;
|
void SetBounds(const gfx::Rect& bounds) override;
|
||||||
gfx::Rect GetBounds() override;
|
gfx::Rect GetBounds() override;
|
||||||
void SetContentSize(const gfx::Size& size) override;
|
void SetContentSizeConstraints(
|
||||||
gfx::Size GetContentSize() override;
|
const extensions::SizeConstraints& size_constraints) 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;
|
void SetResizable(bool resizable) override;
|
||||||
bool IsResizable() override;
|
bool IsResizable() override;
|
||||||
void SetAlwaysOnTop(bool top) override;
|
void SetAlwaysOnTop(bool top) override;
|
||||||
|
@ -61,6 +57,7 @@ class NativeWindowMac : public NativeWindow {
|
||||||
void SetSkipTaskbar(bool skip) override;
|
void SetSkipTaskbar(bool skip) override;
|
||||||
void SetKiosk(bool kiosk) override;
|
void SetKiosk(bool kiosk) override;
|
||||||
bool IsKiosk() override;
|
bool IsKiosk() override;
|
||||||
|
void SetBackgroundColor(const std::string& color_name) override;
|
||||||
void SetRepresentedFilename(const std::string& filename) override;
|
void SetRepresentedFilename(const std::string& filename) override;
|
||||||
std::string GetRepresentedFilename() override;
|
std::string GetRepresentedFilename() override;
|
||||||
void SetDocumentEdited(bool edited) override;
|
void SetDocumentEdited(bool edited) override;
|
||||||
|
@ -75,12 +72,10 @@ class NativeWindowMac : public NativeWindow {
|
||||||
void SetVisibleOnAllWorkspaces(bool visible) override;
|
void SetVisibleOnAllWorkspaces(bool visible) override;
|
||||||
bool IsVisibleOnAllWorkspaces() override;
|
bool IsVisibleOnAllWorkspaces() override;
|
||||||
|
|
||||||
// Returns true if |point| in local Cocoa coordinate system falls within
|
// Refresh the DraggableRegion views.
|
||||||
// the draggable region.
|
void UpdateDraggableRegionViews() {
|
||||||
bool IsWithinDraggableRegion(NSPoint point) const;
|
UpdateDraggableRegionViews(draggable_regions_);
|
||||||
|
}
|
||||||
// Called to handle a mouse event.
|
|
||||||
void HandleMouseEvent(NSEvent* event);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// NativeWindow:
|
// NativeWindow:
|
||||||
|
@ -88,13 +83,24 @@ class NativeWindowMac : public NativeWindow {
|
||||||
content::WebContents*,
|
content::WebContents*,
|
||||||
const content::NativeWebKeyboardEvent&) override;
|
const content::NativeWebKeyboardEvent&) override;
|
||||||
|
|
||||||
|
// Return a vector of non-draggable regions that fill a window of size
|
||||||
|
// |width| by |height|, but leave gaps where the window should be draggable.
|
||||||
|
std::vector<gfx::Rect> CalculateNonDraggableRegions(
|
||||||
|
const std::vector<DraggableRegion>& regions, int width, int height);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// NativeWindow:
|
||||||
|
gfx::Size ContentSizeToWindowSize(const gfx::Size& size) override;
|
||||||
|
gfx::Size WindowSizeToContentSize(const gfx::Size& size) override;
|
||||||
|
void UpdateDraggableRegions(
|
||||||
|
const std::vector<DraggableRegion>& regions) override;
|
||||||
|
|
||||||
void InstallView();
|
void InstallView();
|
||||||
void UninstallView();
|
void UninstallView();
|
||||||
|
|
||||||
// Install the drag view, which will cover the whole window and decides
|
// Install the drag view, which will cover the whole window and decides
|
||||||
// whehter we can drag.
|
// whehter we can drag.
|
||||||
void InstallDraggableRegionView();
|
void UpdateDraggableRegionViews(const std::vector<DraggableRegion>& regions);
|
||||||
|
|
||||||
base::scoped_nsobject<AtomNSWindow> window_;
|
base::scoped_nsobject<AtomNSWindow> window_;
|
||||||
base::scoped_nsobject<AtomNSWindowDelegate> window_delegate_;
|
base::scoped_nsobject<AtomNSWindowDelegate> window_delegate_;
|
||||||
|
@ -102,6 +108,8 @@ class NativeWindowMac : public NativeWindow {
|
||||||
// The view that will fill the whole frameless window.
|
// The view that will fill the whole frameless window.
|
||||||
base::scoped_nsobject<FullSizeContentView> content_view_;
|
base::scoped_nsobject<FullSizeContentView> content_view_;
|
||||||
|
|
||||||
|
std::vector<DraggableRegion> draggable_regions_;
|
||||||
|
|
||||||
bool is_kiosk_;
|
bool is_kiosk_;
|
||||||
|
|
||||||
NSInteger attention_request_id_; // identifier from requestUserAttention
|
NSInteger attention_request_id_; // identifier from requestUserAttention
|
||||||
|
@ -109,10 +117,6 @@ class NativeWindowMac : public NativeWindow {
|
||||||
// The presentation options before entering kiosk mode.
|
// The presentation options before entering kiosk mode.
|
||||||
NSApplicationPresentationOptions kiosk_options_;
|
NSApplicationPresentationOptions kiosk_options_;
|
||||||
|
|
||||||
// Mouse location since the last mouse event, in screen coordinates. This is
|
|
||||||
// used in custom drag to compute the window movement.
|
|
||||||
NSPoint last_mouse_offset_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(NativeWindowMac);
|
DISALLOW_COPY_AND_ASSIGN(NativeWindowMac);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "content/public/browser/render_view_host.h"
|
#include "content/public/browser/render_view_host.h"
|
||||||
#include "content/public/browser/render_widget_host_view.h"
|
#include "content/public/browser/render_widget_host_view.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
|
#include "ui/gfx/skia_util.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -146,6 +147,7 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidResize:(NSNotification*)notification {
|
- (void)windowDidResize:(NSNotification*)notification {
|
||||||
|
shell_->UpdateDraggableRegionViews();
|
||||||
shell_->NotifyWindowResize();
|
shell_->NotifyWindowResize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,43 +259,23 @@ bool ScopedDisableResize::disable_resize_ = false;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface ControlRegionView : NSView {
|
@interface ControlRegionView : NSView
|
||||||
@private
|
|
||||||
atom::NativeWindowMac* shellWindow_; // Weak; owns self.
|
|
||||||
}
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation ControlRegionView
|
@implementation ControlRegionView
|
||||||
|
|
||||||
- (id)initWithShellWindow:(atom::NativeWindowMac*)shellWindow {
|
|
||||||
if ((self = [super init]))
|
|
||||||
shellWindow_ = shellWindow;
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)mouseDownCanMoveWindow {
|
- (BOOL)mouseDownCanMoveWindow {
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSView*)hitTest:(NSPoint)aPoint {
|
- (NSView*)hitTest:(NSPoint)aPoint {
|
||||||
if (!shellWindow_->IsWithinDraggableRegion(aPoint)) {
|
return nil;
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseDown:(NSEvent*)event {
|
@end
|
||||||
shellWindow_->HandleMouseEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)mouseDragged:(NSEvent*)event {
|
|
||||||
shellWindow_->HandleMouseEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)acceptsFirstMouse:(NSEvent*)event {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@interface NSView (WebContentsView)
|
||||||
|
- (void)setMouseDownCanMoveWindow:(BOOL)can_move;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface AtomProgressBar : NSProgressIndicator
|
@interface AtomProgressBar : NSProgressIndicator
|
||||||
|
@ -350,6 +332,8 @@ NativeWindowMac::NativeWindowMac(
|
||||||
|
|
||||||
bool useStandardWindow = true;
|
bool useStandardWindow = true;
|
||||||
options.Get(switches::kStandardWindow, &useStandardWindow);
|
options.Get(switches::kStandardWindow, &useStandardWindow);
|
||||||
|
bool resizable = true;
|
||||||
|
options.Get(switches::kResizable, &resizable);
|
||||||
|
|
||||||
// New title bar styles are available in Yosemite or newer
|
// New title bar styles are available in Yosemite or newer
|
||||||
std::string titleBarStyle;
|
std::string titleBarStyle;
|
||||||
|
@ -357,10 +341,13 @@ NativeWindowMac::NativeWindowMac(
|
||||||
options.Get(switches::kTitleBarStyle, &titleBarStyle);
|
options.Get(switches::kTitleBarStyle, &titleBarStyle);
|
||||||
|
|
||||||
NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask |
|
NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask |
|
||||||
NSMiniaturizableWindowMask | NSResizableWindowMask;
|
NSMiniaturizableWindowMask;
|
||||||
if (!useStandardWindow || transparent() || !has_frame()) {
|
if (!useStandardWindow || transparent() || !has_frame()) {
|
||||||
styleMask |= NSTexturedBackgroundWindowMask;
|
styleMask |= NSTexturedBackgroundWindowMask;
|
||||||
}
|
}
|
||||||
|
if (resizable) {
|
||||||
|
styleMask |= NSResizableWindowMask;
|
||||||
|
}
|
||||||
if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) {
|
if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) {
|
||||||
styleMask |= NSFullSizeContentViewWindowMask;
|
styleMask |= NSFullSizeContentViewWindowMask;
|
||||||
styleMask |= NSUnifiedTitleAndToolbarWindowMask;
|
styleMask |= NSUnifiedTitleAndToolbarWindowMask;
|
||||||
|
@ -434,11 +421,6 @@ NativeWindowMac::NativeWindowMac(
|
||||||
[view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
[view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||||
|
|
||||||
InstallView();
|
InstallView();
|
||||||
|
|
||||||
// Install the DraggableRegionView if it is forced to use draggable regions
|
|
||||||
// for normal window.
|
|
||||||
if (has_frame() && force_using_draggable_region())
|
|
||||||
InstallDraggableRegionView();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeWindowMac::~NativeWindowMac() {
|
NativeWindowMac::~NativeWindowMac() {
|
||||||
|
@ -549,56 +531,30 @@ gfx::Rect NativeWindowMac::GetBounds() {
|
||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::SetContentSize(const gfx::Size& size) {
|
void NativeWindowMac::SetContentSizeConstraints(
|
||||||
if (!has_frame()) {
|
const extensions::SizeConstraints& size_constraints) {
|
||||||
SetSize(size);
|
auto convertSize = [this](const gfx::Size& size) {
|
||||||
return;
|
// Our frameless window still has titlebar attached, so setting contentSize
|
||||||
|
// will result in actual content size being larger.
|
||||||
|
if (!has_frame()) {
|
||||||
|
NSRect frame = NSMakeRect(0, 0, size.width(), size.height());
|
||||||
|
NSRect content = [window_ contentRectForFrameRect:frame];
|
||||||
|
return content.size;
|
||||||
|
} else {
|
||||||
|
return NSMakeSize(size.width(), size.height());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NSView* content = [window_ contentView];
|
||||||
|
if (size_constraints.HasMinimumSize()) {
|
||||||
|
NSSize min_size = convertSize(size_constraints.GetMinimumSize());
|
||||||
|
[window_ setContentMinSize:[content convertSize:min_size toView:nil]];
|
||||||
}
|
}
|
||||||
|
if (size_constraints.HasMaximumSize()) {
|
||||||
NSRect frame_nsrect = [window_ frame];
|
NSSize max_size = convertSize(size_constraints.GetMaximumSize());
|
||||||
NSSize frame = frame_nsrect.size;
|
[window_ setContentMaxSize:[content convertSize:max_size toView:nil]];
|
||||||
NSSize content = [window_ contentRectForFrameRect:frame_nsrect].size;
|
}
|
||||||
|
NativeWindow::SetContentSizeConstraints(size_constraints);
|
||||||
int width = size.width() + frame.width - content.width;
|
|
||||||
int height = size.height() + frame.height - content.height;
|
|
||||||
frame_nsrect.origin.y -= height - frame_nsrect.size.height;
|
|
||||||
frame_nsrect.size.width = width;
|
|
||||||
frame_nsrect.size.height = height;
|
|
||||||
[window_ setFrame:frame_nsrect display:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx::Size NativeWindowMac::GetContentSize() {
|
|
||||||
if (!has_frame())
|
|
||||||
return GetSize();
|
|
||||||
|
|
||||||
NSRect bounds = [[window_ contentView] bounds];
|
|
||||||
return gfx::Size(bounds.size.width, bounds.size.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NativeWindowMac::SetMinimumSize(const gfx::Size& size) {
|
|
||||||
NSSize min_size = NSMakeSize(size.width(), size.height());
|
|
||||||
NSView* content = [window_ contentView];
|
|
||||||
[window_ setContentMinSize:[content convertSize:min_size toView:nil]];
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx::Size NativeWindowMac::GetMinimumSize() {
|
|
||||||
NSView* content = [window_ contentView];
|
|
||||||
NSSize min_size = [content convertSize:[window_ contentMinSize]
|
|
||||||
fromView:nil];
|
|
||||||
return gfx::Size(min_size.width, min_size.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NativeWindowMac::SetMaximumSize(const gfx::Size& size) {
|
|
||||||
NSSize max_size = NSMakeSize(size.width(), size.height());
|
|
||||||
NSView* content = [window_ contentView];
|
|
||||||
[window_ setContentMaxSize:[content convertSize:max_size toView:nil]];
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx::Size NativeWindowMac::GetMaximumSize() {
|
|
||||||
NSView* content = [window_ contentView];
|
|
||||||
NSSize max_size = [content convertSize:[window_ contentMaxSize]
|
|
||||||
fromView:nil];
|
|
||||||
return gfx::Size(max_size.width, max_size.height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::SetResizable(bool resizable) {
|
void NativeWindowMac::SetResizable(bool resizable) {
|
||||||
|
@ -679,6 +635,9 @@ bool NativeWindowMac::IsKiosk() {
|
||||||
return is_kiosk_;
|
return is_kiosk_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeWindowMac::SetBackgroundColor(const std::string& color_name) {
|
||||||
|
}
|
||||||
|
|
||||||
void NativeWindowMac::SetRepresentedFilename(const std::string& filename) {
|
void NativeWindowMac::SetRepresentedFilename(const std::string& filename) {
|
||||||
[window_ setRepresentedFilename:base::SysUTF8ToNSString(filename)];
|
[window_ setRepresentedFilename:base::SysUTF8ToNSString(filename)];
|
||||||
}
|
}
|
||||||
|
@ -767,36 +726,6 @@ bool NativeWindowMac::IsVisibleOnAllWorkspaces() {
|
||||||
return collectionBehavior & NSWindowCollectionBehaviorCanJoinAllSpaces;
|
return collectionBehavior & NSWindowCollectionBehaviorCanJoinAllSpaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NativeWindowMac::IsWithinDraggableRegion(NSPoint point) const {
|
|
||||||
if (!draggable_region())
|
|
||||||
return false;
|
|
||||||
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
|
|
||||||
// to match these two.
|
|
||||||
return draggable_region()->contains(point.x, webViewHeight - point.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NativeWindowMac::HandleMouseEvent(NSEvent* event) {
|
|
||||||
NSPoint eventLoc = [event locationInWindow];
|
|
||||||
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(
|
|
||||||
frame_origin.x - current_mouse_location.x,
|
|
||||||
frame_origin.y - current_mouse_location.y);
|
|
||||||
} else if ([event type] == NSLeftMouseDragged) {
|
|
||||||
[window_ setFrameOrigin:NSMakePoint(
|
|
||||||
current_mouse_location.x + last_mouse_offset_.x,
|
|
||||||
current_mouse_location.y + last_mouse_offset_.y)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NativeWindowMac::HandleKeyboardEvent(
|
void NativeWindowMac::HandleKeyboardEvent(
|
||||||
content::WebContents*,
|
content::WebContents*,
|
||||||
const content::NativeWebKeyboardEvent& event) {
|
const content::NativeWebKeyboardEvent& event) {
|
||||||
|
@ -821,6 +750,48 @@ void NativeWindowMac::HandleKeyboardEvent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<gfx::Rect> NativeWindowMac::CalculateNonDraggableRegions(
|
||||||
|
const std::vector<DraggableRegion>& regions, int width, int height) {
|
||||||
|
std::vector<gfx::Rect> result;
|
||||||
|
if (regions.empty()) {
|
||||||
|
result.push_back(gfx::Rect(0, 0, width, height));
|
||||||
|
} else {
|
||||||
|
scoped_ptr<SkRegion> draggable(DraggableRegionsToSkRegion(regions));
|
||||||
|
scoped_ptr<SkRegion> non_draggable(new SkRegion);
|
||||||
|
non_draggable->op(0, 0, width, height, SkRegion::kUnion_Op);
|
||||||
|
non_draggable->op(*draggable, SkRegion::kDifference_Op);
|
||||||
|
for (SkRegion::Iterator it(*non_draggable); !it.done(); it.next()) {
|
||||||
|
result.push_back(gfx::SkIRectToRect(it.rect()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::Size NativeWindowMac::ContentSizeToWindowSize(const gfx::Size& size) {
|
||||||
|
if (!has_frame())
|
||||||
|
return size;
|
||||||
|
|
||||||
|
NSRect content = NSMakeRect(0, 0, size.width(), size.height());
|
||||||
|
NSRect frame = [window_ frameRectForContentRect:content];
|
||||||
|
return gfx::Size(frame.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::Size NativeWindowMac::WindowSizeToContentSize(const gfx::Size& size) {
|
||||||
|
if (!has_frame())
|
||||||
|
return size;
|
||||||
|
|
||||||
|
NSRect frame = NSMakeRect(0, 0, size.width(), size.height());
|
||||||
|
NSRect content = [window_ contentRectForFrameRect:frame];
|
||||||
|
return gfx::Size(content.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeWindowMac::UpdateDraggableRegions(
|
||||||
|
const std::vector<DraggableRegion>& regions) {
|
||||||
|
NativeWindow::UpdateDraggableRegions(regions);
|
||||||
|
draggable_regions_ = regions;
|
||||||
|
UpdateDraggableRegionViews(regions);
|
||||||
|
}
|
||||||
|
|
||||||
void NativeWindowMac::InstallView() {
|
void NativeWindowMac::InstallView() {
|
||||||
// Make sure the bottom corner is rounded: http://crbug.com/396264.
|
// Make sure the bottom corner is rounded: http://crbug.com/396264.
|
||||||
[[window_ contentView] setWantsLayer:YES];
|
[[window_ contentView] setWantsLayer:YES];
|
||||||
|
@ -843,8 +814,6 @@ void NativeWindowMac::InstallView() {
|
||||||
[view setFrame:[content_view_ bounds]];
|
[view setFrame:[content_view_ bounds]];
|
||||||
[content_view_ addSubview:view];
|
[content_view_ addSubview:view];
|
||||||
|
|
||||||
InstallDraggableRegionView();
|
|
||||||
|
|
||||||
[[window_ standardWindowButton:NSWindowZoomButton] setHidden:YES];
|
[[window_ standardWindowButton:NSWindowZoomButton] setHidden:YES];
|
||||||
[[window_ standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
|
[[window_ standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
|
||||||
[[window_ standardWindowButton:NSWindowCloseButton] setHidden:YES];
|
[[window_ standardWindowButton:NSWindowCloseButton] setHidden:YES];
|
||||||
|
@ -861,14 +830,55 @@ void NativeWindowMac::UninstallView() {
|
||||||
[view removeFromSuperview];
|
[view removeFromSuperview];
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::InstallDraggableRegionView() {
|
void NativeWindowMac::UpdateDraggableRegionViews(
|
||||||
|
const std::vector<DraggableRegion>& regions) {
|
||||||
|
if (has_frame() && !force_using_draggable_region())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 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 = web_contents()->GetNativeView();
|
NSView* webView = web_contents()->GetNativeView();
|
||||||
base::scoped_nsobject<NSView> controlRegion(
|
NSInteger webViewWidth = NSWidth([webView bounds]);
|
||||||
[[ControlRegionView alloc] initWithShellWindow:this]);
|
NSInteger webViewHeight = NSHeight([webView bounds]);
|
||||||
[controlRegion setFrame:NSMakeRect(0, 0,
|
|
||||||
NSWidth([webView bounds]),
|
[webView setMouseDownCanMoveWindow:YES];
|
||||||
NSHeight([webView bounds]))];
|
|
||||||
[webView addSubview:controlRegion];
|
// 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];
|
||||||
|
|
||||||
|
// Draggable regions is implemented by having the whole web view draggable
|
||||||
|
// (mouseDownCanMoveWindow) and overlaying regions that are not draggable.
|
||||||
|
std::vector<gfx::Rect> system_drag_exclude_areas =
|
||||||
|
CalculateNonDraggableRegions(regions, webViewWidth, webViewHeight);
|
||||||
|
|
||||||
|
// Create and add a 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] initWithFrame:NSZeroRect]);
|
||||||
|
[controlRegion setFrame:NSMakeRect(iter->x(),
|
||||||
|
webViewHeight - iter->bottom(),
|
||||||
|
iter->width(),
|
||||||
|
iter->height())];
|
||||||
|
[webView addSubview:controlRegion];
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppKit will not update its cache of mouseDownCanMoveWindow unless something
|
||||||
|
// changes. Previously we tried adding an NSView and removing it, but for some
|
||||||
|
// reason it required reposting the mouse-down event, and didn't always work.
|
||||||
|
// Calling the below seems to be an effective solution.
|
||||||
|
[window_ setMovableByWindowBackground:NO];
|
||||||
|
[window_ setMovableByWindowBackground:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
#include "ui/base/window_open_disposition.h"
|
#include "ui/base/window_open_disposition.h"
|
||||||
#include "url/gurl.h"
|
#include "url/gurl.h"
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
class NativeWindowObserver {
|
class NativeWindowObserver {
|
||||||
|
@ -55,6 +59,11 @@ class NativeWindowObserver {
|
||||||
virtual void OnWindowEnterHtmlFullScreen() {}
|
virtual void OnWindowEnterHtmlFullScreen() {}
|
||||||
virtual void OnWindowLeaveHtmlFullScreen() {}
|
virtual void OnWindowLeaveHtmlFullScreen() {}
|
||||||
|
|
||||||
|
// Called when window message received
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
virtual void OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Called when renderer is hung.
|
// Called when renderer is hung.
|
||||||
virtual void OnRendererUnresponsive() {}
|
virtual void OnRendererUnresponsive() {}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#elif defined(OS_WIN)
|
#elif defined(OS_WIN)
|
||||||
#include "atom/browser/ui/views/win_frame_view.h"
|
#include "atom/browser/ui/views/win_frame_view.h"
|
||||||
#include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h"
|
#include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h"
|
||||||
|
#include "skia/ext/skia_utils_win.h"
|
||||||
#include "ui/base/win/shell.h"
|
#include "ui/base/win/shell.h"
|
||||||
#include "ui/gfx/win/dpi.h"
|
#include "ui/gfx/win/dpi.h"
|
||||||
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
|
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
|
||||||
|
@ -77,69 +78,28 @@ bool IsAltModifier(const content::NativeWebKeyboardEvent& event) {
|
||||||
(modifiers == (Modifiers::AltKey | Modifiers::IsRight));
|
(modifiers == (Modifiers::AltKey | Modifiers::IsRight));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
SkColor ParseHexColor(const std::string& name) {
|
||||||
// Convert Win32 WM_APPCOMMANDS to strings.
|
SkColor result = 0xFF000000;
|
||||||
const char* AppCommandToString(int command_id) {
|
unsigned value = 0;
|
||||||
switch (command_id) {
|
auto color = name.substr(1);
|
||||||
case APPCOMMAND_BROWSER_BACKWARD : return "browser-backward";
|
unsigned length = color.size();
|
||||||
case APPCOMMAND_BROWSER_FORWARD : return "browser-forward";
|
if (length != 3 && length != 6)
|
||||||
case APPCOMMAND_BROWSER_REFRESH : return "browser-refresh";
|
return result;
|
||||||
case APPCOMMAND_BROWSER_STOP : return "browser-stop";
|
for (unsigned i = 0; i < length; ++i) {
|
||||||
case APPCOMMAND_BROWSER_SEARCH : return "browser-search";
|
if (!base::IsHexDigit(color[i]))
|
||||||
case APPCOMMAND_BROWSER_FAVORITES : return "browser-favorites";
|
return result;
|
||||||
case APPCOMMAND_BROWSER_HOME : return "browser-home";
|
value <<= 4;
|
||||||
case APPCOMMAND_VOLUME_MUTE : return "volume-mute";
|
value |= (color[i] < 'A' ? color[i] - '0' : (color[i] - 'A' + 10) & 0xF);
|
||||||
case APPCOMMAND_VOLUME_DOWN : return "volume-down";
|
|
||||||
case APPCOMMAND_VOLUME_UP : return "volume-up";
|
|
||||||
case APPCOMMAND_MEDIA_NEXTTRACK : return "media-nexttrack";
|
|
||||||
case APPCOMMAND_MEDIA_PREVIOUSTRACK : return "media-previoustrack";
|
|
||||||
case APPCOMMAND_MEDIA_STOP : return "media-stop";
|
|
||||||
case APPCOMMAND_MEDIA_PLAY_PAUSE : return "media-play_pause";
|
|
||||||
case APPCOMMAND_LAUNCH_MAIL : return "launch-mail";
|
|
||||||
case APPCOMMAND_LAUNCH_MEDIA_SELECT : return "launch-media-select";
|
|
||||||
case APPCOMMAND_LAUNCH_APP1 : return "launch-app1";
|
|
||||||
case APPCOMMAND_LAUNCH_APP2 : return "launch-app2";
|
|
||||||
case APPCOMMAND_BASS_DOWN : return "bass-down";
|
|
||||||
case APPCOMMAND_BASS_BOOST : return "bass-boost";
|
|
||||||
case APPCOMMAND_BASS_UP : return "bass-up";
|
|
||||||
case APPCOMMAND_TREBLE_DOWN : return "treble-down";
|
|
||||||
case APPCOMMAND_TREBLE_UP : return "treble-up";
|
|
||||||
case APPCOMMAND_MICROPHONE_VOLUME_MUTE : return "microphone-volume-mute";
|
|
||||||
case APPCOMMAND_MICROPHONE_VOLUME_DOWN : return "microphone-volume-down";
|
|
||||||
case APPCOMMAND_MICROPHONE_VOLUME_UP : return "microphone-volume-up";
|
|
||||||
case APPCOMMAND_HELP : return "help";
|
|
||||||
case APPCOMMAND_FIND : return "find";
|
|
||||||
case APPCOMMAND_NEW : return "new";
|
|
||||||
case APPCOMMAND_OPEN : return "open";
|
|
||||||
case APPCOMMAND_CLOSE : return "close";
|
|
||||||
case APPCOMMAND_SAVE : return "save";
|
|
||||||
case APPCOMMAND_PRINT : return "print";
|
|
||||||
case APPCOMMAND_UNDO : return "undo";
|
|
||||||
case APPCOMMAND_REDO : return "redo";
|
|
||||||
case APPCOMMAND_COPY : return "copy";
|
|
||||||
case APPCOMMAND_CUT : return "cut";
|
|
||||||
case APPCOMMAND_PASTE : return "paste";
|
|
||||||
case APPCOMMAND_REPLY_TO_MAIL : return "reply-to-mail";
|
|
||||||
case APPCOMMAND_FORWARD_MAIL : return "forward-mail";
|
|
||||||
case APPCOMMAND_SEND_MAIL : return "send-mail";
|
|
||||||
case APPCOMMAND_SPELL_CHECK : return "spell-check";
|
|
||||||
case APPCOMMAND_MIC_ON_OFF_TOGGLE : return "mic-on-off-toggle";
|
|
||||||
case APPCOMMAND_CORRECTION_LIST : return "correction-list";
|
|
||||||
case APPCOMMAND_MEDIA_PLAY : return "media-play";
|
|
||||||
case APPCOMMAND_MEDIA_PAUSE : return "media-pause";
|
|
||||||
case APPCOMMAND_MEDIA_RECORD : return "media-record";
|
|
||||||
case APPCOMMAND_MEDIA_FAST_FORWARD : return "media-fast-forward";
|
|
||||||
case APPCOMMAND_MEDIA_REWIND : return "media-rewind";
|
|
||||||
case APPCOMMAND_MEDIA_CHANNEL_UP : return "media-channel-up";
|
|
||||||
case APPCOMMAND_MEDIA_CHANNEL_DOWN : return "media-channel-down";
|
|
||||||
case APPCOMMAND_DELETE : return "delete";
|
|
||||||
case APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE:
|
|
||||||
return "dictate-or-command-control-toggle";
|
|
||||||
default:
|
|
||||||
return "unknown";
|
|
||||||
}
|
}
|
||||||
|
if (length == 6) {
|
||||||
|
result |= value;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result |= (value & 0xF00) << 12 | (value & 0xF00) << 8
|
||||||
|
| (value & 0xF0) << 8 | (value & 0xF0) << 4
|
||||||
|
| (value & 0xF) << 4 | (value & 0xF);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
class NativeWindowClientView : public views::ClientView {
|
class NativeWindowClientView : public views::ClientView {
|
||||||
public:
|
public:
|
||||||
|
@ -186,7 +146,8 @@ NativeWindowViews::NativeWindowViews(
|
||||||
// will not allow us to resize the window larger than scree.
|
// will not allow us to resize the window larger than scree.
|
||||||
// Setting directly to INT_MAX somehow doesn't work, so we just devide
|
// Setting directly to INT_MAX somehow doesn't work, so we just devide
|
||||||
// by 10, which should still be large enough.
|
// by 10, which should still be large enough.
|
||||||
maximum_size_.SetSize(INT_MAX / 10, INT_MAX / 10);
|
SetContentSizeConstraints(extensions::SizeConstraints(
|
||||||
|
gfx::Size(), gfx::Size(INT_MAX / 10, INT_MAX / 10)));
|
||||||
|
|
||||||
int width = 800, height = 600;
|
int width = 800, height = 600;
|
||||||
options.Get(switches::kWidth, &width);
|
options.Get(switches::kWidth, &width);
|
||||||
|
@ -268,13 +229,8 @@ NativeWindowViews::NativeWindowViews(
|
||||||
|
|
||||||
// Add web view.
|
// Add web view.
|
||||||
SetLayoutManager(new MenuLayout(this, kMenuBarHeight));
|
SetLayoutManager(new MenuLayout(this, kMenuBarHeight));
|
||||||
set_background(views::Background::CreateStandardPanelBackground());
|
|
||||||
AddChildView(web_view_);
|
|
||||||
|
|
||||||
if (has_frame() &&
|
AddChildView(web_view_);
|
||||||
options.Get(switches::kUseContentSize, &use_content_size_) &&
|
|
||||||
use_content_size_)
|
|
||||||
bounds = ContentBoundsToWindowBounds(bounds);
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
// Save initial window state.
|
// Save initial window state.
|
||||||
|
@ -316,8 +272,14 @@ NativeWindowViews::NativeWindowViews(
|
||||||
if (transparent() && !has_frame())
|
if (transparent() && !has_frame())
|
||||||
wm::SetShadowType(GetNativeWindow(), wm::SHADOW_TYPE_NONE);
|
wm::SetShadowType(GetNativeWindow(), wm::SHADOW_TYPE_NONE);
|
||||||
|
|
||||||
|
gfx::Size size = bounds.size();
|
||||||
|
if (has_frame() &&
|
||||||
|
options.Get(switches::kUseContentSize, &use_content_size_) &&
|
||||||
|
use_content_size_)
|
||||||
|
size = ContentSizeToWindowSize(size);
|
||||||
|
|
||||||
window_->UpdateWindowIcon();
|
window_->UpdateWindowIcon();
|
||||||
window_->CenterWindow(bounds.size());
|
window_->CenterWindow(size);
|
||||||
Layout();
|
Layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,42 +402,26 @@ gfx::Rect NativeWindowViews::GetBounds() {
|
||||||
return window_->GetWindowBoundsInScreen();
|
return window_->GetWindowBoundsInScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowViews::SetContentSize(const gfx::Size& size) {
|
|
||||||
if (!has_frame()) {
|
|
||||||
NativeWindow::SetSize(size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx::Rect bounds = window_->GetWindowBoundsInScreen();
|
|
||||||
bounds.set_size(size);
|
|
||||||
SetBounds(ContentBoundsToWindowBounds(bounds));
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx::Size NativeWindowViews::GetContentSize() {
|
gfx::Size NativeWindowViews::GetContentSize() {
|
||||||
if (!has_frame())
|
#if defined(OS_WIN)
|
||||||
return GetSize();
|
if (IsMinimized())
|
||||||
|
return NativeWindow::GetContentSize();
|
||||||
|
#endif
|
||||||
|
|
||||||
gfx::Size content_size =
|
return web_view_->size();
|
||||||
window_->non_client_view()->frame_view()->GetBoundsForClientView().size();
|
|
||||||
if (menu_bar_ && menu_bar_visible_)
|
|
||||||
content_size.set_height(content_size.height() - kMenuBarHeight);
|
|
||||||
return content_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowViews::SetMinimumSize(const gfx::Size& size) {
|
void NativeWindowViews::SetContentSizeConstraints(
|
||||||
minimum_size_ = size;
|
const extensions::SizeConstraints& size_constraints) {
|
||||||
}
|
NativeWindow::SetContentSizeConstraints(size_constraints);
|
||||||
|
// widget_delegate() is only available after Init() is called, we make use of
|
||||||
gfx::Size NativeWindowViews::GetMinimumSize() {
|
// this to determine whether native widget has initialized.
|
||||||
return minimum_size_;
|
if (window_ && window_->widget_delegate())
|
||||||
}
|
window_->OnSizeConstraintsChanged();
|
||||||
|
#if defined(USE_X11)
|
||||||
void NativeWindowViews::SetMaximumSize(const gfx::Size& size) {
|
if (resizable_)
|
||||||
maximum_size_ = size;
|
old_size_constraints_ = size_constraints;
|
||||||
}
|
#endif
|
||||||
|
|
||||||
gfx::Size NativeWindowViews::GetMaximumSize() {
|
|
||||||
return maximum_size_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowViews::SetResizable(bool resizable) {
|
void NativeWindowViews::SetResizable(bool resizable) {
|
||||||
|
@ -494,11 +440,13 @@ void NativeWindowViews::SetResizable(bool resizable) {
|
||||||
// On Linux there is no "resizable" property of a window, we have to set
|
// On Linux there is no "resizable" property of a window, we have to set
|
||||||
// both the minimum and maximum size to the window size to achieve it.
|
// both the minimum and maximum size to the window size to achieve it.
|
||||||
if (resizable) {
|
if (resizable) {
|
||||||
SetMaximumSize(gfx::Size());
|
SetContentSizeConstraints(old_size_constraints_);
|
||||||
SetMinimumSize(gfx::Size());
|
|
||||||
} else {
|
} else {
|
||||||
SetMaximumSize(GetSize());
|
old_size_constraints_ = GetContentSizeConstraints();
|
||||||
SetMinimumSize(GetSize());
|
resizable_ = false;
|
||||||
|
gfx::Size content_size = GetContentSize();
|
||||||
|
SetContentSizeConstraints(
|
||||||
|
extensions::SizeConstraints(content_size, content_size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -572,6 +520,21 @@ bool NativeWindowViews::IsKiosk() {
|
||||||
return IsFullscreen();
|
return IsFullscreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeWindowViews::SetBackgroundColor(const std::string& color_name) {
|
||||||
|
// web views' background color.
|
||||||
|
SkColor background_color = ParseHexColor(color_name);
|
||||||
|
set_background(views::Background::CreateSolidBackground(background_color));
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
// Set the background color of native window.
|
||||||
|
HBRUSH brush = CreateSolidBrush(skia::SkColorToCOLORREF(background_color));
|
||||||
|
ULONG_PTR previous_brush = SetClassLongPtr(
|
||||||
|
GetAcceleratedWidget(), GCLP_HBRBACKGROUND, (LONG)brush);
|
||||||
|
if (previous_brush)
|
||||||
|
DeleteObject((HBRUSH)previous_brush);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) {
|
void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) {
|
||||||
if (menu_model == nullptr) {
|
if (menu_model == nullptr) {
|
||||||
// Remove accelerators
|
// Remove accelerators
|
||||||
|
@ -610,8 +573,24 @@ void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) {
|
||||||
|
|
||||||
if (!menu_bar_autohide_) {
|
if (!menu_bar_autohide_) {
|
||||||
SetMenuBarVisibility(true);
|
SetMenuBarVisibility(true);
|
||||||
if (use_content_size_)
|
if (use_content_size_) {
|
||||||
|
// Enlarge the size constraints for the menu.
|
||||||
|
extensions::SizeConstraints constraints = GetContentSizeConstraints();
|
||||||
|
if (constraints.HasMinimumSize()) {
|
||||||
|
gfx::Size min_size = constraints.GetMinimumSize();
|
||||||
|
min_size.set_height(min_size.height() + kMenuBarHeight);
|
||||||
|
constraints.set_minimum_size(min_size);
|
||||||
|
}
|
||||||
|
if (constraints.HasMaximumSize()) {
|
||||||
|
gfx::Size max_size = constraints.GetMaximumSize();
|
||||||
|
max_size.set_height(max_size.height() + kMenuBarHeight);
|
||||||
|
constraints.set_maximum_size(max_size);
|
||||||
|
}
|
||||||
|
SetContentSizeConstraints(constraints);
|
||||||
|
|
||||||
|
// Resize the window to make sure content size is not changed.
|
||||||
SetContentSize(content_size);
|
SetContentSize(content_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -814,103 +793,45 @@ void NativeWindowViews::OnWidgetMove() {
|
||||||
NotifyWindowMove();
|
NotifyWindowMove();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
gfx::Size NativeWindowViews::ContentSizeToWindowSize(const gfx::Size& size) {
|
||||||
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
|
if (!has_frame())
|
||||||
std::string command = AppCommandToString(command_id);
|
|
||||||
NotifyWindowExecuteWindowsCommand(command);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NativeWindowViews::PreHandleMSG(
|
|
||||||
UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) {
|
|
||||||
switch (message) {
|
|
||||||
case WM_COMMAND:
|
|
||||||
// Handle thumbar button click message.
|
|
||||||
if (HIWORD(w_param) == THBN_CLICKED)
|
|
||||||
return taskbar_host_.HandleThumbarButtonEvent(LOWORD(w_param));
|
|
||||||
return false;
|
|
||||||
case WM_SIZE:
|
|
||||||
// Handle window state change.
|
|
||||||
HandleSizeEvent(w_param, l_param);
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
|
|
||||||
// Here we handle the WM_SIZE event in order to figure out what is the current
|
|
||||||
// window state and notify the user accordingly.
|
|
||||||
switch (w_param) {
|
|
||||||
case SIZE_MAXIMIZED:
|
|
||||||
last_window_state_ = ui::SHOW_STATE_MAXIMIZED;
|
|
||||||
NotifyWindowMaximize();
|
|
||||||
break;
|
|
||||||
case SIZE_MINIMIZED:
|
|
||||||
last_window_state_ = ui::SHOW_STATE_MINIMIZED;
|
|
||||||
NotifyWindowMinimize();
|
|
||||||
break;
|
|
||||||
case SIZE_RESTORED:
|
|
||||||
if (last_window_state_ == ui::SHOW_STATE_NORMAL) {
|
|
||||||
// Window was resized so we save it's new size.
|
|
||||||
last_normal_size_ = GetSize();
|
|
||||||
} else {
|
|
||||||
switch (last_window_state_) {
|
|
||||||
case ui::SHOW_STATE_MAXIMIZED:
|
|
||||||
last_window_state_ = ui::SHOW_STATE_NORMAL;
|
|
||||||
|
|
||||||
// When the window is restored we resize it to the previous known
|
|
||||||
// normal size.
|
|
||||||
NativeWindow::SetSize(last_normal_size_);
|
|
||||||
|
|
||||||
NotifyWindowUnmaximize();
|
|
||||||
break;
|
|
||||||
case ui::SHOW_STATE_MINIMIZED:
|
|
||||||
if (IsFullscreen()) {
|
|
||||||
last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
|
|
||||||
NotifyWindowEnterFullScreen();
|
|
||||||
} else {
|
|
||||||
last_window_state_ = ui::SHOW_STATE_NORMAL;
|
|
||||||
|
|
||||||
// When the window is restored we resize it to the previous known
|
|
||||||
// normal size.
|
|
||||||
NativeWindow::SetSize(last_normal_size_);
|
|
||||||
|
|
||||||
NotifyWindowRestore();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gfx::Size NativeWindowViews::WindowSizeToFramelessSize(
|
|
||||||
const gfx::Size& size) {
|
|
||||||
if (size.width() == 0 && size.height() == 0)
|
|
||||||
return size;
|
return size;
|
||||||
|
|
||||||
gfx::Rect window_bounds = gfx::Rect(size);
|
gfx::Size window_size(size);
|
||||||
if (use_content_size_) {
|
|
||||||
if (menu_bar_ && menu_bar_visible_) {
|
|
||||||
window_bounds.set_height(window_bounds.height() + kMenuBarHeight);
|
|
||||||
}
|
|
||||||
} else if (has_frame()) {
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
gfx::Size frame_size = gfx::win::ScreenToDIPRect(
|
gfx::Rect dpi_bounds =
|
||||||
window_->non_client_view()->GetWindowBoundsForClientBounds(
|
gfx::Rect(gfx::Point(), gfx::win::DIPToScreenSize(size));
|
||||||
gfx::Rect())).size();
|
gfx::Rect window_bounds = gfx::win::ScreenToDIPRect(
|
||||||
#else
|
window_->non_client_view()->GetWindowBoundsForClientBounds(dpi_bounds));
|
||||||
gfx::Size frame_size =
|
window_size = window_bounds.size();
|
||||||
window_->non_client_view()->GetWindowBoundsForClientBounds(
|
|
||||||
gfx::Rect()).size();
|
|
||||||
#endif
|
#endif
|
||||||
window_bounds.set_height(window_bounds.height() - frame_size.height());
|
|
||||||
window_bounds.set_width(window_bounds.width() - frame_size.width());
|
|
||||||
}
|
|
||||||
|
|
||||||
return window_bounds.size();
|
if (menu_bar_ && menu_bar_visible_)
|
||||||
|
window_size.set_height(window_size.height() + kMenuBarHeight);
|
||||||
|
return window_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::Size NativeWindowViews::WindowSizeToContentSize(const gfx::Size& size) {
|
||||||
|
if (!has_frame())
|
||||||
|
return size;
|
||||||
|
|
||||||
|
gfx::Size content_size(size);
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
content_size = gfx::win::DIPToScreenSize(content_size);
|
||||||
|
RECT rect;
|
||||||
|
SetRectEmpty(&rect);
|
||||||
|
HWND hwnd = GetAcceleratedWidget();
|
||||||
|
DWORD style = ::GetWindowLong(hwnd, GWL_STYLE);
|
||||||
|
DWORD ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||||
|
AdjustWindowRectEx(&rect, style, FALSE, ex_style);
|
||||||
|
content_size.set_width(content_size.width() - (rect.right - rect.left));
|
||||||
|
content_size.set_height(content_size.height() - (rect.bottom - rect.top));
|
||||||
|
content_size = gfx::win::ScreenToDIPSize(content_size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (menu_bar_ && menu_bar_visible_)
|
||||||
|
content_size.set_height(content_size.height() - kMenuBarHeight);
|
||||||
|
return content_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowViews::HandleKeyboardEvent(
|
void NativeWindowViews::HandleKeyboardEvent(
|
||||||
|
@ -954,6 +875,14 @@ void NativeWindowViews::HandleKeyboardEvent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gfx::Size NativeWindowViews::GetMinimumSize() {
|
||||||
|
return NativeWindow::GetMinimumSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::Size NativeWindowViews::GetMaximumSize() {
|
||||||
|
return NativeWindow::GetMaximumSize();
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeWindowViews::AcceleratorPressed(const ui::Accelerator& accelerator) {
|
bool NativeWindowViews::AcceleratorPressed(const ui::Accelerator& accelerator) {
|
||||||
return accelerator_util::TriggerAcceleratorTableCommand(
|
return accelerator_util::TriggerAcceleratorTableCommand(
|
||||||
&accelerator_table_, accelerator);
|
&accelerator_table_, accelerator);
|
||||||
|
@ -976,26 +905,6 @@ void NativeWindowViews::RegisterAccelerators(ui::MenuModel* menu_model) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::Rect NativeWindowViews::ContentBoundsToWindowBounds(
|
|
||||||
const gfx::Rect& bounds) {
|
|
||||||
gfx::Point origin = bounds.origin();
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
gfx::Rect dpi_bounds = gfx::win::DIPToScreenRect(bounds);
|
|
||||||
gfx::Rect window_bounds = gfx::win::ScreenToDIPRect(
|
|
||||||
window_->non_client_view()->GetWindowBoundsForClientBounds(dpi_bounds));
|
|
||||||
#else
|
|
||||||
gfx::Rect window_bounds =
|
|
||||||
window_->non_client_view()->GetWindowBoundsForClientBounds(bounds);
|
|
||||||
#endif
|
|
||||||
// The window's position would also be changed, but we only want to change
|
|
||||||
// the size.
|
|
||||||
window_bounds.set_origin(origin);
|
|
||||||
|
|
||||||
if (menu_bar_ && menu_bar_visible_)
|
|
||||||
window_bounds.set_height(window_bounds.height() + kMenuBarHeight);
|
|
||||||
return window_bounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
ui::WindowShowState NativeWindowViews::GetRestoredState() {
|
ui::WindowShowState NativeWindowViews::GetRestoredState() {
|
||||||
if (IsMaximized())
|
if (IsMaximized())
|
||||||
return ui::SHOW_STATE_MAXIMIZED;
|
return ui::SHOW_STATE_MAXIMIZED;
|
||||||
|
|
|
@ -63,12 +63,9 @@ class NativeWindowViews : public NativeWindow,
|
||||||
bool IsFullscreen() const override;
|
bool IsFullscreen() const override;
|
||||||
void SetBounds(const gfx::Rect& bounds) override;
|
void SetBounds(const gfx::Rect& bounds) override;
|
||||||
gfx::Rect GetBounds() override;
|
gfx::Rect GetBounds() override;
|
||||||
void SetContentSize(const gfx::Size& size) override;
|
|
||||||
gfx::Size GetContentSize() override;
|
gfx::Size GetContentSize() override;
|
||||||
void SetMinimumSize(const gfx::Size& size) override;
|
void SetContentSizeConstraints(
|
||||||
gfx::Size GetMinimumSize() override;
|
const extensions::SizeConstraints& size_constraints) override;
|
||||||
void SetMaximumSize(const gfx::Size& size) override;
|
|
||||||
gfx::Size GetMaximumSize() override;
|
|
||||||
void SetResizable(bool resizable) override;
|
void SetResizable(bool resizable) override;
|
||||||
bool IsResizable() override;
|
bool IsResizable() override;
|
||||||
void SetAlwaysOnTop(bool top) override;
|
void SetAlwaysOnTop(bool top) override;
|
||||||
|
@ -80,6 +77,7 @@ class NativeWindowViews : public NativeWindow,
|
||||||
void SetSkipTaskbar(bool skip) override;
|
void SetSkipTaskbar(bool skip) override;
|
||||||
void SetKiosk(bool kiosk) override;
|
void SetKiosk(bool kiosk) override;
|
||||||
bool IsKiosk() override;
|
bool IsKiosk() override;
|
||||||
|
void SetBackgroundColor(const std::string& color_name) override;
|
||||||
void SetMenu(ui::MenuModel* menu_model) override;
|
void SetMenu(ui::MenuModel* menu_model) override;
|
||||||
gfx::NativeWindow GetNativeWindow() override;
|
gfx::NativeWindow GetNativeWindow() override;
|
||||||
void SetOverlayIcon(const gfx::Image& overlay,
|
void SetOverlayIcon(const gfx::Image& overlay,
|
||||||
|
@ -94,8 +92,6 @@ class NativeWindowViews : public NativeWindow,
|
||||||
|
|
||||||
gfx::AcceleratedWidget GetAcceleratedWidget();
|
gfx::AcceleratedWidget GetAcceleratedWidget();
|
||||||
|
|
||||||
gfx::Size WindowSizeToFramelessSize(const gfx::Size& size);
|
|
||||||
|
|
||||||
views::Widget* widget() const { return window_.get(); }
|
views::Widget* widget() const { return window_.get(); }
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
|
@ -142,20 +138,20 @@ class NativeWindowViews : public NativeWindow,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// NativeWindow:
|
// NativeWindow:
|
||||||
|
gfx::Size ContentSizeToWindowSize(const gfx::Size& size) override;
|
||||||
|
gfx::Size WindowSizeToContentSize(const gfx::Size& size) override;
|
||||||
void HandleKeyboardEvent(
|
void HandleKeyboardEvent(
|
||||||
content::WebContents*,
|
content::WebContents*,
|
||||||
const content::NativeWebKeyboardEvent& event) override;
|
const content::NativeWebKeyboardEvent& event) override;
|
||||||
|
|
||||||
// views::View:
|
// views::View:
|
||||||
|
gfx::Size GetMinimumSize() override;
|
||||||
|
gfx::Size GetMaximumSize() override;
|
||||||
bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
|
bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
|
||||||
|
|
||||||
// Register accelerators supported by the menu model.
|
// Register accelerators supported by the menu model.
|
||||||
void RegisterAccelerators(ui::MenuModel* menu_model);
|
void RegisterAccelerators(ui::MenuModel* menu_model);
|
||||||
|
|
||||||
// Converts between client area and window area, since we include the menu bar
|
|
||||||
// in client area we need to substract/add menu bar's height in convertions.
|
|
||||||
gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& content_bounds);
|
|
||||||
|
|
||||||
// Returns the restore state for the window.
|
// Returns the restore state for the window.
|
||||||
ui::WindowShowState GetRestoredState();
|
ui::WindowShowState GetRestoredState();
|
||||||
|
|
||||||
|
@ -172,6 +168,11 @@ class NativeWindowViews : public NativeWindow,
|
||||||
|
|
||||||
// Handles window state events.
|
// Handles window state events.
|
||||||
scoped_ptr<WindowStateWatcher> window_state_watcher_;
|
scoped_ptr<WindowStateWatcher> window_state_watcher_;
|
||||||
|
|
||||||
|
// The "resizable" flag on Linux is implemented by setting size constraints,
|
||||||
|
// we need to make sure size constraints are restored when window becomes
|
||||||
|
// resizable again.
|
||||||
|
extensions::SizeConstraints old_size_constraints_;
|
||||||
#elif defined(OS_WIN)
|
#elif defined(OS_WIN)
|
||||||
// Weak ref.
|
// Weak ref.
|
||||||
AtomDesktopWindowTreeHostWin* atom_desktop_window_tree_host_win_;
|
AtomDesktopWindowTreeHostWin* atom_desktop_window_tree_host_win_;
|
||||||
|
@ -197,8 +198,6 @@ class NativeWindowViews : public NativeWindow,
|
||||||
bool use_content_size_;
|
bool use_content_size_;
|
||||||
bool resizable_;
|
bool resizable_;
|
||||||
std::string title_;
|
std::string title_;
|
||||||
gfx::Size minimum_size_;
|
|
||||||
gfx::Size maximum_size_;
|
|
||||||
gfx::Size widget_size_;
|
gfx::Size widget_size_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(NativeWindowViews);
|
DISALLOW_COPY_AND_ASSIGN(NativeWindowViews);
|
||||||
|
|
162
atom/browser/native_window_views_win.cc
Normal file
162
atom/browser/native_window_views_win.cc
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
// 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/browser/native_window_views.h"
|
||||||
|
#include "content/public/browser/browser_accessibility_state.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Convert Win32 WM_APPCOMMANDS to strings.
|
||||||
|
const char* AppCommandToString(int command_id) {
|
||||||
|
switch (command_id) {
|
||||||
|
case APPCOMMAND_BROWSER_BACKWARD : return "browser-backward";
|
||||||
|
case APPCOMMAND_BROWSER_FORWARD : return "browser-forward";
|
||||||
|
case APPCOMMAND_BROWSER_REFRESH : return "browser-refresh";
|
||||||
|
case APPCOMMAND_BROWSER_STOP : return "browser-stop";
|
||||||
|
case APPCOMMAND_BROWSER_SEARCH : return "browser-search";
|
||||||
|
case APPCOMMAND_BROWSER_FAVORITES : return "browser-favorites";
|
||||||
|
case APPCOMMAND_BROWSER_HOME : return "browser-home";
|
||||||
|
case APPCOMMAND_VOLUME_MUTE : return "volume-mute";
|
||||||
|
case APPCOMMAND_VOLUME_DOWN : return "volume-down";
|
||||||
|
case APPCOMMAND_VOLUME_UP : return "volume-up";
|
||||||
|
case APPCOMMAND_MEDIA_NEXTTRACK : return "media-nexttrack";
|
||||||
|
case APPCOMMAND_MEDIA_PREVIOUSTRACK : return "media-previoustrack";
|
||||||
|
case APPCOMMAND_MEDIA_STOP : return "media-stop";
|
||||||
|
case APPCOMMAND_MEDIA_PLAY_PAUSE : return "media-play_pause";
|
||||||
|
case APPCOMMAND_LAUNCH_MAIL : return "launch-mail";
|
||||||
|
case APPCOMMAND_LAUNCH_MEDIA_SELECT : return "launch-media-select";
|
||||||
|
case APPCOMMAND_LAUNCH_APP1 : return "launch-app1";
|
||||||
|
case APPCOMMAND_LAUNCH_APP2 : return "launch-app2";
|
||||||
|
case APPCOMMAND_BASS_DOWN : return "bass-down";
|
||||||
|
case APPCOMMAND_BASS_BOOST : return "bass-boost";
|
||||||
|
case APPCOMMAND_BASS_UP : return "bass-up";
|
||||||
|
case APPCOMMAND_TREBLE_DOWN : return "treble-down";
|
||||||
|
case APPCOMMAND_TREBLE_UP : return "treble-up";
|
||||||
|
case APPCOMMAND_MICROPHONE_VOLUME_MUTE : return "microphone-volume-mute";
|
||||||
|
case APPCOMMAND_MICROPHONE_VOLUME_DOWN : return "microphone-volume-down";
|
||||||
|
case APPCOMMAND_MICROPHONE_VOLUME_UP : return "microphone-volume-up";
|
||||||
|
case APPCOMMAND_HELP : return "help";
|
||||||
|
case APPCOMMAND_FIND : return "find";
|
||||||
|
case APPCOMMAND_NEW : return "new";
|
||||||
|
case APPCOMMAND_OPEN : return "open";
|
||||||
|
case APPCOMMAND_CLOSE : return "close";
|
||||||
|
case APPCOMMAND_SAVE : return "save";
|
||||||
|
case APPCOMMAND_PRINT : return "print";
|
||||||
|
case APPCOMMAND_UNDO : return "undo";
|
||||||
|
case APPCOMMAND_REDO : return "redo";
|
||||||
|
case APPCOMMAND_COPY : return "copy";
|
||||||
|
case APPCOMMAND_CUT : return "cut";
|
||||||
|
case APPCOMMAND_PASTE : return "paste";
|
||||||
|
case APPCOMMAND_REPLY_TO_MAIL : return "reply-to-mail";
|
||||||
|
case APPCOMMAND_FORWARD_MAIL : return "forward-mail";
|
||||||
|
case APPCOMMAND_SEND_MAIL : return "send-mail";
|
||||||
|
case APPCOMMAND_SPELL_CHECK : return "spell-check";
|
||||||
|
case APPCOMMAND_MIC_ON_OFF_TOGGLE : return "mic-on-off-toggle";
|
||||||
|
case APPCOMMAND_CORRECTION_LIST : return "correction-list";
|
||||||
|
case APPCOMMAND_MEDIA_PLAY : return "media-play";
|
||||||
|
case APPCOMMAND_MEDIA_PAUSE : return "media-pause";
|
||||||
|
case APPCOMMAND_MEDIA_RECORD : return "media-record";
|
||||||
|
case APPCOMMAND_MEDIA_FAST_FORWARD : return "media-fast-forward";
|
||||||
|
case APPCOMMAND_MEDIA_REWIND : return "media-rewind";
|
||||||
|
case APPCOMMAND_MEDIA_CHANNEL_UP : return "media-channel-up";
|
||||||
|
case APPCOMMAND_MEDIA_CHANNEL_DOWN : return "media-channel-down";
|
||||||
|
case APPCOMMAND_DELETE : return "delete";
|
||||||
|
case APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE:
|
||||||
|
return "dictate-or-command-control-toggle";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
|
||||||
|
std::string command = AppCommandToString(command_id);
|
||||||
|
NotifyWindowExecuteWindowsCommand(command);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeWindowViews::PreHandleMSG(
|
||||||
|
UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) {
|
||||||
|
NotifyWindowMessage(message, w_param, l_param);
|
||||||
|
|
||||||
|
switch (message) {
|
||||||
|
// Screen readers send WM_GETOBJECT in order to get the accessibility
|
||||||
|
// object, so take this opportunity to push Chromium into accessible
|
||||||
|
// mode if it isn't already, always say we didn't handle the message
|
||||||
|
// because we still want Chromium to handle returning the actual
|
||||||
|
// accessibility object.
|
||||||
|
case WM_GETOBJECT: {
|
||||||
|
const DWORD obj_id = static_cast<DWORD>(l_param);
|
||||||
|
if (obj_id == OBJID_CLIENT) {
|
||||||
|
const auto axState = content::BrowserAccessibilityState::GetInstance();
|
||||||
|
if (axState && !axState->IsAccessibleBrowser())
|
||||||
|
axState->OnScreenReaderDetected();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case WM_COMMAND:
|
||||||
|
// Handle thumbar button click message.
|
||||||
|
if (HIWORD(w_param) == THBN_CLICKED)
|
||||||
|
return taskbar_host_.HandleThumbarButtonEvent(LOWORD(w_param));
|
||||||
|
return false;
|
||||||
|
case WM_SIZE:
|
||||||
|
// Handle window state change.
|
||||||
|
HandleSizeEvent(w_param, l_param);
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
|
||||||
|
// Here we handle the WM_SIZE event in order to figure out what is the current
|
||||||
|
// window state and notify the user accordingly.
|
||||||
|
switch (w_param) {
|
||||||
|
case SIZE_MAXIMIZED:
|
||||||
|
last_window_state_ = ui::SHOW_STATE_MAXIMIZED;
|
||||||
|
NotifyWindowMaximize();
|
||||||
|
break;
|
||||||
|
case SIZE_MINIMIZED:
|
||||||
|
last_window_state_ = ui::SHOW_STATE_MINIMIZED;
|
||||||
|
NotifyWindowMinimize();
|
||||||
|
break;
|
||||||
|
case SIZE_RESTORED:
|
||||||
|
if (last_window_state_ == ui::SHOW_STATE_NORMAL) {
|
||||||
|
// Window was resized so we save it's new size.
|
||||||
|
last_normal_size_ = GetSize();
|
||||||
|
} else {
|
||||||
|
switch (last_window_state_) {
|
||||||
|
case ui::SHOW_STATE_MAXIMIZED:
|
||||||
|
last_window_state_ = ui::SHOW_STATE_NORMAL;
|
||||||
|
|
||||||
|
// When the window is restored we resize it to the previous known
|
||||||
|
// normal size.
|
||||||
|
NativeWindow::SetSize(last_normal_size_);
|
||||||
|
|
||||||
|
NotifyWindowUnmaximize();
|
||||||
|
break;
|
||||||
|
case ui::SHOW_STATE_MINIMIZED:
|
||||||
|
if (IsFullscreen()) {
|
||||||
|
last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
|
||||||
|
NotifyWindowEnterFullScreen();
|
||||||
|
} else {
|
||||||
|
last_window_state_ = ui::SHOW_STATE_NORMAL;
|
||||||
|
|
||||||
|
// When the window is restored we resize it to the previous known
|
||||||
|
// normal size.
|
||||||
|
NativeWindow::SetSize(last_normal_size_);
|
||||||
|
|
||||||
|
NotifyWindowRestore();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace atom
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
#include "atom/common/native_mate_converters/callback.h"
|
#include "atom/common/native_mate_converters/callback.h"
|
||||||
#include "atom/common/native_mate_converters/v8_value_converter.h"
|
#include "atom/common/native_mate_converters/v8_value_converter.h"
|
||||||
#include "native_mate/function_template.h"
|
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
@ -16,34 +15,14 @@ namespace internal {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct CallbackHolder {
|
|
||||||
ResponseCallback callback;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Cached JavaScript version of |HandlerCallback|.
|
|
||||||
v8::Persistent<v8::FunctionTemplate> g_handler_callback_;
|
|
||||||
|
|
||||||
// The callback which is passed to |handler|.
|
// The callback which is passed to |handler|.
|
||||||
void HandlerCallback(v8::Isolate* isolate,
|
void HandlerCallback(const ResponseCallback& callback, mate::Arguments* args) {
|
||||||
v8::Local<v8::External> external,
|
|
||||||
v8::Local<v8::Object> state,
|
|
||||||
mate::Arguments* args) {
|
|
||||||
// Check if the callback has already been called.
|
|
||||||
v8::Local<v8::String> called_symbol = mate::StringToSymbol(isolate, "called");
|
|
||||||
if (state->Has(called_symbol))
|
|
||||||
return; // no nothing
|
|
||||||
else
|
|
||||||
state->Set(called_symbol, v8::Boolean::New(isolate, true));
|
|
||||||
|
|
||||||
// If there is no argument passed then we failed.
|
// If there is no argument passed then we failed.
|
||||||
scoped_ptr<CallbackHolder> holder(
|
|
||||||
static_cast<CallbackHolder*>(external->Value()));
|
|
||||||
CHECK(holder);
|
|
||||||
v8::Local<v8::Value> value;
|
v8::Local<v8::Value> value;
|
||||||
if (!args->GetNext(&value)) {
|
if (!args->GetNext(&value)) {
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
content::BrowserThread::IO, FROM_HERE,
|
content::BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(holder->callback, false, nullptr));
|
base::Bind(callback, false, nullptr));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,42 +32,7 @@ void HandlerCallback(v8::Isolate* isolate,
|
||||||
scoped_ptr<base::Value> options(converter.FromV8Value(value, context));
|
scoped_ptr<base::Value> options(converter.FromV8Value(value, context));
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
content::BrowserThread::IO, FROM_HERE,
|
content::BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(holder->callback, true, base::Passed(&options)));
|
base::Bind(callback, true, base::Passed(&options)));
|
||||||
}
|
|
||||||
|
|
||||||
// func.bind(func, arg1, arg2).
|
|
||||||
// NB(zcbenz): Using C++11 version crashes VS.
|
|
||||||
v8::Local<v8::Value> BindFunctionWith(v8::Isolate* isolate,
|
|
||||||
v8::Local<v8::Context> context,
|
|
||||||
v8::Local<v8::Function> func,
|
|
||||||
v8::Local<v8::Value> arg1,
|
|
||||||
v8::Local<v8::Value> arg2) {
|
|
||||||
v8::MaybeLocal<v8::Value> bind = func->Get(mate::StringToV8(isolate, "bind"));
|
|
||||||
CHECK(!bind.IsEmpty());
|
|
||||||
v8::Local<v8::Function> bind_func =
|
|
||||||
v8::Local<v8::Function>::Cast(bind.ToLocalChecked());
|
|
||||||
v8::Local<v8::Value> converted[] = { func, arg1, arg2 };
|
|
||||||
return bind_func->Call(
|
|
||||||
context, func, arraysize(converted), converted).ToLocalChecked();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate the callback that will be passed to |handler|.
|
|
||||||
v8::MaybeLocal<v8::Value> GenerateCallback(v8::Isolate* isolate,
|
|
||||||
v8::Local<v8::Context> context,
|
|
||||||
const ResponseCallback& callback) {
|
|
||||||
// The FunctionTemplate is cached.
|
|
||||||
if (g_handler_callback_.IsEmpty())
|
|
||||||
g_handler_callback_.Reset(
|
|
||||||
isolate,
|
|
||||||
mate::CreateFunctionTemplate(isolate, base::Bind(&HandlerCallback)));
|
|
||||||
|
|
||||||
v8::Local<v8::FunctionTemplate> handler_callback =
|
|
||||||
v8::Local<v8::FunctionTemplate>::New(isolate, g_handler_callback_);
|
|
||||||
CallbackHolder* holder = new CallbackHolder;
|
|
||||||
holder->callback = callback;
|
|
||||||
return BindFunctionWith(isolate, context, handler_callback->GetFunction(),
|
|
||||||
v8::External::New(isolate, holder),
|
|
||||||
v8::Object::New(isolate));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -102,16 +46,9 @@ void AskForOptions(v8::Isolate* isolate,
|
||||||
v8::HandleScope handle_scope(isolate);
|
v8::HandleScope handle_scope(isolate);
|
||||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||||
v8::Context::Scope context_scope(context);
|
v8::Context::Scope context_scope(context);
|
||||||
// We don't convert the callback to C++ directly because creating
|
handler.Run(request,
|
||||||
// FunctionTemplate will cause memory leak since V8 never releases it. So we
|
mate::ConvertToV8(isolate,
|
||||||
// have to create the function object in JavaScript to work around it.
|
base::Bind(&HandlerCallback, callback)));
|
||||||
v8::MaybeLocal<v8::Value> wrapped_callback = GenerateCallback(
|
|
||||||
isolate, context, callback);
|
|
||||||
if (wrapped_callback.IsEmpty()) {
|
|
||||||
callback.Run(false, nullptr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
handler.Run(request, wrapped_callback.ToLocalChecked());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsErrorOptions(base::Value* value, int* error) {
|
bool IsErrorOptions(base::Value* value, int* error) {
|
||||||
|
|
|
@ -35,17 +35,14 @@ NodeDebugger::NodeDebugger(v8::Isolate* isolate)
|
||||||
weak_factory_(this) {
|
weak_factory_(this) {
|
||||||
bool use_debug_agent = false;
|
bool use_debug_agent = false;
|
||||||
int port = 5858;
|
int port = 5858;
|
||||||
bool wait_for_connection = false;
|
|
||||||
|
|
||||||
std::string port_str;
|
std::string port_str;
|
||||||
base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
|
base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
|
||||||
if (cmd->HasSwitch("debug")) {
|
if (cmd->HasSwitch("debug")) {
|
||||||
use_debug_agent = true;
|
use_debug_agent = true;
|
||||||
port_str = cmd->GetSwitchValueASCII("debug");
|
port_str = cmd->GetSwitchValueASCII("debug");
|
||||||
}
|
} else if (cmd->HasSwitch("debug-brk")) {
|
||||||
if (cmd->HasSwitch("debug-brk")) {
|
|
||||||
use_debug_agent = true;
|
use_debug_agent = true;
|
||||||
wait_for_connection = true;
|
|
||||||
port_str = cmd->GetSwitchValueASCII("debug-brk");
|
port_str = cmd->GetSwitchValueASCII("debug-brk");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,9 +53,6 @@ NodeDebugger::NodeDebugger(v8::Isolate* isolate)
|
||||||
isolate_->SetData(kIsolateSlot, this);
|
isolate_->SetData(kIsolateSlot, this);
|
||||||
v8::Debug::SetMessageHandler(DebugMessageHandler);
|
v8::Debug::SetMessageHandler(DebugMessageHandler);
|
||||||
|
|
||||||
if (wait_for_connection)
|
|
||||||
v8::Debug::DebugBreak(isolate_);
|
|
||||||
|
|
||||||
uv_async_init(uv_default_loop(), &weak_up_ui_handle_, ProcessMessageInUI);
|
uv_async_init(uv_default_loop(), &weak_up_ui_handle_, ProcessMessageInUI);
|
||||||
|
|
||||||
// Start a new IO thread.
|
// Start a new IO thread.
|
||||||
|
|
|
@ -17,7 +17,11 @@
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>atom.icns</string>
|
<string>atom.icns</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>0.33.6</string>
|
<string>0.34.3</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>0.34.3</string>
|
||||||
|
<key>LSApplicationCategoryType</key>
|
||||||
|
<string>public.app-category.developer-tools</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
<string>10.8.0</string>
|
<string>10.8.0</string>
|
||||||
<key>NSMainNibFile</key>
|
<key>NSMainNibFile</key>
|
||||||
|
|
|
@ -56,8 +56,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 0,33,6,0
|
FILEVERSION 0,34,3,0
|
||||||
PRODUCTVERSION 0,33,6,0
|
PRODUCTVERSION 0,34,3,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -74,12 +74,12 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "GitHub, Inc."
|
VALUE "CompanyName", "GitHub, Inc."
|
||||||
VALUE "FileDescription", "Electron"
|
VALUE "FileDescription", "Electron"
|
||||||
VALUE "FileVersion", "0.33.6"
|
VALUE "FileVersion", "0.34.3"
|
||||||
VALUE "InternalName", "electron.exe"
|
VALUE "InternalName", "electron.exe"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||||
VALUE "OriginalFilename", "electron.exe"
|
VALUE "OriginalFilename", "electron.exe"
|
||||||
VALUE "ProductName", "Electron"
|
VALUE "ProductName", "Electron"
|
||||||
VALUE "ProductVersion", "0.33.6"
|
VALUE "ProductVersion", "0.34.3"
|
||||||
VALUE "SquirrelAwareVersion", "1"
|
VALUE "SquirrelAwareVersion", "1"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
|
@ -79,8 +79,25 @@ class FileDialog {
|
||||||
if (!title.empty())
|
if (!title.empty())
|
||||||
GetPtr()->SetTitle(base::UTF8ToUTF16(title).c_str());
|
GetPtr()->SetTitle(base::UTF8ToUTF16(title).c_str());
|
||||||
|
|
||||||
if (!filterspec.empty())
|
// By default, *.* will be added to the file name if file type is "*.*". In
|
||||||
GetPtr()->SetDefaultExtension(filterspec.front().pszSpec);
|
// Electron, we disable it to make a better experience.
|
||||||
|
//
|
||||||
|
// From MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/
|
||||||
|
// bb775970(v=vs.85).aspx
|
||||||
|
//
|
||||||
|
// If SetDefaultExtension is not called, the dialog will not update
|
||||||
|
// automatically when user choose a new file type in the file dialog.
|
||||||
|
//
|
||||||
|
// We set file extension to the first none-wildcard extension to make
|
||||||
|
// sure the dialog will update file extension automatically.
|
||||||
|
for (size_t i = 0; i < filterspec.size(); ++i) {
|
||||||
|
if (std::wstring(filterspec[i].pszSpec) != L"*.*") {
|
||||||
|
// SetFileTypeIndex is regarded as one-based index.
|
||||||
|
GetPtr()->SetFileTypeIndex(i+1);
|
||||||
|
GetPtr()->SetDefaultExtension(filterspec[i].pszSpec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SetDefaultFolder(default_path);
|
SetDefaultFolder(default_path);
|
||||||
}
|
}
|
||||||
|
@ -255,7 +272,8 @@ bool ShowSaveDialog(atom::NativeWindow* parent_window,
|
||||||
|
|
||||||
bool matched = false;
|
bool matched = false;
|
||||||
for (size_t i = 0; i < filter.second.size(); ++i) {
|
for (size_t i = 0; i < filter.second.size(); ++i) {
|
||||||
if (base::EndsWith(file_name, filter.second[i], false)) {
|
if (filter.second[i] == "*" ||
|
||||||
|
base::EndsWith(file_name, filter.second[i], false)) {
|
||||||
matched = true;
|
matched = true;
|
||||||
break;;
|
break;;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,8 +55,24 @@ void TrayIcon::NotifyRightClicked(const gfx::Rect& bounds, int modifiers) {
|
||||||
OnRightClicked(bounds, modifiers));
|
OnRightClicked(bounds, modifiers));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrayIcon::NotfiyDropFiles(const std::vector<std::string>& files) {
|
void TrayIcon::NotifyDrop() {
|
||||||
|
FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDrop());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrayIcon::NotifyDropFiles(const std::vector<std::string>& files) {
|
||||||
FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDropFiles(files));
|
FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDropFiles(files));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TrayIcon::NotifyDragEntered() {
|
||||||
|
FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDragEntered());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrayIcon::NotifyDragExited() {
|
||||||
|
FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDragExited());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrayIcon::NotifyDragEnded() {
|
||||||
|
FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnDragEnded());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|
|
@ -61,7 +61,11 @@ class TrayIcon {
|
||||||
void NotifyBalloonClosed();
|
void NotifyBalloonClosed();
|
||||||
void NotifyRightClicked(const gfx::Rect& bounds = gfx::Rect(),
|
void NotifyRightClicked(const gfx::Rect& bounds = gfx::Rect(),
|
||||||
int modifiers = 0);
|
int modifiers = 0);
|
||||||
void NotfiyDropFiles(const std::vector<std::string>& files);
|
void NotifyDrop();
|
||||||
|
void NotifyDropFiles(const std::vector<std::string>& files);
|
||||||
|
void NotifyDragEntered();
|
||||||
|
void NotifyDragExited();
|
||||||
|
void NotifyDragEnded();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TrayIcon();
|
TrayIcon();
|
||||||
|
|
|
@ -254,9 +254,23 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender {
|
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender {
|
||||||
|
trayIcon_->NotifyDragEntered();
|
||||||
return NSDragOperationCopy;
|
return NSDragOperationCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)draggingExited:(id <NSDraggingInfo>)sender {
|
||||||
|
trayIcon_->NotifyDragExited();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)draggingEnded:(id <NSDraggingInfo>)sender {
|
||||||
|
trayIcon_->NotifyDragEnded();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender {
|
||||||
|
trayIcon_->NotifyDrop();
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
|
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
|
||||||
NSPasteboard* pboard = [sender draggingPasteboard];
|
NSPasteboard* pboard = [sender draggingPasteboard];
|
||||||
|
|
||||||
|
@ -265,7 +279,7 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||||
NSArray* files = [pboard propertyListForType:NSFilenamesPboardType];
|
NSArray* files = [pboard propertyListForType:NSFilenamesPboardType];
|
||||||
for (NSString* file in files)
|
for (NSString* file in files)
|
||||||
dropFiles.push_back(base::SysNSStringToUTF8(file));
|
dropFiles.push_back(base::SysNSStringToUTF8(file));
|
||||||
trayIcon_->NotfiyDropFiles(dropFiles);
|
trayIcon_->NotifyDropFiles(dropFiles);
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
return NO;
|
return NO;
|
||||||
|
|
|
@ -22,7 +22,11 @@ class TrayIconObserver {
|
||||||
virtual void OnBalloonClicked() {}
|
virtual void OnBalloonClicked() {}
|
||||||
virtual void OnBalloonClosed() {}
|
virtual void OnBalloonClosed() {}
|
||||||
virtual void OnRightClicked(const gfx::Rect& bounds, int modifiers) {}
|
virtual void OnRightClicked(const gfx::Rect& bounds, int modifiers) {}
|
||||||
|
virtual void OnDrop() {}
|
||||||
virtual void OnDropFiles(const std::vector<std::string>& files) {}
|
virtual void OnDropFiles(const std::vector<std::string>& files) {}
|
||||||
|
virtual void OnDragEntered() {}
|
||||||
|
virtual void OnDragExited() {}
|
||||||
|
virtual void OnDragEnded() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~TrayIconObserver() {}
|
virtual ~TrayIconObserver() {}
|
||||||
|
|
|
@ -104,11 +104,11 @@ gfx::Size FramelessView::GetPreferredSize() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::Size FramelessView::GetMinimumSize() const {
|
gfx::Size FramelessView::GetMinimumSize() const {
|
||||||
return window_->GetMinimumSize();
|
return window_->GetContentSizeConstraints().GetMinimumSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::Size FramelessView::GetMaximumSize() const {
|
gfx::Size FramelessView::GetMaximumSize() const {
|
||||||
return window_->GetMaximumSize();
|
return window_->GetContentSizeConstraints().GetMaximumSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* FramelessView::GetClassName() const {
|
const char* FramelessView::GetClassName() const {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue